Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/handlers/replace_let_with_if_let.rs')
-rw-r--r--crates/ide-assists/src/handlers/replace_let_with_if_let.rs59
1 files changed, 46 insertions, 13 deletions
diff --git a/crates/ide-assists/src/handlers/replace_let_with_if_let.rs b/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
index c071d3022d..90f4ff7ad2 100644
--- a/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
+++ b/crates/ide-assists/src/handlers/replace_let_with_if_let.rs
@@ -1,10 +1,10 @@
use ide_db::ty_filter::TryEnum;
use syntax::{
- ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory},
AstNode, T,
+ ast::{self, edit::IndentLevel, edit_in_place::Indent, syntax_factory::SyntaxFactory},
};
-use crate::{AssistContext, AssistId, AssistKind, Assists};
+use crate::{AssistContext, AssistId, Assists};
// Assist: replace_let_with_if_let
//
@@ -38,31 +38,43 @@ pub(crate) fn replace_let_with_if_let(acc: &mut Assists, ctx: &AssistContext<'_>
let target = let_kw.text_range();
acc.add(
- AssistId("replace_let_with_if_let", AssistKind::RefactorRewrite),
+ AssistId::refactor_rewrite("replace_let_with_if_let"),
"Replace let with if let",
target,
|builder| {
let mut editor = builder.make_editor(let_stmt.syntax());
- let make = SyntaxFactory::new();
+ let make = SyntaxFactory::with_mappings();
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());
editor.add_mappings(make.finish_with_mappings());
- builder.add_file_edits(ctx.file_id(), editor);
+ builder.add_file_edits(ctx.vfs_file_id(), editor);
},
)
}
@@ -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!() }
+}
+ ",
+ )
+ }
}