Skip to content

Commit d8341c5

Browse files
committed
Parse for<'a> closure syntax
1 parent e691ae0 commit d8341c5

File tree

12 files changed

+245
-158
lines changed

12 files changed

+245
-158
lines changed

crates/parser/src/grammar/expressions/atom.rs

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,8 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
7171
let done = match p.current() {
7272
T!['('] => tuple_expr(p),
7373
T!['['] => array_expr(p),
74-
T![|] => closure_expr(p),
75-
T![static] | T![async] | T![move] if la == T![|] => closure_expr(p),
76-
T![static] | T![async] if la == T![move] && p.nth(2) == T![|] => closure_expr(p),
77-
T![static] if la == T![async] && p.nth(2) == T![|] => closure_expr(p),
78-
T![static] if la == T![async] && p.nth(2) == T![move] && p.nth(3) == T![|] => {
79-
closure_expr(p)
80-
}
8174
T![if] => if_expr(p),
8275
T![let] => let_expr(p),
83-
8476
T![_] => {
8577
// test destructuring_assignment_wildcard_pat
8678
// fn foo() {
@@ -91,12 +83,16 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
9183
p.bump(T![_]);
9284
m.complete(p, UNDERSCORE_EXPR)
9385
}
94-
9586
T![loop] => loop_expr(p, None),
9687
T![box] => box_expr(p, None),
97-
T![for] => for_expr(p, None),
9888
T![while] => while_expr(p, None),
9989
T![try] => try_block_expr(p, None),
90+
T![match] => match_expr(p),
91+
T![return] => return_expr(p),
92+
T![yield] => yield_expr(p),
93+
T![continue] => continue_expr(p),
94+
T![break] => break_expr(p, r),
95+
10096
LIFETIME_IDENT if la == T![:] => {
10197
let m = p.start();
10298
label(p);
@@ -121,27 +117,21 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
121117
}
122118
}
123119
}
124-
T![async] if la == T!['{'] || (la == T![move] && p.nth(2) == T!['{']) => {
125-
let m = p.start();
126-
p.bump(T![async]);
127-
p.eat(T![move]);
128-
stmt_list(p);
129-
m.complete(p, BLOCK_EXPR)
130-
}
131-
T![match] => match_expr(p),
132-
// test unsafe_block
120+
// test effect_blocks
133121
// fn f() { unsafe { } }
134-
T![unsafe] if la == T!['{'] => {
122+
// fn f() { const { } }
123+
// fn f() { async { } }
124+
// fn f() { async move { } }
125+
T![const] | T![unsafe] | T![async] if la == T!['{'] => {
135126
let m = p.start();
136-
p.bump(T![unsafe]);
127+
p.bump_any();
137128
stmt_list(p);
138129
m.complete(p, BLOCK_EXPR)
139130
}
140-
// test const_block
141-
// fn f() { const { } }
142-
T![const] if la == T!['{'] => {
131+
T![async] if la == T![move] && p.nth(2) == T!['{'] => {
143132
let m = p.start();
144-
p.bump(T![const]);
133+
p.bump(T![async]);
134+
p.eat(T![move]);
145135
stmt_list(p);
146136
m.complete(p, BLOCK_EXPR)
147137
}
@@ -156,10 +146,11 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
156146
stmt_list(p);
157147
m.complete(p, BLOCK_EXPR)
158148
}
159-
T![return] => return_expr(p),
160-
T![yield] => yield_expr(p),
161-
T![continue] => continue_expr(p),
162-
T![break] => break_expr(p, r),
149+
150+
T![static] | T![async] | T![move] | T![|] => closure_expr(p),
151+
T![for] if la == T![<] => closure_expr(p),
152+
T![for] => for_expr(p, None),
153+
163154
_ => {
164155
p.err_recover("expected expression", EXPR_RECOVERY_SET);
165156
return None;
@@ -254,25 +245,30 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
254245
// static move || {};
255246
// static async || {};
256247
// static async move || {};
248+
// for<'a> || {};
249+
// for<'a> move || {};
257250
// }
258251
fn closure_expr(p: &mut Parser) -> CompletedMarker {
259-
assert!(
260-
p.at(T![|])
261-
|| (p.at(T![move]) && p.nth(1) == T![|])
262-
|| (p.at(T![async]) && p.nth(1) == T![|])
263-
|| (p.at(T![async]) && p.nth(1) == T![move] && p.nth(2) == T![|])
264-
|| (p.at(T![static]) && p.nth(1) == T![|])
265-
|| (p.at(T![static]) && p.nth(1) == T![move] && p.nth(2) == T![|])
266-
|| (p.at(T![static]) && p.nth(1) == T![async] && p.nth(2) == T![|])
267-
|| (p.at(T![static])
268-
&& p.nth(1) == T![async]
269-
&& p.nth(2) == T![move]
270-
&& p.nth(3) == T![|])
271-
);
252+
assert!(match p.current() {
253+
T![static] | T![async] | T![move] | T![|] => true,
254+
T![for] => p.nth(1) == T![<],
255+
_ => false,
256+
});
257+
272258
let m = p.start();
259+
260+
if p.at(T![for]) {
261+
types::for_binder(p);
262+
}
263+
273264
p.eat(T![static]);
274265
p.eat(T![async]);
275266
p.eat(T![move]);
267+
268+
if !p.at(T![|]) {
269+
p.error("expected `|`");
270+
return m.complete(p, CLOSURE_EXPR);
271+
}
276272
params::param_list_closure(p);
277273
if opt_ret_type(p) {
278274
// test lambda_ret_block

crates/parser/test_data/parser/err/0024_many_type_parens.rast

Lines changed: 61 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -182,45 +182,44 @@ SOURCE_FILE
182182
WHITESPACE " "
183183
TUPLE_EXPR
184184
L_PAREN "("
185-
FOR_EXPR
185+
CLOSURE_EXPR
186186
FOR_KW "for"
187-
PATH_PAT
188-
PATH
189-
PATH_SEGMENT
190-
L_ANGLE "<"
191-
ERROR
192-
LIFETIME_IDENT "'a"
193-
R_ANGLE ">"
194-
WHITESPACE " "
187+
GENERIC_PARAM_LIST
188+
L_ANGLE "<"
189+
LIFETIME_PARAM
190+
LIFETIME
191+
LIFETIME_IDENT "'a"
192+
R_ANGLE ">"
193+
WHITESPACE " "
194+
BIN_EXPR
195195
BIN_EXPR
196196
BIN_EXPR
197197
BIN_EXPR
198-
BIN_EXPR
199-
PATH_EXPR
200-
PATH
201-
PATH_SEGMENT
202-
NAME_REF
203-
IDENT "Trait"
204-
L_ANGLE "<"
205-
ERROR
206-
LIFETIME_IDENT "'a"
207-
R_ANGLE ">"
208-
ERROR
209-
R_PAREN ")"
210-
WHITESPACE " "
211-
PLUS "+"
212-
WHITESPACE " "
213-
PAREN_EXPR
214-
L_PAREN "("
215198
PATH_EXPR
216199
PATH
217200
PATH_SEGMENT
218201
NAME_REF
219-
IDENT "Copy"
202+
IDENT "Trait"
203+
L_ANGLE "<"
204+
ERROR
205+
LIFETIME_IDENT "'a"
206+
R_ANGLE ">"
207+
ERROR
220208
R_PAREN ")"
221-
R_ANGLE ">"
222-
ERROR
223-
SEMICOLON ";"
209+
WHITESPACE " "
210+
PLUS "+"
211+
WHITESPACE " "
212+
PAREN_EXPR
213+
L_PAREN "("
214+
PATH_EXPR
215+
PATH
216+
PATH_SEGMENT
217+
NAME_REF
218+
IDENT "Copy"
219+
R_PAREN ")"
220+
R_ANGLE ">"
221+
ERROR
222+
SEMICOLON ";"
224223
WHITESPACE "\n "
225224
LET_EXPR
226225
LET_KW "let"
@@ -240,49 +239,48 @@ SOURCE_FILE
240239
L_ANGLE "<"
241240
TUPLE_EXPR
242241
L_PAREN "("
243-
FOR_EXPR
242+
CLOSURE_EXPR
244243
FOR_KW "for"
245-
PATH_PAT
246-
PATH
247-
PATH_SEGMENT
248-
L_ANGLE "<"
249-
ERROR
250-
LIFETIME_IDENT "'a"
251-
R_ANGLE ">"
252-
WHITESPACE " "
244+
GENERIC_PARAM_LIST
245+
L_ANGLE "<"
246+
LIFETIME_PARAM
247+
LIFETIME
248+
LIFETIME_IDENT "'a"
249+
R_ANGLE ">"
250+
WHITESPACE " "
251+
BIN_EXPR
253252
BIN_EXPR
254253
BIN_EXPR
255254
BIN_EXPR
256-
BIN_EXPR
257-
PATH_EXPR
258-
PATH
259-
PATH_SEGMENT
260-
NAME_REF
261-
IDENT "Trait"
262-
L_ANGLE "<"
263-
ERROR
264-
LIFETIME_IDENT "'a"
265-
R_ANGLE ">"
266-
ERROR
267-
R_PAREN ")"
268-
WHITESPACE " "
269-
PLUS "+"
270-
WHITESPACE " "
271-
PAREN_EXPR
272-
L_PAREN "("
273255
PATH_EXPR
274256
PATH
275257
PATH_SEGMENT
276258
NAME_REF
277-
IDENT "Copy"
259+
IDENT "Trait"
260+
L_ANGLE "<"
261+
ERROR
262+
LIFETIME_IDENT "'a"
263+
R_ANGLE ">"
264+
ERROR
278265
R_PAREN ")"
279266
WHITESPACE " "
280267
PLUS "+"
281268
WHITESPACE " "
282269
PAREN_EXPR
283270
L_PAREN "("
284-
ERROR
285-
QUESTION "?"
271+
PATH_EXPR
272+
PATH
273+
PATH_SEGMENT
274+
NAME_REF
275+
IDENT "Copy"
276+
R_PAREN ")"
277+
WHITESPACE " "
278+
PLUS "+"
279+
WHITESPACE " "
280+
PAREN_EXPR
281+
L_PAREN "("
282+
ERROR
283+
QUESTION "?"
286284
PATH_EXPR
287285
PATH
288286
PATH_SEGMENT
@@ -307,23 +305,21 @@ error 141: expected SEMICOLON
307305
error 146: expected SEMICOLON
308306
error 146: expected expression
309307
error 148: expected expression
310-
error 155: expected type
311-
error 158: expected IN_KW
308+
error 158: expected `|`
309+
error 158: expected COMMA
312310
error 165: expected expression
313311
error 168: expected expression
314312
error 179: expected expression
315-
error 180: expected a block
316313
error 180: expected COMMA
317314
error 190: expected EQ
318315
error 190: expected expression
319316
error 191: expected COMMA
320-
error 201: expected type
321-
error 204: expected IN_KW
317+
error 204: expected `|`
318+
error 204: expected COMMA
322319
error 211: expected expression
323320
error 214: expected expression
324321
error 228: expected expression
325322
error 229: expected R_PAREN
326-
error 229: expected a block
327323
error 229: expected COMMA
328324
error 236: expected expression
329325
error 237: expected COMMA

crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rast

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,48 @@ SOURCE_FILE
199199
L_CURLY "{"
200200
R_CURLY "}"
201201
SEMICOLON ";"
202+
WHITESPACE "\n "
203+
EXPR_STMT
204+
CLOSURE_EXPR
205+
FOR_KW "for"
206+
GENERIC_PARAM_LIST
207+
L_ANGLE "<"
208+
LIFETIME_PARAM
209+
LIFETIME
210+
LIFETIME_IDENT "'a"
211+
R_ANGLE ">"
212+
WHITESPACE " "
213+
PARAM_LIST
214+
PIPE "|"
215+
PIPE "|"
216+
WHITESPACE " "
217+
BLOCK_EXPR
218+
STMT_LIST
219+
L_CURLY "{"
220+
R_CURLY "}"
221+
SEMICOLON ";"
222+
WHITESPACE "\n "
223+
EXPR_STMT
224+
CLOSURE_EXPR
225+
FOR_KW "for"
226+
GENERIC_PARAM_LIST
227+
L_ANGLE "<"
228+
LIFETIME_PARAM
229+
LIFETIME
230+
LIFETIME_IDENT "'a"
231+
R_ANGLE ">"
232+
WHITESPACE " "
233+
MOVE_KW "move"
234+
WHITESPACE " "
235+
PARAM_LIST
236+
PIPE "|"
237+
PIPE "|"
238+
WHITESPACE " "
239+
BLOCK_EXPR
240+
STMT_LIST
241+
L_CURLY "{"
242+
R_CURLY "}"
243+
SEMICOLON ";"
202244
WHITESPACE "\n"
203245
R_CURLY "}"
204246
WHITESPACE "\n"

crates/parser/test_data/parser/inline/ok/0106_lambda_expr.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,6 @@ fn foo() {
1010
static move || {};
1111
static async || {};
1212
static async move || {};
13+
for<'a> || {};
14+
for<'a> move || {};
1315
}

crates/parser/test_data/parser/inline/ok/0157_const_block.rast

Lines changed: 0 additions & 24 deletions
This file was deleted.

crates/parser/test_data/parser/inline/ok/0157_const_block.rs

Lines changed: 0 additions & 1 deletion
This file was deleted.

0 commit comments

Comments
 (0)