@@ -9,7 +9,6 @@ use crate::infer::InferOk;
99use  crate :: solve:: inspect; 
1010use  crate :: solve:: inspect:: { InspectGoal ,  ProofTreeInferCtxtExt ,  ProofTreeVisitor } ; 
1111use  crate :: traits:: engine:: TraitEngineExt ; 
12- use  crate :: traits:: outlives_bounds:: InferCtxtExt  as  _; 
1312use  crate :: traits:: query:: evaluate_obligation:: InferCtxtExt ; 
1413use  crate :: traits:: select:: { IntercrateAmbiguityCause ,  TreatInductiveCycleAs } ; 
1514use  crate :: traits:: structural_normalize:: StructurallyNormalizeExt ; 
@@ -21,7 +20,7 @@ use crate::traits::{
2120} ; 
2221use  rustc_data_structures:: fx:: FxIndexSet ; 
2322use  rustc_errors:: Diagnostic ; 
24- use  rustc_hir:: def_id:: { DefId ,  CRATE_DEF_ID ,   LOCAL_CRATE } ; 
23+ use  rustc_hir:: def_id:: { DefId ,  LOCAL_CRATE } ; 
2524use  rustc_infer:: infer:: { DefineOpaqueTypes ,  InferCtxt ,  TyCtxtInferExt } ; 
2625use  rustc_infer:: traits:: { util,  TraitEngine } ; 
2726use  rustc_middle:: traits:: query:: NoSolution ; 
@@ -36,7 +35,6 @@ use rustc_session::lint::builtin::COINDUCTIVE_OVERLAP_IN_COHERENCE;
3635use  rustc_span:: symbol:: sym; 
3736use  rustc_span:: DUMMY_SP ; 
3837use  std:: fmt:: Debug ; 
39- use  std:: iter; 
4038use  std:: ops:: ControlFlow ; 
4139
4240/// Whether we do the orphan check relative to this crate or 
@@ -417,41 +415,8 @@ fn impl_intersection_has_negative_obligation(
417415
418416    plug_infer_with_placeholders ( infcx,  universe,  ( impl1_header. impl_args ,  impl2_header. impl_args ) ) ; 
419417
420-     for  ( predicate,  _)  in  util:: elaborate ( 
421-         tcx, 
422-         tcx. predicates_of ( impl2_def_id) . instantiate ( tcx,  impl2_header. impl_args ) , 
423-     )  { 
424-         let  Some ( negative_predicate)  = predicate. as_predicate ( ) . flip_polarity ( tcx)  else  { 
425-             continue ; 
426-         } ; 
427- 
428-         let  ref  infcx = infcx. fork ( ) ; 
429-         let  ocx = ObligationCtxt :: new ( infcx) ; 
430- 
431-         ocx. register_obligation ( Obligation :: new ( 
432-             tcx, 
433-             ObligationCause :: dummy ( ) , 
434-             param_env, 
435-             negative_predicate, 
436-         ) ) ; 
437-         if  !ocx. select_all_or_error ( ) . is_empty ( )  { 
438-             continue ; 
439-         } 
440- 
441-         // FIXME: We could use the assumed_wf_types from both impls, I think, 
442-         // if that wasn't implemented just for LocalDefId, and we'd need to do 
443-         //the normalization ourselves since this is totally fallible... 
444-         let  outlives_env = OutlivesEnvironment :: new ( param_env) ; 
445- 
446-         let  errors = infcx. resolve_regions ( & outlives_env) ; 
447-         if  !errors. is_empty ( )  { 
448-             continue ; 
449-         } 
450- 
451-         return  true ; 
452-     } 
453- 
454-     false 
418+     util:: elaborate ( tcx,  tcx. predicates_of ( impl2_def_id) . instantiate ( tcx,  impl2_header. impl_args ) ) 
419+         . any ( |( clause,  _) | try_prove_negated_where_clause ( infcx,  clause,  param_env) ) 
455420} 
456421
457422fn  plug_infer_with_placeholders < ' tcx > ( 
@@ -566,60 +531,47 @@ fn plug_infer_with_placeholders<'tcx>(
566531    } ) ; 
567532} 
568533
569- /// Try to prove that a negative impl exist for the obligation or its supertraits. 
570- /// 
571- /// If such a negative impl exists, then the obligation definitely must not hold 
572- /// due to coherence, even if it's not necessarily "knowable" in this crate. Any 
573- /// valid impl downstream would not be able to exist due to the overlapping 
574- /// negative impl. 
575- #[ instrument( level = "debug" ,  skip( infcx) ) ]  
576- fn  negative_impl_exists < ' tcx > ( 
577-     infcx :  & InferCtxt < ' tcx > , 
578-     o :  & PredicateObligation < ' tcx > , 
579-     body_def_id :  DefId , 
580- )  -> bool  { 
581-     // Try to prove a negative obligation exists for super predicates 
582-     for  pred in  util:: elaborate ( infcx. tcx ,  iter:: once ( o. predicate ) )  { 
583-         if  prove_negated_obligation ( infcx. fork ( ) ,  & o. with ( infcx. tcx ,  pred) ,  body_def_id)  { 
584-             return  true ; 
585-         } 
586-     } 
587- 
588-     false 
589- } 
590- 
591- #[ instrument( level = "debug" ,  skip( infcx) ) ]  
592- fn  prove_negated_obligation < ' tcx > ( 
593-     infcx :  InferCtxt < ' tcx > , 
594-     o :  & PredicateObligation < ' tcx > , 
595-     body_def_id :  DefId , 
534+ fn  try_prove_negated_where_clause < ' tcx > ( 
535+     root_infcx :  & InferCtxt < ' tcx > , 
536+     clause :  ty:: Clause < ' tcx > , 
537+     param_env :  ty:: ParamEnv < ' tcx > , 
596538)  -> bool  { 
597-     let  tcx = infcx. tcx ; 
598- 
599-     let  Some ( o)  = o. flip_polarity ( tcx)  else  { 
539+     let  Some ( negative_predicate)  = clause. as_predicate ( ) . flip_polarity ( root_infcx. tcx )  else  { 
600540        return  false ; 
601541    } ; 
602542
603-     let  param_env = o. param_env ; 
604-     let  ocx = ObligationCtxt :: new ( & infcx) ; 
605-     ocx. register_obligation ( o) ; 
606-     let  errors = ocx. select_all_or_error ( ) ; 
607-     if  !errors. is_empty ( )  { 
543+     // FIXME(with_negative_coherence): the infcx has region contraints from equating 
544+     // the impl headers as requirements. Given that the only region constraints we 
545+     // get are involving inference regions in the root, it shouldn't matter, but 
546+     // still sus. 
547+     // 
548+     // We probably should just throw away the region obligations registered up until 
549+     // now, or ideally use them as assumptions when proving the region obligations 
550+     // that we get from proving the negative predicate below. 
551+     let  ref  infcx = root_infcx. fork ( ) ; 
552+     let  ocx = ObligationCtxt :: new ( infcx) ; 
553+ 
554+     ocx. register_obligation ( Obligation :: new ( 
555+         infcx. tcx , 
556+         ObligationCause :: dummy ( ) , 
557+         param_env, 
558+         negative_predicate, 
559+     ) ) ; 
560+     if  !ocx. select_all_or_error ( ) . is_empty ( )  { 
608561        return  false ; 
609562    } 
610563
611-     let  body_def_id = body_def_id. as_local ( ) . unwrap_or ( CRATE_DEF_ID ) ; 
564+     // FIXME: We could use the assumed_wf_types from both impls, I think, 
565+     // if that wasn't implemented just for LocalDefId, and we'd need to do 
566+     // the normalization ourselves since this is totally fallible... 
567+     let  outlives_env = OutlivesEnvironment :: new ( param_env) ; 
612568
613-     let  ocx  = ObligationCtxt :: new ( & infcx ) ; 
614-     let   Ok ( wf_tys )  = ocx . assumed_wf_types ( param_env ,  body_def_id )   else  { 
569+     let  errors  = infcx . resolve_regions ( & outlives_env ) ; 
570+     if  !errors . is_empty ( )  { 
615571        return  false ; 
616-     } ; 
572+     } 
617573
618-     let  outlives_env = OutlivesEnvironment :: with_bounds ( 
619-         param_env, 
620-         infcx. implied_bounds_tys ( param_env,  body_def_id,  wf_tys) , 
621-     ) ; 
622-     infcx. resolve_regions ( & outlives_env) . is_empty ( ) 
574+     true 
623575} 
624576
625577/// Returns whether all impls which would apply to the `trait_ref` 
0 commit comments