@@ -10,36 +10,28 @@ use rustc::ty::query::Providers;
1010use rustc:: ty:: { self , TyCtxt , TypeFoldable } ;
1111use rustc_errors:: struct_span_err;
1212use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
13- use rustc_hir:: HirId ;
1413
1514mod builtin;
1615mod inherent_impls;
1716mod inherent_impls_overlap;
1817mod orphan;
1918mod unsafety;
2019
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+ ) ;
2326
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 ;
4231 }
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 ) ;
4335}
4436
4537fn enforce_trait_manually_implementable ( tcx : TyCtxt < ' _ > , impl_def_id : DefId , trait_def_id : DefId ) {
@@ -129,12 +121,17 @@ pub fn provide(providers: &mut Providers<'_>) {
129121}
130122
131123fn 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+
132128 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) ;
138135 }
139136 builtin:: check_trait ( tcx, def_id) ;
140137}
@@ -152,24 +149,20 @@ pub fn check_coherence(tcx: TyCtxt<'_>) {
152149 tcx. ensure ( ) . crate_inherent_impls_overlap_check ( LOCAL_CRATE ) ;
153150}
154151
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+ ) {
161158 let trait_def_id = trait_ref. def_id ;
162159
163160 if trait_ref. references_error ( ) {
164161 debug ! ( "coherence: skipping impl {:?} with error {:?}" , impl_def_id, trait_ref) ;
165162 return ;
166163 }
167164
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`
173166 if let ty:: Dynamic ( ref data, ..) = trait_ref. self_ty ( ) . kind {
174167 // This is something like impl Trait1 for Trait2. Illegal
175168 // if Trait1 is a supertrait of Trait2 or Trait2 is not object safe.
0 commit comments