Unnamed repository; edit this file 'description' to name the repository.
fix: generate delegate methods filters out functions that already exist
on the struct's impls
Jake Heinz 2023-05-02
parent 2fdd1ac · commit a86c431
-rw-r--r--crates/ide-assists/src/handlers/generate_delegate_methods.rs25
-rw-r--r--crates/ide-assists/src/utils.rs7
2 files changed, 30 insertions, 2 deletions
diff --git a/crates/ide-assists/src/handlers/generate_delegate_methods.rs b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
index aecb3826e4..a0813c9115 100644
--- a/crates/ide-assists/src/handlers/generate_delegate_methods.rs
+++ b/crates/ide-assists/src/handlers/generate_delegate_methods.rs
@@ -86,7 +86,8 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
for method in methods {
let adt = ast::Adt::Struct(strukt.clone());
let name = method.name(ctx.db()).to_string();
- let impl_def = find_struct_impl(ctx, &adt, &[name]).flatten();
+ // if `find_struct_impl` returns None, that means that a function named `name` already exists.
+ let Some(impl_def) = find_struct_impl(ctx, &adt, &[name]) else { continue; };
acc.add_group(
&GroupLabel("Generate delegate methods…".to_owned()),
AssistId("generate_delegate_methods", AssistKind::Generate),
@@ -380,4 +381,26 @@ struct Person {
}"#,
)
}
+
+ #[test]
+ fn test_generate_not_eligible_if_fn_exists() {
+ check_assist_not_applicable(
+ generate_delegate_methods,
+ r#"
+struct Age(u8);
+impl Age {
+ fn age(&self) -> u8 {
+ self.0
+ }
+}
+
+struct Person {
+ ag$0e: Age,
+}
+impl Person {
+ fn age(&self) -> u8 { 0 }
+}
+"#,
+ );
+ }
}
diff --git a/crates/ide-assists/src/utils.rs b/crates/ide-assists/src/utils.rs
index f323ebcf7a..77f4b0e3e0 100644
--- a/crates/ide-assists/src/utils.rs
+++ b/crates/ide-assists/src/utils.rs
@@ -338,7 +338,12 @@ fn calc_depth(pat: &ast::Pat, depth: usize) -> usize {
/// `find_struct_impl` looks for impl of a struct, but this also has additional feature
/// where it takes a list of function names and check if they exist inside impl_, if
-/// even one match is found, it returns None
+/// even one match is found, it returns None.
+///
+/// That means this function can have 3 potential return values:
+/// - `None`: an impl exists, but one of the function names within the impl matches one of the provided names.
+/// - `Some(None)`: no impl exists.
+/// - `Some(Some(_))`: an impl exists, with no matching function names.
pub(crate) fn find_struct_impl(
ctx: &AssistContext<'_>,
adt: &ast::Adt,