Skip to content

Commit a646439

Browse files
committed
Auto merge of rust-lang#14483 - jhgg:fix/generate-delegate-methods-autoderef, r=Veykril
assist: autoderef in generate delegate methods fixes rust-lang#14438
2 parents e871540 + f6b0c19 commit a646439

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

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

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::HashSet;
2+
13
use hir::{self, HasCrate, HasSource, HasVisibility};
24
use syntax::ast::{self, make, AstNode, HasGenericParams, HasName, HasVisibility as _};
35

@@ -63,16 +65,23 @@ pub(crate) fn generate_delegate_methods(acc: &mut Assists, ctx: &AssistContext<'
6365
};
6466

6567
let sema_field_ty = ctx.sema.resolve_type(&field_ty)?;
66-
let krate = sema_field_ty.krate(ctx.db());
6768
let mut methods = vec![];
68-
sema_field_ty.iterate_assoc_items(ctx.db(), krate, |item| {
69-
if let hir::AssocItem::Function(f) = item {
70-
if f.self_param(ctx.db()).is_some() && f.is_visible_from(ctx.db(), current_module) {
71-
methods.push(f)
69+
let mut seen_names = HashSet::new();
70+
71+
for ty in sema_field_ty.autoderef(ctx.db()) {
72+
let krate = ty.krate(ctx.db());
73+
ty.iterate_assoc_items(ctx.db(), krate, |item| {
74+
if let hir::AssocItem::Function(f) = item {
75+
if f.self_param(ctx.db()).is_some()
76+
&& f.is_visible_from(ctx.db(), current_module)
77+
&& seen_names.insert(f.name(ctx.db()))
78+
{
79+
methods.push(f)
80+
}
7281
}
73-
}
74-
Option::<()>::None
75-
});
82+
Option::<()>::None
83+
});
84+
}
7685

7786
for method in methods {
7887
let adt = ast::Adt::Struct(strukt.clone());
@@ -314,6 +323,44 @@ impl<T> Person<T> {
314323
);
315324
}
316325

326+
#[test]
327+
fn test_generates_delegate_autoderef() {
328+
check_assist(
329+
generate_delegate_methods,
330+
r#"
331+
//- minicore: deref
332+
struct Age(u8);
333+
impl Age {
334+
fn age(&self) -> u8 {
335+
self.0
336+
}
337+
}
338+
struct AgeDeref(Age);
339+
impl core::ops::Deref for AgeDeref { type Target = Age; }
340+
struct Person {
341+
ag$0e: AgeDeref,
342+
}
343+
impl Person {}"#,
344+
r#"
345+
struct Age(u8);
346+
impl Age {
347+
fn age(&self) -> u8 {
348+
self.0
349+
}
350+
}
351+
struct AgeDeref(Age);
352+
impl core::ops::Deref for AgeDeref { type Target = Age; }
353+
struct Person {
354+
age: AgeDeref,
355+
}
356+
impl Person {
357+
$0fn age(&self) -> u8 {
358+
self.age.age()
359+
}
360+
}"#,
361+
);
362+
}
363+
317364
#[test]
318365
fn test_generate_delegate_visibility() {
319366
check_assist_not_applicable(

0 commit comments

Comments
 (0)