add is_blocklike func on BlockLike

This commit is contained in:
XFFXFF 2023-03-07 08:24:05 +08:00
parent 98990affe5
commit 6e97527eae
3 changed files with 14 additions and 17 deletions

View File

@ -198,6 +198,10 @@ impl BlockLike {
fn is_block(self) -> bool { fn is_block(self) -> bool {
self == BlockLike::Block self == BlockLike::Block
} }
fn is_blocklike(kind: SyntaxKind) -> bool {
matches!(kind, BLOCK_EXPR | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR)
}
} }
const VISIBILITY_FIRST: TokenSet = TokenSet::new(&[T![pub], T![crate]]); const VISIBILITY_FIRST: TokenSet = TokenSet::new(&[T![pub], T![crate]]);

View File

@ -121,28 +121,23 @@ pub(super) fn stmt(p: &mut Parser<'_>, semicolon: Semicolon) {
types::ascription(p); types::ascription(p);
} }
let mut is_block_like_expr_after_eq = false; let mut expr_after_eq: Option<CompletedMarker> = None;
if p.eat(T![=]) { if p.eat(T![=]) {
// test let_stmt_init // test let_stmt_init
// fn f() { let x = 92; } // fn f() { let x = 92; }
let expr = expressions::expr(p); expr_after_eq = expressions::expr(p);
if let Some(expr) = expr {
is_block_like_expr_after_eq = match expr.kind() {
IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true,
_ => false,
};
}
} }
if p.at(T![else]) { if p.at(T![else]) {
// test_err let_else_right_curly_brace // test_err let_else_right_curly_brace
// fn func() { let Some(_) = {Some(1)} else { panic!("h") };} // fn func() { let Some(_) = {Some(1)} else { panic!("h") };}
if is_block_like_expr_after_eq { if let Some(expr) = expr_after_eq {
if BlockLike::is_blocklike(expr.kind()) {
p.error( p.error(
"right curly brace `}` before `else` in a `let...else` statement not allowed", "right curly brace `}` before `else` in a `let...else` statement not allowed",
) )
} }
}
// test let_else // test let_else
// fn f() { let Some(x) = opt else { return }; } // fn f() { let Some(x) = opt else { return }; }

View File

@ -163,10 +163,8 @@ pub(super) fn atom_expr(
return None; return None;
} }
}; };
let blocklike = match done.kind() { let blocklike =
IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => BlockLike::Block, if BlockLike::is_blocklike(done.kind()) { BlockLike::Block } else { BlockLike::NotBlock };
_ => BlockLike::NotBlock,
};
Some((done, blocklike)) Some((done, blocklike))
} }