1 use super::*;
2
3 // test expr_literals
4 // fn foo() {
5 // let _ = true;
6 // let _ = false;
7 // let _ = 1;
8 // let _ = 2.0;
9 // let _ = b'a';
10 // let _ = 'b';
11 // let _ = "c";
12 // let _ = r"d";
13 // let _ = b"e";
14 // let _ = br"f";
15 // let _ = c"g";
16 // let _ = cr"h";
17 // }
18 pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[
19 T![true],
20 T![false],
21 INT_NUMBER,
22 FLOAT_NUMBER,
23 BYTE,
24 CHAR,
25 STRING,
26 BYTE_STRING,
27 C_STRING,
28 ]);
29
literal(p: &mut Parser<'_>) -> Option<CompletedMarker>30 pub(crate) fn literal(p: &mut Parser<'_>) -> Option<CompletedMarker> {
31 if !p.at_ts(LITERAL_FIRST) {
32 return None;
33 }
34 let m = p.start();
35 p.bump_any();
36 Some(m.complete(p, LITERAL))
37 }
38
39 // E.g. for after the break in `if break {}`, this should not match
40 pub(super) const ATOM_EXPR_FIRST: TokenSet =
41 LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[
42 T!['('],
43 T!['{'],
44 T!['['],
45 T![|],
46 T![async],
47 T![box],
48 T![break],
49 T![const],
50 T![continue],
51 T![do],
52 T![for],
53 T![if],
54 T![let],
55 T![loop],
56 T![match],
57 T![move],
58 T![return],
59 T![static],
60 T![try],
61 T![unsafe],
62 T![while],
63 T![yield],
64 LIFETIME_IDENT,
65 ]));
66
67 pub(super) const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[T![')'], T![']']]);
68
atom_expr( p: &mut Parser<'_>, r: Restrictions, ) -> Option<(CompletedMarker, BlockLike)>69 pub(super) fn atom_expr(
70 p: &mut Parser<'_>,
71 r: Restrictions,
72 ) -> Option<(CompletedMarker, BlockLike)> {
73 if let Some(m) = literal(p) {
74 return Some((m, BlockLike::NotBlock));
75 }
76 if paths::is_path_start(p) {
77 return Some(path_expr(p, r));
78 }
79 let la = p.nth(1);
80 let done = match p.current() {
81 T!['('] => tuple_expr(p),
82 T!['['] => array_expr(p),
83 T![if] => if_expr(p),
84 T![let] => let_expr(p),
85 T![_] => {
86 // test destructuring_assignment_wildcard_pat
87 // fn foo() {
88 // _ = 1;
89 // Some(_) = None;
90 // }
91 let m = p.start();
92 p.bump(T![_]);
93 m.complete(p, UNDERSCORE_EXPR)
94 }
95 T![loop] => loop_expr(p, None),
96 T![box] => box_expr(p, None),
97 T![while] => while_expr(p, None),
98 T![try] => try_block_expr(p, None),
99 T![match] => match_expr(p),
100 T![return] => return_expr(p),
101 T![yield] => yield_expr(p),
102 T![do] if p.nth_at_contextual_kw(1, T![yeet]) => yeet_expr(p),
103 T![continue] => continue_expr(p),
104 T![break] => break_expr(p, r),
105
106 LIFETIME_IDENT if la == T![:] => {
107 let m = p.start();
108 label(p);
109 match p.current() {
110 T![loop] => loop_expr(p, Some(m)),
111 T![for] => for_expr(p, Some(m)),
112 T![while] => while_expr(p, Some(m)),
113 // test labeled_block
114 // fn f() { 'label: {}; }
115 T!['{'] => {
116 stmt_list(p);
117 m.complete(p, BLOCK_EXPR)
118 }
119 _ => {
120 // test_err misplaced_label_err
121 // fn main() {
122 // 'loop: impl
123 // }
124 p.error("expected a loop or block");
125 m.complete(p, ERROR);
126 return None;
127 }
128 }
129 }
130 // test effect_blocks
131 // fn f() { unsafe { } }
132 // fn f() { const { } }
133 // fn f() { async { } }
134 // fn f() { async move { } }
135 T![const] | T![unsafe] | T![async] if la == T!['{'] => {
136 let m = p.start();
137 p.bump_any();
138 stmt_list(p);
139 m.complete(p, BLOCK_EXPR)
140 }
141 T![async] if la == T![move] && p.nth(2) == T!['{'] => {
142 let m = p.start();
143 p.bump(T![async]);
144 p.eat(T![move]);
145 stmt_list(p);
146 m.complete(p, BLOCK_EXPR)
147 }
148 T!['{'] => {
149 // test for_range_from
150 // fn foo() {
151 // for x in 0 .. {
152 // break;
153 // }
154 // }
155 let m = p.start();
156 stmt_list(p);
157 m.complete(p, BLOCK_EXPR)
158 }
159
160 T![const] | T![static] | T![async] | T![move] | T![|] => closure_expr(p),
161 T![for] if la == T![<] => closure_expr(p),
162 T![for] => for_expr(p, None),
163
164 _ => {
165 p.err_and_bump("expected expression");
166 return None;
167 }
168 };
169 let blocklike =
170 if BlockLike::is_blocklike(done.kind()) { BlockLike::Block } else { BlockLike::NotBlock };
171 Some((done, blocklike))
172 }
173
174 // test tuple_expr
175 // fn foo() {
176 // ();
177 // (1);
178 // (1,);
179 // }
tuple_expr(p: &mut Parser<'_>) -> CompletedMarker180 fn tuple_expr(p: &mut Parser<'_>) -> CompletedMarker {
181 assert!(p.at(T!['(']));
182 let m = p.start();
183 p.expect(T!['(']);
184
185 let mut saw_comma = false;
186 let mut saw_expr = false;
187
188 // test_err tuple_expr_leading_comma
189 // fn foo() {
190 // (,);
191 // }
192 if p.eat(T![,]) {
193 p.error("expected expression");
194 saw_comma = true;
195 }
196
197 while !p.at(EOF) && !p.at(T![')']) {
198 saw_expr = true;
199
200 // test tuple_attrs
201 // const A: (i64, i64) = (1, #[cfg(test)] 2);
202 if expr(p).is_none() {
203 break;
204 }
205
206 if !p.at(T![')']) {
207 saw_comma = true;
208 p.expect(T![,]);
209 }
210 }
211 p.expect(T![')']);
212 m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR })
213 }
214
215 // test array_expr
216 // fn foo() {
217 // [];
218 // [1];
219 // [1, 2,];
220 // [1; 2];
221 // }
array_expr(p: &mut Parser<'_>) -> CompletedMarker222 fn array_expr(p: &mut Parser<'_>) -> CompletedMarker {
223 assert!(p.at(T!['[']));
224 let m = p.start();
225
226 let mut n_exprs = 0u32;
227 let mut has_semi = false;
228
229 p.bump(T!['[']);
230 while !p.at(EOF) && !p.at(T![']']) {
231 n_exprs += 1;
232
233 // test array_attrs
234 // const A: &[i64] = &[1, #[cfg(test)] 2];
235 if expr(p).is_none() {
236 break;
237 }
238
239 if n_exprs == 1 && p.eat(T![;]) {
240 has_semi = true;
241 continue;
242 }
243
244 if has_semi || !p.at(T![']']) && !p.expect(T![,]) {
245 break;
246 }
247 }
248 p.expect(T![']']);
249
250 m.complete(p, ARRAY_EXPR)
251 }
252
253 // test lambda_expr
254 // fn foo() {
255 // || ();
256 // || -> i32 { 92 };
257 // |x| x;
258 // move |x: i32,| x;
259 // async || {};
260 // move || {};
261 // async move || {};
262 // static || {};
263 // static move || {};
264 // static async || {};
265 // static async move || {};
266 // for<'a> || {};
267 // for<'a> move || {};
268 // }
closure_expr(p: &mut Parser<'_>) -> CompletedMarker269 fn closure_expr(p: &mut Parser<'_>) -> CompletedMarker {
270 assert!(match p.current() {
271 T![const] | T![static] | T![async] | T![move] | T![|] => true,
272 T![for] => p.nth(1) == T![<],
273 _ => false,
274 });
275
276 let m = p.start();
277
278 if p.at(T![for]) {
279 types::for_binder(p);
280 }
281 // test const_closure
282 // fn main() { let cl = const || _ = 0; }
283 p.eat(T![const]);
284 p.eat(T![static]);
285 p.eat(T![async]);
286 p.eat(T![move]);
287
288 if !p.at(T![|]) {
289 p.error("expected `|`");
290 return m.complete(p, CLOSURE_EXPR);
291 }
292 params::param_list_closure(p);
293 if opt_ret_type(p) {
294 // test lambda_ret_block
295 // fn main() { || -> i32 { 92 }(); }
296 block_expr(p);
297 } else if p.at_ts(EXPR_FIRST) {
298 // test closure_body_underscore_assignment
299 // fn main() { || _ = 0; }
300 expr(p);
301 } else {
302 p.error("expected expression");
303 }
304 m.complete(p, CLOSURE_EXPR)
305 }
306
307 // test if_expr
308 // fn foo() {
309 // if true {};
310 // if true {} else {};
311 // if true {} else if false {} else {};
312 // if S {};
313 // if { true } { } else { };
314 // }
if_expr(p: &mut Parser<'_>) -> CompletedMarker315 fn if_expr(p: &mut Parser<'_>) -> CompletedMarker {
316 assert!(p.at(T![if]));
317 let m = p.start();
318 p.bump(T![if]);
319 expr_no_struct(p);
320 block_expr(p);
321 if p.at(T![else]) {
322 p.bump(T![else]);
323 if p.at(T![if]) {
324 if_expr(p);
325 } else {
326 block_expr(p);
327 }
328 }
329 m.complete(p, IF_EXPR)
330 }
331
332 // test label
333 // fn foo() {
334 // 'a: loop {}
335 // 'b: while true {}
336 // 'c: for x in () {}
337 // }
label(p: &mut Parser<'_>)338 fn label(p: &mut Parser<'_>) {
339 assert!(p.at(LIFETIME_IDENT) && p.nth(1) == T![:]);
340 let m = p.start();
341 lifetime(p);
342 p.bump_any();
343 m.complete(p, LABEL);
344 }
345
346 // test loop_expr
347 // fn foo() {
348 // loop {};
349 // }
loop_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker350 fn loop_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
351 assert!(p.at(T![loop]));
352 let m = m.unwrap_or_else(|| p.start());
353 p.bump(T![loop]);
354 block_expr(p);
355 m.complete(p, LOOP_EXPR)
356 }
357
358 // test while_expr
359 // fn foo() {
360 // while true {};
361 // while let Some(x) = it.next() {};
362 // while { true } {};
363 // }
while_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker364 fn while_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
365 assert!(p.at(T![while]));
366 let m = m.unwrap_or_else(|| p.start());
367 p.bump(T![while]);
368 expr_no_struct(p);
369 block_expr(p);
370 m.complete(p, WHILE_EXPR)
371 }
372
373 // test for_expr
374 // fn foo() {
375 // for x in [] {};
376 // }
for_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker377 fn for_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
378 assert!(p.at(T![for]));
379 let m = m.unwrap_or_else(|| p.start());
380 p.bump(T![for]);
381 patterns::pattern(p);
382 p.expect(T![in]);
383 expr_no_struct(p);
384 block_expr(p);
385 m.complete(p, FOR_EXPR)
386 }
387
388 // test let_expr
389 // fn foo() {
390 // if let Some(_) = None && true {}
391 // while 1 == 5 && (let None = None) {}
392 // }
let_expr(p: &mut Parser<'_>) -> CompletedMarker393 fn let_expr(p: &mut Parser<'_>) -> CompletedMarker {
394 let m = p.start();
395 p.bump(T![let]);
396 patterns::pattern_top(p);
397 p.expect(T![=]);
398 expr_let(p);
399 m.complete(p, LET_EXPR)
400 }
401
402 // test match_expr
403 // fn foo() {
404 // match () { };
405 // match S {};
406 // match { } { _ => () };
407 // match { S {} } {};
408 // }
match_expr(p: &mut Parser<'_>) -> CompletedMarker409 fn match_expr(p: &mut Parser<'_>) -> CompletedMarker {
410 assert!(p.at(T![match]));
411 let m = p.start();
412 p.bump(T![match]);
413 expr_no_struct(p);
414 if p.at(T!['{']) {
415 match_arm_list(p);
416 } else {
417 p.error("expected `{`");
418 }
419 m.complete(p, MATCH_EXPR)
420 }
421
match_arm_list(p: &mut Parser<'_>)422 pub(crate) fn match_arm_list(p: &mut Parser<'_>) {
423 assert!(p.at(T!['{']));
424 let m = p.start();
425 p.eat(T!['{']);
426
427 // test match_arms_inner_attribute
428 // fn foo() {
429 // match () {
430 // #![doc("Inner attribute")]
431 // #![doc("Can be")]
432 // #![doc("Stacked")]
433 // _ => (),
434 // }
435 // }
436 attributes::inner_attrs(p);
437
438 while !p.at(EOF) && !p.at(T!['}']) {
439 if p.at(T!['{']) {
440 error_block(p, "expected match arm");
441 continue;
442 }
443 match_arm(p);
444 }
445 p.expect(T!['}']);
446 m.complete(p, MATCH_ARM_LIST);
447 }
448
449 // test match_arm
450 // fn foo() {
451 // match () {
452 // _ => (),
453 // _ if Test > Test{field: 0} => (),
454 // X | Y if Z => (),
455 // | X | Y if Z => (),
456 // | X => (),
457 // };
458 // }
match_arm(p: &mut Parser<'_>)459 fn match_arm(p: &mut Parser<'_>) {
460 let m = p.start();
461 // test match_arms_outer_attributes
462 // fn foo() {
463 // match () {
464 // #[cfg(feature = "some")]
465 // _ => (),
466 // #[cfg(feature = "other")]
467 // _ => (),
468 // #[cfg(feature = "many")]
469 // #[cfg(feature = "attributes")]
470 // #[cfg(feature = "before")]
471 // _ => (),
472 // }
473 // }
474 attributes::outer_attrs(p);
475
476 patterns::pattern_top_r(p, TokenSet::EMPTY);
477 if p.at(T![if]) {
478 match_guard(p);
479 }
480 p.expect(T![=>]);
481 let blocklike = match expr_stmt(p, None) {
482 Some((_, blocklike)) => blocklike,
483 None => BlockLike::NotBlock,
484 };
485
486 // test match_arms_commas
487 // fn foo() {
488 // match () {
489 // _ => (),
490 // _ => {}
491 // _ => ()
492 // }
493 // }
494 if !p.eat(T![,]) && !blocklike.is_block() && !p.at(T!['}']) {
495 p.error("expected `,`");
496 }
497 m.complete(p, MATCH_ARM);
498 }
499
500 // test match_guard
501 // fn foo() {
502 // match () {
503 // _ if foo => (),
504 // _ if let foo = bar => (),
505 // }
506 // }
match_guard(p: &mut Parser<'_>) -> CompletedMarker507 fn match_guard(p: &mut Parser<'_>) -> CompletedMarker {
508 assert!(p.at(T![if]));
509 let m = p.start();
510 p.bump(T![if]);
511 expr(p);
512 m.complete(p, MATCH_GUARD)
513 }
514
515 // test block
516 // fn a() {}
517 // fn b() { let _ = 1; }
518 // fn c() { 1; 2; }
519 // fn d() { 1; 2 }
block_expr(p: &mut Parser<'_>)520 pub(crate) fn block_expr(p: &mut Parser<'_>) {
521 if !p.at(T!['{']) {
522 p.error("expected a block");
523 return;
524 }
525 let m = p.start();
526 stmt_list(p);
527 m.complete(p, BLOCK_EXPR);
528 }
529
stmt_list(p: &mut Parser<'_>) -> CompletedMarker530 fn stmt_list(p: &mut Parser<'_>) -> CompletedMarker {
531 assert!(p.at(T!['{']));
532 let m = p.start();
533 p.bump(T!['{']);
534 expr_block_contents(p);
535 p.expect(T!['}']);
536 m.complete(p, STMT_LIST)
537 }
538
539 // test return_expr
540 // fn foo() {
541 // return;
542 // return 92;
543 // }
return_expr(p: &mut Parser<'_>) -> CompletedMarker544 fn return_expr(p: &mut Parser<'_>) -> CompletedMarker {
545 assert!(p.at(T![return]));
546 let m = p.start();
547 p.bump(T![return]);
548 if p.at_ts(EXPR_FIRST) {
549 expr(p);
550 }
551 m.complete(p, RETURN_EXPR)
552 }
553
554 // test yield_expr
555 // fn foo() {
556 // yield;
557 // yield 1;
558 // }
yield_expr(p: &mut Parser<'_>) -> CompletedMarker559 fn yield_expr(p: &mut Parser<'_>) -> CompletedMarker {
560 assert!(p.at(T![yield]));
561 let m = p.start();
562 p.bump(T![yield]);
563 if p.at_ts(EXPR_FIRST) {
564 expr(p);
565 }
566 m.complete(p, YIELD_EXPR)
567 }
568
569 // test yeet_expr
570 // fn foo() {
571 // do yeet;
572 // do yeet 1
573 // }
yeet_expr(p: &mut Parser<'_>) -> CompletedMarker574 fn yeet_expr(p: &mut Parser<'_>) -> CompletedMarker {
575 assert!(p.at(T![do]));
576 assert!(p.nth_at_contextual_kw(1, T![yeet]));
577 let m = p.start();
578 p.bump(T![do]);
579 p.bump_remap(T![yeet]);
580 if p.at_ts(EXPR_FIRST) {
581 expr(p);
582 }
583 m.complete(p, YEET_EXPR)
584 }
585
586 // test continue_expr
587 // fn foo() {
588 // loop {
589 // continue;
590 // continue 'l;
591 // }
592 // }
continue_expr(p: &mut Parser<'_>) -> CompletedMarker593 fn continue_expr(p: &mut Parser<'_>) -> CompletedMarker {
594 assert!(p.at(T![continue]));
595 let m = p.start();
596 p.bump(T![continue]);
597 if p.at(LIFETIME_IDENT) {
598 lifetime(p);
599 }
600 m.complete(p, CONTINUE_EXPR)
601 }
602
603 // test break_expr
604 // fn foo() {
605 // loop {
606 // break;
607 // break 'l;
608 // break 92;
609 // break 'l 92;
610 // }
611 // }
break_expr(p: &mut Parser<'_>, r: Restrictions) -> CompletedMarker612 fn break_expr(p: &mut Parser<'_>, r: Restrictions) -> CompletedMarker {
613 assert!(p.at(T![break]));
614 let m = p.start();
615 p.bump(T![break]);
616 if p.at(LIFETIME_IDENT) {
617 lifetime(p);
618 }
619 // test break_ambiguity
620 // fn foo(){
621 // if break {}
622 // while break {}
623 // for i in break {}
624 // match break {}
625 // }
626 if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
627 expr(p);
628 }
629 m.complete(p, BREAK_EXPR)
630 }
631
632 // test try_block_expr
633 // fn foo() {
634 // let _ = try {};
635 // }
try_block_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker636 fn try_block_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
637 assert!(p.at(T![try]));
638 let m = m.unwrap_or_else(|| p.start());
639 // Special-case `try!` as macro.
640 // This is a hack until we do proper edition support
641 if p.nth_at(1, T![!]) {
642 // test try_macro_fallback
643 // fn foo() { try!(Ok(())); }
644 let macro_call = p.start();
645 let path = p.start();
646 let path_segment = p.start();
647 let name_ref = p.start();
648 p.bump_remap(IDENT);
649 name_ref.complete(p, NAME_REF);
650 path_segment.complete(p, PATH_SEGMENT);
651 path.complete(p, PATH);
652 let _block_like = items::macro_call_after_excl(p);
653 macro_call.complete(p, MACRO_CALL);
654 return m.complete(p, MACRO_EXPR);
655 }
656
657 p.bump(T![try]);
658 if p.at(T!['{']) {
659 stmt_list(p);
660 } else {
661 p.error("expected a block");
662 }
663 m.complete(p, BLOCK_EXPR)
664 }
665
666 // test box_expr
667 // fn foo() {
668 // let x = box 1i32;
669 // let y = (box 1i32, box 2i32);
670 // let z = Foo(box 1i32, box 2i32);
671 // }
box_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker672 fn box_expr(p: &mut Parser<'_>, m: Option<Marker>) -> CompletedMarker {
673 assert!(p.at(T![box]));
674 let m = m.unwrap_or_else(|| p.start());
675 p.bump(T![box]);
676 if p.at_ts(EXPR_FIRST) {
677 expr(p);
678 }
679 m.complete(p, BOX_EXPR)
680 }
681