11//! Completes references after dot (fields and method calls).
22
3- use std:: ops:: ControlFlow ;
3+ use std:: { collections :: hash_map , ops:: ControlFlow } ;
44
5- use hir:: { Complete , Function , HasContainer , ItemContainer , MethodCandidateCallback } ;
6- use ide_db:: FxHashSet ;
5+ use hir:: { Complete , Function , HasContainer , ItemContainer , MethodCandidateCallback , Name } ;
6+ use ide_db:: { FxHashMap , FxHashSet } ;
77use itertools:: Either ;
88use syntax:: SmolStr ;
99
@@ -239,6 +239,9 @@ fn complete_methods(
239239 // duplicated, trait methods can. And it is still useful to show all of them (even when there
240240 // is also an inherent method, especially considering that it may be private, and filtered later).
241241 seen_methods : FxHashSet < Function > ,
242+ // However, duplicate inherent methods is usually meaningless
243+ // https://github.com/rust-lang/rust-analyzer/issues/20773#issuecomment-4302781553
244+ seen_inherent_methods : FxHashMap < Name , Function > ,
242245 }
243246
244247 impl < F > MethodCandidateCallback for Callback < ' _ , ' _ , F >
@@ -249,7 +252,21 @@ fn complete_methods(
249252 // `where` clauses or `dyn Trait`.
250253 fn on_inherent_method ( & mut self , func : hir:: Function ) -> ControlFlow < ( ) > {
251254 if func. self_param ( self . ctx . db ) . is_some ( ) && self . seen_methods . insert ( func) {
252- ( self . f ) ( func) ;
255+ let same_name = self . seen_inherent_methods . entry ( func. name ( self . ctx . db ) ) ;
256+ let do_complete = match & same_name {
257+ hash_map:: Entry :: Vacant ( _) => true ,
258+ hash_map:: Entry :: Occupied ( same_func) => {
259+ match self . ctx . is_visible ( same_func. get ( ) ) {
260+ crate :: context:: Visible :: Yes => false ,
261+ crate :: context:: Visible :: Editable => true ,
262+ crate :: context:: Visible :: No => true ,
263+ }
264+ }
265+ } ;
266+ if do_complete {
267+ same_name. insert_entry ( func) ;
268+ ( self . f ) ( func) ;
269+ }
253270 }
254271 ControlFlow :: Continue ( ( ) )
255272 }
@@ -277,7 +294,12 @@ fn complete_methods(
277294 & ctx. scope ,
278295 traits_in_scope,
279296 None ,
280- Callback { ctx, f, seen_methods : FxHashSet :: default ( ) } ,
297+ Callback {
298+ ctx,
299+ f,
300+ seen_methods : FxHashSet :: default ( ) ,
301+ seen_inherent_methods : FxHashMap :: default ( ) ,
302+ } ,
281303 ) ;
282304}
283305
@@ -869,6 +891,86 @@ fn test(a: A) {
869891 ) ;
870892 }
871893
894+ #[ test]
895+ fn test_inherent_method_no_same_name ( ) {
896+ check_no_kw (
897+ r#"
898+ //- minicore: deref
899+ struct A {}
900+ struct B {}
901+ impl core::ops::Deref for A {
902+ type Target = B;
903+ fn deref(&self) -> &Self::Target { loop {} }
904+ }
905+ trait Foo { fn foo(&self) -> u32 {} }
906+ impl Foo for A {}
907+ impl Foo for B {}
908+ impl A { fn foo(&self) -> u8 {} }
909+ impl B { fn foo(&self) -> u16 {} }
910+ fn test(a: A) {
911+ a.$0
912+ }
913+ "# ,
914+ expect ! [ [ r#"
915+ me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
916+ me foo() fn(&self) -> u8
917+ me foo() (as Foo) fn(&self) -> u32
918+ "# ] ] ,
919+ ) ;
920+
921+ check_no_kw (
922+ r#"
923+ //- minicore: deref
924+ //- /dep.rs crate:dep
925+ pub struct A {}
926+ pub struct B {}
927+ pub struct C {}
928+ pub struct D {}
929+ pub struct E {}
930+ pub struct F {}
931+ impl core::ops::Deref for A {
932+ type Target = B;
933+ fn deref(&self) -> &Self::Target { loop {} }
934+ }
935+ impl core::ops::Deref for B {
936+ type Target = C;
937+ fn deref(&self) -> &Self::Target { loop {} }
938+ }
939+ impl core::ops::Deref for C {
940+ type Target = D;
941+ fn deref(&self) -> &Self::Target { loop {} }
942+ }
943+ impl core::ops::Deref for D {
944+ type Target = E;
945+ fn deref(&self) -> &Self::Target { loop {} }
946+ }
947+ impl core::ops::Deref for E {
948+ type Target = F;
949+ fn deref(&self) -> &Self::Target { loop {} }
950+ }
951+ pub trait Foo { fn foo(&self) -> u32 {} }
952+ impl Foo for A {}
953+ impl Foo for B {}
954+ impl A { fn foo(&self) -> u8 {} }
955+ impl B { pub fn foo(&self) -> u16 {} }
956+ impl C { fn foo(&self) -> i8 {} }
957+ impl D { fn foo(&self) -> i16 {} }
958+ impl E { pub fn foo(&self) -> i32 {} }
959+ impl F { pub fn foo(&self) -> f32 {} }
960+ //- /main.rs crate:main deps:dep
961+ use dep::*;
962+ fn test(a: A) {
963+ a.$0
964+ }
965+ "# ,
966+ expect ! [ [ r#"
967+ me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
968+ me foo() fn(&self) -> u16
969+ me foo() (as Foo) fn(&self) -> u32
970+ "# ] ] ,
971+ ) ;
972+ }
973+
872974 #[ test]
873975 fn test_completion_works_in_consts ( ) {
874976 check_no_kw (
0 commit comments