diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs index 44cf9b6611eedb3af8ca01f7ae6299646a8cdb3e..7975b946ee5ba0f48caf75f7a156edbaee8aff91 100644 --- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs +++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs @@ -7,7 +7,6 @@ use crate::infer::region_constraints::VerifyBound; use crate::infer::RegionRelations; use crate::infer::RegionVariableOrigin; -use crate::infer::RegionckMode; use crate::infer::SubregionOrigin; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::graph::implementation::{ @@ -33,32 +32,23 @@ pub(crate) fn resolve<'tcx>( region_rels: &RegionRelations<'_, 'tcx>, var_infos: VarInfos, data: RegionConstraintData<'tcx>, - mode: RegionckMode, ) -> (LexicalRegionResolutions<'tcx>, Vec>) { let mut errors = vec![]; let mut resolver = LexicalResolver { region_rels, var_infos, data }; - match mode { - RegionckMode::Solve => { - let values = resolver.infer_variable_values(&mut errors); - (values, errors) - } - RegionckMode::Erase => { - // Skip region inference entirely. - (resolver.erased_data(region_rels.tcx), Vec::new()) - } - } + let values = resolver.infer_variable_values(&mut errors); + (values, errors) } /// Contains the result of lexical region resolution. Offers methods /// to lookup up the final value of a region variable. #[derive(Clone)] pub struct LexicalRegionResolutions<'tcx> { - values: IndexVec>, - error_region: ty::Region<'tcx>, + pub(crate) values: IndexVec>, + pub(crate) error_region: ty::Region<'tcx>, } #[derive(Copy, Clone, Debug)] -enum VarValue<'tcx> { +pub(crate) enum VarValue<'tcx> { Value(Region<'tcx>), ErrorValue, } @@ -162,19 +152,6 @@ fn construct_var_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx } } - /// An erased version of the lexical region resolutions. Used when we're - /// erasing regions and suppressing errors: in item bodies with - /// `-Zborrowck=mir`. - fn erased_data(&self, tcx: TyCtxt<'tcx>) -> LexicalRegionResolutions<'tcx> { - LexicalRegionResolutions { - error_region: tcx.lifetimes.re_static, - values: IndexVec::from_elem_n( - VarValue::Value(tcx.lifetimes.re_erased), - self.num_vars(), - ), - } - } - fn dump_constraints(&self, free_regions: &RegionRelations<'_, 'tcx>) { debug!("----() Start constraint listing (context={:?}) ()----", free_regions.context); for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() { diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index 0e30b136622a020d2d029a4c1ea2ec0dbad3c1b9..017c7abc3aabb94ac07785e101b11d1ad7ecda7e 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -84,20 +84,6 @@ pub struct InferOk<'tcx, T> { ut::InPlace, &'a mut InferCtxtUndoLogs<'tcx>>, >; -/// How we should handle region solving. -/// -/// This is used so that the region values inferred by HIR region solving are -/// not exposed, and so that we can avoid doing work in HIR typeck that MIR -/// typeck will also do. -#[derive(Copy, Clone, Debug, Default)] -pub enum RegionckMode { - /// The default mode: report region errors, don't erase regions. - #[default] - Solve, - /// Erase the results of region after solving. - Erase, -} - /// This type contains all the things within `InferCtxt` that sit within a /// `RefCell` and are involved with taking/rolling back snapshots. Snapshot /// operations are hot enough that we want only one call to `borrow_mut` per @@ -1248,6 +1234,33 @@ pub fn set_tainted_by_errors(&self) { self.tainted_by_errors_flag.set(true) } + pub fn skip_region_resolution(&self) { + let (var_infos, _) = { + let mut inner = self.inner.borrow_mut(); + let inner = &mut *inner; + // Note: `inner.region_obligations` may not be empty, because we + // didn't necessarily call `process_registered_region_obligations`. + // This is okay, because that doesn't introduce new vars. + inner + .region_constraint_storage + .take() + .expect("regions already resolved") + .with_log(&mut inner.undo_log) + .into_infos_and_data() + }; + + let lexical_region_resolutions = LexicalRegionResolutions { + error_region: self.tcx.lifetimes.re_static, + values: rustc_index::vec::IndexVec::from_elem_n( + crate::infer::lexical_region_resolve::VarValue::Value(self.tcx.lifetimes.re_erased), + var_infos.len(), + ), + }; + + let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); + assert!(old_value.is_none()); + } + /// Process the region constraints and return any any errors that /// result. After this, no more unification operations should be /// done -- or the compiler will panic -- but it is legal to use @@ -1256,7 +1269,6 @@ pub fn resolve_regions( &self, region_context: DefId, outlives_env: &OutlivesEnvironment<'tcx>, - mode: RegionckMode, ) -> Vec> { let (var_infos, data) = { let mut inner = self.inner.borrow_mut(); @@ -1278,7 +1290,7 @@ pub fn resolve_regions( &RegionRelations::new(self.tcx, region_context, outlives_env.free_region_map()); let (lexical_region_resolutions, errors) = - lexical_region_resolve::resolve(region_rels, var_infos, data, mode); + lexical_region_resolve::resolve(region_rels, var_infos, data); let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions)); assert!(old_value.is_none()); @@ -1294,9 +1306,8 @@ pub fn resolve_regions_and_report_errors( &self, region_context: DefId, outlives_env: &OutlivesEnvironment<'tcx>, - mode: RegionckMode, ) { - let errors = self.resolve_regions(region_context, outlives_env, mode); + let errors = self.resolve_regions(region_context, outlives_env); if !self.is_tainted_by_errors() { // As a heuristic, just skip reporting region errors diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index e7f0e47f12c6e87daaeeca6182c518f90b3351c6..b37db4b9e18294c116a3aadb70451ae3ca2c7f7a 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -5,7 +5,7 @@ //! [trait-specialization]: https://rustc-dev-guide.rust-lang.org/traits/specialization.html use crate::infer::outlives::env::OutlivesEnvironment; -use crate::infer::{CombinedSnapshot, InferOk, RegionckMode}; +use crate::infer::{CombinedSnapshot, InferOk}; use crate::traits::select::IntercrateAmbiguityCause; use crate::traits::util::impl_subject_and_oblig; use crate::traits::SkipLeakCheck; @@ -413,7 +413,7 @@ fn resolve_negative_obligation<'cx, 'tcx>( param_env, ); - let errors = infcx.resolve_regions(region_context, &outlives_env, RegionckMode::default()); + let errors = infcx.resolve_regions(region_context, &outlives_env); if !errors.is_empty() { return false; diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 03757b5447eead25d56b0677274a9674e8d7764c..34b0f431b8e2dc0329ce65cc2cd649a801a7d4d1 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -23,7 +23,7 @@ pub mod wf; use crate::infer::outlives::env::OutlivesEnvironment; -use crate::infer::{InferCtxt, RegionckMode, TyCtxtInferExt}; +use crate::infer::{InferCtxt, TyCtxtInferExt}; use crate::traits::error_reporting::InferCtxtExt as _; use crate::traits::query::evaluate_obligation::InferCtxtExt as _; use rustc_errors::ErrorGuaranteed; @@ -240,11 +240,7 @@ fn do_normalize_predicates<'tcx>( // cares about declarations like `'a: 'b`. let outlives_env = OutlivesEnvironment::new(elaborated_env); - infcx.resolve_regions_and_report_errors( - region_context, - &outlives_env, - RegionckMode::default(), - ); + infcx.resolve_regions_and_report_errors(region_context, &outlives_env); let predicates = match infcx.fully_resolve(predicates) { Ok(predicates) => predicates, diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs index 65b38b3f2e70bba3b97015d38a099ee14a8e0e32..161ec31793dd8ce333709a73e2d9e3c1c587000e 100644 --- a/compiler/rustc_typeck/src/check/regionck.rs +++ b/compiler/rustc_typeck/src/check/regionck.rs @@ -82,7 +82,7 @@ use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::PatKind; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{self, InferCtxt, RegionObligation, RegionckMode}; +use rustc_infer::infer::{self, InferCtxt, RegionObligation}; use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId}; use rustc_middle::ty::adjustment; use rustc_middle::ty::{self, Ty}; @@ -163,7 +163,8 @@ pub fn regionck_expr(&self, body: &'tcx hir::Body<'tcx>) { rcx.visit_body(body); rcx.visit_region_obligations(id); } - rcx.resolve_regions_and_report_errors(RegionckMode::Erase); + // Checked by NLL + rcx.fcx.skip_region_resolution(); } /// Region checking during the WF phase for items. `wf_tys` are the @@ -175,7 +176,7 @@ pub fn regionck_item(&self, item_id: hir::HirId, span: Span, wf_tys: FxHashSet( add_constraints(&infcx, region_bound_pairs); - let errors = infcx.resolve_regions( - id.expect_owner().to_def_id(), - &outlives_environment, - RegionckMode::default(), - ); + let errors = infcx.resolve_regions(id.expect_owner().to_def_id(), &outlives_environment); debug!(?errors, "errors"); diff --git a/compiler/rustc_typeck/src/coherence/builtin.rs b/compiler/rustc_typeck/src/coherence/builtin.rs index 9f4e6a46d73220596ce13b2108f80868a101805b..c647c2a4c1baa65f2cf96655eefef7a26895143d 100644 --- a/compiler/rustc_typeck/src/coherence/builtin.rs +++ b/compiler/rustc_typeck/src/coherence/builtin.rs @@ -9,7 +9,7 @@ use rustc_hir::ItemKind; use rustc_infer::infer; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{RegionckMode, TyCtxtInferExt}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::ty::adjustment::CoerceUnsizedInfo; use rustc_middle::ty::{self, suggest_constraining_type_params, Ty, TyCtxt, TypeFoldable}; use rustc_trait_selection::traits::error_reporting::InferCtxtExt; @@ -349,11 +349,7 @@ fn visit_implementation_of_dispatch_from_dyn<'tcx>(tcx: TyCtxt<'tcx>, impl_did: // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - infcx.resolve_regions_and_report_errors( - impl_did.to_def_id(), - &outlives_env, - RegionckMode::default(), - ); + infcx.resolve_regions_and_report_errors(impl_did.to_def_id(), &outlives_env); } } _ => { @@ -610,11 +606,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn // Finally, resolve all regions. let outlives_env = OutlivesEnvironment::new(param_env); - infcx.resolve_regions_and_report_errors( - impl_did.to_def_id(), - &outlives_env, - RegionckMode::default(), - ); + infcx.resolve_regions_and_report_errors(impl_did.to_def_id(), &outlives_env); CoerceUnsizedInfo { custom_kind: kind } }) diff --git a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs index bb97d00be32ccf41af60926b0944753c4e5b7284..0ecc28e6054d505e147b282d99a7381707493567 100644 --- a/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_typeck/src/impl_wf_check/min_specialization.rs @@ -71,7 +71,7 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::outlives::env::OutlivesEnvironment; -use rustc_infer::infer::{InferCtxt, RegionckMode, TyCtxtInferExt}; +use rustc_infer::infer::{InferCtxt, TyCtxtInferExt}; use rustc_infer::traits::specialization_graph::Node; use rustc_middle::ty::subst::{GenericArg, InternalSubsts, SubstsRef}; use rustc_middle::ty::trait_def::TraitSpecializationKind; @@ -164,7 +164,7 @@ fn get_impl_substs<'tcx>( // Conservatively use an empty `ParamEnv`. let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty()); - infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default()); + infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env); let Ok(impl2_substs) = infcx.fully_resolve(impl2_substs) else { tcx.sess.emit_err(SubstsOnOverriddenImpl { span }); return None;