Skip to content

Commit 36353bb

Browse files
Merge #4833
4833: Separating parsing of `for` in predicates and types r=matklad a=matthewjasper We now correctly accept `for<'a> (&'a F): Fn(&'a str)` in a where clause and correctly reject `for<'a> &'a u32` as a type. Co-authored-by: Matthew Jasper <mjjasper1@gmail.com>
2 parents bd61ad7 + 8622e4c commit 36353bb

File tree

14 files changed

+843
-291
lines changed

14 files changed

+843
-291
lines changed

crates/ra_parser/src/grammar/type_params.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,14 @@ fn where_predicate(p: &mut Parser) {
191191
}
192192
_ => {
193193
// test where_pred_for
194-
// fn test<F>()
194+
// fn for_trait<F>()
195195
// where
196196
// for<'a> F: Fn(&'a str)
197197
// { }
198+
if p.at(T![for]) {
199+
types::for_binder(p);
200+
}
201+
198202
types::type_(p);
199203

200204
if p.at(T![:]) {

crates/ra_parser/src/grammar/types.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,19 +216,21 @@ pub(super) fn for_binder(p: &mut Parser) {
216216

217217
// test for_type
218218
// type A = for<'a> fn() -> ();
219-
// fn foo<T>(_t: &T) where for<'a> &'a T: Iterator {}
220-
// fn bar<T>(_t: &T) where for<'a> &'a mut T: Iterator {}
221-
// fn baz<T>(_t: &T) where for<'a> <&'a T as Baz>::Foo: Iterator {}
219+
// type B = for<'a> unsafe extern "C" fn(&'a ()) -> ();
220+
// type Obj = for<'a> PartialEq<&'a i32>;
222221
pub(super) fn for_type(p: &mut Parser) {
223222
assert!(p.at(T![for]));
224223
let m = p.start();
225224
for_binder(p);
226225
match p.current() {
227-
T![fn] | T![unsafe] | T![extern] => fn_pointer_type(p),
228-
T![&] => reference_type(p),
229-
_ if paths::is_path_start(p) => path_type_(p, false),
230-
_ => p.error("expected a path"),
226+
T![fn] | T![unsafe] | T![extern] => {}
227+
// OK: legacy trait object format
228+
_ if paths::is_use_path_start(p) => {}
229+
_ => {
230+
p.error("expected a function pointer or path");
231+
}
231232
}
233+
type_no_bounds(p);
232234
m.complete(p, FOR_TYPE);
233235
}
234236

crates/ra_syntax/src/ast.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ where
285285
let pred = predicates.next().unwrap();
286286
let mut bounds = pred.type_bound_list().unwrap().bounds();
287287

288+
assert!(pred.for_token().is_none());
289+
assert!(pred.type_param_list().is_none());
288290
assert_eq!("T", pred.type_ref().unwrap().syntax().text().to_string());
289291
assert_bound("Clone", bounds.next());
290292
assert_bound("Copy", bounds.next());
@@ -322,6 +324,8 @@ where
322324
let pred = predicates.next().unwrap();
323325
let mut bounds = pred.type_bound_list().unwrap().bounds();
324326

325-
assert_eq!("for<'a> F", pred.type_ref().unwrap().syntax().text().to_string());
327+
assert!(pred.for_token().is_some());
328+
assert_eq!("<'a>", pred.type_param_list().unwrap().syntax().text().to_string());
329+
assert_eq!("F", pred.type_ref().unwrap().syntax().text().to_string());
326330
assert_bound("Fn(&'a str)", bounds.next());
327331
}

crates/ra_syntax/src/ast/generated/nodes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,8 @@ pub struct WherePred {
20522052
}
20532053
impl ast::TypeBoundsOwner for WherePred {}
20542054
impl WherePred {
2055+
pub fn for_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![for]) }
2056+
pub fn type_param_list(&self) -> Option<TypeParamList> { support::child(&self.syntax) }
20552057
pub fn lifetime_token(&self) -> Option<SyntaxToken> {
20562058
support::token(&self.syntax, T![lifetime])
20572059
}

crates/ra_syntax/test_data/parser/err/0027_incomplere_where_for.rast

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,16 @@ SOURCE_FILE@0..30
1212
WHERE_KW@13..18 "where"
1313
WHITESPACE@18..19 " "
1414
WHERE_PRED@19..26
15-
FOR_TYPE@19..26
16-
FOR_KW@19..22 "for"
17-
TYPE_PARAM_LIST@22..26
18-
L_ANGLE@22..23 "<"
19-
LIFETIME_PARAM@23..25
20-
LIFETIME@23..25 "\'a"
21-
R_ANGLE@25..26 ">"
15+
FOR_KW@19..22 "for"
16+
TYPE_PARAM_LIST@22..26
17+
L_ANGLE@22..23 "<"
18+
LIFETIME_PARAM@23..25
19+
LIFETIME@23..25 "\'a"
20+
R_ANGLE@25..26 ">"
2221
WHITESPACE@26..27 "\n"
2322
BLOCK_EXPR@27..29
2423
L_CURLY@27..28 "{"
2524
R_CURLY@28..29 "}"
2625
WHITESPACE@29..30 "\n"
27-
error 26..26: expected a path
26+
error 26..26: expected type
2827
error 26..26: expected colon
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
SOURCE_FILE@0..239
2+
TYPE_ALIAS_DEF@0..30
3+
TYPE_KW@0..4 "type"
4+
WHITESPACE@4..5 " "
5+
NAME@5..11
6+
IDENT@5..11 "ForRef"
7+
WHITESPACE@11..12 " "
8+
EQ@12..13 "="
9+
WHITESPACE@13..14 " "
10+
FOR_TYPE@14..29
11+
FOR_KW@14..17 "for"
12+
TYPE_PARAM_LIST@17..21
13+
L_ANGLE@17..18 "<"
14+
LIFETIME_PARAM@18..20
15+
LIFETIME@18..20 "\'a"
16+
R_ANGLE@20..21 ">"
17+
WHITESPACE@21..22 " "
18+
REFERENCE_TYPE@22..29
19+
AMP@22..23 "&"
20+
LIFETIME@23..25 "\'a"
21+
WHITESPACE@25..26 " "
22+
PATH_TYPE@26..29
23+
PATH@26..29
24+
PATH_SEGMENT@26..29
25+
NAME_REF@26..29
26+
IDENT@26..29 "u32"
27+
SEMICOLON@29..30 ";"
28+
WHITESPACE@30..31 "\n"
29+
TYPE_ALIAS_DEF@31..64
30+
TYPE_KW@31..35 "type"
31+
WHITESPACE@35..36 " "
32+
NAME@36..42
33+
IDENT@36..42 "ForTup"
34+
WHITESPACE@42..43 " "
35+
EQ@43..44 "="
36+
WHITESPACE@44..45 " "
37+
FOR_TYPE@45..63
38+
FOR_KW@45..48 "for"
39+
TYPE_PARAM_LIST@48..52
40+
L_ANGLE@48..49 "<"
41+
LIFETIME_PARAM@49..51
42+
LIFETIME@49..51 "\'a"
43+
R_ANGLE@51..52 ">"
44+
WHITESPACE@52..53 " "
45+
TUPLE_TYPE@53..63
46+
L_PAREN@53..54 "("
47+
REFERENCE_TYPE@54..61
48+
AMP@54..55 "&"
49+
LIFETIME@55..57 "\'a"
50+
WHITESPACE@57..58 " "
51+
PATH_TYPE@58..61
52+
PATH@58..61
53+
PATH_SEGMENT@58..61
54+
NAME_REF@58..61
55+
IDENT@58..61 "u32"
56+
COMMA@61..62 ","
57+
R_PAREN@62..63 ")"
58+
SEMICOLON@63..64 ";"
59+
WHITESPACE@64..65 "\n"
60+
TYPE_ALIAS_DEF@65..95
61+
TYPE_KW@65..69 "type"
62+
WHITESPACE@69..70 " "
63+
NAME@70..78
64+
IDENT@70..78 "ForSlice"
65+
WHITESPACE@78..79 " "
66+
EQ@79..80 "="
67+
WHITESPACE@80..81 " "
68+
FOR_TYPE@81..94
69+
FOR_KW@81..84 "for"
70+
TYPE_PARAM_LIST@84..88
71+
L_ANGLE@84..85 "<"
72+
LIFETIME_PARAM@85..87
73+
LIFETIME@85..87 "\'a"
74+
R_ANGLE@87..88 ">"
75+
WHITESPACE@88..89 " "
76+
SLICE_TYPE@89..94
77+
L_BRACK@89..90 "["
78+
PATH_TYPE@90..93
79+
PATH@90..93
80+
PATH_SEGMENT@90..93
81+
NAME_REF@90..93
82+
IDENT@90..93 "u32"
83+
R_BRACK@93..94 "]"
84+
SEMICOLON@94..95 ";"
85+
WHITESPACE@95..96 "\n"
86+
TYPE_ALIAS_DEF@96..149
87+
TYPE_KW@96..100 "type"
88+
WHITESPACE@100..101 " "
89+
NAME@101..109
90+
IDENT@101..109 "ForForFn"
91+
WHITESPACE@109..110 " "
92+
EQ@110..111 "="
93+
WHITESPACE@111..112 " "
94+
FOR_TYPE@112..148
95+
FOR_KW@112..115 "for"
96+
TYPE_PARAM_LIST@115..119
97+
L_ANGLE@115..116 "<"
98+
LIFETIME_PARAM@116..118
99+
LIFETIME@116..118 "\'a"
100+
R_ANGLE@118..119 ">"
101+
WHITESPACE@119..120 " "
102+
FOR_TYPE@120..148
103+
FOR_KW@120..123 "for"
104+
TYPE_PARAM_LIST@123..127
105+
L_ANGLE@123..124 "<"
106+
LIFETIME_PARAM@124..126
107+
LIFETIME@124..126 "\'b"
108+
R_ANGLE@126..127 ">"
109+
WHITESPACE@127..128 " "
110+
FN_POINTER_TYPE@128..148
111+
FN_KW@128..130 "fn"
112+
PARAM_LIST@130..148
113+
L_PAREN@130..131 "("
114+
PARAM@131..138
115+
REFERENCE_TYPE@131..138
116+
AMP@131..132 "&"
117+
LIFETIME@132..134 "\'a"
118+
WHITESPACE@134..135 " "
119+
PATH_TYPE@135..138
120+
PATH@135..138
121+
PATH_SEGMENT@135..138
122+
NAME_REF@135..138
123+
IDENT@135..138 "i32"
124+
COMMA@138..139 ","
125+
WHITESPACE@139..140 " "
126+
PARAM@140..147
127+
REFERENCE_TYPE@140..147
128+
AMP@140..141 "&"
129+
LIFETIME@141..143 "\'b"
130+
WHITESPACE@143..144 " "
131+
PATH_TYPE@144..147
132+
PATH@144..147
133+
PATH_SEGMENT@144..147
134+
NAME_REF@144..147
135+
IDENT@144..147 "i32"
136+
R_PAREN@147..148 ")"
137+
SEMICOLON@148..149 ";"
138+
WHITESPACE@149..150 "\n"
139+
FN_DEF@150..238
140+
FN_KW@150..152 "fn"
141+
WHITESPACE@152..153 " "
142+
NAME@153..164
143+
IDENT@153..164 "for_for_for"
144+
TYPE_PARAM_LIST@164..167
145+
L_ANGLE@164..165 "<"
146+
TYPE_PARAM@165..166
147+
NAME@165..166
148+
IDENT@165..166 "T"
149+
R_ANGLE@166..167 ">"
150+
PARAM_LIST@167..169
151+
L_PAREN@167..168 "("
152+
R_PAREN@168..169 ")"
153+
WHITESPACE@169..170 "\n"
154+
WHERE_CLAUSE@170..234
155+
WHERE_KW@170..175 "where"
156+
WHITESPACE@175..180 "\n "
157+
WHERE_PRED@180..233
158+
FOR_KW@180..183 "for"
159+
TYPE_PARAM_LIST@183..187
160+
L_ANGLE@183..184 "<"
161+
LIFETIME_PARAM@184..186
162+
LIFETIME@184..186 "\'a"
163+
R_ANGLE@186..187 ">"
164+
WHITESPACE@187..188 " "
165+
FOR_TYPE@188..227
166+
FOR_KW@188..191 "for"
167+
TYPE_PARAM_LIST@191..195
168+
L_ANGLE@191..192 "<"
169+
LIFETIME_PARAM@192..194
170+
LIFETIME@192..194 "\'b"
171+
R_ANGLE@194..195 ">"
172+
WHITESPACE@195..196 " "
173+
FOR_TYPE@196..227
174+
FOR_KW@196..199 "for"
175+
TYPE_PARAM_LIST@199..203
176+
L_ANGLE@199..200 "<"
177+
LIFETIME_PARAM@200..202
178+
LIFETIME@200..202 "\'c"
179+
R_ANGLE@202..203 ">"
180+
WHITESPACE@203..204 " "
181+
FN_POINTER_TYPE@204..227
182+
FN_KW@204..206 "fn"
183+
PARAM_LIST@206..227
184+
L_PAREN@206..207 "("
185+
PARAM@207..212
186+
REFERENCE_TYPE@207..212
187+
AMP@207..208 "&"
188+
LIFETIME@208..210 "\'a"
189+
WHITESPACE@210..211 " "
190+
PATH_TYPE@211..212
191+
PATH@211..212
192+
PATH_SEGMENT@211..212
193+
NAME_REF@211..212
194+
IDENT@211..212 "T"
195+
COMMA@212..213 ","
196+
WHITESPACE@213..214 " "
197+
PARAM@214..219
198+
REFERENCE_TYPE@214..219
199+
AMP@214..215 "&"
200+
LIFETIME@215..217 "\'b"
201+
WHITESPACE@217..218 " "
202+
PATH_TYPE@218..219
203+
PATH@218..219
204+
PATH_SEGMENT@218..219
205+
NAME_REF@218..219
206+
IDENT@218..219 "T"
207+
COMMA@219..220 ","
208+
WHITESPACE@220..221 " "
209+
PARAM@221..226
210+
REFERENCE_TYPE@221..226
211+
AMP@221..222 "&"
212+
LIFETIME@222..224 "\'c"
213+
WHITESPACE@224..225 " "
214+
PATH_TYPE@225..226
215+
PATH@225..226
216+
PATH_SEGMENT@225..226
217+
NAME_REF@225..226
218+
IDENT@225..226 "T"
219+
R_PAREN@226..227 ")"
220+
COLON@227..228 ":"
221+
WHITESPACE@228..229 " "
222+
TYPE_BOUND_LIST@229..233
223+
TYPE_BOUND@229..233
224+
PATH_TYPE@229..233
225+
PATH@229..233
226+
PATH_SEGMENT@229..233
227+
NAME_REF@229..233
228+
IDENT@229..233 "Copy"
229+
COMMA@233..234 ","
230+
WHITESPACE@234..235 "\n"
231+
BLOCK_EXPR@235..238
232+
L_CURLY@235..236 "{"
233+
WHITESPACE@236..237 "\n"
234+
R_CURLY@237..238 "}"
235+
WHITESPACE@238..239 "\n"
236+
error 21..21: expected a function pointer or path
237+
error 52..52: expected a function pointer or path
238+
error 88..88: expected a function pointer or path
239+
error 119..119: expected a function pointer or path
240+
error 195..195: expected a function pointer or path
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
type ForRef = for<'a> &'a u32;
2+
type ForTup = for<'a> (&'a u32,);
3+
type ForSlice = for<'a> [u32];
4+
type ForForFn = for<'a> for<'b> fn(&'a i32, &'b i32);
5+
fn for_for_for<T>()
6+
where
7+
for<'a> for<'b> for<'c> fn(&'a T, &'b T, &'c T): Copy,
8+
{
9+
}

0 commit comments

Comments
 (0)