about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-03-25 13:20:12 +0000
committerGitHub <noreply@github.com>2025-03-25 13:20:12 +0000
commit65f8181523ba78d88b98177a05e56ba6ea351653 (patch)
treed58885ad7ddf8c052b56a50229ce1fe68d9dc758
parente142e4e9c9b8d6f2437e22c84741ec787eb4d101 (diff)
parent5100bfd57a77c3cf635a88835a10a70801bc25cb (diff)
downloadrust-65f8181523ba78d88b98177a05e56ba6ea351653.tar.gz
rust-65f8181523ba78d88b98177a05e56ba6ea351653.zip
Merge pull request #19433 from snprajwal/fix-replace-let-else
fix(ide-assists): `let else` to `if let else`
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs49
1 files changed, 41 insertions, 8 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
index a2dcbf948d8..fd17231a7b6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
@@ -45,19 +45,31 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_>
             let mut editor = builder.make_editor(let_stmt.syntax());
             let make = SyntaxFactory::new();
             let ty = ctx.sema.type_of_expr(&init);
-            let happy_variant = ty
-                .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
-                .map(|it| it.happy_case());
-            let pat = match happy_variant {
-                None => original_pat,
-                Some(var_name) => {
-                    make.tuple_struct_pat(make.ident_path(var_name), [original_pat]).into()
+            let pat = if let_stmt.let_else().is_some() {
+                // Do not add the wrapper type that implements `Try`,
+                // since the statement already wraps the pattern.
+                original_pat
+            } else {
+                let happy_variant = ty
+                    .and_then(|ty| TryEnum::from_ty(&ctx.sema, &ty.adjusted()))
+                    .map(|it| it.happy_case());
+                match happy_variant {
+                    None => original_pat,
+                    Some(var_name) => {
+                        make.tuple_struct_pat(make.ident_path(var_name), [original_pat]).into()
+                    }
                 }
             };
 
             let block = make.block_expr([], None);
             block.indent(IndentLevel::from_node(let_stmt.syntax()));
-            let if_expr = make.expr_if(make.expr_let(pat, init).into(), block, None);
+            let if_expr = make.expr_if(
+                make.expr_let(pat, init).into(),
+                block,
+                let_stmt
+                    .let_else()
+                    .and_then(|let_else| let_else.block_expr().map(ast::ElseBranch::from)),
+            );
             let if_stmt = make.expr_stmt(if_expr.into());
 
             editor.replace(let_stmt.syntax(), if_stmt.syntax());
@@ -94,4 +106,25 @@ fn main() {
             ",
         )
     }
+
+    #[test]
+    fn replace_let_else() {
+        check_assist(
+            replace_let_with_if_let,
+            r"
+//- minicore: option
+fn main() {
+    let a = Some(1);
+    $0let Some(_) = a else { unreachable!() };
+}
+            ",
+            r"
+fn main() {
+    let a = Some(1);
+    if let Some(_) = a {
+    } else { unreachable!() }
+}
+            ",
+        )
+    }
 }