Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/ide-assists/src/handlers/replace_method_eager_lazy.rs | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs b/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs index 7aa9a82109..39e15578cb 100644 --- a/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs +++ b/crates/ide-assists/src/handlers/replace_method_eager_lazy.rs @@ -1,5 +1,5 @@ use hir::Semantics; -use ide_db::{RootDatabase, assists::AssistId, defs::Definition}; +use ide_db::{RootDatabase, assists::AssistId, defs::Definition, famous_defs::FamousDefs}; use syntax::{ AstNode, ast::{self, Expr, HasArgList, make, syntax_factory::SyntaxFactory}, @@ -64,7 +64,20 @@ pub(crate) fn replace_with_lazy_method( format!("Replace {method_name} with {method_name_lazy}"), call.syntax().text_range(), |builder| { - let closured = into_closure(&last_arg, &method_name_lazy); + let param_name = match &*method_name_lazy { + "and_then" => "it", + "or_else" | "unwrap_or_else" => { + if let Some(result) = FamousDefs(&ctx.sema, scope.krate()).core_result_Result() + && result.ty(ctx.db()).could_unify_with(ctx.db(), &receiver_ty) + { + "e" + } else { + "" + } + } + _ => "", + }; + let closured = into_closure(&last_arg, param_name); builder.replace(method_name.syntax().text_range(), method_name_lazy); builder.replace_ast(last_arg, closured); }, @@ -83,7 +96,7 @@ fn lazy_method_name(name: &str) -> String { } } -fn into_closure(param: &Expr, name_lazy: &str) -> Expr { +fn into_closure(param: &Expr, param_name: &str) -> Expr { (|| { if let ast::Expr::CallExpr(call) = param { if call.arg_list()?.args().count() == 0 { Some(call.expr()?) } else { None } @@ -92,8 +105,9 @@ fn into_closure(param: &Expr, name_lazy: &str) -> Expr { } })() .unwrap_or_else(|| { - let pats = (name_lazy == "and_then") - .then(|| make::untyped_param(make::ext::simple_ident_pat(make::name("it")).into())); + let pats = (!param_name.is_empty()).then(|| { + make::untyped_param(make::ext::simple_ident_pat(make::name(param_name)).into()) + }); make::expr_closure(pats, param.clone()).into() }) } @@ -213,7 +227,7 @@ mod tests { check_assist( replace_with_lazy_method, r#" -//- minicore: option, fn +//- minicore: option, result, fn fn foo() { let foo = Some(1); return foo.unwrap_$0or(2); @@ -229,6 +243,26 @@ fn foo() { } #[test] + fn replace_or_with_or_else_with_parameter() { + check_assist( + replace_with_lazy_method, + r#" +//- minicore: option, result, fn +fn foo() { + let foo = Ok(1); + return foo.unwrap_$0or(2); +} +"#, + r#" +fn foo() { + let foo = Ok(1); + return foo.unwrap_or_else(|e| 2); +} +"#, + ) + } + + #[test] fn replace_or_with_or_else_call() { check_assist( replace_with_lazy_method, |