@@ -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,24 +88,18 @@ 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- |overlap| {
78- self . check_for_common_items_in_impls ( impl1_def_id, impl2_def_id, overlap) ;
79- false
80- } ,
81- || true ,
82- ) ;
83- }
84- }
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+ |overlap| {
98+ self . check_for_common_items_in_impls ( impl1_def_id, impl2_def_id, overlap) ;
99+ false
100+ } ,
101+ || true ,
102+ ) ;
85103 }
86104}
87105
@@ -92,8 +110,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
92110 | hir:: ItemKind :: Struct ( ..)
93111 | hir:: ItemKind :: Trait ( ..)
94112 | hir:: ItemKind :: Union ( ..) => {
95- let type_def_id = self . tcx . hir ( ) . local_def_id ( item. hir_id ) ;
96- self . check_for_overlapping_inherent_impls ( type_def_id) ;
113+ let ty_def_id = self . tcx . hir ( ) . local_def_id ( item. hir_id ) ;
114+ let impls = self . tcx . inherent_impls ( ty_def_id) ;
115+
116+ for ( i, & impl1_def_id) in impls. iter ( ) . enumerate ( ) {
117+ for & impl2_def_id in & impls[ ( i + 1 ) ..] {
118+ if self . impls_have_common_items ( impl1_def_id, impl2_def_id) {
119+ self . check_for_overlapping_inherent_impls ( impl1_def_id, impl2_def_id) ;
120+ }
121+ }
122+ }
97123 }
98124 _ => { }
99125 }
0 commit comments