1
Fork 0

move considering_regions to the infcx

This commit is contained in:
lcnr 2022-07-20 11:40:15 +02:00
parent ceeb5ade20
commit 608625dae9
12 changed files with 75 additions and 88 deletions

View file

@ -30,7 +30,9 @@ pub fn codegen_fulfill_obligation<'tcx>(
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(|infcx| {
let mut infcx_builder =
tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(DefiningAnchor::Bubble);
infcx_builder.enter(|infcx| {
//~^ HACK `Bubble` is required for
// this test to pass: type-alias-impl-trait/assoc-projection-ice.rs
let mut selcx = SelectionContext::new(&infcx);

View file

@ -15,8 +15,6 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
pub trait TraitEngineExt<'tcx> {
fn new(tcx: TyCtxt<'tcx>) -> Box<Self>;
fn new_ignoring_regions(tcx: TyCtxt<'tcx>) -> Box<Self>;
}
impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
@ -27,14 +25,6 @@ impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> {
Box::new(FulfillmentContext::new())
}
}
fn new_ignoring_regions(tcx: TyCtxt<'tcx>) -> Box<Self> {
if tcx.sess.opts.unstable_opts.chalk {
Box::new(ChalkFulfillmentContext::new())
} else {
Box::new(FulfillmentContext::new_ignoring_regions())
}
}
}
/// Used if you want to have pleasant experience when dealing

View file

@ -58,19 +58,6 @@ pub struct FulfillmentContext<'tcx> {
relationships: FxHashMap<ty::TyVid, ty::FoundRelationships>,
// Should this fulfillment context register type-lives-for-region
// obligations on its parent infcx? In some cases, region
// obligations are either already known to hold (normalization) or
// hopefully verified elsewhere (type-impls-bound), and therefore
// should not be checked.
//
// Note that if we are normalizing a type that we already
// know is well-formed, there should be no harm setting this
// to true - all the region variables should be determinable
// using the RFC 447 rules, which don't depend on
// type-lives-for-region constraints, and because the type
// is well-formed, the constraints should hold.
register_region_obligations: bool,
// Is it OK to register obligations into this infcx inside
// an infcx snapshot?
//
@ -103,7 +90,6 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
FulfillmentContext {
predicates: ObligationForest::new(),
relationships: FxHashMap::default(),
register_region_obligations: true,
usable_in_snapshot: false,
}
}
@ -112,30 +98,18 @@ impl<'a, 'tcx> FulfillmentContext<'tcx> {
FulfillmentContext {
predicates: ObligationForest::new(),
relationships: FxHashMap::default(),
register_region_obligations: true,
usable_in_snapshot: true,
}
}
pub fn new_ignoring_regions() -> FulfillmentContext<'tcx> {
FulfillmentContext {
predicates: ObligationForest::new(),
relationships: FxHashMap::default(),
register_region_obligations: false,
usable_in_snapshot: false,
}
}
/// Attempts to select obligations using `selcx`.
fn select(&mut self, selcx: &mut SelectionContext<'a, 'tcx>) -> Vec<FulfillmentError<'tcx>> {
let span = debug_span!("select", obligation_forest_size = ?self.predicates.len());
let _enter = span.enter();
// Process pending obligations.
let outcome: Outcome<_, _> = self.predicates.process_obligations(&mut FulfillProcessor {
selcx,
register_region_obligations: self.register_region_obligations,
});
let outcome: Outcome<_, _> =
self.predicates.process_obligations(&mut FulfillProcessor { selcx });
// FIXME: if we kept the original cache key, we could mark projection
// obligations as complete for the projection cache here.
@ -239,7 +213,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
struct FulfillProcessor<'a, 'b, 'tcx> {
selcx: &'a mut SelectionContext<'b, 'tcx>,
register_region_obligations: bool,
}
fn mk_pending(os: Vec<PredicateObligation<'_>>) -> Vec<PendingPredicateObligation<'_>> {
@ -385,19 +358,21 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
}
ty::PredicateKind::RegionOutlives(data) => {
match infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data)) {
Ok(()) => ProcessResult::Changed(vec![]),
Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)),
if infcx.considering_regions || data.has_placeholders() {
match infcx
.region_outlives_predicate(&obligation.cause, Binder::dummy(data))
{
Ok(()) => ProcessResult::Changed(vec![]),
Err(_) => ProcessResult::Error(CodeSelectionError(Unimplemented)),
}
} else {
ProcessResult::Changed(vec![])
}
}
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(t_a, r_b)) => {
if self.register_region_obligations {
self.selcx.infcx().register_region_obligation_with_cause(
t_a,
r_b,
&obligation.cause,
);
if infcx.considering_regions {
infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause);
}
ProcessResult::Changed(vec![])
}

View file

@ -163,7 +163,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'a, 'tcx>(
// The handling of regions in this area of the code is terrible,
// see issue #29149. We should be able to improve on this with
// NLL.
let mut fulfill_cx = FulfillmentContext::new_ignoring_regions();
let mut fulfill_cx = FulfillmentContext::new();
// We can use a dummy node-id here because we won't pay any mind
// to region obligations that arise (there shouldn't really be any
@ -207,21 +207,21 @@ fn do_normalize_predicates<'tcx>(
predicates: Vec<ty::Predicate<'tcx>>,
) -> Result<Vec<ty::Predicate<'tcx>>, ErrorGuaranteed> {
let span = cause.span;
tcx.infer_ctxt().enter(|infcx| {
// FIXME. We should really... do something with these region
// obligations. But this call just continues the older
// behavior (i.e., doesn't cause any new bugs), and it would
// take some further refactoring to actually solve them. In
// particular, we would have to handle implied bounds
// properly, and that code is currently largely confined to
// regionck (though I made some efforts to extract it
// out). -nmatsakis
//
// @arielby: In any case, these obligations are checked
// by wfcheck anyway, so I'm not sure we have to check
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
let fulfill_cx = FulfillmentContext::new_ignoring_regions();
// FIXME. We should really... do something with these region
// obligations. But this call just continues the older
// behavior (i.e., doesn't cause any new bugs), and it would
// take some further refactoring to actually solve them. In
// particular, we would have to handle implied bounds
// properly, and that code is currently largely confined to
// regionck (though I made some efforts to extract it
// out). -nmatsakis
//
// @arielby: In any case, these obligations are checked
// by wfcheck anyway, so I'm not sure we have to check
// them here too, and we will remove this function when
// we move over to lazy normalization *anyway*.
tcx.infer_ctxt().ignoring_regions().enter(|infcx| {
let fulfill_cx = FulfillmentContext::new();
let predicates =
match fully_normalize(&infcx, fulfill_cx, cause, elaborated_env, predicates) {
Ok(predicates) => predicates,

View file

@ -207,18 +207,7 @@ fn fulfill_implication<'a, 'tcx>(
// (which are packed up in penv)
infcx.save_and_restore_in_snapshot_flag(|infcx| {
// If we came from `translate_substs`, we already know that the
// predicates for our impl hold (after all, we know that a more
// specialized impl holds, so our impl must hold too), and
// we only want to process the projections to determine the
// the types in our substs using RFC 447, so we can safely
// ignore region obligations, which allows us to avoid threading
// a node-id to assign them with.
//
// If we came from specialization graph construction, then
// we already make a mockery out of the region system, so
// why not ignore them a bit earlier?
let mut fulfill_cx = FulfillmentContext::new_ignoring_regions();
let mut fulfill_cx = FulfillmentContext::new();
for oblig in obligations.chain(more_obligations) {
fulfill_cx.register_predicate_obligation(&infcx, oblig);
}