• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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