]> git.lizzy.rs Git - rust.git/blobdiff - crates/ide_assists/src/handlers/replace_let_with_if_let.rs
Merge #11481
[rust.git] / crates / ide_assists / src / handlers / replace_let_with_if_let.rs
index f811234c07fcb08d04f0597fdc4b3b7719907a8c..a5fa8a110d31eed11ca4b4f0b9cad6b0a46fc8bc 100644 (file)
@@ -14,7 +14,7 @@
 
 // Assist: replace_let_with_if_let
 //
-// Replaces `let` with an `if-let`.
+// Replaces `let` with an `if let`.
 //
 // ```
 // # enum Option<T> { Some(T), None }
 // ```
 pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
     let let_kw = ctx.find_token_syntax_at_offset(T![let])?;
-    let let_stmt = let_kw.ancestors().find_map(ast::LetStmt::cast)?;
+    let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?;
     let init = let_stmt.initializer()?;
     let original_pat = let_stmt.pat()?;
-    let ty = ctx.sema.type_of_expr(&init)?;
-    let happy_variant = TryEnum::from_ty(&ctx.sema, &ty).map(|it| it.happy_case());
 
     let target = let_kw.text_range();
     acc.add(
         AssistId("replace_let_with_if_let", AssistKind::RefactorRewrite),
-        "Replace with if-let",
+        "Replace let with if let",
         target,
         |edit| {
-            let with_placeholder: ast::Pat = match happy_variant {
-                None => make::wildcard_pat().into(),
-                Some(var_name) => make::tuple_struct_pat(
-                    make::ext::ident_path(var_name),
-                    once(make::wildcard_pat().into()),
-                )
-                .into(),
+            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::ext::ident_path(var_name), once(original_pat))
+                        .into()
+                }
             };
+
             let block =
-                make::block_expr(None, None).indent(IndentLevel::from_node(let_stmt.syntax()));
-            let if_ = make::expr_if(make::condition(init, Some(with_placeholder)), block, None);
+                make::ext::empty_block_expr().indent(IndentLevel::from_node(let_stmt.syntax()));
+            let if_ = make::expr_if(make::expr_let(pat, init).into(), block, None);
             let stmt = make::expr_stmt(if_);
 
-            let placeholder = stmt.syntax().descendants().find_map(ast::WildcardPat::cast).unwrap();
-            let stmt = stmt.replace_descendant(placeholder.into(), original_pat);
-
             edit.replace_ast(ast::Stmt::from(let_stmt), ast::Stmt::from(stmt));
         },
     )