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