mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2026-04-17 21:24:52 +00:00
Merge pull request #20967 from A4-Tacks/replace-eager-lazy-and-then
Fix not applicable on `and` for replace_method_eager_lazy
This commit is contained in:
@@ -35,10 +35,7 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_
|
||||
let (_, receiver_ty) = callable.receiver_param(ctx.sema.db)?;
|
||||
let n_params = callable.n_params() + 1;
|
||||
|
||||
let method_name_lazy = format!(
|
||||
"{method_name}{}",
|
||||
if method_name.text().ends_with("or") { "_else" } else { "_with" }
|
||||
);
|
||||
let method_name_lazy = lazy_method_name(&method_name.text());
|
||||
|
||||
receiver_ty.iterate_method_candidates_with_traits(
|
||||
ctx.sema.db,
|
||||
@@ -70,6 +67,18 @@ pub(crate) fn replace_with_lazy_method(acc: &mut Assists, ctx: &AssistContext<'_
|
||||
)
|
||||
}
|
||||
|
||||
fn lazy_method_name(name: &str) -> String {
|
||||
if ends_is(name, "or") {
|
||||
format!("{name}_else")
|
||||
} else if ends_is(name, "and") {
|
||||
format!("{name}_then")
|
||||
} else if ends_is(name, "then_some") {
|
||||
name.strip_suffix("_some").unwrap().to_owned()
|
||||
} else {
|
||||
format!("{name}_with")
|
||||
}
|
||||
}
|
||||
|
||||
fn into_closure(param: &Expr) -> Expr {
|
||||
(|| {
|
||||
if let ast::Expr::CallExpr(call) = param {
|
||||
@@ -117,9 +126,7 @@ pub(crate) fn replace_with_eager_method(acc: &mut Assists, ctx: &AssistContext<'
|
||||
}
|
||||
|
||||
let method_name_text = method_name.text();
|
||||
let method_name_eager = method_name_text
|
||||
.strip_suffix("_else")
|
||||
.or_else(|| method_name_text.strip_suffix("_with"))?;
|
||||
let method_name_eager = eager_method_name(&method_name_text)?;
|
||||
|
||||
receiver_ty.iterate_method_candidates_with_traits(
|
||||
ctx.sema.db,
|
||||
@@ -156,6 +163,20 @@ fn into_call(param: &Expr) -> Expr {
|
||||
.unwrap_or_else(|| make::expr_call(param.clone(), make::arg_list(Vec::new())).into())
|
||||
}
|
||||
|
||||
fn eager_method_name(name: &str) -> Option<&str> {
|
||||
if name == "then" {
|
||||
return Some("then_some");
|
||||
}
|
||||
|
||||
name.strip_suffix("_else")
|
||||
.or_else(|| name.strip_suffix("_then"))
|
||||
.or_else(|| name.strip_suffix("_with"))
|
||||
}
|
||||
|
||||
fn ends_is(name: &str, end: &str) -> bool {
|
||||
name.strip_suffix(end).is_some_and(|s| s.is_empty() || s.ends_with('_'))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::tests::check_assist;
|
||||
@@ -294,6 +315,86 @@ fn foo() {
|
||||
let foo = Some("foo");
|
||||
return foo.map_or(42, |v| v.len());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_and_with_and_then() {
|
||||
check_assist(
|
||||
replace_with_lazy_method,
|
||||
r#"
|
||||
//- minicore: option, fn
|
||||
fn foo() {
|
||||
let foo = Some("foo");
|
||||
return foo.and$0(Some("bar"));
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn foo() {
|
||||
let foo = Some("foo");
|
||||
return foo.and_then(|| Some("bar"));
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_and_then_with_and() {
|
||||
check_assist(
|
||||
replace_with_eager_method,
|
||||
r#"
|
||||
//- minicore: option, fn
|
||||
fn foo() {
|
||||
let foo = Some("foo");
|
||||
return foo.and_then$0(|| Some("bar"));
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn foo() {
|
||||
let foo = Some("foo");
|
||||
return foo.and(Some("bar"));
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_then_some_with_then() {
|
||||
check_assist(
|
||||
replace_with_lazy_method,
|
||||
r#"
|
||||
//- minicore: option, fn, bool_impl
|
||||
fn foo() {
|
||||
let foo = true;
|
||||
let x = foo.then_some$0(2);
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn foo() {
|
||||
let foo = true;
|
||||
let x = foo.then(|| 2);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn replace_then_with_then_some() {
|
||||
check_assist(
|
||||
replace_with_eager_method,
|
||||
r#"
|
||||
//- minicore: option, fn, bool_impl
|
||||
fn foo() {
|
||||
let foo = true;
|
||||
let x = foo.then$0(|| 2);
|
||||
}
|
||||
"#,
|
||||
r#"
|
||||
fn foo() {
|
||||
let foo = true;
|
||||
let x = foo.then_some(2);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1988,6 +1988,10 @@ pub mod num {
|
||||
// region:bool_impl
|
||||
#[lang = "bool"]
|
||||
impl bool {
|
||||
pub fn then_some<T>(self, t: T) -> Option<T> {
|
||||
if self { Some(t) } else { None }
|
||||
}
|
||||
|
||||
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
||||
if self { Some(f()) } else { None }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user