From 5b8ec210483321623a420eb654504a02ed4428a3 Mon Sep 17 00:00:00 2001 From: A4-Tacks Date: Fri, 5 Jun 2026 17:44:53 +0800 Subject: [PATCH] fix: offer on other if let for replace_if_let_with_match Example --- ```rust fn foo(state: Option, enable: Option) -> i32 { if let Some(true) = state { 1 } else if let Some(true) = enable { 2 } else { 0 } } ``` **Before this PR** Assist not applicable **After this PR** ```rust fn foo(state: Option, enable: Option) -> i32 { match state { Some(true) => 1, _ if let Some(true) = enable => 2, _ => 0, } } ``` --- .../src/handlers/replace_if_let_with_match.rs | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs index ff2d0544b2a1..371b8216c8a6 100644 --- a/crates/ide-assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/ide-assists/src/handlers/replace_if_let_with_match.rs @@ -51,6 +51,8 @@ pub(crate) fn replace_if_let_with_match( acc: &mut Assists, ctx: &AssistContext<'_, '_>, ) -> Option<()> { + let (editor, _) = SyntaxEditor::new(ctx.source_file().syntax().clone()); + let make = editor.make(); let if_expr: ast::IfExpr = ctx.find_node_at_offset()?; let available_range = TextRange::new( if_expr.syntax().text_range().start(), @@ -82,14 +84,22 @@ pub(crate) fn replace_if_let_with_match( let cond = if_expr.condition()?; let (cond, guard) = match let_and_guard(&cond, ctx)? { (None, guard) => (None, Some(guard?)), - (Some((pat, expr)), guard) => { - if scrutinee_to_be_expr.syntax().text() != expr.syntax().text() { - // Only if all condition expressions are equal we can merge them into a match - return None; - } + (Some((pat, expr)), guard) + if scrutinee_to_be_expr.syntax().text() == expr.syntax().text() => + { pat_seen = true; (Some(pat), guard) } + (Some((pat, expr)), guard) => { + let mut guard_chain = make.expr_let(pat, expr).into(); + if let Some(guard) = guard { + let guard = wrap_paren(guard, make, ast::prec::ExprPrecedence::LAnd); + guard_chain = make + .expr_bin(guard_chain, ast::BinaryOp::LogicOp(ast::LogicOp::And), guard) + .into() + } + (None, Some(guard_chain)) + } }; let guard = if let Some(guard) = &guard { Some(guard.dedent(indent).indent(IndentLevel(1))) @@ -114,7 +124,6 @@ pub(crate) fn replace_if_let_with_match( format!("Replace if{let_} with match"), available_range, move |builder| { - let editor = builder.make_editor(if_expr.syntax()); let make = editor.make(); let match_expr: ast::Expr = { let else_arm = make_else_arm(ctx, make, else_block, &cond_bodies); @@ -869,6 +878,8 @@ impl VariantData { false } else if cond() { true + } else if let Some(rewrite) = other { + rewrite } else { bar( 123 @@ -884,6 +895,7 @@ impl VariantData { VariantData::Struct(..) => true, VariantData::Tuple(..) => false, _ if cond() => true, + _ if let Some(rewrite) = other => rewrite, _ => { bar( 123