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::{
region_rels: &RegionRelations<'_, 'tcx>,
var_infos: VarInfos,
data: RegionConstraintData<'tcx>,
- mode: RegionckMode,
) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
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<RegionVid, VarValue<'tcx>>,
- error_region: ty::Region<'tcx>,
+ pub(crate) values: IndexVec<RegionVid, VarValue<'tcx>>,
+ pub(crate) error_region: ty::Region<'tcx>,
}
#[derive(Copy, Clone, Debug)]
-enum VarValue<'tcx> {
+pub(crate) enum VarValue<'tcx> {
Value(Region<'tcx>),
ErrorValue,
}
}
}
- /// 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() {
ut::InPlace<T, &'a mut ut::UnificationStorage<T>, &'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
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
&self,
region_context: DefId,
outlives_env: &OutlivesEnvironment<'tcx>,
- mode: RegionckMode,
) -> Vec<RegionResolutionError<'tcx>> {
let (var_infos, data) = {
let mut inner = self.inner.borrow_mut();
&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());
&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
//! [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;
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;
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;
// 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,
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};
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
rcx.outlives_environment.add_implied_bounds(self, wf_tys, item_id, span);
rcx.outlives_environment.save_implied_bounds(item_id);
rcx.visit_region_obligations(item_id);
- rcx.resolve_regions_and_report_errors(RegionckMode::default());
+ rcx.resolve_regions_and_report_errors();
}
/// Region check a function body. Not invoked on closures, but
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
}
- rcx.resolve_regions_and_report_errors(RegionckMode::Erase);
+ // Checked by NLL
+ rcx.fcx.skip_region_resolution();
}
}
self.select_all_obligations_or_error();
}
- fn resolve_regions_and_report_errors(&self, mode: RegionckMode) {
+ fn resolve_regions_and_report_errors(&self) {
self.infcx.process_registered_region_obligations(
self.outlives_environment.region_bound_pairs_map(),
Some(self.tcx.lifetimes.re_root_empty),
self.fcx.resolve_regions_and_report_errors(
self.subject_def_id.to_def_id(),
&self.outlives_environment,
- mode,
);
}
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
use rustc_infer::infer::outlives::obligations::TypeOutlives;
use rustc_infer::infer::region_constraints::GenericKind;
-use rustc_infer::infer::{self, RegionckMode};
-use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
+use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
use rustc_middle::ty::trait_def::TraitSpecializationKind;
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");
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;
// 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);
}
}
_ => {
// 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 }
})
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;
// 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;