Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 9c0c13e

Browse files
committed
Auto merge of rust-lang#14707 - jhgg:fix/generate-delegate-method-filtering, r=lnicola
fix: generate delegate methods filters out functions that already exist on the struct's impls fixes rust-lang#14703
2 parents 2fdd1ac + a86c431 commit 9c0c13e

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

crates/ide-assists/src/handlers/generate_delegate_methods.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
8686
for method in methods {
8787
let adt = ast::Adt::Struct(strukt.clone());
8888
let name = method.name(ctx.db()).to_string();
89-
let impl_def = find_struct_impl(ctx, &adt, &[name]).flatten();
89+
// if `find_struct_impl` returns None, that means that a function named `name` already exists.
90+
let Some(impl_def) = find_struct_impl(ctx, &adt, &[name]) else { continue; };
9091
acc.add_group(
9192
&GroupLabel("Generate delegate methods…".to_owned()),
9293
AssistId("generate_delegate_methods", AssistKind::Generate),
@@ -380,4 +381,26 @@ struct Person {
380381
}"#,
381382
)
382383
}
384+
385+
#[test]
386+
fn test_generate_not_eligible_if_fn_exists() {
387+
check_assist_not_applicable(
388+
generate_delegate_methods,
389+
r#"
390+
struct Age(u8);
391+
impl Age {
392+
fn age(&self) -> u8 {
393+
self.0
394+
}
395+
}
396+
397+
struct Person {
398+
ag$0e: Age,
399+
}
400+
impl Person {
401+
fn age(&self) -> u8 { 0 }
402+
}
403+
"#,
404+
);
405+
}
383406
}

crates/ide-assists/src/utils.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,12 @@ fn calc_depth(pat: &ast::Pat, depth: usize) -> usize {
338338

339339
/// `find_struct_impl` looks for impl of a struct, but this also has additional feature
340340
/// where it takes a list of function names and check if they exist inside impl_, if
341-
/// even one match is found, it returns None
341+
/// even one match is found, it returns None.
342+
///
343+
/// That means this function can have 3 potential return values:
344+
/// - `None`: an impl exists, but one of the function names within the impl matches one of the provided names.
345+
/// - `Some(None)`: no impl exists.
346+
/// - `Some(Some(_))`: an impl exists, with no matching function names.
342347
pub(crate) fn find_struct_impl(
343348
ctx: &AssistContext<'_>,
344349
adt: &ast::Adt,

0 commit comments

Comments
 (0)