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