@@ -92,122 +92,141 @@ impl<'tcx> ChildrenExt<'tcx> for Children {
9292 simplified_self : Option < SimplifiedType > ,
9393 overlap_mode : OverlapMode ,
9494 ) -> Result < OverlapResult < ' tcx > , OverlapError < ' tcx > > {
95- let mut last_lint = None ;
96- let mut replace_children = Vec :: new ( ) ;
97-
9895 let possible_siblings = match simplified_self {
9996 Some ( st) => PotentialSiblings :: Filtered ( filtered_children ( self , st) ) ,
10097 None => PotentialSiblings :: Unfiltered ( iter_children ( self ) ) ,
10198 } ;
10299
103- for possible_sibling in possible_siblings {
104- debug ! ( ?possible_sibling) ;
105-
106- let create_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' tcx > | {
107- let trait_ref = overlap. impl_header . trait_ref . unwrap ( ) ;
108- let self_ty = trait_ref. self_ty ( ) ;
109-
110- OverlapError {
111- with_impl : possible_sibling,
112- trait_ref,
113- // Only report the `Self` type if it has at least
114- // some outer concrete shell; otherwise, it's
115- // not adding much information.
116- self_ty : self_ty. has_concrete_skeleton ( ) . then_some ( self_ty) ,
117- intercrate_ambiguity_causes : overlap. intercrate_ambiguity_causes ,
118- involves_placeholder : overlap. involves_placeholder ,
119- }
120- } ;
121-
122- let report_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' tcx > ,
123- last_lint : & mut _ | {
124- // Found overlap, but no specialization; error out or report future-compat warning.
125-
126- // Do we *still* get overlap if we disable the future-incompatible modes?
127- let should_err = traits:: overlapping_impls (
128- tcx,
129- possible_sibling,
130- impl_def_id,
131- traits:: SkipLeakCheck :: default ( ) ,
132- overlap_mode,
133- )
134- . is_some ( ) ;
135-
136- let error = create_overlap_error ( overlap) ;
137-
138- if should_err {
139- Err ( error)
140- } else {
141- * last_lint = Some ( FutureCompatOverlapError {
142- error,
143- kind : FutureCompatOverlapErrorKind :: LeakCheck ,
144- } ) ;
145-
146- Ok ( ( false , false ) )
147- }
148- } ;
100+ let result = overlap_check_considering_specialization (
101+ tcx,
102+ impl_def_id,
103+ possible_siblings,
104+ overlap_mode,
105+ ) ;
106+
107+ if let Ok ( OverlapResult :: NoOverlap ( _) ) = result {
108+ // No overlap with any potential siblings, so add as a new sibling.
109+ debug ! ( "placing as new sibling" ) ;
110+ self . insert_blindly ( tcx, impl_def_id) ;
111+ }
112+
113+ result
114+ }
115+ }
116+
117+ fn overlap_check_considering_specialization < ' tcx > (
118+ tcx : TyCtxt < ' tcx > ,
119+ impl_def_id : DefId ,
120+ possible_siblings : PotentialSiblings < impl Iterator < Item = DefId > , impl Iterator < Item = DefId > > ,
121+ overlap_mode : OverlapMode ,
122+ ) -> Result < OverlapResult < ' tcx > , OverlapError < ' tcx > > {
123+ let mut last_lint = None ;
124+ let mut replace_children = Vec :: new ( ) ;
125+
126+ for possible_sibling in possible_siblings {
127+ debug ! ( ?possible_sibling) ;
128+
129+ let create_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' tcx > | {
130+ let trait_ref = overlap. impl_header . trait_ref . unwrap ( ) ;
131+ let self_ty = trait_ref. self_ty ( ) ;
132+
133+ OverlapError {
134+ with_impl : possible_sibling,
135+ trait_ref,
136+ // Only report the `Self` type if it has at least
137+ // some outer concrete shell; otherwise, it's
138+ // not adding much information.
139+ self_ty : self_ty. has_concrete_skeleton ( ) . then_some ( self_ty) ,
140+ intercrate_ambiguity_causes : overlap. intercrate_ambiguity_causes ,
141+ involves_placeholder : overlap. involves_placeholder ,
142+ }
143+ } ;
149144
150- let last_lint_mut = & mut last_lint;
151- let ( le, ge) = traits:: overlapping_impls (
145+ let report_overlap_error = |overlap : traits:: coherence:: OverlapResult < ' tcx > ,
146+ last_lint : & mut _ | {
147+ // Found overlap, but no specialization; error out or report future-compat warning.
148+
149+ // Do we *still* get overlap if we disable the future-incompatible modes?
150+ let should_err = traits:: overlapping_impls (
152151 tcx,
153152 possible_sibling,
154153 impl_def_id,
155- traits:: SkipLeakCheck :: Yes ,
154+ traits:: SkipLeakCheck :: default ( ) ,
156155 overlap_mode,
157156 )
158- . map_or ( Ok ( ( false , false ) ) , |overlap| {
159- if let Some ( overlap_kind) =
160- tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling)
161- {
162- match overlap_kind {
163- ty:: ImplOverlapKind :: Permitted { marker : _ } => { }
164- ty:: ImplOverlapKind :: Issue33140 => {
165- * last_lint_mut = Some ( FutureCompatOverlapError {
166- error : create_overlap_error ( overlap) ,
167- kind : FutureCompatOverlapErrorKind :: Issue33140 ,
168- } ) ;
169- }
170- }
157+ . is_some ( ) ;
158+
159+ let error = create_overlap_error ( overlap) ;
171160
172- return Ok ( ( false , false ) ) ;
161+ if should_err {
162+ Err ( error)
163+ } else {
164+ * last_lint = Some ( FutureCompatOverlapError {
165+ error,
166+ kind : FutureCompatOverlapErrorKind :: LeakCheck ,
167+ } ) ;
168+
169+ Ok ( ( false , false ) )
170+ }
171+ } ;
172+
173+ let last_lint_mut = & mut last_lint;
174+ let ( le, ge) = traits:: overlapping_impls (
175+ tcx,
176+ possible_sibling,
177+ impl_def_id,
178+ traits:: SkipLeakCheck :: Yes ,
179+ overlap_mode,
180+ )
181+ . map_or ( Ok ( ( false , false ) ) , |overlap| {
182+ if let Some ( overlap_kind) =
183+ tcx. impls_are_allowed_to_overlap ( impl_def_id, possible_sibling)
184+ {
185+ match overlap_kind {
186+ ty:: ImplOverlapKind :: Permitted { marker : _ } => { }
187+ ty:: ImplOverlapKind :: Issue33140 => {
188+ * last_lint_mut = Some ( FutureCompatOverlapError {
189+ error : create_overlap_error ( overlap) ,
190+ kind : FutureCompatOverlapErrorKind :: Issue33140 ,
191+ } ) ;
192+ }
173193 }
174194
175- let le = tcx . specializes ( ( impl_def_id , possible_sibling ) ) ;
176- let ge = tcx . specializes ( ( possible_sibling , impl_def_id ) ) ;
195+ return Ok ( ( false , false ) ) ;
196+ }
177197
178- if le == ge { report_overlap_error ( overlap , last_lint_mut ) } else { Ok ( ( le , ge ) ) }
179- } ) ? ;
198+ let le = tcx . specializes ( ( impl_def_id , possible_sibling ) ) ;
199+ let ge = tcx . specializes ( ( possible_sibling , impl_def_id ) ) ;
180200
181- if le && !ge {
182- debug ! (
183- "descending as child of TraitRef {:?}" ,
184- tcx. impl_trait_ref( possible_sibling) . unwrap( ) . subst_identity( )
185- ) ;
201+ if le == ge { report_overlap_error ( overlap, last_lint_mut) } else { Ok ( ( le, ge) ) }
202+ } ) ?;
186203
187- // The impl specializes `possible_sibling`.
188- return Ok ( OverlapResult :: SpecializeOne ( possible_sibling) ) ;
189- } else if ge && !le {
190- debug ! (
191- "placing as parent of TraitRef {:?}" ,
192- tcx. impl_trait_ref( possible_sibling) . unwrap( ) . subst_identity( )
193- ) ;
204+ if le && !ge {
205+ debug ! (
206+ "descending as child of TraitRef {:?}" ,
207+ tcx. impl_trait_ref( possible_sibling) . unwrap( ) . subst_identity( )
208+ ) ;
194209
195- replace_children. push ( possible_sibling) ;
196- } else {
197- // Either there's no overlap, or the overlap was already reported by
198- // `overlap_error`.
199- }
200- }
210+ // The impl specializes `possible_sibling`.
211+ return Ok ( OverlapResult :: SpecializeOne ( possible_sibling) ) ;
212+ } else if ge && !le {
213+ debug ! (
214+ "placing as parent of TraitRef {:?}" ,
215+ tcx. impl_trait_ref( possible_sibling) . unwrap( ) . subst_identity( )
216+ ) ;
201217
202- if !replace_children. is_empty ( ) {
203- return Ok ( OverlapResult :: SpecializeAll ( replace_children) ) ;
218+ replace_children. push ( possible_sibling) ;
219+ } else {
220+ // Either there's no overlap, or the overlap was already reported by
221+ // `overlap_error`.
204222 }
223+ }
205224
206- // No overlap with any potential siblings, so add as a new sibling.
207- debug ! ( "placing as new sibling" ) ;
208- self . insert_blindly ( tcx, impl_def_id) ;
209- Ok ( OverlapResult :: NoOverlap ( last_lint) )
225+ if !replace_children. is_empty ( ) {
226+ return Ok ( OverlapResult :: SpecializeAll ( replace_children) ) ;
210227 }
228+
229+ Ok ( OverlapResult :: NoOverlap ( last_lint) )
211230}
212231
213232fn iter_children ( children : & mut Children ) -> impl Iterator < Item = DefId > + ' _ {
0 commit comments