Extract obligation resolution to function
This commit is contained in:
parent
64dfd3b234
commit
61a05ef8d6
1 changed files with 53 additions and 37 deletions
|
@ -17,7 +17,7 @@ use crate::traits::{
|
||||||
use rustc_errors::Diagnostic;
|
use rustc_errors::Diagnostic;
|
||||||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_hir::CRATE_HIR_ID;
|
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_infer::traits::{util, TraitEngine};
|
||||||
use rustc_middle::traits::specialization_graph::OverlapMode;
|
use rustc_middle::traits::specialization_graph::OverlapMode;
|
||||||
use rustc_middle::ty::fast_reject::{self, TreatParams};
|
use rustc_middle::ty::fast_reject::{self, TreatParams};
|
||||||
|
@ -361,11 +361,29 @@ fn negative_impl_exists<'cx, 'tcx>(
|
||||||
o: &PredicateObligation<'tcx>,
|
o: &PredicateObligation<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let infcx = &selcx.infcx().fork();
|
let infcx = &selcx.infcx().fork();
|
||||||
|
|
||||||
|
if resolve_negative_obligation(infcx, param_env, region_context, o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for o in util::elaborate_predicates(infcx.tcx, iter::once(o.predicate)) {
|
||||||
|
if resolve_negative_obligation(infcx, param_env, region_context, &o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 tcx = infcx.tcx;
|
||||||
|
|
||||||
let super_obligations = util::elaborate_predicates(tcx, iter::once(o.predicate));
|
|
||||||
|
|
||||||
for o in iter::once(o.clone()).chain(super_obligations) {
|
|
||||||
if let Some(o) = o.flip_polarity(tcx) {
|
if let Some(o) = o.flip_polarity(tcx) {
|
||||||
let mut fulfillment_cx = FulfillmentContext::new();
|
let mut fulfillment_cx = FulfillmentContext::new();
|
||||||
fulfillment_cx.register_predicate_obligation(infcx, o);
|
fulfillment_cx.register_predicate_obligation(infcx, o);
|
||||||
|
@ -373,7 +391,7 @@ fn negative_impl_exists<'cx, 'tcx>(
|
||||||
let errors = fulfillment_cx.select_all_or_error(infcx);
|
let errors = fulfillment_cx.select_all_or_error(infcx);
|
||||||
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
continue;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut outlives_env = OutlivesEnvironment::new(param_env);
|
let mut outlives_env = OutlivesEnvironment::new(param_env);
|
||||||
|
@ -392,16 +410,14 @@ fn negative_impl_exists<'cx, 'tcx>(
|
||||||
param_env,
|
param_env,
|
||||||
);
|
);
|
||||||
|
|
||||||
let errors =
|
let errors = infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default());
|
||||||
infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default());
|
|
||||||
|
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
continue;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue