From e3deeec2f26eee44d10c28efe95c06bd5ea6123b Mon Sep 17 00:00:00 2001 From: jnyfah Date: Thu, 16 Jan 2025 12:11:55 +0100 Subject: [PATCH] update blocklike --- crates/parser/src/event.rs | 2 +- crates/parser/src/grammar.rs | 5 +++-- crates/parser/src/grammar/expressions.rs | 10 ++++------ crates/parser/src/grammar/expressions/atom.rs | 2 +- crates/parser/src/parser.rs | 4 +--- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/crates/parser/src/event.rs b/crates/parser/src/event.rs index e38571dd3e..b197b086f3 100644 --- a/crates/parser/src/event.rs +++ b/crates/parser/src/event.rs @@ -12,7 +12,7 @@ use crate::{ /// `Parser` produces a flat list of `Event`s. /// They are converted to a tree-structure in /// a separate pass, via `TreeBuilder`. -#[derive(Debug)] +#[derive(Debug, PartialEq)] pub(crate) enum Event { /// This event signifies the start of the node. /// It should be either abandoned (in which case the diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index fe6b904bd8..d3aa56c7eb 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs @@ -204,8 +204,9 @@ impl BlockLike { self == BlockLike::Block } - fn is_blocklike(kind: SyntaxKind) -> bool { - matches!(kind, BLOCK_EXPR | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR) + fn is_blocklike(expr: &CompletedMarker, p: &Parser<'_>) -> bool { + matches!(expr.kind(), BLOCK_EXPR | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR) + || (expr.last_token(p) == Some(T!['}']) && !matches!(expr.kind(), CLOSURE_EXPR)) } } diff --git a/crates/parser/src/grammar/expressions.rs b/crates/parser/src/grammar/expressions.rs index 6494ce8d71..e7ba33bcb6 100644 --- a/crates/parser/src/grammar/expressions.rs +++ b/crates/parser/src/grammar/expressions.rs @@ -134,12 +134,10 @@ pub(super) fn let_stmt(p: &mut Parser<'_>, with_semi: Semicolon) { // test_err let_else_right_curly_brace // fn func() { let Some(_) = {Some(1)} else { panic!("h") };} if let Some(expr) = expr_after_eq { - if let Some(token) = expr.last_token(p) { - if token == T!['}'] { - p.error( - "right curly brace `}` before `else` in a `let...else` statement not allowed" - ) - } + if BlockLike::is_blocklike(&expr, p) { + p.error( + "right curly brace `}` before `else` in a `let...else` statement not allowed", + ) } } diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index 407320e1d0..40705d4a39 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs @@ -198,7 +198,7 @@ pub(super) fn atom_expr( } }; let blocklike = - if BlockLike::is_blocklike(done.kind()) { BlockLike::Block } else { BlockLike::NotBlock }; + if BlockLike::is_blocklike(&done, p) { BlockLike::Block } else { BlockLike::NotBlock }; Some((done, blocklike)) } diff --git a/crates/parser/src/parser.rs b/crates/parser/src/parser.rs index 832ba8d23a..2f6ba52574 100644 --- a/crates/parser/src/parser.rs +++ b/crates/parser/src/parser.rs @@ -391,9 +391,7 @@ impl CompletedMarker { pub(crate) fn last_token(&self, p: &Parser<'_>) -> Option { let end_pos = self.end_pos as usize; - if end_pos > p.events.len() { - return None; - } + debug_assert_eq!(p.events[end_pos - 1], Event::Finish); p.events[..end_pos].iter().rev().find_map(|event| match event { Event::Token { kind, .. } => Some(*kind), _ => None,