@@ -17,6 +17,30 @@ struct InherentOverlapChecker<'tcx> {
1717}
1818
1919impl InherentOverlapChecker < ' tcx > {
20+ /// Checks whether any associated items in impls 1 and 2 share the same identifier and
21+ /// namespace.
22+ fn impls_have_common_items ( & self , impl1 : DefId , impl2 : DefId ) -> bool {
23+ let impl_items1 = self . tcx . associated_items ( impl1) ;
24+ let impl_items2 = self . tcx . associated_items ( impl2) ;
25+
26+ for item1 in & impl_items1[ ..] {
27+ for item2 in & impl_items2[ ..] {
28+ // Avoid costly `.modern()` calls as much as possible by doing them as late as we
29+ // can. Compare raw symbols first.
30+ if item1. ident . name == item2. ident . name
31+ && Namespace :: from ( item1. kind ) == Namespace :: from ( item2. kind )
32+ {
33+ // Symbols and namespace match, compare hygienically.
34+ if item1. ident . modern ( ) == item2. ident . modern ( ) {
35+ return true ;
36+ }
37+ }
38+ }
39+ }
40+
41+ false
42+ }
43+
2044 fn check_for_common_items_in_impls (
2145 & self ,
2246 impl1 : DefId ,
@@ -64,27 +88,21 @@ impl InherentOverlapChecker<'tcx> {
6488 }
6589 }
6690
67- fn check_for_overlapping_inherent_impls ( & self , ty_def_id : DefId ) {
68- let impls = self . tcx . inherent_impls ( ty_def_id) ;
69-
70- for ( i, & impl1_def_id) in impls. iter ( ) . enumerate ( ) {
71- for & impl2_def_id in & impls[ ( i + 1 ) ..] {
72- traits:: overlapping_impls (
73- self . tcx ,
74- impl1_def_id,
75- impl2_def_id,
76- IntercrateMode :: Issue43355 ,
77- // We go ahead and just skip the leak check for
78- // inherent impls without warning.
79- SkipLeakCheck :: Yes ,
80- |overlap| {
81- self . check_for_common_items_in_impls ( impl1_def_id, impl2_def_id, overlap) ;
82- false
83- } ,
84- || true ,
85- ) ;
86- }
87- }
91+ fn check_for_overlapping_inherent_impls ( & self , impl1_def_id : DefId , impl2_def_id : DefId ) {
92+ traits:: overlapping_impls (
93+ self . tcx ,
94+ impl1_def_id,
95+ impl2_def_id,
96+ IntercrateMode :: Issue43355 ,
97+ // We go ahead and just skip the leak check for
98+ // inherent impls without warning.
99+ SkipLeakCheck :: Yes ,
100+ |overlap| {
101+ self . check_for_common_items_in_impls ( impl1_def_id, impl2_def_id, overlap) ;
102+ false
103+ } ,
104+ || true ,
105+ ) ;
88106 }
89107}
90108
@@ -95,8 +113,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
95113 | hir:: ItemKind :: Struct ( ..)
96114 | hir:: ItemKind :: Trait ( ..)
97115 | hir:: ItemKind :: Union ( ..) => {
98- let type_def_id = self . tcx . hir ( ) . local_def_id ( item. hir_id ) ;
99- self . check_for_overlapping_inherent_impls ( type_def_id) ;
116+ let ty_def_id = self . tcx . hir ( ) . local_def_id ( item. hir_id ) ;
117+ let impls = self . tcx . inherent_impls ( ty_def_id) ;
118+
119+ for ( i, & impl1_def_id) in impls. iter ( ) . enumerate ( ) {
120+ for & impl2_def_id in & impls[ ( i + 1 ) ..] {
121+ if self . impls_have_common_items ( impl1_def_id, impl2_def_id) {
122+ self . check_for_overlapping_inherent_impls ( impl1_def_id, impl2_def_id) ;
123+ }
124+ }
125+ }
100126 }
101127 _ => { }
102128 }
0 commit comments