@@ -10,36 +10,28 @@ use rustc::ty::query::Providers;
10
10
use rustc:: ty:: { self , TyCtxt , TypeFoldable } ;
11
11
use rustc_errors:: struct_span_err;
12
12
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
13
- use rustc_hir:: HirId ;
14
13
15
14
mod builtin;
16
15
mod inherent_impls;
17
16
mod inherent_impls_overlap;
18
17
mod orphan;
19
18
mod unsafety;
20
19
21
- fn check_impl ( tcx : TyCtxt < ' _ > , hir_id : HirId ) {
22
- let impl_def_id = tcx. hir ( ) . local_def_id ( hir_id) ;
20
+ fn check_impl ( tcx : TyCtxt < ' _ > , impl_def_id : DefId , trait_ref : ty:: TraitRef < ' _ > ) {
21
+ debug ! (
22
+ "(checking implementation) adding impl for trait '{:?}', item '{}'" ,
23
+ trait_ref,
24
+ tcx. def_path_str( impl_def_id)
25
+ ) ;
23
26
24
- // If there are no traits, then this implementation must have a
25
- // base type.
26
-
27
- if let Some ( trait_ref) = tcx. impl_trait_ref ( impl_def_id) {
28
- debug ! (
29
- "(checking implementation) adding impl for trait '{:?}', item '{}'" ,
30
- trait_ref,
31
- tcx. def_path_str( impl_def_id)
32
- ) ;
33
-
34
- // Skip impls where one of the self type is an error type.
35
- // This occurs with e.g., resolve failures (#30589).
36
- if trait_ref. references_error ( ) {
37
- return ;
38
- }
39
-
40
- enforce_trait_manually_implementable ( tcx, impl_def_id, trait_ref. def_id ) ;
41
- enforce_empty_impls_for_marker_traits ( tcx, impl_def_id, trait_ref. def_id ) ;
27
+ // Skip impls where one of the self type is an error type.
28
+ // This occurs with e.g., resolve failures (#30589).
29
+ if trait_ref. references_error ( ) {
30
+ return ;
42
31
}
32
+
33
+ enforce_trait_manually_implementable ( tcx, impl_def_id, trait_ref. def_id ) ;
34
+ enforce_empty_impls_for_marker_traits ( tcx, impl_def_id, trait_ref. def_id ) ;
43
35
}
44
36
45
37
fn enforce_trait_manually_implementable ( tcx : TyCtxt < ' _ > , impl_def_id : DefId , trait_def_id : DefId ) {
@@ -129,12 +121,17 @@ pub fn provide(providers: &mut Providers<'_>) {
129
121
}
130
122
131
123
fn coherent_trait ( tcx : TyCtxt < ' _ > , def_id : DefId ) {
124
+ // Trigger building the specialization graph for the trait. This will detect and report any
125
+ // overlap errors.
126
+ tcx. specialization_graph_of ( def_id) ;
127
+
132
128
let impls = tcx. hir ( ) . trait_impls ( def_id) ;
133
- for & impl_id in impls {
134
- check_impl ( tcx, impl_id) ;
135
- }
136
- for & impl_id in impls {
137
- check_impl_overlap ( tcx, impl_id) ;
129
+ for & hir_id in impls {
130
+ let impl_def_id = tcx. hir ( ) . local_def_id ( hir_id) ;
131
+ let trait_ref = tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) ;
132
+
133
+ check_impl ( tcx, impl_def_id, trait_ref) ;
134
+ check_object_overlap ( tcx, impl_def_id, trait_ref) ;
138
135
}
139
136
builtin:: check_trait ( tcx, def_id) ;
140
137
}
@@ -152,24 +149,20 @@ pub fn check_coherence(tcx: TyCtxt<'_>) {
152
149
tcx. ensure ( ) . crate_inherent_impls_overlap_check ( LOCAL_CRATE ) ;
153
150
}
154
151
155
- /// Overlap: no two impls for the same trait are implemented for the
156
- /// same type. Likewise, no two inherent impls for a given type
157
- /// constructor provide a method with the same name.
158
- fn check_impl_overlap < ' tcx > ( tcx : TyCtxt < ' tcx > , hir_id : HirId ) {
159
- let impl_def_id = tcx. hir ( ) . local_def_id ( hir_id ) ;
160
- let trait_ref = tcx . impl_trait_ref ( impl_def_id ) . unwrap ( ) ;
152
+ /// Checks whether an impl overlaps with the automatic `impl Trait for dyn Trait`.
153
+ fn check_object_overlap < ' tcx > (
154
+ tcx : TyCtxt < ' tcx > ,
155
+ impl_def_id : DefId ,
156
+ trait_ref : ty :: TraitRef < ' tcx > ,
157
+ ) {
161
158
let trait_def_id = trait_ref. def_id ;
162
159
163
160
if trait_ref. references_error ( ) {
164
161
debug ! ( "coherence: skipping impl {:?} with error {:?}" , impl_def_id, trait_ref) ;
165
162
return ;
166
163
}
167
164
168
- // Trigger building the specialization graph for the trait of this impl.
169
- // This will detect any overlap errors.
170
- tcx. specialization_graph_of ( trait_def_id) ;
171
-
172
- // check for overlap with the automatic `impl Trait for Trait`
165
+ // check for overlap with the automatic `impl Trait for dyn Trait`
173
166
if let ty:: Dynamic ( ref data, ..) = trait_ref. self_ty ( ) . kind {
174
167
// This is something like impl Trait1 for Trait2. Illegal
175
168
// if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
0 commit comments