Unnamed repository; edit this file 'description' to name the repository.
fix: Handle the final statement in `SyntaxFactory::block_expr` properly
This caused a bug that was rather tricky to hunt down!
Giga Bowser 2024-12-10
parent d881208 · commit 59cd717
-rw-r--r--crates/syntax/src/ast/syntax_factory/constructors.rs21
1 files changed, 15 insertions, 6 deletions
diff --git a/crates/syntax/src/ast/syntax_factory/constructors.rs b/crates/syntax/src/ast/syntax_factory/constructors.rs
index 54f17bd721..44f67d83dc 100644
--- a/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -58,22 +58,31 @@ impl SyntaxFactory {
tail_expr: Option<ast::Expr>,
) -> ast::BlockExpr {
let stmts = stmts.into_iter().collect_vec();
- let input = stmts.iter().map(|it| it.syntax().clone()).collect_vec();
+ let mut input = stmts.iter().map(|it| it.syntax().clone()).collect_vec();
let ast = make::block_expr(stmts, tail_expr.clone()).clone_for_update();
- if let Some((mut mapping, stmt_list)) = self.mappings().zip(ast.stmt_list()) {
+ if let Some(mut mapping) = self.mappings() {
+ let stmt_list = ast.stmt_list().unwrap();
let mut builder = SyntaxMappingBuilder::new(stmt_list.syntax().clone());
+ if let Some(input) = tail_expr {
+ builder.map_node(
+ input.syntax().clone(),
+ stmt_list.tail_expr().unwrap().syntax().clone(),
+ );
+ } else if let Some(ast_tail) = stmt_list.tail_expr() {
+ // The parser interpreted the last statement (probably a statement with a block) as an Expr
+ let last_stmt = input.pop().unwrap();
+
+ builder.map_node(last_stmt, ast_tail.syntax().clone());
+ }
+
builder.map_children(
input.into_iter(),
stmt_list.statements().map(|it| it.syntax().clone()),
);
- if let Some((input, output)) = tail_expr.zip(stmt_list.tail_expr()) {
- builder.map_node(input.syntax().clone(), output.syntax().clone());
- }
-
builder.finish(&mut mapping);
}