Skip to content

Commit 2e472bb

Browse files
bugadanimatklad
andcommitted
Fix replace_match_with_if_let removing blocks with modifiers
Co-authored-by: Aleksey Kladov <[email protected]>
1 parent 8e9ccbf commit 2e472bb

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

crates/ide_assists/src/handlers/replace_if_let_with_match.rs

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -207,21 +207,23 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext)
207207
"Replace match with if let",
208208
target,
209209
move |edit| {
210+
fn make_block_expr(expr: ast::Expr) -> ast::BlockExpr {
211+
// Blocks with modifiers (unsafe, async, etc.) are parsed as BlockExpr, but are
212+
// formatted without enclosing braces. If we encounter such block exprs,
213+
// wrap them in another BlockExpr.
214+
match expr {
215+
ast::Expr::BlockExpr(block) if block.modifier().is_none() => block,
216+
expr => make::block_expr(iter::empty(), Some(expr)),
217+
}
218+
}
219+
210220
let condition = make::condition(scrutinee, Some(if_let_pat));
211-
let then_block = match then_expr.reset_indent() {
212-
ast::Expr::BlockExpr(block) => block,
213-
expr => make::block_expr(iter::empty(), Some(expr)),
214-
};
221+
let then_block = make_block_expr(then_expr.reset_indent());
215222
let else_expr = if is_empty_expr(&else_expr) { None } else { Some(else_expr) };
216223
let if_let_expr = make::expr_if(
217224
condition,
218225
then_block,
219-
else_expr
220-
.map(|expr| match expr {
221-
ast::Expr::BlockExpr(block) => block,
222-
expr => (make::block_expr(iter::empty(), Some(expr))),
223-
})
224-
.map(ast::ElseBranch::Block),
226+
else_expr.map(make_block_expr).map(ast::ElseBranch::Block),
225227
)
226228
.indent(IndentLevel::from_node(match_expr.syntax()));
227229

@@ -917,4 +919,30 @@ fn foo() {
917919
"#,
918920
);
919921
}
922+
923+
#[test]
924+
fn test_replace_match_with_if_let_keeps_unsafe_block() {
925+
check_assist(
926+
replace_match_with_if_let,
927+
r#"
928+
impl VariantData {
929+
pub fn is_struct(&self) -> bool {
930+
$0match *self {
931+
VariantData::Struct(..) => true,
932+
_ => unsafe { unreachable_unchecked() },
933+
}
934+
}
935+
} "#,
936+
r#"
937+
impl VariantData {
938+
pub fn is_struct(&self) -> bool {
939+
if let VariantData::Struct(..) = *self {
940+
true
941+
} else {
942+
unsafe { unreachable_unchecked() }
943+
}
944+
}
945+
} "#,
946+
)
947+
}
920948
}

0 commit comments

Comments
 (0)