Skip to content

Commit 0cdcc7b

Browse files
committed
fix: Handle the final statement in SyntaxFactory::block_expr properly
This caused a bug that was rather tricky to hunt down!
1 parent c6c10b3 commit 0cdcc7b

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

crates/syntax/src/ast/syntax_factory/constructors.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -58,22 +58,31 @@ impl SyntaxFactory {
5858
tail_expr: Option<ast::Expr>,
5959
) -> ast::BlockExpr {
6060
let stmts = stmts.into_iter().collect_vec();
61-
let input = stmts.iter().map(|it| it.syntax().clone()).collect_vec();
61+
let mut input = stmts.iter().map(|it| it.syntax().clone()).collect_vec();
6262

6363
let ast = make::block_expr(stmts, tail_expr.clone()).clone_for_update();
6464

65-
if let Some((mut mapping, stmt_list)) = self.mappings().zip(ast.stmt_list()) {
65+
if let Some(mut mapping) = self.mappings() {
66+
let stmt_list = ast.stmt_list().unwrap();
6667
let mut builder = SyntaxMappingBuilder::new(stmt_list.syntax().clone());
6768

69+
if let Some(input) = tail_expr {
70+
builder.map_node(
71+
input.syntax().clone(),
72+
stmt_list.tail_expr().unwrap().syntax().clone(),
73+
);
74+
} else if let Some(ast_tail) = stmt_list.tail_expr() {
75+
// The parser interpreted the last statement (probably a statement with a block) as an Expr
76+
let last_stmt = input.pop().unwrap();
77+
78+
builder.map_node(last_stmt, ast_tail.syntax().clone());
79+
}
80+
6881
builder.map_children(
6982
input.into_iter(),
7083
stmt_list.statements().map(|it| it.syntax().clone()),
7184
);
7285

73-
if let Some((input, output)) = tail_expr.zip(stmt_list.tail_expr()) {
74-
builder.map_node(input.syntax().clone(), output.syntax().clone());
75-
}
76-
7786
builder.finish(&mut mapping);
7887
}
7988

0 commit comments

Comments
 (0)