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 | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs index 4cac04a32a..b7d72b8d33 100644 --- a/crates/parser/src/grammar/generic_args.rs +++ b/crates/parser/src/grammar/generic_args.rs @@ -76,7 +76,29 @@ fn generic_arg(p: &mut Parser<'_>) -> bool { } } } - IDENT if p.nth(1) == T!['('] && p.nth_at(2, T![..]) => return_type_arg(p), + 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, } @@ -140,20 +162,3 @@ fn type_arg(p: &mut Parser<'_>) { types::type_(p); m.complete(p, TYPE_ARG); } - -// test return_type_arg -// type T = S<foo(..): Send>; -pub(super) fn return_type_arg(p: &mut Parser<'_>) { - let m = p.start(); - p.expect(IDENT); - p.expect(T!['(']); - p.expect(T![..]); - p.expect(T![')']); - if !p.at(T![:]) { - p.error("expected :"); - m.abandon(p); - return; - } - generic_params::bounds(p); - m.complete(p, RETURN_TYPE_ARG); -} |