Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/generic_args.rs')
| -rw-r--r-- | crates/parser/src/grammar/generic_args.rs | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs index 919d9b91eb..e589b69934 100644 --- a/crates/parser/src/grammar/generic_args.rs +++ b/crates/parser/src/grammar/generic_args.rs @@ -28,6 +28,7 @@ const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[ BYTE, STRING, BYTE_STRING, + C_STRING, ]) .union(types::TYPE_FIRST); @@ -35,7 +36,7 @@ const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[ // type T = S<i32>; fn generic_arg(p: &mut Parser<'_>) -> bool { match p.current() { - LIFETIME_IDENT => lifetime_arg(p), + LIFETIME_IDENT if !p.nth_at(1, T![+]) => lifetime_arg(p), T!['{'] | T![true] | T![false] | T![-] => const_arg(p), k if k.is_literal() => const_arg(p), // test associated_type_bounds @@ -76,6 +77,29 @@ fn generic_arg(p: &mut Parser<'_>) -> bool { } } } + IDENT if p.nth_at(1, T!['(']) => { + let m = p.start(); + name_ref(p); + params::param_list_fn_trait(p); + if p.at(T![:]) && !p.at(T![::]) { + // test associated_return_type_bounds + // fn foo<T: Foo<foo(): Send, bar(i32): Send, baz(i32, i32): Send>>() {} + generic_params::bounds(p); + m.complete(p, ASSOC_TYPE_ARG); + } else { + // test bare_dyn_types_with_paren_as_generic_args + // type A = S<Fn(i32)>; + // type A = S<Fn(i32) + Send>; + // type B = S<Fn(i32) -> i32>; + // type C = S<Fn(i32) -> i32 + Send>; + opt_ret_type(p); + let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH); + let m = paths::type_path_for_qualifier(p, m); + let m = m.precede(p).complete(p, PATH_TYPE); + let m = types::opt_type_bounds_as_dyn_trait_type(p, m); + m.precede(p).complete(p, TYPE_ARG); + } + } _ if p.at_ts(types::TYPE_FIRST) => type_arg(p), _ => return false, } |