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