Skip to content

Commit 609621d

Browse files
authored
Merge pull request rust-lang#18593 from Veykril/push-nokqpzuqtmww
Fix parsing of parenthesized type args and RTN
2 parents 1b54eea + 2b4dc9c commit 609621d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1020
-698
lines changed

src/tools/rust-analyzer/crates/hir-def/src/path/lower.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub(super) fn lower_path(ctx: &mut LowerCtx<'_>, mut path: ast::Path) -> Option<
4848
.or_else(|| {
4949
lower_generic_args_from_fn_path(
5050
ctx,
51-
segment.param_list(),
51+
segment.parenthesized_arg_list(),
5252
segment.ret_type(),
5353
)
5454
});
@@ -247,12 +247,12 @@ pub(super) fn lower_generic_args(
247247
/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
248248
fn lower_generic_args_from_fn_path(
249249
ctx: &mut LowerCtx<'_>,
250-
params: Option<ast::ParamList>,
250+
args: Option<ast::ParenthesizedArgList>,
251251
ret_type: Option<ast::RetType>,
252252
) -> Option<GenericArgs> {
253-
let params = params?;
253+
let params = args?;
254254
let mut param_types = Vec::new();
255-
for param in params.params() {
255+
for param in params.type_args() {
256256
let type_ref = TypeRef::from_ast_opt(ctx, param.ty());
257257
param_types.push(type_ref);
258258
}

src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,8 @@ impl Ctx<'_> {
286286
return None;
287287
}
288288
if path.segment().map_or(false, |s| {
289-
s.param_list().is_some() || (s.self_token().is_some() && path.parent_path().is_none())
289+
s.parenthesized_arg_list().is_some()
290+
|| (s.self_token().is_some() && path.parent_path().is_none())
290291
}) {
291292
// don't try to qualify `Fn(Foo) -> Bar` paths, they are in prelude anyway
292293
// don't try to qualify sole `self` either, they are usually locals, but are returned as modules due to namespace clashing

src/tools/rust-analyzer/crates/ide-ssr/src/matching.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,8 @@ impl<'db, 'sema> Matcher<'db, 'sema> {
359359
)?;
360360
self.attempt_match_opt(
361361
phase,
362-
pattern_segment.param_list(),
363-
code_segment.param_list(),
362+
pattern_segment.parenthesized_arg_list(),
363+
code_segment.parenthesized_arg_list(),
364364
)?;
365365
}
366366
if matches!(phase, Phase::Second(_)) {

src/tools/rust-analyzer/crates/ide/src/inlay_hints/lifetime.rs

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,15 @@ pub(super) fn fn_hints(
4141
fd,
4242
config,
4343
file_id,
44-
param_list,
44+
param_list.params().filter_map(|it| {
45+
Some((
46+
it.pat().and_then(|it| match it {
47+
ast::Pat::IdentPat(p) => p.name(),
48+
_ => None,
49+
}),
50+
it.ty()?,
51+
))
52+
}),
4553
generic_param_list,
4654
ret_type,
4755
self_param,
@@ -90,7 +98,15 @@ pub(super) fn fn_ptr_hints(
9098
fd,
9199
config,
92100
file_id,
93-
param_list,
101+
param_list.params().filter_map(|it| {
102+
Some((
103+
it.pat().and_then(|it| match it {
104+
ast::Pat::IdentPat(p) => p.name(),
105+
_ => None,
106+
}),
107+
it.ty()?,
108+
))
109+
}),
94110
generic_param_list,
95111
ret_type,
96112
None,
@@ -148,7 +164,7 @@ pub(super) fn fn_path_hints(
148164
fd,
149165
config,
150166
file_id,
151-
param_list,
167+
param_list.type_args().filter_map(|it| Some((None, it.ty()?))),
152168
generic_param_list,
153169
ret_type,
154170
None,
@@ -177,8 +193,8 @@ pub(super) fn fn_path_hints(
177193
)
178194
}
179195

180-
fn path_as_fn(path: &ast::Path) -> Option<(ast::ParamList, Option<ast::RetType>)> {
181-
path.segment().and_then(|it| it.param_list().zip(Some(it.ret_type())))
196+
fn path_as_fn(path: &ast::Path) -> Option<(ast::ParenthesizedArgList, Option<ast::RetType>)> {
197+
path.segment().and_then(|it| it.parenthesized_arg_list().zip(Some(it.ret_type())))
182198
}
183199

184200
fn hints_(
@@ -187,7 +203,7 @@ fn hints_(
187203
FamousDefs(_, _): &FamousDefs<'_, '_>,
188204
config: &InlayHintsConfig,
189205
_file_id: EditionedFileId,
190-
param_list: ast::ParamList,
206+
params: impl Iterator<Item = (Option<ast::Name>, ast::Type)>,
191207
generic_param_list: Option<ast::GenericParamList>,
192208
ret_type: Option<ast::RetType>,
193209
self_param: Option<ast::SelfParam>,
@@ -217,45 +233,34 @@ fn hints_(
217233
let is_elided = is_elided(&lifetime);
218234
acc.push((None, self_param.amp_token(), lifetime, is_elided));
219235
}
220-
param_list
221-
.params()
222-
.filter_map(|it| {
223-
Some((
224-
it.pat().and_then(|it| match it {
225-
ast::Pat::IdentPat(p) => p.name(),
226-
_ => None,
227-
}),
228-
it.ty()?,
229-
))
230-
})
231-
.for_each(|(name, ty)| {
232-
// FIXME: check path types
233-
walk_ty(&ty, &mut |ty| match ty {
234-
ast::Type::RefType(r) => {
235-
let lifetime = r.lifetime();
236-
let is_elided = is_elided(&lifetime);
237-
acc.push((name.clone(), r.amp_token(), lifetime, is_elided));
238-
false
239-
}
240-
ast::Type::FnPtrType(_) => {
236+
params.for_each(|(name, ty)| {
237+
// FIXME: check path types
238+
walk_ty(&ty, &mut |ty| match ty {
239+
ast::Type::RefType(r) => {
240+
let lifetime = r.lifetime();
241+
let is_elided = is_elided(&lifetime);
242+
acc.push((name.clone(), r.amp_token(), lifetime, is_elided));
243+
false
244+
}
245+
ast::Type::FnPtrType(_) => {
246+
is_trivial = false;
247+
true
248+
}
249+
ast::Type::PathType(t) => {
250+
if t.path()
251+
.and_then(|it| it.segment())
252+
.and_then(|it| it.parenthesized_arg_list())
253+
.is_some()
254+
{
241255
is_trivial = false;
242256
true
257+
} else {
258+
false
243259
}
244-
ast::Type::PathType(t) => {
245-
if t.path()
246-
.and_then(|it| it.segment())
247-
.and_then(|it| it.param_list())
248-
.is_some()
249-
{
250-
is_trivial = false;
251-
true
252-
} else {
253-
false
254-
}
255-
}
256-
_ => false,
257-
})
258-
});
260+
}
261+
_ => false,
262+
})
263+
});
259264
acc
260265
};
261266

@@ -339,7 +344,10 @@ fn hints_(
339344
true
340345
}
341346
ast::Type::PathType(t) => {
342-
if t.path().and_then(|it| it.segment()).and_then(|it| it.param_list()).is_some()
347+
if t.path()
348+
.and_then(|it| it.segment())
349+
.and_then(|it| it.parenthesized_arg_list())
350+
.is_some()
343351
{
344352
is_trivial = false;
345353
true

src/tools/rust-analyzer/crates/parser/src/grammar/expressions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ fn method_call_expr<const FLOAT_RECOVERY: bool>(
525525
p.bump(T![.]);
526526
}
527527
name_ref(p);
528-
generic_args::opt_generic_arg_list(p, true);
528+
generic_args::opt_generic_arg_list_expr(p);
529529
if p.at(T!['(']) {
530530
arg_list(p);
531531
} else {

src/tools/rust-analyzer/crates/parser/src/grammar/generic_args.rs

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
use super::*;
22

3-
// test_err generic_arg_list_recover
4-
// type T = T<0, ,T>;
5-
pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: bool) {
3+
// test_err generic_arg_list_recover_expr
4+
// const _: () = T::<0, ,T>;
5+
// const _: () = T::<0, ,T>();
6+
pub(super) fn opt_generic_arg_list_expr(p: &mut Parser<'_>) {
67
let m;
78
if p.at(T![::]) && p.nth(2) == T![<] {
89
m = p.start();
910
p.bump(T![::]);
10-
} else if !colon_colon_required && p.at(T![<]) && p.nth(1) != T![=] {
11-
m = p.start();
1211
} else {
1312
return;
1413
}
@@ -25,7 +24,7 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser<'_>, colon_colon_required: boo
2524
m.complete(p, GENERIC_ARG_LIST);
2625
}
2726

28-
const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
27+
pub(crate) const GENERIC_ARG_FIRST: TokenSet = TokenSet::new(&[
2928
LIFETIME_IDENT,
3029
IDENT,
3130
T!['{'],
@@ -47,20 +46,23 @@ const GENERIC_ARG_RECOVERY_SET: TokenSet = TokenSet::new(&[T![>], T![,]]);
4746

4847
// test generic_arg
4948
// type T = S<i32>;
50-
fn generic_arg(p: &mut Parser<'_>) -> bool {
49+
pub(crate) fn generic_arg(p: &mut Parser<'_>) -> bool {
5150
match p.current() {
5251
LIFETIME_IDENT if !p.nth_at(1, T![+]) => lifetime_arg(p),
5352
T!['{'] | T![true] | T![false] | T![-] => const_arg(p),
5453
k if k.is_literal() => const_arg(p),
55-
// test associated_type_bounds
56-
// fn print_all<T: Iterator<Item, Item::Item, Item::<true>, Item: Display, Item<'a> = Item>>(printables: T) {}
54+
// test generic_arg_bounds
55+
// type Plain = Foo<Item, Item::Item, Item: Bound, Item = Item>;
56+
// type GenericArgs = Foo<Item<T>, Item::<T>, Item<T>: Bound, Item::<T>: Bound, Item<T> = Item, Item::<T> = Item>;
57+
// type ParenthesizedArgs = Foo<Item(T), Item::(T), Item(T): Bound, Item::(T): Bound, Item(T) = Item, Item::(T) = Item>;
58+
// type RTN = Foo<Item(..), Item(..), Item(..): Bound, Item(..): Bound, Item(..) = Item, Item(..) = Item>;
5759

5860
// test macro_inside_generic_arg
5961
// type A = Foo<syn::Token![_]>;
60-
IDENT if [T![<], T![=], T![:]].contains(&p.nth(1)) && !p.nth_at(1, T![::]) => {
62+
IDENT => {
6163
let m = p.start();
6264
name_ref(p);
63-
opt_generic_arg_list(p, false);
65+
paths::opt_path_type_args(p);
6466
match p.current() {
6567
T![=] => {
6668
p.bump_any();
@@ -88,45 +90,26 @@ fn generic_arg(p: &mut Parser<'_>) -> bool {
8890
}
8991
// test assoc_type_bound
9092
// type T = StreamingIterator<Item<'a>: Clone>;
93+
// type T = StreamingIterator<Item(T): Clone>;
9194
T![:] if !p.at(T![::]) => {
9295
generic_params::bounds(p);
9396
m.complete(p, ASSOC_TYPE_ARG);
9497
}
98+
// Turned out to be just a normal path type (mirror `path_or_macro_type`)
9599
_ => {
96100
let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH);
97101
let m = paths::type_path_for_qualifier(p, m);
98-
m.precede(p).complete(p, PATH_TYPE).precede(p).complete(p, TYPE_ARG);
102+
let m = if p.at(T![!]) && !p.at(T![!=]) {
103+
let m = m.precede(p);
104+
items::macro_call_after_excl(p);
105+
m.complete(p, MACRO_CALL).precede(p).complete(p, MACRO_TYPE)
106+
} else {
107+
m.precede(p).complete(p, PATH_TYPE)
108+
};
109+
types::opt_type_bounds_as_dyn_trait_type(p, m).precede(p).complete(p, TYPE_ARG);
99110
}
100111
}
101112
}
102-
IDENT if p.nth_at(1, T!['(']) => {
103-
let m = p.start();
104-
name_ref(p);
105-
if p.nth_at(1, T![..]) {
106-
let rtn = p.start();
107-
p.bump(T!['(']);
108-
p.bump(T![..]);
109-
p.expect(T![')']);
110-
rtn.complete(p, RETURN_TYPE_SYNTAX);
111-
// test return_type_syntax_assoc_type_bound
112-
// fn foo<T: Trait<method(..): Send>>() {}
113-
generic_params::bounds(p);
114-
m.complete(p, ASSOC_TYPE_ARG);
115-
} else {
116-
params::param_list_fn_trait(p);
117-
// test bare_dyn_types_with_paren_as_generic_args
118-
// type A = S<Fn(i32)>;
119-
// type A = S<Fn(i32) + Send>;
120-
// type B = S<Fn(i32) -> i32>;
121-
// type C = S<Fn(i32) -> i32 + Send>;
122-
opt_ret_type(p);
123-
let m = m.complete(p, PATH_SEGMENT).precede(p).complete(p, PATH);
124-
let m = paths::type_path_for_qualifier(p, m);
125-
let m = m.precede(p).complete(p, PATH_TYPE);
126-
let m = types::opt_type_bounds_as_dyn_trait_type(p, m);
127-
m.precede(p).complete(p, TYPE_ARG);
128-
}
129-
}
130113
_ if p.at_ts(types::TYPE_FIRST) => type_arg(p),
131114
_ => return false,
132115
}
@@ -190,7 +173,7 @@ pub(super) fn const_arg(p: &mut Parser<'_>) {
190173
m.complete(p, CONST_ARG);
191174
}
192175

193-
fn type_arg(p: &mut Parser<'_>) {
176+
pub(crate) fn type_arg(p: &mut Parser<'_>) {
194177
let m = p.start();
195178
types::type_(p);
196179
m.complete(p, TYPE_ARG);

src/tools/rust-analyzer/crates/parser/src/grammar/params.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,6 @@ pub(super) fn param_list_fn_def(p: &mut Parser<'_>) {
1414
list_(p, Flavor::FnDef);
1515
}
1616

17-
// test param_list_opt_patterns
18-
// fn foo<F: FnMut(&mut Foo<'a>)>(){}
19-
pub(super) fn param_list_fn_trait(p: &mut Parser<'_>) {
20-
list_(p, Flavor::FnTrait);
21-
}
22-
2317
pub(super) fn param_list_fn_ptr(p: &mut Parser<'_>) {
2418
list_(p, Flavor::FnPointer);
2519
}
@@ -28,10 +22,9 @@ pub(super) fn param_list_closure(p: &mut Parser<'_>) {
2822
list_(p, Flavor::Closure);
2923
}
3024

31-
#[derive(Debug, Clone, Copy)]
25+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3226
enum Flavor {
33-
FnDef, // Includes trait fn params; omitted param idents are not supported
34-
FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
27+
FnDef, // Includes trait fn params; omitted param idents are not supported
3528
FnPointer,
3629
Closure,
3730
}
@@ -41,7 +34,7 @@ fn list_(p: &mut Parser<'_>, flavor: Flavor) {
4134

4235
let (bra, ket) = match flavor {
4336
Closure => (T![|], T![|]),
44-
FnDef | FnTrait | FnPointer => (T!['('], T![')']),
37+
FnDef | FnPointer => (T!['('], T![')']),
4538
};
4639

4740
let list_marker = p.start();
@@ -119,11 +112,6 @@ fn param(p: &mut Parser<'_>, m: Marker, flavor: Flavor) {
119112
}
120113
}
121114
}
122-
// test value_parameters_no_patterns
123-
// type F = Box<Fn(i32, &i32, &i32, ())>;
124-
Flavor::FnTrait => {
125-
types::type_(p);
126-
}
127115
// test fn_pointer_param_ident_path
128116
// type Foo = fn(Bar::Baz);
129117
// type Qux = fn(baz: Bar::Baz);

0 commit comments

Comments
 (0)