Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-def/src/path/lower.rs8
-rw-r--r--crates/ide-db/src/path_transform.rs3
-rw-r--r--crates/ide-ssr/src/matching.rs4
-rw-r--r--crates/ide/src/inlay_hints/lifetime.rs94
-rw-r--r--crates/parser/src/grammar/expressions.rs2
-rw-r--r--crates/parser/src/grammar/generic_args.rs65
-rw-r--r--crates/parser/src/grammar/params.rs18
-rw-r--r--crates/parser/src/grammar/paths.rs100
-rw-r--r--crates/parser/src/grammar/types.rs4
-rw-r--r--crates/parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/parser/test_data/generated/runner.rs32
-rw-r--r--crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast33
-rw-r--r--crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs1
-rw-r--r--crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rast79
-rw-r--r--crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rs2
-rw-r--r--crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast39
-rw-r--r--crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast111
-rw-r--r--crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/async_trait_bound.rast4
-rw-r--r--crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast175
-rw-r--r--crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs4
-rw-r--r--crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rast461
-rw-r--r--crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rs4
-rw-r--r--crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast48
-rw-r--r--crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast128
-rw-r--r--crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs3
-rw-r--r--crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rast49
-rw-r--r--crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rast43
-rw-r--r--crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rs2
-rw-r--r--crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast10
-rw-r--r--crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast60
-rw-r--r--crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs1
-rw-r--r--crates/parser/test_data/parser/inline/ok/where_pred_for.rast4
-rw-r--r--crates/parser/test_data/parser/ok/0045_block_attrs.rast2
-rw-r--r--crates/parser/test_data/parser/ok/0051_parameter_attrs.rast57
-rw-r--r--crates/parser/test_data/parser/ok/0051_parameter_attrs.rs2
-rw-r--r--crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast8
-rw-r--r--crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast2
-rw-r--r--crates/parser/test_data/parser/ok/0067_where_for_pred.rast8
-rw-r--r--crates/syntax/rust.ungram5
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs38
44 files changed, 1020 insertions, 698 deletions
diff --git a/crates/hir-def/src/path/lower.rs b/crates/hir-def/src/path/lower.rs
index 553e615b94..37c94a5f11 100644
--- a/crates/hir-def/src/path/lower.rs
+++ b/crates/hir-def/src/path/lower.rs
@@ -48,7 +48,7 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<
.or_else(|| {
lower_generic_args_from_fn_path(
ctx,
- segment.param_list(),
+ segment.parenthesized_arg_list(),
segment.ret_type(),
)
});
@@ -247,12 +247,12 @@ pub(super) fn lower_generic_args(
/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
fn lower_generic_args_from_fn_path(
ctx: &mut LowerCtx<'_>,
- params: Option<ast::ParamList>,
+ args: Option<ast::ParenthesizedArgList>,
ret_type: Option<ast::RetType>,
) -> Option<GenericArgs> {
- let params = params?;
+ let params = args?;
let mut param_types = Vec::new();
- for param in params.params() {
+ for param in params.type_args() {
let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
param_types.push(type_ref);
}
diff --git a/crates/ide-db/src/path_transform.rs b/crates/ide-db/src/path_transform.rs
index 49b3ca290f..a508f2fedd 100644
--- a/crates/ide-db/src/path_transform.rs
+++ b/crates/ide-db/src/path_transform.rs
@@ -286,7 +286,8 @@ impl Ctx<'_> {
return None;
}
if path.segment().map_or(false, |s| {
- s.param_list().is_some() || (s.self_token().is_some() && path.parent_path().is_none())
+ s.parenthesized_arg_list().is_some()
+ || (s.self_token().is_some() && path.parent_path().is_none())
}) {
// don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
// don't try to qualify sole `self` either, they are usually locals, but are returned as modules due to namespace clashing
diff --git a/crates/ide-ssr/src/matching.rs b/crates/ide-ssr/src/matching.rs
index 6569f0f555..4edc3633fb 100644
--- a/crates/ide-ssr/src/matching.rs
+++ b/crates/ide-ssr/src/matching.rs
@@ -359,8 +359,8 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
)?;
self.attempt_match_opt(
phase,
- pattern_segment.param_list(),
- code_segment.param_list(),
+ pattern_segment.parenthesized_arg_list(),
+ code_segment.parenthesized_arg_list(),
)?;
}
if matches!(phase, Phase::Second(_)) {
diff --git a/crates/ide/src/inlay_hints/lifetime.rs b/crates/ide/src/inlay_hints/lifetime.rs
index 2163c959b1..1fdd698991 100644
--- a/crates/ide/src/inlay_hints/lifetime.rs
+++ b/crates/ide/src/inlay_hints/lifetime.rs
@@ -41,7 +41,15 @@ pub(super) fn fn_hints(
fd,
config,
file_id,
- param_list,
+ param_list.params().filter_map(|it| {
+ Some((
+ it.pat().and_then(|it| match it {
+ ast::Pat::IdentPat(p) => p.name(),
+ _ => None,
+ }),
+ it.ty()?,
+ ))
+ }),
generic_param_list,
ret_type,
self_param,
@@ -90,7 +98,15 @@ pub(super) fn fn_ptr_hints(
fd,
config,
file_id,
- param_list,
+ param_list.params().filter_map(|it| {
+ Some((
+ it.pat().and_then(|it| match it {
+ ast::Pat::IdentPat(p) => p.name(),
+ _ => None,
+ }),
+ it.ty()?,
+ ))
+ }),
generic_param_list,
ret_type,
None,
@@ -148,7 +164,7 @@ pub(super) fn fn_path_hints(
fd,
config,
file_id,
- param_list,
+ param_list.type_args().filter_map(|it| Some((None, it.ty()?))),
generic_param_list,
ret_type,
None,
@@ -177,8 +193,8 @@ pub(super) fn fn_path_hints(
)
}
-fn path_as_fn(path: &ast::Path) -> Option<(ast::ParamList, Option<ast::RetType>)> {
- path.segment().and_then(|it| it.param_list().zip(Some(it.ret_type())))
+fn path_as_fn(path: &ast::Path) -> Option<(ast::ParenthesizedArgList, Option<ast::RetType>)> {
+ path.segment().and_then(|it| it.parenthesized_arg_list().zip(Some(it.ret_type())))
}
fn hints_(
@@ -187,7 +203,7 @@ fn hints_(
FamousDefs(_, _): &FamousDefs<'_, '_>,
config: &InlayHintsConfig,
_file_id: EditionedFileId,
- param_list: ast::ParamList,
+ params: impl Iterator<Item = (Option<ast::Name>, ast::Type)>,
generic_param_list: Option<ast::GenericParamList>,
ret_type: Option<ast::RetType>,
self_param: Option<ast::SelfParam>,
@@ -217,45 +233,34 @@ fn hints_(
let is_elided = is_elided(&lifetime);
acc.push((None, self_param.amp_token(), lifetime, is_elided));
}
- param_list
- .params()
- .filter_map(|it| {
- Some((
- it.pat().and_then(|it| match it {
- ast::Pat::IdentPat(p) => p.name(),
- _ => None,
- }),
- it.ty()?,
- ))
- })
- .for_each(|(name, ty)| {
- // FIXME: check path types
- walk_ty(&ty, &mut |ty| match ty {
- ast::Type::RefType(r) => {
- let lifetime = r.lifetime();
- let is_elided = is_elided(&lifetime);
- acc.push((name.clone(), r.amp_token(), lifetime, is_elided));
- false
- }
- ast::Type::FnPtrType(_) => {
+ params.for_each(|(name, ty)| {
+ // FIXME: check path types
+ walk_ty(&ty, &mut |ty| match ty {
+ ast::Type::RefType(r) => {
+ let lifetime = r.lifetime();
+ let is_elided = is_elided(&lifetime);
+ acc.push((name.clone(), r.amp_token(), lifetime, is_elided));
+ false
+ }
+ ast::Type::FnPtrType(_) => {
+ is_trivial = false;
+ true
+ }
+ ast::Type::PathType(t) => {
+ if t.path()
+ .and_then(|it| it.segment())
+ .and_then(|it| it.parenthesized_arg_list())
+ .is_some()
+ {
is_trivial = false;
true
+ } else {
+ false
}
- ast::Type::PathType(t) => {
- if t.path()
- .and_then(|it| it.segment())
- .and_then(|it| it.param_list())
- .is_some()
- {
- is_trivial = false;
- true
- } else {
- false
- }
- }
- _ => false,
- })
- });
+ }
+ _ => false,
+ })
+ });
acc
};
@@ -339,7 +344,10 @@ fn hints_(
true
}
ast::Type::PathType(t) => {
- if t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
+ if t.path()
+ .and_then(|it| it.segment())
+ .and_then(|it| it.parenthesized_arg_list())
+ .is_some()
{
is_trivial = false;
true
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs
index e565874a42..349bce0939 100644
--- a/crates/parser/src/grammar/expressions.rs
+++ b/crates/parser/src/grammar/expressions.rs
@@ -525,7 +525,7 @@ fn method_call_expr<const FLOAT_RECOVERY: bool>(
p.bump(T![.]);
}
name_ref(p);
- generic_args::opt_generic_arg_list(p, true);
+ generic_args::opt_generic_arg_list_expr(p);
if p.at(T!['(']) {
arg_list(p);
} else {
diff --git a/crates/parser/src/grammar/generic_args.rs b/crates/parser/src/grammar/generic_args.rs
index 77379ef147..737010985b 100644
--- a/crates/parser/src/grammar/generic_args.rs
+++ b/crates/parser/src/grammar/generic_args.rs
@@ -1,14 +1,13 @@
use super::*;
-// test_err generic_arg_list_recover
-// type T = T<0, ,T>;
-pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: bool) {
+// test_err generic_arg_list_recover_expr
+// const _: () = T::<0, ,T>;
+// const _: () = T::<0, ,T>();
+pub(super) fn opt_generic_arg_list_expr(p: &mut Parser<'_>) {
let m;
if p.at(T![::]) && p.nth(2) == T![<] {
m = p.start();
p.bump(T![::]);
- } else if !colon_colon_required && p.at(T![<]) && p.nth(1) != T![=] {
- m = p.start();
} else {
return;
}
@@ -25,7 +24,7 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: boo
m.complete(p, GENERIC_ARG_LIST);
}
-const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
+pub(crate) const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
LIFETIME_IDENT,
IDENT,
T!['{'],
@@ -47,20 +46,23 @@ const GENERIC_ARG_RECOVERY_SET: TokenSet = TokenSet::new(&[T![>], T![,]]);
// test generic_arg
// type T = S<i32>;
-fn generic_arg(p: &mut Parser<'_>) -> bool {
+pub(crate) fn generic_arg(p: &mut Parser<'_>) -> bool {
match p.current() {
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
- // fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
+ // test generic_arg_bounds
+ // type Plain = Foo<Item, Item::Item, Item: Bound, Item = Item>;
+ // type GenericArgs = Foo<Item<T>, Item::<T>, Item<T>: Bound, Item::<T>: Bound, Item<T> = Item, Item::<T> = Item>;
+ // type ParenthesizedArgs = Foo<Item(T), Item::(T), Item(T): Bound, Item::(T): Bound, Item(T) = Item, Item::(T) = Item>;
+ // type RTN = Foo<Item(..), Item(..), Item(..): Bound, Item(..): Bound, Item(..) = Item, Item(..) = Item>;
// test macro_inside_generic_arg
// type A = Foo<syn::Token![_]>;
- IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) && !p.nth_at(1, T![::]) => {
+ IDENT => {
let m = p.start();
name_ref(p);
- opt_generic_arg_list(p, false);
+ paths::opt_path_type_args(p);
match p.current() {
T![=] => {
p.bump_any();
@@ -88,45 +90,26 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
}
// test assoc_type_bound
// type T = StreamingIterator<Item<'a>: Clone>;
+ // type T = StreamingIterator<Item(T): Clone>;
T![:] if !p.at(T![::]) => {
generic_params::bounds(p);
m.complete(p, ASSOC_TYPE_ARG);
}
+ // Turned out to be just a normal path type (mirror `path_or_macro_type`)
_ => {
let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH);
let m = paths::type_path_for_qualifier(p, m);
- m.precede(p).complete(p, PATH_TYPE).precede(p).complete(p, TYPE_ARG);
+ let m = if p.at(T![!]) && !p.at(T![!=]) {
+ let m = m.precede(p);
+ items::macro_call_after_excl(p);
+ m.complete(p, MACRO_CALL).precede(p).complete(p, MACRO_TYPE)
+ } else {
+ m.precede(p).complete(p, PATH_TYPE)
+ };
+ types::opt_type_bounds_as_dyn_trait_type(p, m).precede(p).complete(p, TYPE_ARG);
}
}
}
- IDENT if p.nth_at(1, T!['(']) => {
- let m = p.start();
- name_ref(p);
- if p.nth_at(1, T![..]) {
- let rtn = p.start();
- p.bump(T!['(']);
- p.bump(T![..]);
- p.expect(T![')']);
- rtn.complete(p, RETURN_TYPE_SYNTAX);
- // test return_type_syntax_assoc_type_bound
- // fn foo<T: Trait<method(..): Send>>() {}
- generic_params::bounds(p);
- m.complete(p, ASSOC_TYPE_ARG);
- } else {
- params::param_list_fn_trait(p);
- // 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,
}
@@ -190,7 +173,7 @@ pub(super) fn const_arg(p: &mut Parser<'_>) {
m.complete(p, CONST_ARG);
}
-fn type_arg(p: &mut Parser<'_>) {
+pub(crate) fn type_arg(p: &mut Parser<'_>) {
let m = p.start();
types::type_(p);
m.complete(p, TYPE_ARG);
diff --git a/crates/parser/src/grammar/params.rs b/crates/parser/src/grammar/params.rs
index c535267c16..51ffcd0706 100644
--- a/crates/parser/src/grammar/params.rs
+++ b/crates/parser/src/grammar/params.rs
@@ -14,12 +14,6 @@ pub(super) fn param_list_fn_def(p: &mut Parser<'_>) {
list_(p, Flavor::FnDef);
}
-// test param_list_opt_patterns
-// fn foo<F: FnMut(&mut Foo<'a>)>(){}
-pub(super) fn param_list_fn_trait(p: &mut Parser<'_>) {
- list_(p, Flavor::FnTrait);
-}
-
pub(super) fn param_list_fn_ptr(p: &mut Parser<'_>) {
list_(p, Flavor::FnPointer);
}
@@ -28,10 +22,9 @@ pub(super) fn param_list_closure(p: &mut Parser<'_>) {
list_(p, Flavor::Closure);
}
-#[derive(Debug, Clone, Copy)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Flavor {
- FnDef, // Includes trait fn params; omitted param idents are not supported
- FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
+ FnDef, // Includes trait fn params; omitted param idents are not supported
FnPointer,
Closure,
}
@@ -41,7 +34,7 @@ fn list_(p: &mut Parser<'_>, flavor: Flavor) {
let (bra, ket) = match flavor {
Closure => (T![|], T![|]),
- FnDef | FnTrait | FnPointer => (T!['('], T![')']),
+ FnDef | FnPointer => (T!['('], T![')']),
};
let list_marker = p.start();
@@ -119,11 +112,6 @@ fn param(p: &mut Parser<'_>, m: Marker, flavor: Flavor) {
}
}
}
- // test value_parameters_no_patterns
- // type F = Box<Fn(i32, &i32, &i32, ())>;
- Flavor::FnTrait => {
- types::type_(p);
- }
// test fn_pointer_param_ident_path
// type Foo = fn(Bar::Baz);
// type Qux = fn(baz: Bar::Baz);
diff --git a/crates/parser/src/grammar/paths.rs b/crates/parser/src/grammar/paths.rs
index 15b3529642..b3652f7cd3 100644
--- a/crates/parser/src/grammar/paths.rs
+++ b/crates/parser/src/grammar/paths.rs
@@ -110,7 +110,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<Completed
match p.current() {
IDENT => {
name_ref(p);
- opt_path_type_args(p, mode);
+ opt_path_args(p, mode);
}
// test crate_path
// use crate::foo;
@@ -142,38 +142,74 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) -> Option<Completed
Some(m.complete(p, PATH_SEGMENT))
}
-fn opt_path_type_args(p: &mut Parser<'_>, mode: Mode) {
+pub(crate) fn opt_path_type_args(p: &mut Parser<'_>) {
+ // test typepathfn_with_coloncolon
+ // type F = Start::(Middle) -> (Middle)::End;
+ // type GenericArg = S<Start(Middle)::End>;
+ let m;
+ if p.at(T![::]) && matches!(p.nth(2), T![<] | T!['(']) {
+ m = p.start();
+ p.bump(T![::]);
+ } else if (p.current() == T![<] && p.nth(1) != T![=]) || p.current() == T!['('] {
+ m = p.start();
+ } else {
+ return;
+ }
+ let current = p.current();
+ if current == T![<] {
+ // test_err generic_arg_list_recover
+ // type T = T<0, ,T>;
+ // type T = T::<0, ,T>;
+ delimited(
+ p,
+ T![<],
+ T![>],
+ T![,],
+ || "expected generic argument".into(),
+ generic_args::GENERIC_ARG_FIRST,
+ generic_args::generic_arg,
+ );
+ m.complete(p, GENERIC_ARG_LIST);
+ } else if p.nth_at(1, T![..]) {
+ // test return_type_syntax_in_path
+ // fn foo<T>()
+ // where
+ // T::method(..): Send,
+ // method(..): Send,
+ // method::(..): Send,
+ // {}
+ p.bump(T!['(']);
+ p.bump(T![..]);
+ p.expect(T![')']);
+ m.complete(p, RETURN_TYPE_SYNTAX);
+ } else {
+ // test path_fn_trait_args
+ // type F = Box<Fn(i32) -> ()>;
+ // type F = Box<::Fn(i32) -> ()>;
+ // type F = Box<Fn::(i32) -> ()>;
+ // type F = Box<::Fn::(i32) -> ()>;
+ delimited(
+ p,
+ T!['('],
+ T![')'],
+ T![,],
+ || "expected type".into(),
+ types::TYPE_FIRST,
+ |p| {
+ let progress = types::TYPE_FIRST.contains(p.current());
+ generic_args::type_arg(p);
+ progress
+ },
+ );
+ m.complete(p, PARENTHESIZED_ARG_LIST);
+ opt_ret_type(p);
+ }
+}
+
+fn opt_path_args(p: &mut Parser<'_>, mode: Mode) {
match mode {
Mode::Use | Mode::Attr | Mode::Vis => {}
- Mode::Type => {
- // test typepathfn_with_coloncolon
- // type F = Start::(Middle) -> (Middle)::End;
- // type GenericArg = S<Start(Middle)::End>;
- if p.at(T![::]) && p.nth_at(2, T!['(']) {
- p.bump(T![::]);
- }
- if p.at(T!['(']) {
- if p.nth_at(1, T![..]) {
- // test return_type_syntax_in_path
- // fn foo<T>()
- // where
- // T::method(..): Send,
- // {}
- let rtn = p.start();
- p.bump(T!['(']);
- p.bump(T![..]);
- p.expect(T![')']);
- rtn.complete(p, RETURN_TYPE_SYNTAX);
- } else {
- // test path_fn_trait_args
- // type F = Box<Fn(i32) -> ()>;
- params::param_list_fn_trait(p);
- opt_ret_type(p);
- }
- } else {
- generic_args::opt_generic_arg_list(p, false);
- }
- }
- Mode::Expr => generic_args::opt_generic_arg_list(p, true),
+ Mode::Type => opt_path_type_args(p),
+ Mode::Expr => generic_args::opt_generic_arg_list_expr(p),
}
}
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index f4e57d3d6f..35198ccbe3 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -50,7 +50,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
// Some path types are not allowed to have bounds (no plus)
T![<] => path_type_bounds(p, allow_bounds),
T![ident] if !p.edition().at_least_2018() && is_dyn_weak(p) => dyn_trait_type_weak(p),
- _ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
+ _ if paths::is_path_start(p) => path_or_macro_type(p, allow_bounds),
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
_ => {
p.err_recover("expected type", TYPE_RECOVERY_SET);
@@ -337,7 +337,7 @@ pub(super) fn path_type(p: &mut Parser<'_>) {
// test macro_call_type
// type A = foo!();
// type B = crate::foo!();
-fn path_or_macro_type_(p: &mut Parser<'_>, allow_bounds: bool) {
+fn path_or_macro_type(p: &mut Parser<'_>, allow_bounds: bool) {
assert!(paths::is_path_start(p));
let r = p.start();
let m = p.start();
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs
index 21730244a3..0c9c6ffd71 100644
--- a/crates/parser/src/syntax_kind/generated.rs
+++ b/crates/parser/src/syntax_kind/generated.rs
@@ -256,6 +256,7 @@ pub enum SyntaxKind {
OR_PAT,
PARAM,
PARAM_LIST,
+ PARENTHESIZED_ARG_LIST,
PAREN_EXPR,
PAREN_PAT,
PAREN_TYPE,
diff --git a/crates/parser/test_data/generated/runner.rs b/crates/parser/test_data/generated/runner.rs
index 3db8b51a4b..6d114037bf 100644
--- a/crates/parser/test_data/generated/runner.rs
+++ b/crates/parser/test_data/generated/runner.rs
@@ -39,10 +39,6 @@ mod ok {
#[test]
fn assoc_type_eq() { run_and_expect_no_errors("test_data/parser/inline/ok/assoc_type_eq.rs"); }
#[test]
- fn associated_type_bounds() {
- run_and_expect_no_errors("test_data/parser/inline/ok/associated_type_bounds.rs");
- }
- #[test]
fn async_trait_bound() {
run_and_expect_no_errors("test_data/parser/inline/ok/async_trait_bound.rs");
}
@@ -59,12 +55,6 @@ mod ok {
);
}
#[test]
- fn bare_dyn_types_with_paren_as_generic_args() {
- run_and_expect_no_errors(
- "test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs",
- );
- }
- #[test]
fn become_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/become_expr.rs"); }
#[test]
fn bind_pat() { run_and_expect_no_errors("test_data/parser/inline/ok/bind_pat.rs"); }
@@ -281,6 +271,10 @@ mod ok {
#[test]
fn generic_arg() { run_and_expect_no_errors("test_data/parser/inline/ok/generic_arg.rs"); }
#[test]
+ fn generic_arg_bounds() {
+ run_and_expect_no_errors("test_data/parser/inline/ok/generic_arg_bounds.rs");
+ }
+ #[test]
fn generic_param_attribute() {
run_and_expect_no_errors("test_data/parser/inline/ok/generic_param_attribute.rs");
}
@@ -423,10 +417,6 @@ mod ok {
#[test]
fn param_list() { run_and_expect_no_errors("test_data/parser/inline/ok/param_list.rs"); }
#[test]
- fn param_list_opt_patterns() {
- run_and_expect_no_errors("test_data/parser/inline/ok/param_list_opt_patterns.rs");
- }
- #[test]
fn param_list_vararg() {
run_and_expect_no_errors("test_data/parser/inline/ok/param_list_vararg.rs");
}
@@ -521,12 +511,6 @@ mod ok {
#[test]
fn return_expr() { run_and_expect_no_errors("test_data/parser/inline/ok/return_expr.rs"); }
#[test]
- fn return_type_syntax_assoc_type_bound() {
- run_and_expect_no_errors(
- "test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs",
- );
- }
- #[test]
fn return_type_syntax_in_path() {
run_and_expect_no_errors("test_data/parser/inline/ok/return_type_syntax_in_path.rs");
}
@@ -685,10 +669,6 @@ mod ok {
#[test]
fn use_tree_star() { run_and_expect_no_errors("test_data/parser/inline/ok/use_tree_star.rs"); }
#[test]
- fn value_parameters_no_patterns() {
- run_and_expect_no_errors("test_data/parser/inline/ok/value_parameters_no_patterns.rs");
- }
- #[test]
fn variant_discriminant() {
run_and_expect_no_errors("test_data/parser/inline/ok/variant_discriminant.rs");
}
@@ -754,6 +734,10 @@ mod err {
run_and_expect_errors("test_data/parser/inline/err/generic_arg_list_recover.rs");
}
#[test]
+ fn generic_arg_list_recover_expr() {
+ run_and_expect_errors("test_data/parser/inline/err/generic_arg_list_recover_expr.rs");
+ }
+ #[test]
fn generic_param_list_recover() {
run_and_expect_errors("test_data/parser/inline/err/generic_param_list_recover.rs");
}
diff --git a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast
index 4cf5a3386b..16183ce9ef 100644
--- a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast
+++ b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rast
@@ -30,4 +30,37 @@ SOURCE_FILE
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "T"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ CONST_ARG
+ LITERAL
+ INT_NUMBER "0"
+ COMMA ","
+ WHITESPACE " "
+ ERROR
+ COMMA ","
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
error 14: expected generic argument
+error 35: expected generic argument
diff --git a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs
index 7d849aa1be..aa65a0673a 100644
--- a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs
+++ b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover.rs
@@ -1 +1,2 @@
type T = T<0, ,T>;
+type T = T::<0, ,T>;
diff --git a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rast b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rast
new file mode 100644
index 0000000000..de403d3049
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rast
@@ -0,0 +1,79 @@
+SOURCE_FILE
+ CONST
+ CONST_KW "const"
+ WHITESPACE " "
+ UNDERSCORE "_"
+ COLON ":"
+ WHITESPACE " "
+ TUPLE_TYPE
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ CONST_ARG
+ LITERAL
+ INT_NUMBER "0"
+ COMMA ","
+ WHITESPACE " "
+ ERROR
+ COMMA ","
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ CONST
+ CONST_KW "const"
+ WHITESPACE " "
+ UNDERSCORE "_"
+ COLON ":"
+ WHITESPACE " "
+ TUPLE_TYPE
+ L_PAREN "("
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ CALL_EXPR
+ PATH_EXPR
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ CONST_ARG
+ LITERAL
+ INT_NUMBER "0"
+ COMMA ","
+ WHITESPACE " "
+ ERROR
+ COMMA ","
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ ARG_LIST
+ L_PAREN "("
+ R_PAREN ")"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+error 21: expected generic argument
+error 47: expected generic argument
diff --git a/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rs b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rs
new file mode 100644
index 0000000000..74cc63ac4a
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/err/generic_arg_list_recover_expr.rs
@@ -0,0 +1,2 @@
+const _: () = T::<0, ,T>;
+const _: () = T::<0, ,T>();
diff --git a/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast b/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast
index f2e4e01069..0f62e1dd18 100644
--- a/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast
+++ b/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rast
@@ -35,3 +35,42 @@ SOURCE_FILE
R_ANGLE ">"
SEMICOLON ";"
WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "T"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "StreamingIterator"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Clone"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs b/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs
index daae97e4fd..83fea1c6c8 100644
--- a/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs
+++ b/crates/parser/test_data/parser/inline/ok/assoc_type_bound.rs
@@ -1 +1,2 @@
type T = StreamingIterator<Item<'a>: Clone>;
+type T = StreamingIterator<Item(T): Clone>;
diff --git a/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast b/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast
deleted file mode 100644
index 8cbc98c51c..0000000000
--- a/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rast
+++ /dev/null
@@ -1,111 +0,0 @@
-SOURCE_FILE
- FN
- FN_KW "fn"
- WHITESPACE " "
- NAME
- IDENT "print_all"
- GENERIC_PARAM_LIST
- L_ANGLE "<"
- TYPE_PARAM
- NAME
- IDENT "T"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Iterator"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Item"
- COMMA ","
- WHITESPACE " "
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Item"
- COLON2 "::"
- PATH_SEGMENT
- NAME_REF
- IDENT "Item"
- COMMA ","
- WHITESPACE " "
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Item"
- GENERIC_ARG_LIST
- COLON2 "::"
- L_ANGLE "<"
- CONST_ARG
- LITERAL
- TRUE_KW "true"
- R_ANGLE ">"
- COMMA ","
- WHITESPACE " "
- ASSOC_TYPE_ARG
- NAME_REF
- IDENT "Item"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Display"
- COMMA ","
- WHITESPACE " "
- ASSOC_TYPE_ARG
- NAME_REF
- IDENT "Item"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- LIFETIME_ARG
- LIFETIME
- LIFETIME_IDENT "'a"
- R_ANGLE ">"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Item"
- R_ANGLE ">"
- R_ANGLE ">"
- PARAM_LIST
- L_PAREN "("
- PARAM
- IDENT_PAT
- NAME
- IDENT "printables"
- COLON ":"
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "T"
- R_PAREN ")"
- WHITESPACE " "
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- R_CURLY "}"
- WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs b/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs
deleted file mode 100644
index 0f7a2d1608..0000000000
--- a/crates/parser/test_data/parser/inline/ok/associated_type_bounds.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
diff --git a/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast b/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast
index ebf758286a..df0ba55d03 100644
--- a/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast
+++ b/crates/parser/test_data/parser/inline/ok/async_trait_bound.rast
@@ -23,9 +23,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
REF_TYPE
AMP "&"
PATH_TYPE
diff --git a/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast b/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast
deleted file mode 100644
index d5f97bad89..0000000000
--- a/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rast
+++ /dev/null
@@ -1,175 +0,0 @@
-SOURCE_FILE
- TYPE_ALIAS
- TYPE_KW "type"
- WHITESPACE " "
- NAME
- IDENT "A"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "S"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Fn"
- PARAM_LIST
- L_PAREN "("
- PARAM
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- R_PAREN ")"
- R_ANGLE ">"
- SEMICOLON ";"
- WHITESPACE "\n"
- TYPE_ALIAS
- TYPE_KW "type"
- WHITESPACE " "
- NAME
- IDENT "A"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "S"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- DYN_TRAIT_TYPE
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Fn"
- PARAM_LIST
- L_PAREN "("
- PARAM
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- R_PAREN ")"
- WHITESPACE " "
- PLUS "+"
- WHITESPACE " "
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Send"
- R_ANGLE ">"
- SEMICOLON ";"
- WHITESPACE "\n"
- TYPE_ALIAS
- TYPE_KW "type"
- WHITESPACE " "
- NAME
- IDENT "B"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "S"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Fn"
- PARAM_LIST
- L_PAREN "("
- PARAM
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- R_PAREN ")"
- WHITESPACE " "
- RET_TYPE
- THIN_ARROW "->"
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- R_ANGLE ">"
- SEMICOLON ";"
- WHITESPACE "\n"
- TYPE_ALIAS
- TYPE_KW "type"
- WHITESPACE " "
- NAME
- IDENT "C"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "S"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- DYN_TRAIT_TYPE
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Fn"
- PARAM_LIST
- L_PAREN "("
- PARAM
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- R_PAREN ")"
- WHITESPACE " "
- RET_TYPE
- THIN_ARROW "->"
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- WHITESPACE " "
- PLUS "+"
- WHITESPACE " "
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Send"
- R_ANGLE ">"
- SEMICOLON ";"
- WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs b/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs
deleted file mode 100644
index 800002b1b8..0000000000
--- a/crates/parser/test_data/parser/inline/ok/bare_dyn_types_with_paren_as_generic_args.rs
+++ /dev/null
@@ -1,4 +0,0 @@
-type A = S<Fn(i32)>;
-type A = S<Fn(i32) + Send>;
-type B = S<Fn(i32) -> i32>;
-type C = S<Fn(i32) -> i32 + Send>;
diff --git a/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rast b/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rast
new file mode 100644
index 0000000000..fee5913aca
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rast
@@ -0,0 +1,461 @@
+SOURCE_FILE
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "Plain"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COLON2 "::"
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "GenericArgs"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ GENERIC_ARG_LIST
+ COLON2 "::"
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_ANGLE ">"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "ParenthesizedArgs"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "T"
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "RTN"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Foo"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE " "
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Bound"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ COMMA ","
+ WHITESPACE " "
+ ASSOC_TYPE_ARG
+ NAME_REF
+ IDENT "Item"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Item"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rs b/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rs
new file mode 100644
index 0000000000..1abd0aeb59
--- /dev/null
+++ b/crates/parser/test_data/parser/inline/ok/generic_arg_bounds.rs
@@ -0,0 +1,4 @@
+type Plain = Foo<Item, Item::Item, Item: Bound, Item = Item>;
+type GenericArgs = Foo<Item<T>, Item::<T>, Item<T>: Bound, Item::<T>: Bound, Item<T> = Item, Item::<T> = Item>;
+type ParenthesizedArgs = Foo<Item(T), Item::(T), Item(T): Bound, Item::(T): Bound, Item(T) = Item, Item::(T) = Item>;
+type RTN = Foo<Item(..), Item(..), Item(..): Bound, Item(..): Bound, Item(..) = Item, Item(..) = Item>;
diff --git a/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast b/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast
deleted file mode 100644
index e9d93a0d0a..0000000000
--- a/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rast
+++ /dev/null
@@ -1,48 +0,0 @@
-SOURCE_FILE
- FN
- FN_KW "fn"
- WHITESPACE " "
- NAME
- IDENT "foo"
- GENERIC_PARAM_LIST
- L_ANGLE "<"
- TYPE_PARAM
- NAME
- IDENT "F"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "FnMut"
- PARAM_LIST
- L_PAREN "("
- PARAM
- REF_TYPE
- AMP "&"
- MUT_KW "mut"
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Foo"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- LIFETIME_ARG
- LIFETIME
- LIFETIME_IDENT "'a"
- R_ANGLE ">"
- R_PAREN ")"
- R_ANGLE ">"
- PARAM_LIST
- L_PAREN "("
- R_PAREN ")"
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- R_CURLY "}"
- WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs b/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs
deleted file mode 100644
index 9b93442c0f..0000000000
--- a/crates/parser/test_data/parser/inline/ok/param_list_opt_patterns.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn foo<F: FnMut(&mut Foo<'a>)>(){}
diff --git a/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast b/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast
index fd83daf841..924f7ba2c9 100644
--- a/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast
+++ b/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rast
@@ -20,9 +20,133 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ R_PAREN ")"
+ WHITESPACE " "
+ RET_TYPE
+ THIN_ARROW "->"
+ WHITESPACE " "
+ TUPLE_TYPE
+ L_PAREN "("
+ R_PAREN ")"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "F"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Box"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ COLON2 "::"
+ NAME_REF
+ IDENT "Fn"
+ PARENTHESIZED_ARG_LIST
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ R_PAREN ")"
+ WHITESPACE " "
+ RET_TYPE
+ THIN_ARROW "->"
+ WHITESPACE " "
+ TUPLE_TYPE
+ L_PAREN "("
+ R_PAREN ")"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "F"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Box"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Fn"
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
+ L_PAREN "("
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "i32"
+ R_PAREN ")"
+ WHITESPACE " "
+ RET_TYPE
+ THIN_ARROW "->"
+ WHITESPACE " "
+ TUPLE_TYPE
+ L_PAREN "("
+ R_PAREN ")"
+ R_ANGLE ">"
+ SEMICOLON ";"
+ WHITESPACE "\n"
+ TYPE_ALIAS
+ TYPE_KW "type"
+ WHITESPACE " "
+ NAME
+ IDENT "F"
+ WHITESPACE " "
+ EQ "="
+ WHITESPACE " "
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Box"
+ GENERIC_ARG_LIST
+ L_ANGLE "<"
+ TYPE_ARG
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ COLON2 "::"
+ NAME_REF
+ IDENT "Fn"
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
+ L_PAREN "("
+ TYPE_ARG
PATH_TYPE
PATH
PATH_SEGMENT
diff --git a/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs b/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs
index 17ed20e5b1..7aa655d7ea 100644
--- a/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs
+++ b/crates/parser/test_data/parser/inline/ok/path_fn_trait_args.rs
@@ -1 +1,4 @@
type F = Box<Fn(i32) -> ()>;
+type F = Box<::Fn(i32) -> ()>;
+type F = Box<Fn::(i32) -> ()>;
+type F = Box<::Fn::(i32) -> ()>;
diff --git a/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rast b/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rast
deleted file mode 100644
index 30e0e73bbd..0000000000
--- a/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rast
+++ /dev/null
@@ -1,49 +0,0 @@
-SOURCE_FILE
- FN
- FN_KW "fn"
- WHITESPACE " "
- NAME
- IDENT "foo"
- GENERIC_PARAM_LIST
- L_ANGLE "<"
- TYPE_PARAM
- NAME
- IDENT "T"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Trait"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- ASSOC_TYPE_ARG
- NAME_REF
- IDENT "method"
- RETURN_TYPE_SYNTAX
- L_PAREN "("
- DOT2 ".."
- R_PAREN ")"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Send"
- R_ANGLE ">"
- R_ANGLE ">"
- PARAM_LIST
- L_PAREN "("
- R_PAREN ")"
- WHITESPACE " "
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- R_CURLY "}"
- WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs b/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs
deleted file mode 100644
index 8a4cf4c3a0..0000000000
--- a/crates/parser/test_data/parser/inline/ok/return_type_syntax_assoc_type_bound.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn foo<T: Trait<method(..): Send>>() {}
diff --git a/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rast b/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rast
index 501dccd79d..15a0558b53 100644
--- a/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rast
+++ b/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rast
@@ -42,6 +42,49 @@ SOURCE_FILE
NAME_REF
IDENT "Send"
COMMA ","
+ WHITESPACE "\n "
+ WHERE_PRED
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "method"
+ RETURN_TYPE_SYNTAX
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Send"
+ COMMA ","
+ WHITESPACE "\n "
+ WHERE_PRED
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "method"
+ RETURN_TYPE_SYNTAX
+ COLON2 "::"
+ L_PAREN "("
+ DOT2 ".."
+ R_PAREN ")"
+ COLON ":"
+ WHITESPACE " "
+ TYPE_BOUND_LIST
+ TYPE_BOUND
+ PATH_TYPE
+ PATH
+ PATH_SEGMENT
+ NAME_REF
+ IDENT "Send"
+ COMMA ","
WHITESPACE "\n"
BLOCK_EXPR
STMT_LIST
diff --git a/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rs b/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rs
index a9b63fb01c..64b48c1638 100644
--- a/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rs
+++ b/crates/parser/test_data/parser/inline/ok/return_type_syntax_in_path.rs
@@ -1,4 +1,6 @@
fn foo<T>()
where
T::method(..): Send,
+ method(..): Send,
+ method::(..): Send,
{}
diff --git a/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast b/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast
index 67277d0639..fb442bfb73 100644
--- a/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast
+++ b/crates/parser/test_data/parser/inline/ok/typepathfn_with_coloncolon.rast
@@ -13,10 +13,10 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Start"
- COLON2 "::"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
+ COLON2 "::"
L_PAREN "("
- PARAM
+ TYPE_ARG
PATH_TYPE
PATH
PATH_SEGMENT
@@ -63,9 +63,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Start"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
PATH_TYPE
PATH
PATH_SEGMENT
diff --git a/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast b/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast
deleted file mode 100644
index 902b06484c..0000000000
--- a/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rast
+++ /dev/null
@@ -1,60 +0,0 @@
-SOURCE_FILE
- TYPE_ALIAS
- TYPE_KW "type"
- WHITESPACE " "
- NAME
- IDENT "F"
- WHITESPACE " "
- EQ "="
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Box"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- TYPE_ARG
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Fn"
- PARAM_LIST
- L_PAREN "("
- PARAM
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- COMMA ","
- WHITESPACE " "
- PARAM
- REF_TYPE
- AMP "&"
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- COMMA ","
- WHITESPACE " "
- PARAM
- REF_TYPE
- AMP "&"
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "i32"
- COMMA ","
- WHITESPACE " "
- PARAM
- TUPLE_TYPE
- L_PAREN "("
- R_PAREN ")"
- R_PAREN ")"
- R_ANGLE ">"
- SEMICOLON ";"
- WHITESPACE "\n"
diff --git a/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs b/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs
deleted file mode 100644
index 93636e926e..0000000000
--- a/crates/parser/test_data/parser/inline/ok/value_parameters_no_patterns.rs
+++ /dev/null
@@ -1 +0,0 @@
-type F = Box<Fn(i32, &i32, &i32, ())>;
diff --git a/crates/parser/test_data/parser/inline/ok/where_pred_for.rast b/crates/parser/test_data/parser/inline/ok/where_pred_for.rast
index 8407e99f61..0cc365efbe 100644
--- a/crates/parser/test_data/parser/inline/ok/where_pred_for.rast
+++ b/crates/parser/test_data/parser/inline/ok/where_pred_for.rast
@@ -40,9 +40,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
REF_TYPE
AMP "&"
LIFETIME
diff --git a/crates/parser/test_data/parser/ok/0045_block_attrs.rast b/crates/parser/test_data/parser/ok/0045_block_attrs.rast
index fad574a476..c22d99f1ae 100644
--- a/crates/parser/test_data/parser/ok/0045_block_attrs.rast
+++ b/crates/parser/test_data/parser/ok/0045_block_attrs.rast
@@ -180,7 +180,7 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
diff --git a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast
index f8b11e7782..eafee90db4 100644
--- a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast
+++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rast
@@ -138,63 +138,6 @@ SOURCE_FILE
WHITESPACE " "
R_CURLY "}"
WHITESPACE "\n\n"
- FN
- FN_KW "fn"
- WHITESPACE " "
- NAME
- IDENT "foo"
- GENERIC_PARAM_LIST
- L_ANGLE "<"
- TYPE_PARAM
- NAME
- IDENT "F"
- COLON ":"
- WHITESPACE " "
- TYPE_BOUND_LIST
- TYPE_BOUND
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "FnMut"
- PARAM_LIST
- L_PAREN "("
- PARAM
- ATTR
- POUND "#"
- L_BRACK "["
- META
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "attr"
- R_BRACK "]"
- WHITESPACE " "
- REF_TYPE
- AMP "&"
- MUT_KW "mut"
- WHITESPACE " "
- PATH_TYPE
- PATH
- PATH_SEGMENT
- NAME_REF
- IDENT "Foo"
- GENERIC_ARG_LIST
- L_ANGLE "<"
- LIFETIME_ARG
- LIFETIME
- LIFETIME_IDENT "'a"
- R_ANGLE ">"
- R_PAREN ")"
- R_ANGLE ">"
- PARAM_LIST
- L_PAREN "("
- R_PAREN ")"
- BLOCK_EXPR
- STMT_LIST
- L_CURLY "{"
- R_CURLY "}"
- WHITESPACE "\n\n"
TRAIT
TRAIT_KW "trait"
WHITESPACE " "
diff --git a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs
index de350d8587..0a0100e5d0 100644
--- a/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs
+++ b/crates/parser/test_data/parser/ok/0051_parameter_attrs.rs
@@ -3,8 +3,6 @@ fn g2(#[attr1] x: u8) {}
extern "C" { fn printf(format: *const i8, #[attr] ...) -> i32; }
-fn foo<F: FnMut(#[attr] &mut Foo<'a>)>(){}
-
trait Foo {
fn bar(#[attr] _: u64, # [attr] mut x: i32);
}
diff --git a/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast
index 4e1e31f376..31cca601ca 100644
--- a/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast
+++ b/crates/parser/test_data/parser/ok/0054_qual_path_in_type_arg.rast
@@ -58,9 +58,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "FnMut"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
PATH_TYPE
PATH
PATH
@@ -101,9 +101,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "FnMut"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
REF_TYPE
AMP "&"
PATH_TYPE
diff --git a/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
index ba7b6042a9..d7ee11077c 100644
--- a/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
+++ b/crates/parser/test_data/parser/ok/0065_plus_after_fn_trait_bound.rast
@@ -32,7 +32,7 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
R_PAREN ")"
WHITESPACE " "
diff --git a/crates/parser/test_data/parser/ok/0067_where_for_pred.rast b/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
index 136fce93d7..cd3b21ae94 100644
--- a/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
+++ b/crates/parser/test_data/parser/ok/0067_where_for_pred.rast
@@ -40,9 +40,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
REF_TYPE
AMP "&"
LIFETIME
@@ -165,9 +165,9 @@ SOURCE_FILE
PATH_SEGMENT
NAME_REF
IDENT "Fn"
- PARAM_LIST
+ PARENTHESIZED_ARG_LIST
L_PAREN "("
- PARAM
+ TYPE_ARG
REF_TYPE
AMP "&"
LIFETIME
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
index 02c59646a9..30428329dd 100644
--- a/crates/syntax/rust.ungram
+++ b/crates/syntax/rust.ungram
@@ -37,7 +37,7 @@ Path =
PathSegment =
'::'? NameRef
| NameRef GenericArgList?
-| NameRef ParamList RetType?
+| NameRef ParenthesizedArgList RetType?
| NameRef ReturnTypeSyntax
| '<' Type ('as' PathType)? '>'
@@ -49,6 +49,9 @@ ReturnTypeSyntax =
// Generics //
//*************************//
+ParenthesizedArgList =
+ '::'? '(' (TypeArg (',' TypeArg)* ','?)? ')'
+
GenericArgList =
'::'? '<' (GenericArg (',' GenericArg)* ','?)? '>'
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 23d2b355a9..01dcb646b3 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -1363,6 +1363,21 @@ impl ParenType {
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct ParenthesizedArgList {
+ pub(crate) syntax: SyntaxNode,
+}
+impl ParenthesizedArgList {
+ #[inline]
+ pub fn type_args(&self) -> AstChildren<TypeArg> { support::children(&self.syntax) }
+ #[inline]
+ pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
+ #[inline]
+ pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
+ #[inline]
+ pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Path {
pub(crate) syntax: SyntaxNode,
}
@@ -1403,7 +1418,9 @@ impl PathSegment {
#[inline]
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
#[inline]
- pub fn param_list(&self) -> Option<ParamList> { support::child(&self.syntax) }
+ pub fn parenthesized_arg_list(&self) -> Option<ParenthesizedArgList> {
+ support::child(&self.syntax)
+ }
#[inline]
pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
#[inline]
@@ -3760,6 +3777,20 @@ impl AstNode for ParenType {
#[inline]
fn syntax(&self) -> &SyntaxNode { &self.syntax }
}
+impl AstNode for ParenthesizedArgList {
+ #[inline]
+ fn can_cast(kind: SyntaxKind) -> bool { kind == PARENTHESIZED_ARG_LIST }
+ #[inline]
+ fn cast(syntax: SyntaxNode) -> Option<Self> {
+ if Self::can_cast(syntax.kind()) {
+ Some(Self { syntax })
+ } else {
+ None
+ }
+ }
+ #[inline]
+ fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
impl AstNode for Path {
#[inline]
fn can_cast(kind: SyntaxKind) -> bool { kind == PATH }
@@ -7097,6 +7128,11 @@ impl std::fmt::Display for ParenType {
std::fmt::Display::fmt(self.syntax(), f)
}
}
+impl std::fmt::Display for ParenthesizedArgList {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Display::fmt(self.syntax(), f)
+ }
+}
impl std::fmt::Display for Path {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(self.syntax(), f)