@@ -86,10 +86,10 @@ impl<'tcx> Children {
8686 impl_def_id, simplified_self, possible_sibling,
8787 ) ;
8888
89- let overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > | {
90- // Found overlap, but no specialization; error out.
89+ let create_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > | {
9190 let trait_ref = overlap. impl_header . trait_ref . unwrap ( ) ;
9291 let self_ty = trait_ref. self_ty ( ) ;
92+
9393 OverlapError {
9494 with_impl : possible_sibling,
9595 trait_desc : trait_ref. print_only_trait_path ( ) . to_string ( ) ,
@@ -106,21 +106,49 @@ impl<'tcx> Children {
106106 }
107107 } ;
108108
109- let allowed_to_overlap =
110- tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling) ;
109+ let report_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' _ > ,
110+ last_lint : & mut _ | {
111+ // Found overlap, but no specialization; error out or report future-compat warning.
112+
113+ // Do we *still* get overlap if we disable the future-incompatible modes?
114+ let should_err = traits:: overlapping_impls (
115+ tcx,
116+ possible_sibling,
117+ impl_def_id,
118+ traits:: SkipLeakCheck :: default ( ) ,
119+ |_| true ,
120+ || false ,
121+ ) ;
122+
123+ let error = create_overlap_error ( overlap) ;
124+
125+ if should_err {
126+ Err ( error)
127+ } else {
128+ * last_lint = Some ( FutureCompatOverlapError {
129+ error,
130+ kind : FutureCompatOverlapErrorKind :: LeakCheck ,
131+ } ) ;
132+
133+ Ok ( ( false , false ) )
134+ }
135+ } ;
111136
137+ let last_lint_mut = & mut last_lint;
112138 let ( le, ge) = traits:: overlapping_impls (
113139 tcx,
114140 possible_sibling,
115141 impl_def_id,
116- traits:: SkipLeakCheck :: default ( ) ,
142+ traits:: SkipLeakCheck :: Yes ,
117143 |overlap| {
118- if let Some ( overlap_kind) = & allowed_to_overlap {
144+ if let Some ( overlap_kind) =
145+ tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling)
146+ {
119147 match overlap_kind {
120148 ty:: ImplOverlapKind :: Permitted { marker : _ } => { }
121149 ty:: ImplOverlapKind :: Issue33140 => {
122- last_lint = Some ( FutureCompatOverlapError {
123- error : overlap_error ( overlap) ,
150+ * last_lint_mut = Some ( FutureCompatOverlapError {
151+ error : create_overlap_error ( overlap) ,
124152 kind : FutureCompatOverlapErrorKind :: Issue33140 ,
125153 } ) ;
126154 }
@@ -132,7 +160,11 @@ impl<'tcx> Children {
132160 let le = tcx. specializes ( ( impl_def_id, possible_sibling) ) ;
133161 let ge = tcx. specializes ( ( possible_sibling, impl_def_id) ) ;
134162
135- if le == ge { Err ( overlap_error ( overlap) ) } else { Ok ( ( le, ge) ) }
163+ if le == ge {
164+ report_overlap_error ( overlap, last_lint_mut)
165+ } else {
166+ Ok ( ( le, ge) )
167+ }
136168 } ,
137169 || Ok ( ( false , false ) ) ,
138170 ) ?;
@@ -153,27 +185,8 @@ impl<'tcx> Children {
153185
154186 replace_children. push ( possible_sibling) ;
155187 } else {
156- if let None = allowed_to_overlap {
157- // Do future-compat checks for overlap.
158-
159- if last_lint. is_none ( ) {
160- traits:: overlapping_impls (
161- tcx,
162- possible_sibling,
163- impl_def_id,
164- traits:: SkipLeakCheck :: Yes ,
165- |overlap| {
166- last_lint = Some ( FutureCompatOverlapError {
167- error : overlap_error ( overlap) ,
168- kind : FutureCompatOverlapErrorKind :: LeakCheck ,
169- } ) ;
170- } ,
171- || ( ) ,
172- ) ;
173- }
174- }
175-
176- // no overlap (error bailed already via ?)
188+ // Either there's no overlap, or the overlap was already reported by
189+ // `overlap_error`.
177190 }
178191 }
179192
0 commit comments