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 | 46 |
1 files changed, 22 insertions, 24 deletions
diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 64057a4a67..9dbba89c56 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -5,10 +5,11 @@ use super::*; pub(crate) use self::atom::{block_expr, match_arm_list}; pub(super) use self::atom::{literal, LITERAL_FIRST}; -pub(super) enum StmtWithSemi { - Yes, - No, +#[derive(PartialEq, Eq)] +pub(super) enum Semicolon { + Required, Optional, + Forbidden, } const EXPR_FIRST: TokenSet = LHS_FIRST; @@ -28,7 +29,11 @@ fn expr_no_struct(p: &mut Parser) { expr_bp(p, None, r, 1); } -pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { +pub(super) fn stmt(p: &mut Parser, semicolon: Semicolon) { + if p.eat(T![;]) { + return; + } + let m = p.start(); // test attr_on_expr_stmt // fn foo() { @@ -40,7 +45,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { attributes::outer_attrs(p); if p.at(T![let]) { - let_stmt(p, m, with_semi); + let_stmt(p, m, semicolon); return; } @@ -52,7 +57,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { }; if let Some((cm, blocklike)) = expr_stmt(p, Some(m)) { - if !(p.at(T!['}']) || (prefer_expr && p.at(EOF))) { + if !(p.at(T!['}']) || (semicolon != Semicolon::Required && p.at(EOF))) { // test no_semi_after_block // fn foo() { // if true {} @@ -68,27 +73,26 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { // test!{} // } let m = cm.precede(p); - match with_semi { - StmtWithSemi::No => (), - StmtWithSemi::Optional => { - p.eat(T![;]); - } - StmtWithSemi::Yes => { + match semicolon { + Semicolon::Required => { if blocklike.is_block() { p.eat(T![;]); } else { p.expect(T![;]); } } + Semicolon::Optional => { + p.eat(T![;]); + } + Semicolon::Forbidden => (), } - m.complete(p, EXPR_STMT); } } // test let_stmt // fn f() { let x: i32 = 92; } - fn let_stmt(p: &mut Parser, m: Marker, with_semi: StmtWithSemi) { + fn let_stmt(p: &mut Parser, m: Marker, with_semi: Semicolon) { p.bump(T![let]); patterns::pattern(p); if p.at(T![:]) { @@ -113,11 +117,11 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) { } match with_semi { - StmtWithSemi::No => (), - StmtWithSemi::Optional => { + Semicolon::Forbidden => (), + Semicolon::Optional => { p.eat(T![;]); } - StmtWithSemi::Yes => { + Semicolon::Required => { p.expect(T![;]); } } @@ -143,13 +147,7 @@ pub(super) fn expr_block_contents(p: &mut Parser) { // fn f() {}; // struct S {}; // } - - if p.at(T![;]) { - p.bump(T![;]); - continue; - } - - stmt(p, StmtWithSemi::Yes, false); + stmt(p, Semicolon::Required); } } |