Skip to content

Commit f93743d

Browse files
committed
Auto merge of rust-lang#17646 - Veykril:dyn-parse, r=lnicola
Add missing dyn parse special cases in 2015 edition There were a few more special cases to consider here -> rust-lang/reference#1538
2 parents 4a62086 + 89d24c0 commit f93743d

File tree

4 files changed

+162
-70
lines changed

4 files changed

+162
-70
lines changed

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

-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ use super::*;
22

33
pub(super) const PATH_FIRST: TokenSet =
44
TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![Self], T![:], T![<]]);
5-
pub(super) const WEAK_DYN_PATH_FIRST: TokenSet =
6-
TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![Self]]);
75

86
pub(super) fn is_path_start(p: &Parser<'_>) -> bool {
97
is_use_path_start(p) || p.at(T![<]) || p.at(T![Self])

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

+28-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use crate::grammar::paths::WEAK_DYN_PATH_FIRST;
2-
31
use super::*;
42

53
pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
@@ -51,13 +49,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
5149
T![dyn] => dyn_trait_type(p),
5250
// Some path types are not allowed to have bounds (no plus)
5351
T![<] => path_type_bounds(p, allow_bounds),
54-
T![ident]
55-
if !p.edition().at_least_2018()
56-
&& p.at_contextual_kw(T![dyn])
57-
&& WEAK_DYN_PATH_FIRST.contains(p.nth(1)) =>
58-
{
59-
dyn_trait_type_weak(p)
60-
}
52+
T![ident] if !p.edition().at_least_2018() && is_dyn_weak(p) => dyn_trait_type_weak(p),
6153
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
6254
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
6355
_ => {
@@ -66,6 +58,25 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
6658
}
6759
}
6860

