]> git.lizzy.rs Git - rust.git/blob - crates/parser/src/grammar/expressions.rs
54eb96d84e5a4bad52fd5d328830a753c698b299
[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(IDENT)
300                 && p.at_contextual_kw("raw")
301                 && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const]))
302             {
303                 p.bump_remap(T![raw]);
304                 p.bump_any();
305             } else {
306                 p.eat(T![mut]);
307             }
308             REF_EXPR
309         }
310         // test unary_expr
311         // fn foo() {
312         //     **&1;
313         //     !!true;
314         //     --1;
315         // }
316         T![*] | T![!] | T![-] => {
317             m = p.start();
318             p.bump_any();
319             PREFIX_EXPR
320         }
321         _ => {
322             // test full_range_expr
323             // fn foo() { xs[..]; }
324             for op in [T![..=], T![..]] {
325                 if p.at(op) {
326                     m = p.start();
327                     p.bump(op);
328                     if p.at_ts(EXPR_FIRST) && !(r.forbid_structs && p.at(T!['{'])) {
329                         expr_bp(p, None, r, 2);
330                     }
331                     let cm = m.complete(p, RANGE_EXPR);
332                     return Some((cm, BlockLike::NotBlock));
333                 }
334             }
335
336             // test expression_after_block
337             // fn foo() {
338             //    let mut p = F{x: 5};
339             //    {p}.x = 10;
340             // }
341             let (lhs, blocklike) = atom::atom_expr(p, r)?;
342             let (cm, block_like) =
343                 postfix_expr(p, lhs, blocklike, !(r.prefer_stmt && blocklike.is_block()));
344             return Some((cm, block_like));
345         }
346     };
347     // parse the interior of the unary expression
348     expr_bp(p, None, r, 255);
349     let cm = m.complete(p, kind);
350     Some((cm, BlockLike::NotBlock))
351 }
352
353 fn postfix_expr(
354     p: &mut Parser,
355     mut lhs: CompletedMarker,
356     // Calls are disallowed if the type is a block and we prefer statements because the call cannot be disambiguated from a tuple
357     // E.g. `while true {break}();` is parsed as
358     // `while true {break}; ();`
359     mut block_like: BlockLike,
360     mut allow_calls: bool,
361 ) -> (CompletedMarker, BlockLike) {
362     loop {
363         lhs = match p.current() {
364             // test stmt_postfix_expr_ambiguity
365             // fn foo() {
366             //     match () {
367             //         _ => {}
368             //         () => {}
369             //         [] => {}
370             //     }
371             // }
372             T!['('] if allow_calls => call_expr(p, lhs),
373             T!['['] if allow_calls => index_expr(p, lhs),
374             T![.] => match postfix_dot_expr(p, lhs) {
375                 Ok(it) => it,
376                 Err(it) => {
377                     lhs = it;
378                     break;
379                 }
380             },
381             T![?] => try_expr(p, lhs),
382             _ => break,
383         };
384         allow_calls = true;
385         block_like = BlockLike::NotBlock;
386     }
387     return (lhs, block_like);
388
389     fn postfix_dot_expr(
390         p: &mut Parser,
391         lhs: CompletedMarker,
392     ) -> Result<CompletedMarker, CompletedMarker> {
393         assert!(p.at(T![.]));
394         if p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])) {
395             return Ok(method_call_expr(p, lhs));
396         }
397
398         // test await_expr
399         // fn foo() {
400         //     x.await;
401         //     x.0.await;
402         //     x.0().await?.hello();
403         // }
404         if p.nth(1) == T![await] {
405             let m = lhs.precede(p);
406             p.bump(T![.]);
407             p.bump(T![await]);
408             return Ok(m.complete(p, AWAIT_EXPR));
409         }
410
411         if p.at(T![..=]) || p.at(T![..]) {
412             return Err(lhs);
413         }
414
415         Ok(field_expr(p, lhs))
416     }
417 }
418
419 // test call_expr
420 // fn foo() {
421 //     let _ = f();
422 //     let _ = f()(1)(1, 2,);
423 //     let _ = f(<Foo>::func());
424 //     f(<Foo as Trait>::func());
425 // }
426 fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
427     assert!(p.at(T!['(']));
428     let m = lhs.precede(p);
429     arg_list(p);
430     m.complete(p, CALL_EXPR)
431 }
432
433 // test index_expr
434 // fn foo() {
435 //     x[1][2];
436 // }
437 fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
438     assert!(p.at(T!['[']));
439     let m = lhs.precede(p);
440     p.bump(T!['[']);
441     expr(p);
442     p.expect(T![']']);
443     m.complete(p, INDEX_EXPR)
444 }
445
446 // test method_call_expr
447 // fn foo() {
448 //     x.foo();
449 //     y.bar::<T>(1, 2,);
450 // }
451 fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
452     assert!(p.at(T![.]) && p.nth(1) == IDENT && (p.nth(2) == T!['('] || p.nth_at(2, T![::])));
453     let m = lhs.precede(p);
454     p.bump_any();
455     name_ref(p);
456     generic_args::opt_generic_arg_list(p, true);
457     if p.at(T!['(']) {
458         arg_list(p);
459     }
460     m.complete(p, METHOD_CALL_EXPR)
461 }
462
463 // test field_expr
464 // fn foo() {
465 //     x.foo;
466 //     x.0.bar;
467 //     x.0();
468 // }
469
470 // test_err bad_tuple_index_expr
471 // fn foo() {
472 //     x.0.;
473 //     x.1i32;
474 //     x.0x01;
475 // }
476 fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
477     assert!(p.at(T![.]));
478     let m = lhs.precede(p);
479     p.bump(T![.]);
480     if p.at(IDENT) || p.at(INT_NUMBER) {
481         name_ref_or_index(p);
482     } else if p.at(FLOAT_NUMBER) {
483         // FIXME: How to recover and instead parse INT + T![.]?
484         p.bump_any();
485     } else {
486         p.error("expected field name or number");
487     }
488     m.complete(p, FIELD_EXPR)
489 }
490
491 // test try_expr
492 // fn foo() {
493 //     x?;
494 // }
495 fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
496     assert!(p.at(T![?]));
497     let m = lhs.precede(p);
498     p.bump(T![?]);
499     m.complete(p, TRY_EXPR)
500 }
501
502 // test cast_expr
503 // fn foo() {
504 //     82 as i32;
505 //     81 as i8 + 1;
506 //     79 as i16 - 1;
507 //     0x36 as u8 <= 0x37;
508 // }
509 fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker {
510     assert!(p.at(T![as]));
511     let m = lhs.precede(p);
512     p.bump(T![as]);
513     // Use type_no_bounds(), because cast expressions are not
514     // allowed to have bounds.
515     types::type_no_bounds(p);
516     m.complete(p, CAST_EXPR)
517 }
518
519 fn arg_list(p: &mut Parser) {
520     assert!(p.at(T!['(']));
521     let m = p.start();
522     p.bump(T!['(']);
523     while !p.at(T![')']) && !p.at(EOF) {
524         // test arg_with_attr
525         // fn main() {
526         //     foo(#[attr] 92)
527         // }
528         if !expr(p) {
529             break;
530         }
531         if !p.at(T![')']) && !p.expect(T![,]) {
532             break;
533         }
534     }
535     p.eat(T![')']);
536     m.complete(p, ARG_LIST);
537 }
538
539 // test path_expr
540 // fn foo() {
541 //     let _ = a;
542 //     let _ = a::b;
543 //     let _ = ::a::<b>;
544 //     let _ = format!();
545 // }
546 fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) {
547     assert!(paths::is_path_start(p));
548     let m = p.start();
549     paths::expr_path(p);
550     match p.current() {
551         T!['{'] if !r.forbid_structs => {
552             record_expr_field_list(p);
553             (m.complete(p, RECORD_EXPR), BlockLike::NotBlock)
554         }
555         T![!] if !p.at(T![!=]) => {
556             let block_like = items::macro_call_after_excl(p);
557             (m.complete(p, MACRO_CALL), block_like)
558         }
559         _ => (m.complete(p, PATH_EXPR), BlockLike::NotBlock),
560     }
561 }
562
563 // test record_lit
564 // fn foo() {
565 //     S {};
566 //     S { x, y: 32, };
567 //     S { x, y: 32, ..Default::default() };
568 //     TupleStruct { 0: 1 };
569 // }
570 pub(crate) fn record_expr_field_list(p: &mut Parser) {
571     assert!(p.at(T!['{']));
572     let m = p.start();
573     p.bump(T!['{']);
574     while !p.at(EOF) && !p.at(T!['}']) {
575         let m = p.start();
576         // test record_literal_field_with_attr
577         // fn main() {
578         //     S { #[cfg(test)] field: 1 }
579         // }
580         attributes::outer_attrs(p);
581
582         match p.current() {
583             IDENT | INT_NUMBER => {
584                 // test_err record_literal_before_ellipsis_recovery
585                 // fn main() {
586                 //     S { field ..S::default() }
587                 // }
588                 if p.nth_at(1, T![:]) || p.nth_at(1, T![..]) {
589                     name_ref_or_index(p);
590                     p.expect(T![:]);
591                 }
592                 expr(p);
593                 m.complete(p, RECORD_EXPR_FIELD);
594             }
595             T![.] if p.at(T![..]) => {
596                 m.abandon(p);
597                 p.bump(T![..]);
598                 expr(p);
599             }
600             T!['{'] => {
601                 error_block(p, "expected a field");
602                 m.abandon(p);
603             }
604             _ => {
605                 p.err_and_bump("expected identifier");
606                 m.abandon(p);
607             }
608         }
609         if !p.at(T!['}']) {
610             p.expect(T![,]);
611         }
612     }
613     p.expect(T!['}']);
614     m.complete(p, RECORD_EXPR_FIELD_LIST);
615 }