Skip to content

Commit d7a0302

Browse files
committed
handle divergence in child if expr for unnecessary else diagnostic fix
1 parent 62cc4f9 commit d7a0302

File tree

1 file changed

+73
-6
lines changed

1 file changed

+73
-6
lines changed

crates/ide-diagnostics/src/handlers/remove_unnecessary_else.rs

Lines changed: 73 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,43 @@ fn fixes(ctx: &DiagnosticsContext<'_>, d: &RemoveUnnecessaryElse) -> Option<Vec<
3535
let if_expr = d.if_expr.value.to_node(&root);
3636
let if_expr = ctx.sema.original_ast_node(if_expr.clone())?;
3737

38-
let indent = IndentLevel::from_node(if_expr.syntax());
39-
let replacement = match if_expr.else_branch()? {
38+
let mut indent = IndentLevel::from_node(if_expr.syntax());
39+
let has_parent_if_expr = if_expr.syntax().parent().and_then(ast::IfExpr::cast).is_some();
40+
if has_parent_if_expr {
41+
indent = indent + 1;
42+
}
43+
let else_replacement = match if_expr.else_branch()? {
4044
ast::ElseBranch::Block(ref block) => {
4145
block.statements().map(|stmt| format!("\n{indent}{stmt}")).join("")
4246
}
4347
ast::ElseBranch::IfExpr(ref nested_if_expr) => {
4448
format!("\n{indent}{nested_if_expr}")
4549
}
4650
};
47-
let range = TextRange::new(
48-
if_expr.then_branch()?.syntax().text_range().end(),
49-
if_expr.syntax().text_range().end(),
50-
);
51+
let (replacement, range) = if has_parent_if_expr {
52+
let base_indent = IndentLevel::from_node(if_expr.syntax());
53+
let then_indent = base_indent + 1;
54+
let then_child_indent = then_indent + 1;
55+
56+
let condition = if_expr.condition()?;
57+
let then_stmts = if_expr
58+
.then_branch()?
59+
.statements()
60+
.map(|stmt| format!("\n{then_child_indent}{stmt}"))
61+
.join("");
62+
let then_replacement =
63+
format!("\n{then_indent}if {condition} {{{then_stmts}\n{then_indent}}}",);
64+
let replacement = format!("{{{then_replacement}{else_replacement}\n{base_indent}}}");
65+
(replacement, if_expr.syntax().text_range())
66+
} else {
67+
(
68+
else_replacement,
69+
TextRange::new(
70+
if_expr.then_branch()?.syntax().text_range().end(),
71+
if_expr.syntax().text_range().end(),
72+
),
73+
)
74+
};
5175

5276
let edit = TextEdit::replace(range, replacement);
5377
let source_change =
@@ -143,6 +167,49 @@ fn test() {
143167
);
144168
}
145169

170+
#[test]
171+
fn remove_unnecessary_else_for_return_in_child_if_expr() {
172+
check_diagnostics(
173+
r#"
174+
fn test() {
175+
if foo {
176+
do_something();
177+
} else if qux {
178+
return bar;
179+
} else {
180+
//^^^^ 💡 weak: remove unnecessary else block
181+
do_something_else();
182+
}
183+
}
184+
"#,
185+
);
186+
check_fix(
187+
r#"
188+
fn test() {
189+
if foo {
190+
do_something();
191+
} else if qux {
192+
return bar;
193+
} else$0 {
194+
do_something_else();
195+
}
196+
}
197+
"#,
198+
r#"
199+
fn test() {
200+
if foo {
201+
do_something();
202+
} else {
203+
if qux {
204+
return bar;
205+
}
206+
do_something_else();
207+
}
208+
}
209+
"#,
210+
);
211+
}
212+
146213
#[test]
147214
fn remove_unnecessary_else_for_break() {
148215
check_diagnostics(

0 commit comments

Comments
 (0)