diff options
| author | lcnr <rust@lcnr.de> | 2022-07-20 11:40:15 +0200 |
|---|---|---|
| committer | lcnr <rust@lcnr.de> | 2022-07-21 13:08:56 +0200 |
| commit | 608625dae95cde00e4570eb6c2d63b2244bbf34c (patch) | |
| tree | 7df33e210f9f884331365ef5837f1e3716e3d7f5 /compiler/rustc_trait_selection/src | |
| parent | ceeb5ade201e4181c6d5df2ba96ae5fb2193aadc (diff) | |
| download | rust-608625dae95cde00e4570eb6c2d63b2244bbf34c.tar.gz rust-608625dae95cde00e4570eb6c2d63b2244bbf34c.zip | |
move `considering_regions` to the infcx
Diffstat (limited to 'compiler/rustc_trait_selection/src')
5 files changed, 33 insertions, 77 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index c2b2e319951..5fcaa52d417 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -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); diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 0f7dc6a1257..6c177f63887 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -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 diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 34b37c4e410..9b0ad15bc05 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -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![]) } diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index a14bf72242b..3ef51b0c27a 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -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, diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs index 2c4a453aefc..5f77aae6f22 100644 --- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs @@ -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); } |
