diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2022-03-17 12:09:00 -0300 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2022-03-17 12:15:17 -0300 |
| commit | 61a05ef8d6a0f5b506dc0d29ef04036238a474a9 (patch) | |
| tree | 7250ad5d30224cbed9d034d72918090912124385 | |
| parent | 64dfd3b2340a42f5fda5802d50c9739d38533102 (diff) | |
Extract obligation resolution to function
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/coherence.rs | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 72a06abd8e0..595337b2e91 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -17,7 +17,7 @@ use crate::traits::{ use rustc_errors::Diagnostic; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::CRATE_HIR_ID; -use rustc_infer::infer::TyCtxtInferExt; +use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::{util, TraitEngine}; use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{self, TreatParams}; @@ -361,46 +361,62 @@ fn negative_impl_exists<'cx, 'tcx>( o: &PredicateObligation<'tcx>, ) -> bool { let infcx = &selcx.infcx().fork(); - let tcx = infcx.tcx; - let super_obligations = util::elaborate_predicates(tcx, iter::once(o.predicate)); + if resolve_negative_obligation(infcx, param_env, region_context, o) { + return true; + } - for o in iter::once(o.clone()).chain(super_obligations) { - if let Some(o) = o.flip_polarity(tcx) { - let mut fulfillment_cx = FulfillmentContext::new(); - fulfillment_cx.register_predicate_obligation(infcx, o); + for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) { + if resolve_negative_obligation(infcx, param_env, region_context, &o) { + return true; + } + } - let errors = fulfillment_cx.select_all_or_error(infcx); + false +} - if !errors.is_empty() { - continue; - } +#[instrument(level = "debug", skip(infcx))] +fn resolve_negative_obligation<'cx, 'tcx>( + infcx: &InferCtxt<'cx, 'tcx>, + param_env: ty::ParamEnv<'tcx>, + region_context: DefId, + o: &PredicateObligation<'tcx>, +) -> bool { + let tcx = infcx.tcx; - let mut outlives_env = OutlivesEnvironment::new(param_env); - // FIXME -- add "assumed to be well formed" types into the `outlives_env` + if let Some(o) = o.flip_polarity(tcx) { + let mut fulfillment_cx = FulfillmentContext::new(); + fulfillment_cx.register_predicate_obligation(infcx, o); - // "Save" the accumulated implied bounds into the outlives environment - // (due to the FIXME above, there aren't any, but this step is still needed). - // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used - // by the "dummy" causes elsewhere (body-id is only relevant when checking - // function bodies with closures). - outlives_env.save_implied_bounds(CRATE_HIR_ID); + let errors = fulfillment_cx.select_all_or_error(infcx); - infcx.process_registered_region_obligations( - outlives_env.region_bound_pairs_map(), - Some(tcx.lifetimes.re_root_empty), - param_env, - ); + if !errors.is_empty() { + return false; + } - let errors = - infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default()); + let mut outlives_env = OutlivesEnvironment::new(param_env); + // FIXME -- add "assumed to be well formed" types into the `outlives_env` - if !errors.is_empty() { - continue; - } + // "Save" the accumulated implied bounds into the outlives environment + // (due to the FIXME above, there aren't any, but this step is still needed). + // The "body id" is given as `CRATE_HIR_ID`, which is the same body-id used + // by the "dummy" causes elsewhere (body-id is only relevant when checking + // function bodies with closures). + outlives_env.save_implied_bounds(CRATE_HIR_ID); - return true; + infcx.process_registered_region_obligations( + outlives_env.region_bound_pairs_map(), + Some(tcx.lifetimes.re_root_empty), + param_env, + ); + + let errors = infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default()); + + if !errors.is_empty() { + return false; } + + return true; } false |
