@@ -201,17 +201,17 @@ fn overlap_within_probe<'cx, 'tcx>(
201
201
202
202
match overlap_mode ( tcx, impl1_def_id, impl2_def_id) {
203
203
OverlapMode :: Stable => {
204
- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Stable ) {
204
+ if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header) {
205
205
return None ;
206
206
}
207
207
}
208
208
OverlapMode :: Strict => {
209
- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Strict ) {
209
+ if strict_disjoint ( selcx, param_env, & impl1_header, impl2_header) {
210
210
return None ;
211
211
}
212
212
}
213
213
OverlapMode :: WithNegative => {
214
- if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header, OverlapMode :: Stable )
214
+ if stable_disjoint ( selcx, param_env, & impl1_header, impl2_header)
215
215
|| explicit_disjoint ( selcx, impl1_def_id, impl2_def_id)
216
216
|| explicit_disjoint ( selcx, impl2_def_id, impl1_def_id)
217
217
{
@@ -244,7 +244,35 @@ fn stable_disjoint<'cx, 'tcx>(
244
244
param_env : ty:: ParamEnv < ' tcx > ,
245
245
impl1_header : & ty:: ImplHeader < ' tcx > ,
246
246
impl2_header : ty:: ImplHeader < ' tcx > ,
247
- overlap_mode : OverlapMode ,
247
+ ) -> bool {
248
+ let infcx = selcx. infcx ( ) ;
249
+ let tcx = infcx. tcx ;
250
+
251
+ disjoint_with_filter ( selcx, param_env, impl1_header, impl2_header, |selcx, o| {
252
+ loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
253
+ } )
254
+ }
255
+
256
+ fn strict_disjoint < ' cx , ' tcx > (
257
+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
258
+ param_env : ty:: ParamEnv < ' tcx > ,
259
+ impl1_header : & ty:: ImplHeader < ' tcx > ,
260
+ impl2_header : ty:: ImplHeader < ' tcx > ,
261
+ ) -> bool {
262
+ disjoint_with_filter ( selcx, param_env, impl1_header, impl2_header, |selcx, o| {
263
+ strict_check ( selcx, o)
264
+ } )
265
+ }
266
+
267
+ fn disjoint_with_filter < ' cx , ' tcx > (
268
+ selcx : & mut SelectionContext < ' cx , ' tcx > ,
269
+ param_env : ty:: ParamEnv < ' tcx > ,
270
+ impl1_header : & ty:: ImplHeader < ' tcx > ,
271
+ impl2_header : ty:: ImplHeader < ' tcx > ,
272
+ mut filter : impl FnMut (
273
+ & mut SelectionContext < ' cx , ' tcx > ,
274
+ & rustc_infer:: traits:: Obligation < ' tcx , rustc_middle:: ty:: Predicate < ' tcx > > ,
275
+ ) -> bool ,
248
276
) -> bool {
249
277
debug ! ( "overlap: impl1_header={:?}" , impl1_header) ;
250
278
debug ! ( "overlap: impl2_header={:?}" , impl2_header) ;
@@ -285,7 +313,6 @@ fn stable_disjoint<'cx, 'tcx>(
285
313
// hold we need to check if `&'?a str: !Error` holds, if doesn't hold there's overlap because
286
314
// at some point an impl for `&'?a str: Error` could be added.
287
315
let infcx = selcx. infcx ( ) ;
288
- let tcx = infcx. tcx ;
289
316
let opt_failing_obligation = impl1_header
290
317
. predicates
291
318
. iter ( )
@@ -299,17 +326,7 @@ fn stable_disjoint<'cx, 'tcx>(
299
326
predicate : p,
300
327
} )
301
328
. chain ( obligations)
302
- . find ( |o| {
303
- // if both impl headers are set to strict coherence it means that this will be accepted
304
- // only if it's stated that T: !Trait. So only prove that the negated obligation holds.
305
- match overlap_mode {
306
- OverlapMode :: Stable => {
307
- loose_check ( selcx, o) || tcx. features ( ) . negative_impls && strict_check ( selcx, o)
308
- }
309
- OverlapMode :: Strict => strict_check ( selcx, o) ,
310
- OverlapMode :: WithNegative => loose_check ( selcx, o) ,
311
- }
312
- } ) ;
329
+ . find ( |o| filter ( selcx, o) ) ;
313
330
// FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported
314
331
// to the canonical trait query form, `infcx.predicate_may_hold`, once
315
332
// the new system supports intercrate mode (which coherence needs).
0 commit comments