Skip to content

Commit ebc2465

Browse files
authored
Merge pull request #20587 from ChayimFriedman2/private-inherent
fix: Deduplicate methods in completion by function ID and not by name
2 parents 21614ed + 8a2e845 commit ebc2465

File tree

2 files changed

+47
-8
lines changed

2 files changed

+47
-8
lines changed

crates/ide-completion/src/completions/dot.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use std::ops::ControlFlow;
44

5-
use hir::{Complete, HasContainer, ItemContainer, MethodCandidateCallback, Name};
5+
use hir::{Complete, Function, HasContainer, ItemContainer, MethodCandidateCallback};
66
use ide_db::FxHashSet;
77
use syntax::SmolStr;
88

@@ -237,7 +237,10 @@ fn complete_methods(
237237
struct Callback<'a, F> {
238238
ctx: &'a CompletionContext<'a>,
239239
f: F,
240-
seen_methods: FxHashSet<Name>,
240+
// We deliberately deduplicate by function ID and not name, because while inherent methods cannot be
241+
// duplicated, trait methods can. And it is still useful to show all of them (even when there
242+
// is also an inherent method, especially considering that it may be private, and filtered later).
243+
seen_methods: FxHashSet<Function>,
241244
}
242245

243246
impl<F> MethodCandidateCallback for Callback<'_, F>
@@ -247,9 +250,7 @@ fn complete_methods(
247250
// We don't want to exclude inherent trait methods - that is, methods of traits available from
248251
// `where` clauses or `dyn Trait`.
249252
fn on_inherent_method(&mut self, func: hir::Function) -> ControlFlow<()> {
250-
if func.self_param(self.ctx.db).is_some()
251-
&& self.seen_methods.insert(func.name(self.ctx.db))
252-
{
253+
if func.self_param(self.ctx.db).is_some() && self.seen_methods.insert(func) {
253254
(self.f)(func);
254255
}
255256
ControlFlow::Continue(())
@@ -265,9 +266,7 @@ fn complete_methods(
265266
return ControlFlow::Continue(());
266267
}
267268

268-
if func.self_param(self.ctx.db).is_some()
269-
&& self.seen_methods.insert(func.name(self.ctx.db))
270-
{
269+
if func.self_param(self.ctx.db).is_some() && self.seen_methods.insert(func) {
271270
(self.f)(func);
272271
}
273272

crates/ide-completion/src/tests/expression.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,3 +2632,43 @@ fn let_in_condition() {
26322632
fn let_in_let_chain() {
26332633
check_edit("let", r#"fn f() { if true && $0 {} }"#, r#"fn f() { if true && let $1 = $0 {} }"#);
26342634
}
2635+
2636+
#[test]
2637+
fn private_inherent_and_public_trait() {
2638+
check(
2639+
r#"
2640+
struct Foo;
2641+
2642+
mod private {
2643+
impl super::Foo {
2644+
fn method(&self) {}
2645+
}
2646+
}
2647+
2648+
trait Trait {
2649+
fn method(&self) {}
2650+
}
2651+
impl Trait for Foo {}
2652+
2653+
fn main() {
2654+
Foo.$0
2655+
}
2656+
"#,
2657+
expect![[r#"
2658+
me method() (as Trait) fn(&self)
2659+
sn box Box::new(expr)
2660+
sn call function(expr)
2661+
sn const const {}
2662+
sn dbg dbg!(expr)
2663+
sn dbgr dbg!(&expr)
2664+
sn deref *expr
2665+
sn let let
2666+
sn letm let mut
2667+
sn match match expr {}
2668+
sn ref &expr
2669+
sn refm &mut expr
2670+
sn return return expr
2671+
sn unsafe unsafe {}
2672+
"#]],
2673+
);
2674+
}

0 commit comments

Comments
 (0)