Skip to content

Commit 6fd5769

Browse files
committed
Auto merge of rust-lang#14011 - bvanjoi:fix-unwrap-block, r=jonas-schievink
fix(ide-assists): unwrap block when it parent is let stmt fix rust-lang#13990
2 parents 3e57a77 + 90b1222 commit 6fd5769

File tree

1 file changed

+116
-46
lines changed

1 file changed

+116
-46
lines changed

crates/ide-assists/src/handlers/unwrap_block.rs

+116-46
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use syntax::{
22
ast::{
33
self,
44
edit::{AstNodeEdit, IndentLevel},
5+
make,
56
},
67
AstNode, SyntaxKind, TextRange, T,
78
};
@@ -37,61 +38,89 @@ pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option
3738
parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
3839
}
3940

40-
if matches!(parent.kind(), SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT | SyntaxKind::LET_STMT)
41-
{
42-
return acc.add(assist_id, assist_label, target, |builder| {
41+
let kind = parent.kind();
42+
if matches!(kind, SyntaxKind::STMT_LIST | SyntaxKind::EXPR_STMT) {
43+
acc.add(assist_id, assist_label, target, |builder| {
4344
builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
44-
});
45-
}
46-
47-
let parent = ast::Expr::cast(parent)?;
48-
49-
match parent.clone() {
50-
ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
51-
ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
52-
ast::Expr::IfExpr(if_expr) => {
53-
let then_branch = if_expr.then_branch()?;
54-
if then_branch == block {
55-
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
56-
// For `else if` blocks
57-
let ancestor_then_branch = ancestor.then_branch()?;
58-
45+
})
46+
} else if matches!(kind, SyntaxKind::LET_STMT) {
47+
let parent = ast::LetStmt::cast(parent)?;
48+
let pattern = ast::Pat::cast(parent.syntax().first_child()?)?;
49+
let ty = parent.ty();
50+
let list = block.stmt_list()?;
51+
let replaced = match list.syntax().last_child() {
52+
Some(last) => {
53+
let stmts: Vec<ast::Stmt> = list.statements().collect();
54+
let initializer = ast::Expr::cast(last.clone())?;
55+
let let_stmt = make::let_stmt(pattern, ty, Some(initializer));
56+
if stmts.len() > 0 {
57+
let block = make::block_expr(stmts, None);
58+
format!(
59+
"{}\n {}",
60+
update_expr_string(block.to_string()),
61+
let_stmt.to_string()
62+
)
63+
} else {
64+
let_stmt.to_string()
65+
}
66+
}
67+
None => {
68+
let empty_tuple = make::expr_tuple([]);
69+
make::let_stmt(pattern, ty, Some(empty_tuple)).to_string()
70+
}
71+
};
72+
acc.add(assist_id, assist_label, target, |builder| {
73+
builder.replace(parent.syntax().text_range(), replaced);
74+
})
75+
} else {
76+
let parent = ast::Expr::cast(parent)?;
77+
match parent.clone() {
78+
ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
79+
ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
80+
ast::Expr::IfExpr(if_expr) => {
81+
let then_branch = if_expr.then_branch()?;
82+
if then_branch == block {
83+
if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
84+
// For `else if` blocks
85+
let ancestor_then_branch = ancestor.then_branch()?;
86+
87+
return acc.add(assist_id, assist_label, target, |edit| {
88+
let range_to_del_else_if = TextRange::new(
89+
ancestor_then_branch.syntax().text_range().end(),
90+
l_curly_token.text_range().start(),
91+
);
92+
let range_to_del_rest = TextRange::new(
93+
then_branch.syntax().text_range().end(),
94+
if_expr.syntax().text_range().end(),
95+
);
96+
97+
edit.delete(range_to_del_rest);
98+
edit.delete(range_to_del_else_if);
99+
edit.replace(
100+
target,
101+
update_expr_string_without_newline(then_branch.to_string()),
102+
);
103+
});
104+
}
105+
} else {
59106
return acc.add(assist_id, assist_label, target, |edit| {
60-
let range_to_del_else_if = TextRange::new(
61-
ancestor_then_branch.syntax().text_range().end(),
62-
l_curly_token.text_range().start(),
63-
);
64-
let range_to_del_rest = TextRange::new(
107+
let range_to_del = TextRange::new(
65108
then_branch.syntax().text_range().end(),
66-
if_expr.syntax().text_range().end(),
109+
l_curly_token.text_range().start(),
67110
);
68111

69-
edit.delete(range_to_del_rest);
70-
edit.delete(range_to_del_else_if);
71-
edit.replace(
72-
target,
73-
update_expr_string_without_newline(then_branch.to_string()),
74-
);
112+
edit.delete(range_to_del);
113+
edit.replace(target, update_expr_string_without_newline(block.to_string()));
75114
});
76115
}
77-
} else {
78-
return acc.add(assist_id, assist_label, target, |edit| {
79-
let range_to_del = TextRange::new(
80-
then_branch.syntax().text_range().end(),
81-
l_curly_token.text_range().start(),
82-
);
83-
84-
edit.delete(range_to_del);
85-
edit.replace(target, update_expr_string_without_newline(block.to_string()));
86-
});
87116
}
88-
}
89-
_ => return None,
90-
};
117+
_ => return None,
118+
};
91119

92-
acc.add(assist_id, assist_label, target, |builder| {
93-
builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
94-
})
120+
acc.add(assist_id, assist_label, target, |builder| {
121+
builder.replace(parent.syntax().text_range(), update_expr_string(block.to_string()));
122+
})
123+
}
95124
}
96125

97126
fn update_expr_string(expr_string: String) -> String {
@@ -724,6 +753,19 @@ fn main() -> i32 {
724753
check_assist(
725754
unwrap_block,
726755
r#"
756+
fn main() {
757+
let x = {$0};
758+
}
759+
"#,
760+
r#"
761+
fn main() {
762+
let x = ();
763+
}
764+
"#,
765+
);
766+
check_assist(
767+
unwrap_block,
768+
r#"
727769
fn main() {
728770
let x = {$0
729771
bar
@@ -734,6 +776,34 @@ fn main() {
734776
fn main() {
735777
let x = bar;
736778
}
779+
"#,
780+
);
781+
check_assist(
782+
unwrap_block,
783+
r#"
784+
fn main() -> i32 {
785+
let _ = {$01; 2};
786+
}
787+
"#,
788+
r#"
789+
fn main() -> i32 {
790+
1;
791+
let _ = 2;
792+
}
793+
"#,
794+
);
795+
check_assist(
796+
unwrap_block,
797+
r#"
798+
fn main() -> i32 {
799+
let mut a = {$01; 2};
800+
}
801+
"#,
802+
r#"
803+
fn main() -> i32 {
804+
1;
805+
let mut a = 2;
806+
}
737807
"#,
738808
);
739809
}

0 commit comments

Comments
 (0)