16
16
// mappings. That mapping code resides here.
17
17
18
18
use hir:: def_id:: { DefId , LOCAL_CRATE } ;
19
+ use rustc:: traits;
19
20
use rustc:: ty:: { self , TyCtxt , TypeFoldable } ;
20
21
use rustc:: ty:: maps:: Providers ;
21
22
@@ -25,7 +26,6 @@ mod builtin;
25
26
mod inherent_impls;
26
27
mod inherent_impls_overlap;
27
28
mod orphan;
28
- mod overlap;
29
29
mod unsafety;
30
30
31
31
fn check_impl < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , node_id : ast:: NodeId ) {
@@ -119,7 +119,7 @@ fn coherent_trait<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
119
119
check_impl ( tcx, impl_id) ;
120
120
}
121
121
for & impl_id in impls {
122
- overlap :: check_impl ( tcx, impl_id) ;
122
+ check_impl_overlap ( tcx, impl_id) ;
123
123
}
124
124
builtin:: check_trait ( tcx, def_id) ;
125
125
}
@@ -136,3 +136,46 @@ pub fn check_coherence<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
136
136
ty:: maps:: queries:: crate_inherent_impls:: ensure ( tcx, LOCAL_CRATE ) ;
137
137
ty:: maps:: queries:: crate_inherent_impls_overlap_check:: ensure ( tcx, LOCAL_CRATE ) ;
138
138
}
139
+
140
+ /// Overlap: No two impls for the same trait are implemented for the
141
+ /// same type. Likewise, no two inherent impls for a given type
142
+ /// constructor provide a method with the same name.
143
+ fn check_impl_overlap < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , node_id : ast:: NodeId ) {
144
+ let impl_def_id = tcx. hir . local_def_id ( node_id) ;
145
+ let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
146
+ let trait_def_id = trait_ref. def_id ;
147
+
148
+ if trait_ref. references_error ( ) {
149
+ debug ! ( "coherence: skipping impl {:?} with error {:?}" ,
150
+ impl_def_id, trait_ref) ;
151
+ return
152
+ }
153
+
154
+ // Trigger building the specialization graph for the trait of this impl.
155
+ // This will detect any overlap errors.
156
+ tcx. specialization_graph_of ( trait_def_id) ;
157
+
158
+ // check for overlap with the automatic `impl Trait for Trait`
159
+ if let ty:: TyDynamic ( ref data, ..) = trait_ref. self_ty ( ) . sty {
160
+ // This is something like impl Trait1 for Trait2. Illegal
161
+ // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
162
+
163
+ if data. principal ( ) . map_or ( true , |p| !tcx. is_object_safe ( p. def_id ( ) ) ) {
164
+ // This is an error, but it will be reported by wfcheck. Ignore it here.
165
+ // This is tested by `coherence-impl-trait-for-trait-object-safe.rs`.
166
+ } else {
167
+ let mut supertrait_def_ids =
168
+ traits:: supertrait_def_ids ( tcx,
169
+ data. principal ( ) . unwrap ( ) . def_id ( ) ) ;
170
+ if supertrait_def_ids. any ( |d| d == trait_def_id) {
171
+ span_err ! ( tcx. sess,
172
+ tcx. span_of_impl( impl_def_id) . unwrap( ) ,
173
+ E0371 ,
174
+ "the object type `{}` automatically \
175
+ implements the trait `{}`",
176
+ trait_ref. self_ty( ) ,
177
+ tcx. item_path_str( trait_def_id) ) ;
178
+ }
179
+ }
180
+ }
181
+ }
0 commit comments