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