@@ -17,7 +17,6 @@ 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 ;
21
20
use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
22
21
use rustc_infer:: traits:: { util, TraitEngine } ;
23
22
use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
@@ -305,72 +304,72 @@ fn negative_impl<'cx, 'tcx>(
305
304
// Create an infcx, taking the predicates of impl1 as assumptions:
306
305
tcx. infer_ctxt ( ) . enter ( |infcx| {
307
306
// create a parameter environment corresponding to a (placeholder) instantiation of impl1
308
- let impl1_env = tcx. param_env ( impl1_def_id) ;
309
-
310
- match tcx. impl_subject ( impl1_def_id) {
307
+ let impl_env = tcx. param_env ( impl1_def_id) ;
308
+ let subject1 = match tcx. impl_subject ( impl1_def_id) {
311
309
ImplSubject :: Trait ( impl1_trait_ref) => {
312
- // Normalize the trait reference. The WF rules ought to ensure
313
- // that this always succeeds.
314
- let impl1_trait_ref = match traits:: fully_normalize (
310
+ match traits:: fully_normalize (
315
311
& infcx,
316
312
FulfillmentContext :: new ( ) ,
317
313
ObligationCause :: dummy ( ) ,
318
- impl1_env ,
314
+ impl_env ,
319
315
impl1_trait_ref,
320
316
) {
321
- Ok ( impl1_trait_ref) => impl1_trait_ref,
317
+ Ok ( impl1_trait_ref) => ImplSubject :: Trait ( impl1_trait_ref) ,
322
318
Err ( err) => {
323
319
bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
324
320
}
325
- } ;
321
+ }
322
+ }
323
+ subject @ ImplSubject :: Inherent ( _) => subject,
324
+ } ;
326
325
327
- // Attempt to prove that impl2 applies, given all of the above.
328
- let selcx = & mut SelectionContext :: new ( & infcx) ;
329
- let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
330
- let ( impl2_trait_ref, obligations) =
331
- impl_trait_ref_and_oblig ( selcx, impl1_env, impl2_def_id, impl2_substs) ;
326
+ let ( subject2, obligations) =
327
+ impl_subject_and_obligations ( & infcx, impl_env, subject1, impl2_def_id) ;
332
328
333
- !equate (
334
- & infcx,
335
- impl1_env,
336
- impl1_def_id,
337
- impl1_trait_ref,
338
- impl2_trait_ref,
339
- obligations,
340
- )
341
- }
342
- ImplSubject :: Inherent ( ty1) => {
343
- let ty2 = tcx. type_of ( impl2_def_id) ;
344
- !equate ( & infcx, impl1_env, impl1_def_id, ty1, ty2, iter:: empty ( ) )
345
- }
346
- }
329
+ !equate ( & infcx, impl_env, impl1_def_id, subject1, subject2, obligations)
347
330
} )
348
331
}
349
332
350
- fn equate < ' cx , ' tcx , T : Debug + ToTrace < ' tcx > > (
333
+ fn impl_subject_and_obligations < ' cx , ' tcx > (
351
334
infcx : & InferCtxt < ' cx , ' tcx > ,
352
- impl1_env : ty:: ParamEnv < ' tcx > ,
335
+ impl_env : ty:: ParamEnv < ' tcx > ,
336
+ subject1 : ImplSubject < ' tcx > ,
337
+ impl2_def_id : DefId ,
338
+ ) -> ( ImplSubject < ' tcx > , Box < dyn Iterator < Item = PredicateObligation < ' tcx > > + ' tcx > ) {
339
+ if let ImplSubject :: Trait ( _) = subject1 {
340
+ // Attempt to prove that impl2 applies, given all of the above.
341
+ let selcx = & mut SelectionContext :: new ( & infcx) ;
342
+ let impl2_substs = infcx. fresh_substs_for_item ( DUMMY_SP , impl2_def_id) ;
343
+ let ( impl2_trait_ref, obligations) =
344
+ impl_trait_ref_and_oblig ( selcx, impl_env, impl2_def_id, impl2_substs) ;
345
+
346
+ ( ImplSubject :: Trait ( impl2_trait_ref) , Box :: new ( obligations) )
347
+ } else {
348
+ ( infcx. tcx . impl_subject ( impl2_def_id) , Box :: new ( iter:: empty ( ) ) )
349
+ }
350
+ }
351
+
352
+ fn equate < ' cx , ' tcx > (
353
+ infcx : & InferCtxt < ' cx , ' tcx > ,
354
+ impl_env : ty:: ParamEnv < ' tcx > ,
353
355
impl1_def_id : DefId ,
354
- impl1 : T ,
355
- impl2 : T ,
356
+ subject1 : ImplSubject < ' tcx > ,
357
+ subject2 : ImplSubject < ' tcx > ,
356
358
obligations : impl Iterator < Item = PredicateObligation < ' tcx > > ,
357
359
) -> bool {
358
360
// do the impls unify? If not, not disjoint.
359
- let Ok ( InferOk { obligations : more_obligations, .. } ) = infcx
360
- . at ( & ObligationCause :: dummy ( ) , impl1_env)
361
- . eq ( impl1, impl2) else {
362
- debug ! (
363
- "explicit_disjoint: {:?} does not unify with {:?}" ,
364
- impl1, impl2
365
- ) ;
366
- return true ;
367
- } ;
361
+ let Ok ( InferOk { obligations : more_obligations, .. } ) =
362
+ infcx. at ( & ObligationCause :: dummy ( ) , impl_env) . eq ( subject1, subject2)
363
+ else {
364
+ debug ! ( "explicit_disjoint: {:?} does not unify with {:?}" , subject1, subject2) ;
365
+ return true ;
366
+ } ;
368
367
369
368
let selcx = & mut SelectionContext :: new ( & infcx) ;
370
369
let opt_failing_obligation = obligations
371
370
. into_iter ( )
372
371
. chain ( more_obligations)
373
- . find ( |o| negative_impl_exists ( selcx, impl1_env , impl1_def_id, o) ) ;
372
+ . find ( |o| negative_impl_exists ( selcx, impl_env , impl1_def_id, o) ) ;
374
373
375
374
if let Some ( failing_obligation) = opt_failing_obligation {
376
375
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
0 commit comments