61+
fn is_dyn_weak(p: &Parser<'_>) -> bool {
62+
const WEAK_DYN_PATH_FIRST: TokenSet = TokenSet::new(&[
63+
IDENT,
64+
T![self],
65+
T![super],
66+
T![crate],
67+
T![Self],
68+
T![lifetime_ident],
69+
T![?],
70+
T![for],
71+
T!['('],
72+
]);
73+
74+
p.at_contextual_kw(T![dyn]) && {
75+
let la = p.nth(1);
76+
WEAK_DYN_PATH_FIRST.contains(la) && (la != T![:] || la != T![<])
77+
}
78+
}
79+
6980
pub(super) fn ascription(p: &mut Parser<'_>) {
7081
assert!(p.at(T![:]));
7182
p.bump(T![:]);
@@ -289,9 +300,14 @@ fn dyn_trait_type(p: &mut Parser<'_>) {
289300
}
290301

291302
// test dyn_trait_type_weak 2015
292-
// type A = dyn Iterator<Item=Foo<'a>> + 'a;
293-
// type A = &dyn Iterator<Item=Foo<'a>> + 'a;
294-
// type A = dyn::Path;
303+
// type DynPlain = dyn Path;
304+
// type DynRef = &dyn Path;
305+
// type DynLt = dyn 'a + Path;
306+
// type DynQuestion = dyn ?Path;
307+
// type DynFor = dyn for<'a> Path;
308+
// type DynParen = dyn(Path);
309+
// type Path = dyn::Path;
310+
// type Generic = dyn<Path>;
295311
fn dyn_trait_type_weak(p: &mut Parser<'_>) {
296312
assert!(p.at_contextual_kw(T![dyn]));
297313
let m = p.start();

src/tools/rust-analyzer/crates/parser/test_data/parser/inline/ok/dyn_trait_type_weak.rast

+126-53
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SOURCE_FILE
55
TYPE_KW "type"
66
WHITESPACE " "
77
NAME
8-
IDENT "A"
8+
IDENT "DynPlain"
99
WHITESPACE " "
1010
EQ "="
1111
WHITESPACE " "
@@ -18,38 +18,14 @@ SOURCE_FILE
1818
PATH
1919
PATH_SEGMENT
2020
NAME_REF
21-
IDENT "Iterator"
22-
GENERIC_ARG_LIST
23-
L_ANGLE "<"
24-
ASSOC_TYPE_ARG
25-
NAME_REF
26-
IDENT "Item"
27-
EQ "="
28-
PATH_TYPE
29-
PATH
30-
PATH_SEGMENT
31-
NAME_REF
32-
IDENT "Foo"
33-
GENERIC_ARG_LIST
34-
L_ANGLE "<"
35-
LIFETIME_ARG
36-
LIFETIME
37-
LIFETIME_IDENT "'a"
38-
R_ANGLE ">"
39-
R_ANGLE ">"
40-
WHITESPACE " "
41-
PLUS "+"
42-
WHITESPACE " "
43-
TYPE_BOUND
44-
LIFETIME
45-
LIFETIME_IDENT "'a"
21+
IDENT "Path"
4622
SEMICOLON ";"
4723
WHITESPACE "\n"
4824
TYPE_ALIAS
4925
TYPE_KW "type"
5026
WHITESPACE " "
5127
NAME
52-
IDENT "A"
28+
IDENT "DynRef"
5329
WHITESPACE " "
5430
EQ "="
5531
WHITESPACE " "
@@ -64,38 +40,111 @@ SOURCE_FILE
6440
PATH
6541
PATH_SEGMENT
6642
NAME_REF
67-
IDENT "Iterator"
68-
GENERIC_ARG_LIST
69-
L_ANGLE "<"
70-
ASSOC_TYPE_ARG
71-
NAME_REF
72-
IDENT "Item"
73-
EQ "="
74-
PATH_TYPE
75-
PATH
76-
PATH_SEGMENT
77-
NAME_REF
78-
IDENT "Foo"
79-
GENERIC_ARG_LIST
80-
L_ANGLE "<"
81-
LIFETIME_ARG
82-
LIFETIME
83-
LIFETIME_IDENT "'a"
84-
R_ANGLE ">"
85-
R_ANGLE ">"
86-
WHITESPACE " "
87-
PLUS "+"
88-
WHITESPACE " "
89-
TYPE_BOUND
90-
LIFETIME
91-
LIFETIME_IDENT "'a"
43+
IDENT "Path"
44+
SEMICOLON ";"
45+
WHITESPACE "\n"
46+
TYPE_ALIAS
47+
TYPE_KW "type"
48+
WHITESPACE " "
49+
NAME
50+
IDENT "DynLt"
51+
WHITESPACE " "
52+
EQ "="
53+
WHITESPACE " "
54+
DYN_TRAIT_TYPE
55+
DYN_KW "dyn"
56+
WHITESPACE " "
57+
TYPE_BOUND_LIST
58+
TYPE_BOUND
59+
LIFETIME
60+
LIFETIME_IDENT "'a"
61+
WHITESPACE " "
62+
PLUS "+"
63+
WHITESPACE " "
64+
TYPE_BOUND
65+
PATH_TYPE
66+
PATH
67+
PATH_SEGMENT
68+
NAME_REF
69+
IDENT "Path"
70+
SEMICOLON ";"
71+
WHITESPACE "\n"
72+
TYPE_ALIAS
73+
TYPE_KW "type"
74+
WHITESPACE " "
75+
NAME
76+
IDENT "DynQuestion"
77+
WHITESPACE " "
78+
EQ "="
79+
WHITESPACE " "
80+
DYN_TRAIT_TYPE
81+
DYN_KW "dyn"
82+
WHITESPACE " "
83+
TYPE_BOUND_LIST
84+
TYPE_BOUND
85+
QUESTION "?"
86+
PATH_TYPE
87+
PATH
88+
PATH_SEGMENT
89+
NAME_REF
90+
IDENT "Path"
9291
SEMICOLON ";"
9392
WHITESPACE "\n"
9493
TYPE_ALIAS
9594
TYPE_KW "type"
9695
WHITESPACE " "
9796
NAME
98-
IDENT "A"
97+
IDENT "DynFor"
98+
WHITESPACE " "
99+
EQ "="
100+
WHITESPACE " "
101+
DYN_TRAIT_TYPE
102+
DYN_KW "dyn"
103+
WHITESPACE " "
104+
TYPE_BOUND_LIST
105+
TYPE_BOUND
106+
FOR_TYPE
107+
FOR_KW "for"
108+
GENERIC_PARAM_LIST
109+
L_ANGLE "<"
110+
LIFETIME_PARAM
111+
LIFETIME
112+
LIFETIME_IDENT "'a"
113+
R_ANGLE ">"
114+
WHITESPACE " "
115+
PATH_TYPE
116+
PATH
117+
PATH_SEGMENT
118+
NAME_REF
119+
IDENT "Path"
120+
SEMICOLON ";"
121+
WHITESPACE "\n"
122+
TYPE_ALIAS
123+
TYPE_KW "type"
124+
WHITESPACE " "
125+
NAME
126+
IDENT "DynParen"
127+
WHITESPACE " "
128+
EQ "="
129+
WHITESPACE " "
130+
DYN_TRAIT_TYPE
131+
DYN_KW "dyn"
132+
TYPE_BOUND_LIST
133+
TYPE_BOUND
134+
L_PAREN "("
135+
PATH_TYPE
136+
PATH
137+
PATH_SEGMENT
138+
NAME_REF
139+
IDENT "Path"
140+
R_PAREN ")"
141+
SEMICOLON ";"
142+
WHITESPACE "\n"
143+
TYPE_ALIAS
144+
TYPE_KW "type"
145+
WHITESPACE " "
146+
NAME
147+
IDENT "Path"
99148
WHITESPACE " "
100149
EQ "="
101150
WHITESPACE " "
@@ -111,3 +160,27 @@ SOURCE_FILE
111160
IDENT "Path"
112161
SEMICOLON ";"
113162
WHITESPACE "\n"
163+
TYPE_ALIAS
164+
TYPE_KW "type"
165+
WHITESPACE " "
166+
NAME
167+
IDENT "Generic"
168+
WHITESPACE " "
169+
EQ "="
170+
WHITESPACE " "
171+
PATH_TYPE
172+
PATH
173+
PATH_SEGMENT
174+
NAME_REF
175+
IDENT "dyn"
176+
GENERIC_ARG_LIST
177+
L_ANGLE "<"
178+
TYPE_ARG
179+
PATH_TYPE
180+
PATH
181+
PATH_SEGMENT
182+
NAME_REF
183+
IDENT "Path"
184+
R_ANGLE ">"
185+
SEMICOLON ";"
186+
WHITESPACE "\n"
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
// 2015
2-
type A = dyn Iterator<Item=Foo<'a>> + 'a;
3-
type A = &dyn Iterator<Item=Foo<'a>> + 'a;
4-
type A = dyn::Path;
2+
type DynPlain = dyn Path;
3+
type DynRef = &dyn Path;
4+
type DynLt = dyn 'a + Path;
5+
type DynQuestion = dyn ?Path;
6+
type DynFor = dyn for<'a> Path;
7+
type DynParen = dyn(Path);
8+
type Path = dyn::Path;
9+
type Generic = dyn<Path>;

0 commit comments

Comments
 (0)