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