@@ -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,27 +88,21 @@ 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
- // 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
+ ) ;
88
106
}
89
107
}
90
108
@@ -95,8 +113,16 @@ impl ItemLikeVisitor<'v> for InherentOverlapChecker<'tcx> {
95
113
| hir:: ItemKind :: Struct ( ..)
96
114
| hir:: ItemKind :: Trait ( ..)
97
115
| 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
+ }
100
126
}
101
127
_ => { }
102
128
}
0 commit comments