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.rs | 59 |
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!() } +} + ", + ) + } } |