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