]> git.lizzy.rs Git - rust.git/blob - crates/parser/src/grammar/expressions.rs
Switch parser to use tokens
[rust.git] / crates / parser / src / grammar / expressions.rs
1 mod atom;
2
3 use super::*;
4
5 pub(crate) use self::atom::{block_expr, match_arm_list};
6 pub(super) use self::atom::{literal, LITERAL_FIRST};
7
8 pub(super) enum StmtWithSemi {
9     Yes,
10     No,
11     Optional,
12 }
13
14 const EXPR_FIRST: TokenSet = LHS_FIRST;
15
16 pub(super) fn expr(p: &mut Parser) -> bool {
17     let r = Restrictions { forbid_structs: false, prefer_stmt: false };
18     expr_bp(p, None, r, 1).is_some()
19 }
20
21 pub(super) fn expr_stmt(p: &mut Parser, m: Option<Marker>) -> Option<(CompletedMarker, BlockLike)> {
22     let r = Restrictions { forbid_structs: false, prefer_stmt: true };
23     expr_bp(p, m, r, 1)
24 }
25
26 fn expr_no_struct(p: &mut Parser) {
27     let r = Restrictions { forbid_structs: true, prefer_stmt: false };
28     expr_bp(p, None, r, 1);
29 }
30
31 pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
32     let m = p.start();
33     // test attr_on_expr_stmt
34     // fn foo() {
35     //     #[A] foo();
36     //     #[B] bar!{}
37     //     #[C] #[D] {}
38     //     #[D] return ();
39     // }
40     attributes::outer_attrs(p);
41
42     if p.at(T![let]) {
43         let_stmt(p, m, with_semi);
44         return;
45     }
46
47     // test block_items
48     // fn a() { fn b() {} }
49     let m = match items::opt_item(p, m) {
50         Ok(()) => return,
51         Err(m) => m,
52     };
53
54     if let Some((cm, blocklike)) = expr_stmt(p, Some(m)) {
55         if !(p.at(T!['}']) || (prefer_expr && p.at(EOF))) {
56             // test no_semi_after_block
57             // fn foo() {
58             //     if true {}
59             //     loop {}
60             //     match () {}
61             //     while true {}
62             //     for _ in () {}
63             //     {}
64             //     {}
65             //     macro_rules! test {
66             //          () => {}
67             //     }
68             //     test!{}
69             // }
70             let m = cm.precede(p);
71             match with_semi {
72                 StmtWithSemi::No => (),
73                 StmtWithSemi::Optional => {
74                     p.eat(T![;]);
75                 }
76                 StmtWithSemi::Yes => {
77                     if blocklike.is_block() {
78                         p.eat(T![;]);
79                     } else {
80                         p.expect(T![;]);
81                     }
82                 }
83             }
84
85             m.complete(p, EXPR_STMT);
86         }
87     }
88
89     // test let_stmt
90     // fn f() { let x: i32 = 92; }
91     fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) {
92         p.bump(T![let]);
93         patterns::pattern(p);
94         if p.at(T![:]) {
95             // test let_stmt_ascription
96             // fn f() { let x: i32; }
97             types::ascription(p);
98         }
99         if p.eat(T![=]) {
100             // test let_stmt_init
101             // fn f() { let x = 92; }
102             expressions::expr(p);
103         }
104
105         if p.at(T![else]) {
106             // test let_else
107             // fn f() { let Some(x) = opt else { return }; }
108
109             let m = p.start();
110             p.bump(T![else]);
111             block_expr(p);
112             m.complete(p, LET_ELSE);
113         }
114
115         match with_semi {
116             StmtWithSemi::No => (),
117             StmtWithSemi::Optional => {
118                 p.eat(T![;]);
119             }
120             StmtWithSemi::Yes => {
121                 p.expect(T![;]);
122             }
123         }
124         m.complete(p, LET_STMT);
125     }
126 }
127
128 pub(super) fn expr_block_contents(p: &mut Parser) {
129     attributes::inner_attrs(p);
130
131     while !p.at(EOF) && !p.at(T!['}']) {
132         // test nocontentexpr
133         // fn foo(){
134         //     ;;;some_expr();;;;{;;;};;;;Ok(())
135         // }
136
137         // test nocontentexpr_after_item
138         // fn simple_function() {
139         //     enum LocalEnum {
140         //         One,
141         //         Two,
142         //     };
143         //     fn f() {};
144         //     struct S {};
145         // }
146
147         if p.at(T![;]) {
148             p.bump(T![;]);
149             continue;
150         }
151
152         stmt(p, StmtWithSemi::Yes, false);
153     }
154 }
155
156 #[derive(Clone, Copy)]
157 struct Restrictions {
158     forbid_structs: bool,
159     prefer_stmt: bool,
160 }
161
162 /// Binding powers of operators for a Pratt parser.
163 ///
164 /// See <https://matklad.github.io/2020/04/13/simple-but-powerful-pratt-parsing.html>
165 #[rustfmt::skip]
166 fn current_op(p: &Parser) -> (u8, SyntaxKind) {
167     const NOT_AN_OP: (u8, SyntaxKind) = (0, T![@]);
168     match p.current() {
169         T![|] if p.at(T![||])  => (3,  T![||]),
170         T![|] if p.at(T![|=])  => (1,  T![|=]),
171         T![|]                  => (6,  T![|]),
172         T![>] if p.at(T![>>=]) => (1,  T![>>=]),
173         T![>] if p.at(T![>>])  => (9,  T![>>]),
174         T![>] if p.at(T![>=])  => (5,  T![>=]),
175         T![>]                  => (5,  T![>]),
176         T![=] if p.at(T![=>])  => NOT_AN_OP,
177         T![=] if p.at(T![==])  => (5,  T![==]),
178         T![=]                  => (1,  T![=]),
179         T![<] if p.at(T![<=])  => (5,  T![<=]),
180         T![<] if p.at(T![<<=]) => (1,  T![<<=]),
181         T![<] if p.at(T![<<])  => (9,  T![<<]),
182         T![<]                  => (5,  T![<]),
183         T![+] if p.at(T![+=])  => (1,  T![+=]),
184         T![+]                  => (10, T![+]),
185         T![^] if p.at(T![^=])  => (1,  T![^=]),
186         T![^]                  => (7,  T![^]),
187         T![%] if p.at(T![%=])  => (1,  T![%=]),
188         T![%]                  => (11, T![%]),
189         T![&] if p.at(T![&=])  => (1,  T![&=]),
190         T![&] if p.at(T![&&])  => (4,  T![&&]),
191         T![&]                  => (8,  T![&]),
192         T![/] if p.at(T![/=])  => (1,  T![/=]),
193         T![/]                  => (11, T![/]),
194         T![*] if p.at(T![*=])  => (1,  T![*=]),
195         T![*]                  => (11, T![*]),
196         T![.] if p.at(T![..=]) => (2,  T![..=]),
197         T![.] if p.at(T![..])  => (2,  T![..]),
198         T![!] if p.at(T![!=])  => (5,  T![!=]),
199         T![-] if p.at(T![-=])  => (1,  T![-=]),
200         T![-]                  => (10, T![-]),
201         T![as]                 => (12, T![as]),
202
203         _                      => NOT_AN_OP
204     }
205 }
206
207 // Parses expression with binding power of at least bp.
208 fn expr_bp(
209     p: &mut Parser,
210     m: Option<Marker>,
211     mut r: Restrictions,
212     bp: u8,
213 ) -> Option<(CompletedMarker, BlockLike)> {
214     let m = m.unwrap_or_else(|| {
215         let m = p.start();
216         attributes::outer_attrs(p);
217         m
218     });
219     let mut lhs = match lhs(p, r) {
220         Some((lhs, blocklike)) => {
221             let lhs = lhs.extend_to(p, m);
222             if r.prefer_stmt && blocklike.is_block() {
223                 // test stmt_bin_expr_ambiguity
224                 // fn f() {
225                 //     let _ = {1} & 2;
226                 //     {1} &2;
227                 // }
228                 return Some((lhs, BlockLike::Block));
229             }
230             lhs
231         }
232         None => {
233             m.abandon(p);
234             return None;
235         }
236     };
237
238     loop {
239         let is_range = p.at(T![..]) || p.at(T![..=]);
240         let (op_bp, op) = current_op(p);
241         if op_bp < bp {
242             break;
243         }
244         // test as_precedence
245         // fn f() { let _ = &1 as *const i32; }
246         if p.at(T![as]) {
247             lhs = cast_expr(p, lhs);
248             continue;
249         }
250         let m = lhs.precede(p);
251         p.bump(op);
252
253         // test binop_resets_statementness
254         // fn f() { v = {1}&2; }
255         r = Restrictions { prefer_stmt: false, ..r };
256
257         if is_range {
258             // test postfix_range
259             // fn foo() {
260             //     let x = 1..;
261             //     match 1.. { _ => () };
262             //     match a.b()..S { _ => () };
263             // }
264             let has_trailing_expression =
265                 p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{']));
266             if !has_trailing_expression {
267                 // no RHS
268                 lhs = m.complete(p, RANGE_EXPR);
269                 break;
270             }
271         }
272
273         expr_bp(p, None, Restrictions { prefer_stmt: false, ..r }, op_bp + 1);
274         lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
275     }
276     Some((lhs, BlockLike::NotBlock))
277 }
278
279 const LHS_FIRST: TokenSet =
280     atom::ATOM_EXPR_FIRST.union(TokenSet::new(&[T![&], T![*], T![!], T![.], T![-]]));
281
282 fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
283     let m;
284     let kind = match p.current() {
285         // test ref_expr
286         // fn foo() {
287         //     // reference operator
288         //     let _ = &1;
289         //     let _ = &mut &f();
290         //     let _ = &raw;
291         //     let _ = &raw.0;
292         //     // raw reference operator
293         //     let _ = &raw mut foo;
294         //     let _ = &raw const foo;
295         // }
296         T![&] => {
297             m = p.start();
298             p.bump(T![&]);
299             if p.at_contextual_kw(T![raw]) && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const])) {
300                 p.bump_remap(T![raw]);
301                 p.bump_any();
302             } else {
303                 p.eat(T![mut]);
304             }
305             REF_EXPR
306         }
307         // test unary_expr
308         // fn foo() {
309         //     **&1;
310         //     !!true;
311         //     --1;
312         // }
313         T![*] | T![!] | T![-] => {
314             m = p.start();
315             p.bump_any();
316             PREFIX_EXPR
317         }
318         _ => {
319             // test full_range_expr
320             // fn foo() { xs[..]; }
321             for op in [T![..=], T![..]] {
322                 if p.at(op) {
323                     m = p.start();
324                     p.bump(op);
325                     if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
326                         expr_bp(p, None, r, 2);
327                     }
328                     let cm = m.complete(p, RANGE_EXPR);
329                     return Some((cm, BlockLike::NotBlock));
330                 }
331             }
332
333             // test expression_after_block
334             // fn foo() {
335             //    let mut p = F{x: 5};
336             //    {p}.x = 10;
337             // }
338             let (lhs, blocklike) = atom::atom_expr(p, r)?;
339             let (cm, block_like) =
340                 postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()));
341             return Some((cm, block_like));
342         }
343     };
344     // parse the interior of the unary expression
345     expr_bp(p, None, r, 255);
346     let cm = m.complete(p, kind);
347     Some((cm, BlockLike::NotBlock))
348 }
349
350 fn postfix_expr(
351     p: &mut Parser,
352     mut lhs: CompletedMarker,
353     // Calls are disallowed if the type is a block and we prefer statements because the call cannot be disambiguated from a tuple
354     // E.g. `while true {break}();` is parsed as
355     // `while true {break}; ();`
356     mut block_like: BlockLike,
357     mut allow_calls: bool,
358 ) -> (CompletedMarker, BlockLike) {
359     loop {
360         lhs = match p.current() {
361             // test stmt_postfix_expr_ambiguity
362             // fn foo() {
363             //     match () {
364             //         _ => {}
365             //         () => {}
366             //         [] => {}
367             //     }
368             // }
369             T!['('] if allow_calls => call_expr(p, lhs),
370             T!['['] if allow_calls => index_expr(p, lhs),
371             T![.] => match postfix_dot_expr(p, lhs) {
372                 Ok(it) => it,
373                 Err(it) => {
374                     lhs = it;
375                     break;
376                 }
377             },
378             T![?] => try_expr(p, lhs),
379             _ => break,
380         };
381         allow_calls = true;
382         block_like = BlockLike::NotBlock;
383     }
384     return (lhs, block_like);
385
386     fn postfix_dot_expr(
387         p: &mut Parser,
388         lhs: CompletedMarker,
389     ) -> Result<CompletedMarker, CompletedMarker> {
390         assert!(p.at(T![.]));
391         if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) {
392             return Ok(method_call_expr(p, lhs));
393         }
394
395         // test await_expr
396         // fn foo() {
397         //     x.await;
398         //     x.0.await;
399         //     x.0().await?.hello();
400         // }
401         if p.nth(1) == T![await] {
402             let m = lhs.precede(p);
403             p.bump(T![.]);
404             p.bump(T![await]);
405             return Ok(m.complete(p, AWAIT_EXPR));
406         }
407
408         if p.at(T![..=]) || p.at(T![..]) {
409             return Err(lhs);
410         }
411
412         Ok(field_expr(p, lhs))
413     }
414 }
415
416 // test call_expr
417 // fn foo() {
418 //     let _ = f();
419 //     let _ = f()(1)(1, 2,);
420 //     let _ = f(<Foo>::func());
421 //     f(<Foo as Trait>::func());
422 // }
423 fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
424     assert!(p.at(T!['(']));
425     let m = lhs.precede(p);
426     arg_list(p);
427     m.complete(p, CALL_EXPR)
428 }
429
430 // test index_expr
431 // fn foo() {
432 //     x[1][2];
433 // }
434 fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
435     assert!(p.at(T!['[']));
436     let m = lhs.precede(p);
437     p.bump(T!['[']);
438     expr(p);
439     p.expect(T![']']);
440     m.complete(p, INDEX_EXPR)
441 }
442
443 // test method_call_expr
444 // fn foo() {
445 //     x.foo();
446 //     y.bar::<T>(1, 2,);
447 // }
448 fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
449     assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])));
450     let m = lhs.precede(p);
451     p.bump_any();
452     name_ref(p);
453     generic_args::opt_generic_arg_list(p, true);
454     if p.at(T!['(']) {
455         arg_list(p);
456     }
457     m.complete(p, METHOD_CALL_EXPR)
458 }
459
460 // test field_expr
461 // fn foo() {
462 //     x.foo;
463 //     x.0.bar;
464 //     x.0();
465 // }
466
467 // test_err bad_tuple_index_expr
468 // fn foo() {
469 //     x.0.;
470 //     x.1i32;
471 //     x.0x01;
472 // }
473 fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
474     assert!(p.at(T![.]));
475     let m = lhs.precede(p);
476     p.bump(T![.]);
477     if p.at(IDENT) || p.at(INT_NUMBER) {
478         name_ref_or_index(p);
479     } else if p.at(FLOAT_NUMBER) {
480         // FIXME: How to recover and instead parse INT + T![.]?
481         p.bump_any();
482     } else {
483         p.error("expected field name or number");
484     }
485     m.complete(p, FIELD_EXPR)
486 }
487
488 // test try_expr
489 // fn foo() {
490 //     x?;
491 // }
492 fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
493     assert!(p.at(T![?]));
494     let m = lhs.precede(p);
495     p.bump(T![?]);
496     m.complete(p, TRY_EXPR)
497 }
498
499 // test cast_expr
500 // fn foo() {
501 //     82 as i32;
502 //     81 as i8 + 1;
503 //     79 as i16 - 1;
504 //     0x36 as u8 <= 0x37;
505 // }
506 fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
507     assert!(p.at(T![as]));
508     let m = lhs.precede(p);
509     p.bump(T![as]);
510     // Use type_no_bounds(), because cast expressions are not
511     // allowed to have bounds.
512     types::type_no_bounds(p);
513     m.complete(p, CAST_EXPR)
514 }
515
516 fn arg_list(p: &mut Parser) {
517     assert!(p.at(T!['(']));
518     let m = p.start();
519     p.bump(T!['(']);
520     while !p.at(T![')']) && !p.at(EOF) {
521         // test arg_with_attr
522         // fn main() {
523         //     foo(#[attr] 92)
524         // }
525         if !expr(p) {
526             break;
527         }
528         if !p.at(T![')']) && !p.expect(T![,]) {
529             break;
530         }
531     }
532     p.eat(T![')']);
533     m.complete(p, ARG_LIST);
534 }
535
536 // test path_expr
537 // fn foo() {
538 //     let _ = a;
539 //     let _ = a::b;
540 //     let _ = ::a::<b>;
541 //     let _ = format!();
542 // }
543 fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
544     assert!(paths::is_path_start(p));
545     let m = p.start();
546     paths::expr_path(p);
547     match p.current() {
548         T!['{'] if !r.forbid_structs => {
549             record_expr_field_list(p);
550             (m.complete(p, RECORD_EXPR), BlockLike::NotBlock)
551         }
552         T![!] if !p.at(T![!=]) => {
553             let block_like = items::macro_call_after_excl(p);
554             (m.complete(p, MACRO_CALL), block_like)
555         }
556         _ => (m.complete(p, PATH_EXPR), BlockLike::NotBlock),
557     }
558 }
559
560 // test record_lit
561 // fn foo() {
562 //     S {};
563 //     S { x, y: 32, };
564 //     S { x, y: 32, ..Default::default() };
565 //     TupleStruct { 0: 1 };
566 // }
567 pub(crate) fn record_expr_field_list(p: &mut Parser) {
568     assert!(p.at(T!['{']));
569     let m = p.start();
570     p.bump(T!['{']);
571     while !p.at(EOF) && !p.at(T!['}']) {
572         let m = p.start();
573         // test record_literal_field_with_attr
574         // fn main() {
575         //     S { #[cfg(test)] field: 1 }
576         // }
577         attributes::outer_attrs(p);
578
579         match p.current() {
580             IDENT | INT_NUMBER => {
581                 // test_err record_literal_before_ellipsis_recovery
582                 // fn main() {
583                 //     S { field ..S::default() }
584                 // }
585                 if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
586                     name_ref_or_index(p);
587                     p.expect(T![:]);
588                 }
589                 expr(p);
590                 m.complete(p, RECORD_EXPR_FIELD);
591             }
592             T![.] if p.at(T![..]) => {
593                 m.abandon(p);
594                 p.bump(T![..]);
595                 expr(p);
596             }
597             T!['{'] => {
598                 error_block(p, "expected a field");
599                 m.abandon(p);
600             }
601             _ => {
602                 p.err_and_bump("expected identifier");
603                 m.abandon(p);
604             }
605         }
606         if !p.at(T!['}']) {
607             p.expect(T![,]);
608         }
609     }
610     p.expect(T!['}']);
611     m.complete(p, RECORD_EXPR_FIELD_LIST);
612 }