@@ -17,7 +17,6 @@ use crate::traits::{
1717use rustc_errors:: Diagnostic ;
1818use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
1919use rustc_hir:: CRATE_HIR_ID ;
20- use rustc_infer:: infer:: at:: ToTrace ;
2120use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
2221use rustc_infer:: traits:: { util, TraitEngine } ;
2322use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
@@ -305,72 +304,72 @@ fn negative_impl<'cx, 'tcx>(
305304 // Create an infcx, taking the predicates of impl1 as assumptions:
306305 tcx. infer_ctxt ( ) . enter ( |infcx| {
307306 // 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) {
311309 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 (
315311 & infcx,
316312 FulfillmentContext :: new ( ) ,
317313 ObligationCause :: dummy ( ) ,
318- impl1_env ,
314+ impl_env ,
319315 impl1_trait_ref,
320316 ) {
321- Ok ( impl1_trait_ref) => impl1_trait_ref,
317+ Ok ( impl1_trait_ref) => ImplSubject :: Trait ( impl1_trait_ref) ,
322318 Err ( err) => {
323319 bug ! ( "failed to fully normalize {:?}: {:?}" , impl1_trait_ref, err) ;
324320 }
325- } ;
321+ }
322+ }
323+ subject @ ImplSubject :: Inherent ( _) => subject,
324+ } ;
326325
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) ;
332328
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)
347330 } )
348331}
349332
350- fn equate < ' cx , ' tcx , T : Debug + ToTrace < ' tcx > > (
333+ fn impl_subject_and_obligations < ' cx , ' tcx > (
351334 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 > ,
353355 impl1_def_id : DefId ,
354- impl1 : T ,
355- impl2 : T ,
356+ subject1 : ImplSubject < ' tcx > ,
357+ subject2 : ImplSubject < ' tcx > ,
356358 obligations : impl Iterator < Item = PredicateObligation < ' tcx > > ,
357359) -> bool {
358360 // 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+ } ;
368367
369368 let selcx = & mut SelectionContext :: new ( & infcx) ;
370369 let opt_failing_obligation = obligations
371370 . into_iter ( )
372371 . 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) ) ;
374373
375374 if let Some ( failing_obligation) = opt_failing_obligation {
376375 debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
0 commit comments