Skip to content

Commit 61a05ef

Browse files
committed
Extract obligation resolution to function
1 parent 64dfd3b commit 61a05ef

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::traits::{
1717
use rustc_errors::Diagnostic;
1818
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1919
use rustc_hir::CRATE_HIR_ID;
20-
use rustc_infer::infer::TyCtxtInferExt;
20+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
2121
use rustc_infer::traits::{util, TraitEngine};
2222
use rustc_middle::traits::specialization_graph::OverlapMode;
2323
use 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

Comments
 (0)