@@ -17,7 +17,7 @@ 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:: TyCtxtInferExt ;
20+ use rustc_infer:: infer:: { InferCtxt , TyCtxtInferExt } ;
2121use rustc_infer:: traits:: { util, TraitEngine } ;
2222use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
2323use rustc_middle:: ty:: fast_reject:: { self , TreatParams } ;
@@ -361,46 +361,62 @@ fn negative_impl_exists<'cx, 'tcx>(
361361 o : & PredicateObligation < ' tcx > ,
362362) -> bool {
363363 let infcx = & selcx. infcx ( ) . fork ( ) ;
364- let tcx = infcx. tcx ;
365364
366- let super_obligations = util:: elaborate_predicates ( tcx, iter:: once ( o. predicate ) ) ;
365+ if resolve_negative_obligation ( infcx, param_env, region_context, o) {
366+ return true ;
367+ }
367368
368- for o in iter:: once ( o. clone ( ) ) . chain ( super_obligations) {
369- if let Some ( o) = o. flip_polarity ( tcx) {
370- let mut fulfillment_cx = FulfillmentContext :: new ( ) ;
371- fulfillment_cx. register_predicate_obligation ( infcx, o) ;
369+ for o in util:: elaborate_predicates ( infcx. tcx , iter:: once ( o. predicate ) ) {
370+ if resolve_negative_obligation ( infcx, param_env, region_context, & o) {
371+ return true ;
372+ }
373+ }
372374
373- let errors = fulfillment_cx. select_all_or_error ( infcx) ;
375+ false
376+ }
374377
375- if !errors. is_empty ( ) {
376- continue ;
377- }
378+ #[ instrument( level = "debug" , skip( infcx) ) ]
379+ fn resolve_negative_obligation < ' cx , ' tcx > (
380+ infcx : & InferCtxt < ' cx , ' tcx > ,
381+ param_env : ty:: ParamEnv < ' tcx > ,
382+ region_context : DefId ,
383+ o : & PredicateObligation < ' tcx > ,
384+ ) -> bool {
385+ let tcx = infcx. tcx ;
378386
379- let mut outlives_env = OutlivesEnvironment :: new ( param_env) ;
380- // FIXME -- add "assumed to be well formed" types into the `outlives_env`
387+ if let Some ( o) = o. flip_polarity ( tcx) {
388+ let mut fulfillment_cx = FulfillmentContext :: new ( ) ;
389+ fulfillment_cx. register_predicate_obligation ( infcx, o) ;
381390
382- // "Save" the accumulated implied bounds into the outlives environment
383- // (due to the FIXME above, there aren't any, but this step is still needed).
384- // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
385- // by the "dummy" causes elsewhere (body-id is only relevant when checking
386- // function bodies with closures).
387- outlives_env. save_implied_bounds ( CRATE_HIR_ID ) ;
391+ let errors = fulfillment_cx. select_all_or_error ( infcx) ;
388392
389- infcx. process_registered_region_obligations (
390- outlives_env. region_bound_pairs_map ( ) ,
391- Some ( tcx. lifetimes . re_root_empty ) ,
392- param_env,
393- ) ;
393+ if !errors. is_empty ( ) {
394+ return false ;
395+ }
394396
395- let errors =
396- infcx . resolve_regions ( region_context , & outlives_env , RegionckMode :: default ( ) ) ;
397+ let mut outlives_env = OutlivesEnvironment :: new ( param_env ) ;
398+ // FIXME -- add "assumed to be well formed" types into the `outlives_env`
397399
398- if !errors. is_empty ( ) {
399- continue ;
400- }
400+ // "Save" the accumulated implied bounds into the outlives environment
401+ // (due to the FIXME above, there aren't any, but this step is still needed).
402+ // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used
403+ // by the "dummy" causes elsewhere (body-id is only relevant when checking
404+ // function bodies with closures).
405+ outlives_env. save_implied_bounds ( CRATE_HIR_ID ) ;
401406
402- return true ;
407+ infcx. process_registered_region_obligations (
408+ outlives_env. region_bound_pairs_map ( ) ,
409+ Some ( tcx. lifetimes . re_root_empty ) ,
410+ param_env,
411+ ) ;
412+
413+ let errors = infcx. resolve_regions ( region_context, & outlives_env, RegionckMode :: default ( ) ) ;
414+
415+ if !errors. is_empty ( ) {
416+ return false ;
403417 }
418+
419+ return true ;
404420 }
405421
406422 false
0 commit comments