@@ -17,6 +17,7 @@ use crate::traits::{
17
17
use rustc_errors:: Diagnostic ;
18
18
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
19
19
use rustc_hir:: CRATE_HIR_ID ;
20
+ use rustc_infer:: infer:: at:: ToTrace ;
20
21
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
21
22
use rustc_infer:: traits:: { util, TraitEngine } ;
22
23
use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
@@ -26,6 +27,7 @@ use rustc_middle::ty::subst::Subst;
26
27
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
27
28
use rustc_span:: symbol:: sym;
28
29
use rustc_span:: DUMMY_SP ;
30
+ use std:: fmt:: Debug ;
29
31
use std:: iter;
30
32
31
33
/// Whether we do the orphan check relative to this crate or
@@ -327,56 +329,56 @@ fn negative_impl<'cx, 'tcx>(
327
329
let ( impl2_trait_ref, obligations) =
328
330
impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
329
331
330
- // do the impls unify? If not, not disjoint.
331
- let Ok ( InferOk { obligations : more_obligations, .. } ) = infcx
332
- . at ( & ObligationCause :: dummy ( ) , impl1_env)
333
- . eq ( impl1_trait_ref, impl2_trait_ref) else {
334
- debug ! (
335
- "explicit_disjoint: {:?} does not unify with {:?}" ,
336
- impl1_trait_ref, impl2_trait_ref
337
- ) ;
338
- return false ;
339
- } ;
340
-
341
- let opt_failing_obligation = obligations
342
- . into_iter ( )
343
- . chain ( more_obligations)
344
- . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
345
-
346
- if let Some ( failing_obligation) = opt_failing_obligation {
347
- debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
348
- true
349
- } else {
350
- false
351
- }
332
+ !obligations_satisfiable (
333
+ & infcx,
334
+ impl1_env,
335
+ impl1_def_id,
336
+ impl1_trait_ref,
337
+ impl2_trait_ref,
338
+ obligations,
339
+ )
352
340
} else {
353
341
let ty1 = tcx. type_of ( impl1_def_id) ;
354
342
let ty2 = tcx. type_of ( impl2_def_id) ;
355
343
356
- let Ok ( InferOk { obligations, .. } ) = infcx
357
- . at ( & ObligationCause :: dummy ( ) , impl1_env)
358
- . eq ( ty1, ty2) else {
359
- debug ! (
360
- "explicit_disjoint: {:?} does not unify with {:?}" ,
361
- ty1, ty2
362
- ) ;
363
- return false ;
364
- } ;
365
-
366
- let opt_failing_obligation = obligations
367
- . into_iter ( )
368
- . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
369
-
370
- if let Some ( failing_obligation) = opt_failing_obligation {
371
- debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
372
- true
373
- } else {
374
- false
375
- }
344
+ !obligations_satisfiable ( & infcx, impl1_env, impl1_def_id, ty1, ty2, iter:: empty ( ) )
376
345
}
377
346
} )
378
347
}
379
348
349
+ fn obligations_satisfiable < ' cx , ' tcx , T : Debug + ToTrace < ' tcx > > (
350
+ infcx : & InferCtxt < ' cx , ' tcx > ,
351
+ impl1_env : ty:: ParamEnv < ' tcx > ,
352
+ impl1_def_id : DefId ,
353
+ impl1 : T ,
354
+ impl2 : T ,
355
+ obligations : impl Iterator < Item = PredicateObligation < ' tcx > > ,
356
+ ) -> bool {
357
+ // do the impls unify? If not, not disjoint.
358
+ let Ok ( InferOk { obligations : more_obligations, .. } ) = infcx
359
+ . at ( & ObligationCause :: dummy ( ) , impl1_env)
360
+ . eq ( impl1, impl2) else {
361
+ debug ! (
362
+ "explicit_disjoint: {:?} does not unify with {:?}" ,
363
+ impl1, impl2
364
+ ) ;
365
+ return true ;
366
+ } ;
367
+
368
+ let selcx = & mut SelectionContext :: new ( & infcx) ;
369
+ let opt_failing_obligation = obligations
370
+ . into_iter ( )
371
+ . chain ( more_obligations)
372
+ . find ( |o| negative_impl_exists ( selcx, impl1_env, impl1_def_id, o) ) ;
373
+
374
+ if let Some ( failing_obligation) = opt_failing_obligation {
375
+ debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
376
+ false
377
+ } else {
378
+ true
379
+ }
380
+ }
381
+
380
382
/// Try to prove that a negative impl exist for the given obligation and their super predicates.
381
383
#[ instrument( level = "debug" , skip( selcx) ) ]
382
384
fn negative_impl_exists < ' cx , ' tcx > (
0 commit comments