Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/parser/src/grammar/expressions.rs')
| -rw-r--r-- | crates/parser/src/grammar/expressions.rs | 39 |
1 files changed, 25 insertions, 14 deletions
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 7516ac3c4b..4b080102a2 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -1,5 +1,7 @@ mod atom; +use crate::grammar::attributes::ATTRIBUTE_FIRST; + use super::*; pub(crate) use self::atom::{block_expr, match_arm_list}; @@ -68,6 +70,12 @@ pub(super) fn stmt(p: &mut Parser<'_>, semicolon: Semicolon) { Err(m) => m, }; + if !p.at_ts(EXPR_FIRST) { + p.err_and_bump("expected expression, item or let statement"); + m.abandon(p); + return; + } + if let Some((cm, blocklike)) = expr_stmt(p, Some(m)) { if !(p.at(T!['}']) || (semicolon != Semicolon::Required && p.at(EOF))) { // test no_semi_after_block @@ -227,6 +235,12 @@ fn expr_bp( attributes::outer_attrs(p); m }); + + if !p.at_ts(EXPR_FIRST) { + p.err_recover("expected expression", atom::EXPR_RECOVERY_SET); + m.abandon(p); + return None; + } let mut lhs = match lhs(p, r) { Some((lhs, blocklike)) => { let lhs = lhs.extend_to(p, m); @@ -551,23 +565,20 @@ fn cast_expr(p: &mut Parser<'_>, lhs: CompletedMarker) -> CompletedMarker { m.complete(p, CAST_EXPR) } +// test_err arg_list_recovery +// fn main() { +// foo(bar::); +// foo(bar:); +// foo(bar+); +// } fn arg_list(p: &mut Parser<'_>) { assert!(p.at(T!['('])); let m = p.start(); - p.bump(T!['(']); - while !p.at(T![')']) && !p.at(EOF) { - // test arg_with_attr - // fn main() { - // foo(#[attr] 92) - // } - if !expr(p) { - break; - } - if !p.at(T![')']) && !p.expect(T![,]) { - break; - } - } - p.eat(T![')']); + // test arg_with_attr + // fn main() { + // foo(#[attr] 92) + // } + delimited(p, T!['('], T![')'], T![,], EXPR_FIRST.union(ATTRIBUTE_FIRST), expr); m.complete(p, ARG_LIST); } |