@@ -17,6 +17,30 @@ struct InherentOverlapChecker<'tcx> {
17
17
}
18
18
19
19
impl 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
+
20
44
fn check_for_common_items_in_impls (
21
45
& self ,
22
46
impl1 : DefId ,
@@ -64,24 +88,18 @@ impl InherentOverlapChecker<'tcx> {
64
88
}
65
89
}
66
90
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
+ ) ;
85
103
}
86
104
}
87
105
@@ -92,8 +110,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
92
110
| hir:: ItemKind :: Struct ( ..)
93
111
| hir:: ItemKind :: Trait ( ..)
94
112
| 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
+ }
97
123
}
98
124
_ => { }
99
125
}
0 commit comments