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