Skip to content

Commit 86e3e3f

Browse files
fix: correctly parenthesize inverted condition in convert_if_to_bool_then
The convert_if_to_bool_then assist was producing incorrect code when the Some branch was in the else arm and the condition was a method call expression (e.g. is_empty()). Before: if test.is_empty() { None } else { Some(()) } was incorrectly rewritten to: test.is_empty().then(|| ()) After (correct): (!test.is_empty()).then(|| ()) Root cause: the parenthesization check ran on the original condition before inversion. When invert_boolean_expression produced a PrefixExpr (e.g. !test.is_empty()), it was not being parenthesized because the check had already passed on the original MethodCallExpr. Fix: move the parenthesization check to after the inversion step so it correctly detects PrefixExpr and wraps it in parentheses. A regression test has been added to cover this case.
1 parent af68fc6 commit 86e3e3f

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

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

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
102102
ast::Expr::BlockExpr(block) => unwrap_trivial_block(block),
103103
e => e,
104104
};
105+
let cond = if invert_cond {
106+
invert_boolean_expression(&make, cond)
107+
} else {
108+
cond.clone_for_update()
109+
};
105110

106111
let parenthesize = matches!(
107112
cond,
@@ -123,11 +128,7 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
123128
| ast::Expr::WhileExpr(_)
124129
| ast::Expr::YieldExpr(_)
125130
);
126-
let cond = if invert_cond {
127-
invert_boolean_expression(&make, cond)
128-
} else {
129-
cond.clone_for_update()
130-
};
131+
131132
let cond = if parenthesize { make.expr_paren(cond).into() } else { cond };
132133
let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into()));
133134
let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list);
@@ -588,6 +589,25 @@ fn main() {
588589
None
589590
}
590591
}
592+
",
593+
);
594+
}
595+
#[test]
596+
fn convert_if_to_bool_then_invert_method_call() {
597+
check_assist(
598+
convert_if_to_bool_then,
599+
r"
600+
//- minicore:option
601+
fn main() {
602+
let test = &[()];
603+
let value = if$0 test.is_empty() { None } else { Some(()) };
604+
}
605+
",
606+
r"
607+
fn main() {
608+
let test = &[()];
609+
let value = (!test.is_empty()).then(|| ());
610+
}
591611
",
592612
);
593613
}

0 commit comments

Comments
 (0)