Auto merge of #132623 - nnethercote:rustc_borrowck-cleanups-2, r=Nadrieril

`rustc_borrowck` cleanups, part 2

The code under `do_mir_borrowck` is pretty messy, especially the various types like `MirBorrowckCtxt`, `BorrowckInferCtxt`, `MirTypeckResults`, `MirTypeckRegionConstraints`, `CreateResult`, `TypeChecker`, `TypeVerifier`, `LivenessContext`, `LivenessResults`. This PR does some tidying up, though there's still plenty of mess left afterwards.

A sequel to #132250.

r? `@compiler-errors`
This commit is contained in:
bors 2024-11-19 08:32:27 +00:00
commit 7d40450b2d
23 changed files with 171 additions and 226 deletions

View File

@ -60,7 +60,7 @@ impl<'tcx> UniverseInfo<'tcx> {
UniverseInfo::RelateTys { expected, found } => { UniverseInfo::RelateTys { expected, found } => {
let err = mbcx.infcx.err_ctxt().report_mismatched_types( let err = mbcx.infcx.err_ctxt().report_mismatched_types(
&cause, &cause,
mbcx.param_env, mbcx.infcx.param_env,
expected, expected,
found, found,
TypeError::RegionsPlaceholderMismatch, TypeError::RegionsPlaceholderMismatch,

View File

@ -266,7 +266,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
} }
} }
if self.param_env.caller_bounds().iter().any(|c| { if self.infcx.param_env.caller_bounds().iter().any(|c| {
c.as_trait_clause().is_some_and(|pred| { c.as_trait_clause().is_some_and(|pred| {
pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id()) pred.skip_binder().self_ty() == ty && self.infcx.tcx.is_fn_trait(pred.def_id())
}) })
@ -682,13 +682,13 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Normalize before comparing to see through type aliases and projections. // Normalize before comparing to see through type aliases and projections.
let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args); let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args);
let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args); let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args);
if let Ok(old_ty) = if let Ok(old_ty) = tcx.try_normalize_erasing_regions(
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), old_ty) self.infcx.typing_env(self.infcx.param_env),
&& let Ok(new_ty) = tcx.try_normalize_erasing_regions( old_ty,
self.infcx.typing_env(self.param_env), ) && let Ok(new_ty) = tcx.try_normalize_erasing_regions(
new_ty, self.infcx.typing_env(self.infcx.param_env),
) new_ty,
{ ) {
old_ty == new_ty old_ty == new_ty
} else { } else {
false false
@ -707,15 +707,16 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
// Test the callee's predicates, substituting in `ref_ty` for the moved argument type. // Test the callee's predicates, substituting in `ref_ty` for the moved argument type.
clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| { clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| {
// Normalize before testing to see through type aliases and projections. // Normalize before testing to see through type aliases and projections.
if let Ok(normalized) = if let Ok(normalized) = tcx.try_normalize_erasing_regions(
tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), clause) self.infcx.typing_env(self.infcx.param_env),
{ clause,
) {
clause = normalized; clause = normalized;
} }
self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( self.infcx.predicate_must_hold_modulo_regions(&Obligation::new(
tcx, tcx,
ObligationCause::dummy(), ObligationCause::dummy(),
self.param_env, self.infcx.param_env,
clause, clause,
)) ))
}) })
@ -904,7 +905,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let ty = moved_place.ty(self.body, self.infcx.tcx).ty; let ty = moved_place.ty(self.body, self.infcx.tcx).ty;
debug!("ty: {:?}, kind: {:?}", ty, ty.kind()); debug!("ty: {:?}, kind: {:?}", ty, ty.kind());
let Some(assign_value) = self.infcx.err_ctxt().ty_kind_suggestion(self.param_env, ty) let Some(assign_value) = self.infcx.err_ctxt().ty_kind_suggestion(self.infcx.param_env, ty)
else { else {
return; return;
}; };
@ -1304,7 +1305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool { pub(crate) fn implements_clone(&self, ty: Ty<'tcx>) -> bool {
let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() else { return false }; let Some(clone_trait_def) = self.infcx.tcx.lang_items().clone_trait() else { return false };
self.infcx self.infcx
.type_implements_trait(clone_trait_def, [ty], self.param_env) .type_implements_trait(clone_trait_def, [ty], self.infcx.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
} }
@ -1437,7 +1438,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let ocx = ObligationCtxt::new_with_diagnostics(self.infcx); let ocx = ObligationCtxt::new_with_diagnostics(self.infcx);
let cause = ObligationCause::misc(span, self.mir_def_id()); let cause = ObligationCause::misc(span, self.mir_def_id());
ocx.register_bound(cause, self.param_env, ty, def_id); ocx.register_bound(cause, self.infcx.param_env, ty, def_id);
let errors = ocx.select_all_or_error(); let errors = ocx.select_all_or_error();
// Only emit suggestion if all required predicates are on generic // Only emit suggestion if all required predicates are on generic
@ -1957,7 +1958,8 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
&& let ty::Ref(_, inner, _) = rcvr_ty.kind() && let ty::Ref(_, inner, _) = rcvr_ty.kind()
&& let inner = inner.peel_refs() && let inner = inner.peel_refs()
&& (Holds { ty: inner }).visit_ty(local_ty).is_break() && (Holds { ty: inner }).visit_ty(local_ty).is_break()
&& let None = self.infcx.type_implements_trait_shallow(clone, inner, self.param_env) && let None =
self.infcx.type_implements_trait_shallow(clone, inner, self.infcx.param_env)
{ {
err.span_label( err.span_label(
span, span,
@ -1989,7 +1991,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let obligation = Obligation::new( let obligation = Obligation::new(
self.infcx.tcx, self.infcx.tcx,
ObligationCause::dummy(), ObligationCause::dummy(),
self.param_env, self.infcx.param_env,
trait_ref, trait_ref,
); );
self.infcx.err_ctxt().suggest_derive( self.infcx.err_ctxt().suggest_derive(
@ -3398,7 +3400,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator) if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)
&& self && self
.infcx .infcx
.type_implements_trait(iter_trait, [return_ty], self.param_env) .type_implements_trait(iter_trait, [return_ty], self.infcx.param_env)
.must_apply_modulo_regions() .must_apply_modulo_regions()
{ {
err.span_suggestion_hidden( err.span_suggestion_hidden(
@ -3839,14 +3841,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| { tcx.get_diagnostic_item(sym::deref_target).and_then(|deref_target| {
Instance::try_resolve( Instance::try_resolve(
tcx, tcx,
self.infcx.typing_env(self.param_env), self.infcx.typing_env(self.infcx.param_env),
deref_target, deref_target,
method_args, method_args,
) )
.transpose() .transpose()
}); });
if let Some(Ok(instance)) = deref_target { if let Some(Ok(instance)) = deref_target {
let deref_target_ty = instance.ty(tcx, self.infcx.typing_env(self.param_env)); let deref_target_ty =
instance.ty(tcx, self.infcx.typing_env(self.infcx.param_env));
err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`")); err.note(format!("borrow occurs due to deref coercion to `{deref_target_ty}`"));
err.span_note(tcx.def_span(instance.def_id()), "deref defined here"); err.span_note(tcx.def_span(instance.def_id()), "deref defined here");
} }

View File

@ -864,7 +864,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let kind = call_kind( let kind = call_kind(
self.infcx.tcx, self.infcx.tcx,
self.infcx.typing_env(self.param_env), self.infcx.typing_env(self.infcx.param_env),
method_did, method_did,
method_args, method_args,
*fn_span, *fn_span,
@ -1160,7 +1160,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) {
Some(def_id) => type_known_to_meet_bound_modulo_regions( Some(def_id) => type_known_to_meet_bound_modulo_regions(
self.infcx, self.infcx,
self.param_env, self.infcx.param_env,
Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty), Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty),
def_id, def_id,
), ),
@ -1224,7 +1224,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
BoundRegionConversionTime::FnCall, BoundRegionConversionTime::FnCall,
tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0), tcx.fn_sig(method_did).instantiate(tcx, method_args).input(0),
) )
&& self.infcx.can_eq(self.param_env, ty, self_ty) && self.infcx.can_eq(self.infcx.param_env, ty, self_ty)
{ {
err.subdiagnostic(CaptureReasonSuggest::FreshReborrow { err.subdiagnostic(CaptureReasonSuggest::FreshReborrow {
span: move_span.shrink_to_hi(), span: move_span.shrink_to_hi(),
@ -1258,7 +1258,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Some(errors) = self.infcx.type_implements_trait_shallow( if let Some(errors) = self.infcx.type_implements_trait_shallow(
clone_trait, clone_trait,
ty, ty,
self.param_env, self.infcx.param_env,
) && !has_sugg ) && !has_sugg
{ {
let msg = match &errors[..] { let msg = match &errors[..] {

View File

@ -305,7 +305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let Some(copy_trait_def) = self.infcx.tcx.lang_items().copy_trait() else { return false }; let Some(copy_trait_def) = self.infcx.tcx.lang_items().copy_trait() else { return false };
// This is only going to be ambiguous if there are incoherent impls, because otherwise // This is only going to be ambiguous if there are incoherent impls, because otherwise
// ambiguity should never happen in MIR. // ambiguity should never happen in MIR.
self.infcx.type_implements_trait(copy_trait_def, [ty], self.param_env).may_apply() self.infcx.type_implements_trait(copy_trait_def, [ty], self.infcx.param_env).may_apply()
} }
fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> { fn report_cannot_move_from_static(&mut self, place: Place<'tcx>, span: Span) -> Diag<'infcx> {

View File

@ -1242,7 +1242,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.type_implements_trait_shallow( .type_implements_trait_shallow(
clone_trait, clone_trait,
ty.peel_refs(), ty.peel_refs(),
self.param_env, self.infcx.param_env,
) )
.as_deref() .as_deref()
{ {
@ -1279,7 +1279,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let obligation = traits::Obligation::new( let obligation = traits::Obligation::new(
self.infcx.tcx, self.infcx.tcx,
traits::ObligationCause::dummy(), traits::ObligationCause::dummy(),
self.param_env, self.infcx.param_env,
trait_ref, trait_ref,
); );
self.infcx.err_ctxt().suggest_derive( self.infcx.err_ctxt().suggest_derive(

View File

@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Ok(Some(instance)) = ty::Instance::try_resolve( if let Ok(Some(instance)) = ty::Instance::try_resolve(
tcx, tcx,
self.infcx.typing_env(self.param_env), self.infcx.typing_env(self.infcx.param_env),
*fn_did, *fn_did,
self.infcx.resolve_vars_if_possible(args), self.infcx.resolve_vars_if_possible(args),
) { ) {
@ -1091,7 +1091,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
peeled_ty = ref_ty; peeled_ty = ref_ty;
count += 1; count += 1;
} }
if !self.infcx.type_is_copy_modulo_regions(self.param_env, peeled_ty) { if !self.infcx.type_is_copy_modulo_regions(self.infcx.param_env, peeled_ty) {
return; return;
} }
@ -1160,7 +1160,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let ocx = ObligationCtxt::new(&self.infcx); let ocx = ObligationCtxt::new(&self.infcx);
ocx.register_obligations(preds.iter().map(|(pred, span)| { ocx.register_obligations(preds.iter().map(|(pred, span)| {
trace!(?pred); trace!(?pred);
Obligation::misc(tcx, span, self.mir_def_id(), self.param_env, pred) Obligation::misc(tcx, span, self.mir_def_id(), self.infcx.param_env, pred)
})); }));
if ocx.select_all_or_error().is_empty() && count > 0 { if ocx.select_all_or_error().is_empty() && count > 0 {

View File

@ -140,7 +140,6 @@ fn do_mir_borrowck<'tcx>(
) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) { ) -> (BorrowCheckResult<'tcx>, Option<Box<BodyWithBorrowckFacts<'tcx>>>) {
let def = input_body.source.def_id().expect_local(); let def = input_body.source.def_id().expect_local();
let infcx = BorrowckInferCtxt::new(tcx, def); let infcx = BorrowckInferCtxt::new(tcx, def);
let param_env = tcx.param_env(def);
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls); let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
for var_debug_info in &input_body.var_debug_info { for var_debug_info in &input_body.var_debug_info {
@ -175,8 +174,7 @@ fn do_mir_borrowck<'tcx>(
// will have a lifetime tied to the inference context. // will have a lifetime tied to the inference context.
let mut body_owned = input_body.clone(); let mut body_owned = input_body.clone();
let mut promoted = input_promoted.to_owned(); let mut promoted = input_promoted.to_owned();
let free_regions = let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted);
let body = &body_owned; // no further changes let body = &body_owned; // no further changes
// FIXME(-Znext-solver): A bit dubious that we're only registering // FIXME(-Znext-solver): A bit dubious that we're only registering
@ -192,7 +190,7 @@ fn do_mir_borrowck<'tcx>(
.iter_enumerated() .iter_enumerated()
.map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true))); .map(|(idx, body)| (idx, MoveData::gather_moves(body, tcx, |_| true)));
let mut flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data) let flow_inits = MaybeInitializedPlaces::new(tcx, body, &move_data)
.iterate_to_fixpoint(tcx, body, Some("borrowck")) .iterate_to_fixpoint(tcx, body, Some("borrowck"))
.into_results_cursor(body); .into_results_cursor(body);
@ -213,18 +211,12 @@ fn do_mir_borrowck<'tcx>(
body, body,
&promoted, &promoted,
&location_table, &location_table,
param_env, flow_inits,
&mut flow_inits,
&move_data, &move_data,
&borrow_set, &borrow_set,
tcx.closure_captures(def),
consumer_options, consumer_options,
); );
// `flow_inits` is large, so we drop it as soon as possible. This reduces
// peak memory usage significantly on some benchmarks.
drop(flow_inits);
// Dump MIR results into a file, if that is enabled. This let us // Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging. // write unit-tests, as well as helping with debugging.
nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set); nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set);
@ -251,7 +243,6 @@ fn do_mir_borrowck<'tcx>(
let promoted_body = &promoted[idx]; let promoted_body = &promoted[idx];
let mut promoted_mbcx = MirBorrowckCtxt { let mut promoted_mbcx = MirBorrowckCtxt {
infcx: &infcx, infcx: &infcx,
param_env,
body: promoted_body, body: promoted_body,
move_data: &move_data, move_data: &move_data,
location_table: &location_table, // no need to create a real one for the promoted, it is not used location_table: &location_table, // no need to create a real one for the promoted, it is not used
@ -291,7 +282,6 @@ fn do_mir_borrowck<'tcx>(
let mut mbcx = MirBorrowckCtxt { let mut mbcx = MirBorrowckCtxt {
infcx: &infcx, infcx: &infcx,
param_env,
body, body,
move_data: &move_data, move_data: &move_data,
location_table: &location_table, location_table: &location_table,
@ -448,12 +438,14 @@ fn get_flow_results<'a, 'tcx>(
pub(crate) struct BorrowckInferCtxt<'tcx> { pub(crate) struct BorrowckInferCtxt<'tcx> {
pub(crate) infcx: InferCtxt<'tcx>, pub(crate) infcx: InferCtxt<'tcx>,
pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>, pub(crate) reg_var_to_origin: RefCell<FxIndexMap<ty::RegionVid, RegionCtxt>>,
pub(crate) param_env: ParamEnv<'tcx>,
} }
impl<'tcx> BorrowckInferCtxt<'tcx> { impl<'tcx> BorrowckInferCtxt<'tcx> {
pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id)); let infcx = tcx.infer_ctxt().build(TypingMode::analysis_in_body(tcx, def_id));
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()) } let param_env = tcx.param_env(def_id);
BorrowckInferCtxt { infcx, reg_var_to_origin: RefCell::new(Default::default()), param_env }
} }
pub(crate) fn next_region_var<F>( pub(crate) fn next_region_var<F>(
@ -532,7 +524,6 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> {
struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
infcx: &'infcx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
move_data: &'a MoveData<'tcx>, move_data: &'a MoveData<'tcx>,

View File

@ -30,7 +30,7 @@ use crate::diagnostics::RegionErrors;
use crate::facts::{AllFacts, AllFactsExt, RustcFacts}; use crate::facts::{AllFacts, AllFactsExt, RustcFacts};
use crate::location::LocationTable; use crate::location::LocationTable;
use crate::region_infer::RegionInferenceContext; use crate::region_infer::RegionInferenceContext;
use crate::type_check::{self, MirTypeckRegionConstraints, MirTypeckResults}; use crate::type_check::{self, MirTypeckResults};
use crate::universal_regions::UniversalRegions; use crate::universal_regions::UniversalRegions;
use crate::{BorrowckInferCtxt, polonius, renumber}; use crate::{BorrowckInferCtxt, polonius, renumber};
@ -50,10 +50,9 @@ pub(crate) struct NllOutput<'tcx> {
/// Rewrites the regions in the MIR to use NLL variables, also scraping out the set of universal /// Rewrites the regions in the MIR to use NLL variables, also scraping out the set of universal
/// regions (e.g., region parameters) declared on the function. That set will need to be given to /// regions (e.g., region parameters) declared on the function. That set will need to be given to
/// `compute_regions`. /// `compute_regions`.
#[instrument(skip(infcx, param_env, body, promoted), level = "debug")] #[instrument(skip(infcx, body, promoted), level = "debug")]
pub(crate) fn replace_regions_in_mir<'tcx>( pub(crate) fn replace_regions_in_mir<'tcx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body: &mut Body<'tcx>, body: &mut Body<'tcx>,
promoted: &mut IndexSlice<Promoted, Body<'tcx>>, promoted: &mut IndexSlice<Promoted, Body<'tcx>>,
) -> UniversalRegions<'tcx> { ) -> UniversalRegions<'tcx> {
@ -62,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
debug!(?def); debug!(?def);
// Compute named region information. This also renumbers the inputs/outputs. // Compute named region information. This also renumbers the inputs/outputs.
let universal_regions = UniversalRegions::new(infcx, def, param_env); let universal_regions = UniversalRegions::new(infcx, def);
// Replace all remaining regions with fresh inference variables. // Replace all remaining regions with fresh inference variables.
renumber::renumber_mir(infcx, body, promoted); renumber::renumber_mir(infcx, body, promoted);
@ -81,11 +80,9 @@ pub(crate) fn compute_regions<'a, 'tcx>(
body: &Body<'tcx>, body: &Body<'tcx>,
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
location_table: &LocationTable, location_table: &LocationTable,
param_env: ty::ParamEnv<'tcx>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
upvars: &[&ty::CapturedPlace<'tcx>],
consumer_options: Option<ConsumerOptions>, consumer_options: Option<ConsumerOptions>,
) -> NllOutput<'tcx> { ) -> NllOutput<'tcx> {
let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); let is_polonius_legacy_enabled = infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled();
@ -96,41 +93,27 @@ pub(crate) fn compute_regions<'a, 'tcx>(
let mut all_facts = let mut all_facts =
(polonius_input || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default()); (polonius_input || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default());
let universal_regions = Rc::new(universal_regions);
let elements = Rc::new(DenseLocationMap::new(body)); let elements = Rc::new(DenseLocationMap::new(body));
// Run the MIR type-checker. // Run the MIR type-checker.
let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } = let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } =
type_check::type_check( type_check::type_check(
infcx, infcx,
param_env,
body, body,
promoted, promoted,
Rc::clone(&universal_regions), universal_regions,
location_table, location_table,
borrow_set, borrow_set,
&mut all_facts, &mut all_facts,
flow_inits, flow_inits,
move_data, move_data,
Rc::clone(&elements), Rc::clone(&elements),
upvars,
); );
// Create the region inference context, taking ownership of the // Create the region inference context, taking ownership of the
// region inference data that was contained in `infcx`, and the // region inference data that was contained in `infcx`, and the
// base constraints generated by the type-check. // base constraints generated by the type-check.
let var_origins = infcx.get_region_var_origins(); let var_origins = infcx.get_region_var_origins();
let MirTypeckRegionConstraints {
placeholder_indices,
placeholder_index_to_region: _,
liveness_constraints,
mut outlives_constraints,
mut member_constraints,
universe_causes,
type_tests,
} = constraints;
let placeholder_indices = Rc::new(placeholder_indices);
// If requested, emit legacy polonius facts. // If requested, emit legacy polonius facts.
polonius::emit_facts( polonius::emit_facts(
@ -140,31 +123,14 @@ pub(crate) fn compute_regions<'a, 'tcx>(
body, body,
borrow_set, borrow_set,
move_data, move_data,
&universal_regions,
&universal_region_relations, &universal_region_relations,
); );
if let Some(guar) = universal_regions.tainted_by_errors() {
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
// outlives bounds that we may end up checking.
outlives_constraints = Default::default();
member_constraints = Default::default();
// Also taint the entire scope.
infcx.set_tainted_by_errors(guar);
}
let mut regioncx = RegionInferenceContext::new( let mut regioncx = RegionInferenceContext::new(
infcx, infcx,
var_origins, var_origins,
universal_regions, constraints,
placeholder_indices,
universal_region_relations, universal_region_relations,
outlives_constraints,
member_constraints,
universe_causes,
type_tests,
liveness_constraints,
elements, elements,
); );

View File

@ -12,7 +12,6 @@ use crate::borrow_set::BorrowSet;
use crate::facts::{AllFacts, PoloniusRegionVid}; use crate::facts::{AllFacts, PoloniusRegionVid};
use crate::location::LocationTable; use crate::location::LocationTable;
use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::type_check::free_region_relations::UniversalRegionRelations;
use crate::universal_regions::UniversalRegions;
mod loan_invalidations; mod loan_invalidations;
mod loan_kills; mod loan_kills;
@ -32,7 +31,6 @@ pub(crate) fn emit_facts<'tcx>(
body: &Body<'tcx>, body: &Body<'tcx>,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
move_data: &MoveData<'_>, move_data: &MoveData<'_>,
universal_regions: &UniversalRegions<'_>,
universal_region_relations: &UniversalRegionRelations<'_>, universal_region_relations: &UniversalRegionRelations<'_>,
) { ) {
let Some(all_facts) = all_facts else { let Some(all_facts) = all_facts else {
@ -41,12 +39,7 @@ pub(crate) fn emit_facts<'tcx>(
}; };
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation"); let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
emit_move_facts(all_facts, move_data, location_table, body); emit_move_facts(all_facts, move_data, location_table, body);
emit_universal_region_facts( emit_universal_region_facts(all_facts, borrow_set, universal_region_relations);
all_facts,
borrow_set,
universal_regions,
universal_region_relations,
);
emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set); emit_cfg_and_loan_kills_facts(all_facts, tcx, location_table, body, borrow_set);
emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set); emit_loan_invalidations_facts(all_facts, tcx, location_table, body, borrow_set);
} }
@ -129,7 +122,6 @@ fn emit_move_facts(
fn emit_universal_region_facts( fn emit_universal_region_facts(
all_facts: &mut AllFacts, all_facts: &mut AllFacts,
borrow_set: &BorrowSet<'_>, borrow_set: &BorrowSet<'_>,
universal_regions: &UniversalRegions<'_>,
universal_region_relations: &UniversalRegionRelations<'_>, universal_region_relations: &UniversalRegionRelations<'_>,
) { ) {
// 1: universal regions are modeled in Polonius as a pair: // 1: universal regions are modeled in Polonius as a pair:
@ -138,9 +130,10 @@ fn emit_universal_region_facts(
// the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index // the `borrow_set`, their `BorrowIndex` are synthesized as the universal region index
// added to the existing number of loans, as if they succeeded them in the set. // added to the existing number of loans, as if they succeeded them in the set.
// //
let universal_regions = &universal_region_relations.universal_regions;
all_facts all_facts
.universal_region .universal_region
.extend(universal_regions.universal_regions().map(PoloniusRegionVid::from)); .extend(universal_regions.universal_regions_iter().map(PoloniusRegionVid::from));
let borrow_count = borrow_set.len(); let borrow_count = borrow_set.len();
debug!( debug!(
"emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}", "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}",
@ -148,7 +141,7 @@ fn emit_universal_region_facts(
borrow_count borrow_count
); );
for universal_region in universal_regions.universal_regions() { for universal_region in universal_regions.universal_regions_iter() {
let universal_region_idx = universal_region.index(); let universal_region_idx = universal_region.index();
let placeholder_loan_idx = borrow_count + universal_region_idx; let placeholder_loan_idx = borrow_count + universal_region_idx;
all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into())); all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into()));

View File

@ -23,7 +23,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
for region in self.regions() { for region in self.regions() {
if let NllRegionVariableOrigin::FreeRegion = self.definitions[region].origin { if let NllRegionVariableOrigin::FreeRegion = self.definitions[region].origin {
let classification = self.universal_regions.region_classification(region).unwrap(); let classification =
self.universal_regions().region_classification(region).unwrap();
let outlived_by = self.universal_region_relations.regions_outlived_by(region); let outlived_by = self.universal_region_relations.regions_outlived_by(region);
writeln!( writeln!(
out, out,

View File

@ -31,11 +31,9 @@ use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo};
use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}; use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex};
use crate::nll::PoloniusOutput; use crate::nll::PoloniusOutput;
use crate::region_infer::reverse_sccs::ReverseSccGraph; use crate::region_infer::reverse_sccs::ReverseSccGraph;
use crate::region_infer::values::{ use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues, ToElementIndex};
LivenessValues, PlaceholderIndices, RegionElement, RegionValues, ToElementIndex,
};
use crate::type_check::Locations;
use crate::type_check::free_region_relations::UniversalRegionRelations; use crate::type_check::free_region_relations::UniversalRegionRelations;
use crate::type_check::{Locations, MirTypeckRegionConstraints};
use crate::universal_regions::UniversalRegions; use crate::universal_regions::UniversalRegions;
mod dump_mir; mod dump_mir;
@ -191,10 +189,6 @@ pub struct RegionInferenceContext<'tcx> {
/// Type constraints that we check after solving. /// Type constraints that we check after solving.
type_tests: Vec<TypeTest<'tcx>>, type_tests: Vec<TypeTest<'tcx>>,
/// Information about the universally quantified regions in scope
/// on this function.
universal_regions: Rc<UniversalRegions<'tcx>>,
/// Information about how the universally quantified regions in /// Information about how the universally quantified regions in
/// scope on this function relate to one another. /// scope on this function relate to one another.
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
@ -399,21 +393,36 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn new( pub(crate) fn new(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
var_infos: VarInfos, var_infos: VarInfos,
universal_regions: Rc<UniversalRegions<'tcx>>, constraints: MirTypeckRegionConstraints<'tcx>,
placeholder_indices: Rc<PlaceholderIndices>,
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
mut outlives_constraints: OutlivesConstraintSet<'tcx>,
member_constraints_in: MemberConstraintSet<'tcx, RegionVid>,
universe_causes: FxIndexMap<ty::UniverseIndex, UniverseInfo<'tcx>>,
type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues,
elements: Rc<DenseLocationMap>, elements: Rc<DenseLocationMap>,
) -> Self { ) -> Self {
debug!("universal_regions: {:#?}", universal_regions); let universal_regions = &universal_region_relations.universal_regions;
let MirTypeckRegionConstraints {
placeholder_indices,
placeholder_index_to_region: _,
liveness_constraints,
mut outlives_constraints,
mut member_constraints,
universe_causes,
type_tests,
} = constraints;
debug!("universal_regions: {:#?}", universal_region_relations.universal_regions);
debug!("outlives constraints: {:#?}", outlives_constraints); debug!("outlives constraints: {:#?}", outlives_constraints);
debug!("placeholder_indices: {:#?}", placeholder_indices); debug!("placeholder_indices: {:#?}", placeholder_indices);
debug!("type tests: {:#?}", type_tests); debug!("type tests: {:#?}", type_tests);
if let Some(guar) = universal_region_relations.universal_regions.tainted_by_errors() {
// Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all
// outlives bounds that we may end up checking.
outlives_constraints = Default::default();
member_constraints = Default::default();
// Also taint the entire scope.
infcx.set_tainted_by_errors(guar);
}
// Create a RegionDefinition for each inference variable. // Create a RegionDefinition for each inference variable.
let definitions: IndexVec<_, _> = var_infos let definitions: IndexVec<_, _> = var_infos
.iter() .iter()
@ -438,7 +447,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
let member_constraints = let member_constraints =
Rc::new(member_constraints_in.into_mapped(|r| constraint_sccs.scc(r))); Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r)));
let mut result = Self { let mut result = Self {
var_infos, var_infos,
@ -453,7 +462,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
universe_causes, universe_causes,
scc_values, scc_values,
type_tests, type_tests,
universal_regions,
universal_region_relations, universal_region_relations,
}; };
@ -518,7 +526,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
fn init_free_and_bound_regions(&mut self) { fn init_free_and_bound_regions(&mut self) {
// Update the names (if any) // Update the names (if any)
// This iterator has unstable order but we collect it all into an IndexVec // This iterator has unstable order but we collect it all into an IndexVec
for (external_name, variable) in self.universal_regions.named_universal_regions() { for (external_name, variable) in
self.universal_region_relations.universal_regions.named_universal_regions_iter()
{
debug!( debug!(
"init_free_and_bound_regions: region {:?} has external name {:?}", "init_free_and_bound_regions: region {:?} has external name {:?}",
variable, external_name variable, external_name
@ -562,7 +572,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// ///
/// (Panics if `r` is not a registered universal region.) /// (Panics if `r` is not a registered universal region.)
pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { pub(crate) fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid {
self.universal_regions.to_region_vid(r) self.universal_regions().to_region_vid(r)
} }
/// Returns an iterator over all the outlives constraints. /// Returns an iterator over all the outlives constraints.
@ -574,7 +584,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`. /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diag<'_, ()>) { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diag<'_, ()>) {
self.universal_regions.annotate(tcx, err) self.universal_regions().annotate(tcx, err)
} }
/// Returns `true` if the region `r` contains the point `p`. /// Returns `true` if the region `r` contains the point `p`.
@ -686,7 +696,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
if outlives_requirements.is_empty() { if outlives_requirements.is_empty() {
(None, errors_buffer) (None, errors_buffer)
} else { } else {
let num_external_vids = self.universal_regions.num_global_and_external_regions(); let num_external_vids = self.universal_regions().num_global_and_external_regions();
( (
Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }), Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }),
errors_buffer, errors_buffer,
@ -989,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// always be in the root universe. // always be in the root universe.
if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() { if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p); debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
let static_r = self.universal_regions.fr_static; let static_r = self.universal_regions().fr_static;
propagated_outlives_requirements.push(ClosureOutlivesRequirement { propagated_outlives_requirements.push(ClosureOutlivesRequirement {
subject, subject,
outlived_free_region: static_r, outlived_free_region: static_r,
@ -1032,8 +1042,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// avoid potential non-determinism we approximate this by requiring // avoid potential non-determinism we approximate this by requiring
// T: '1 and T: '2. // T: '1 and T: '2.
for upper_bound in non_local_ub { for upper_bound in non_local_ub {
debug_assert!(self.universal_regions.is_universal_region(upper_bound)); debug_assert!(self.universal_regions().is_universal_region(upper_bound));
debug_assert!(!self.universal_regions.is_local_free_region(upper_bound)); debug_assert!(!self.universal_regions().is_local_free_region(upper_bound));
let requirement = ClosureOutlivesRequirement { let requirement = ClosureOutlivesRequirement {
subject, subject,
@ -1101,7 +1111,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// To do so, we simply check every candidate `u_r` for equality. // To do so, we simply check every candidate `u_r` for equality.
self.scc_values self.scc_values
.universal_regions_outlived_by(r_scc) .universal_regions_outlived_by(r_scc)
.filter(|&u_r| !self.universal_regions.is_local_free_region(u_r)) .filter(|&u_r| !self.universal_regions().is_local_free_region(u_r))
.find(|&u_r| self.eval_equal(u_r, r_vid)) .find(|&u_r| self.eval_equal(u_r, r_vid))
.map(|u_r| ty::Region::new_var(tcx, u_r)) .map(|u_r| ty::Region::new_var(tcx, u_r))
// In case we could not find a named region to map to, // In case we could not find a named region to map to,
@ -1139,9 +1149,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Find the smallest universal region that contains all other // Find the smallest universal region that contains all other
// universal regions within `region`. // universal regions within `region`.
let mut lub = self.universal_regions.fr_fn_body; let mut lub = self.universal_regions().fr_fn_body;
let r_scc = self.constraint_sccs.scc(r); let r_scc = self.constraint_sccs.scc(r);
let static_r = self.universal_regions.fr_static; let static_r = self.universal_regions().fr_static;
for ur in self.scc_values.universal_regions_outlived_by(r_scc) { for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur); let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
debug!(?ur, ?lub, ?new_lub); debug!(?ur, ?lub, ?new_lub);
@ -1288,12 +1298,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!( debug!(
"sup_region's value = {:?} universal={:?}", "sup_region's value = {:?} universal={:?}",
self.region_value_str(sup_region), self.region_value_str(sup_region),
self.universal_regions.is_universal_region(sup_region), self.universal_regions().is_universal_region(sup_region),
); );
debug!( debug!(
"sub_region's value = {:?} universal={:?}", "sub_region's value = {:?} universal={:?}",
self.region_value_str(sub_region), self.region_value_str(sub_region),
self.universal_regions.is_universal_region(sub_region), self.universal_regions().is_universal_region(sub_region),
); );
let sub_region_scc = self.constraint_sccs.scc(sub_region); let sub_region_scc = self.constraint_sccs.scc(sub_region);
@ -1308,7 +1318,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
by super `{sup_region_scc:?}`, promoting to static", by super `{sup_region_scc:?}`, promoting to static",
); );
return self.eval_outlives(sup_region, self.universal_regions.fr_static); return self.eval_outlives(sup_region, self.universal_regions().fr_static);
} }
// Both the `sub_region` and `sup_region` consist of the union // Both the `sub_region` and `sup_region` consist of the union
@ -1332,7 +1342,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Now we have to compare all the points in the sub region and make // Now we have to compare all the points in the sub region and make
// sure they exist in the sup region. // sure they exist in the sup region.
if self.universal_regions.is_universal_region(sup_region) { if self.universal_regions().is_universal_region(sup_region) {
// Micro-opt: universal regions contain all points. // Micro-opt: universal regions contain all points.
debug!("super is universal and hence contains all points"); debug!("super is universal and hence contains all points");
return true; return true;
@ -1736,7 +1746,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2);
let result = { let result = {
r == fr2 || { r == fr2 || {
fr2 == self.universal_regions.fr_static && self.cannot_name_placeholder(fr1, r) fr2 == self.universal_regions().fr_static && self.cannot_name_placeholder(fr1, r)
} }
}; };
debug!("provides_universal_region: result = {:?}", result); debug!("provides_universal_region: result = {:?}", result);
@ -1837,7 +1847,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// A constraint like `'r: 'x` can come from our constraint // A constraint like `'r: 'x` can come from our constraint
// graph. // graph.
let fr_static = self.universal_regions.fr_static; let fr_static = self.universal_regions().fr_static;
let outgoing_edges_from_graph = let outgoing_edges_from_graph =
self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static); self.constraint_graph.outgoing_edges(r, &self.constraints, fr_static);
@ -1952,7 +1962,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx> { pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx> {
self.universal_regions.as_ref() &self.universal_region_relations.universal_regions
} }
/// Tries to find the best constraint to blame for the fact that /// Tries to find the best constraint to blame for the fact that
@ -2212,7 +2222,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// Access to the region graph, built from the outlives constraints. /// Access to the region graph, built from the outlives constraints.
pub(crate) fn region_graph(&self) -> RegionGraph<'_, 'tcx, graph::Normal> { pub(crate) fn region_graph(&self) -> RegionGraph<'_, 'tcx, graph::Normal> {
self.constraint_graph.region_graph(&self.constraints, self.universal_regions.fr_static) self.constraint_graph.region_graph(&self.constraints, self.universal_regions().fr_static)
} }
/// Returns whether the given region is considered live at all points: whether it is a /// Returns whether the given region is considered live at all points: whether it is a

View File

@ -74,7 +74,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
debug!(?opaque_type_key, ?concrete_type); debug!(?opaque_type_key, ?concrete_type);
let mut arg_regions: Vec<(ty::RegionVid, ty::Region<'_>)> = let mut arg_regions: Vec<(ty::RegionVid, ty::Region<'_>)> =
vec![(self.universal_regions.fr_static, infcx.tcx.lifetimes.re_static)]; vec![(self.universal_regions().fr_static, infcx.tcx.lifetimes.re_static)];
let opaque_type_key = let opaque_type_key =
opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| { opaque_type_key.fold_captured_lifetime_args(infcx.tcx, |region| {
@ -88,12 +88,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// the same name and simplifies subsequent handling. // the same name and simplifies subsequent handling.
// See [rustc-dev-guide chapter] § "Semantic lifetime equality". // See [rustc-dev-guide chapter] § "Semantic lifetime equality".
NllRegionVariableOrigin::FreeRegion => self NllRegionVariableOrigin::FreeRegion => self
.universal_regions
.universal_regions() .universal_regions()
.universal_regions_iter()
.filter(|&ur| { .filter(|&ur| {
// See [rustc-dev-guide chapter] § "Closure restrictions". // See [rustc-dev-guide chapter] § "Closure restrictions".
!matches!( !matches!(
self.universal_regions.region_classification(ur), self.universal_regions().region_classification(ur),
Some(RegionClassification::External) Some(RegionClassification::External)
) )
}) })

View File

@ -45,8 +45,8 @@ impl RegionInferenceContext<'_> {
let graph = self.constraint_sccs.reverse(); let graph = self.constraint_sccs.reverse();
let mut paired_scc_regions = self let mut paired_scc_regions = self
.universal_regions
.universal_regions() .universal_regions()
.universal_regions_iter()
.map(|region| (self.constraint_sccs.scc(region), region)) .map(|region| (self.constraint_sccs.scc(region), region))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
paired_scc_regions.sort(); paired_scc_regions.sort();

View File

@ -258,10 +258,9 @@ impl PlaceholderIndices {
/// Here, the variable `'0` would contain the free region `'a`, /// Here, the variable `'0` would contain the free region `'a`,
/// because (since it is returned) it must live for at least `'a`. But /// because (since it is returned) it must live for at least `'a`. But
/// it would also contain various points from within the function. /// it would also contain various points from within the function.
#[derive(Clone)]
pub(crate) struct RegionValues<N: Idx> { pub(crate) struct RegionValues<N: Idx> {
elements: Rc<DenseLocationMap>, elements: Rc<DenseLocationMap>,
placeholder_indices: Rc<PlaceholderIndices>, placeholder_indices: PlaceholderIndices,
points: SparseIntervalMatrix<N, PointIndex>, points: SparseIntervalMatrix<N, PointIndex>,
free_regions: SparseBitMatrix<N, RegionVid>, free_regions: SparseBitMatrix<N, RegionVid>,
@ -277,7 +276,7 @@ impl<N: Idx> RegionValues<N> {
pub(crate) fn new( pub(crate) fn new(
elements: Rc<DenseLocationMap>, elements: Rc<DenseLocationMap>,
num_universal_regions: usize, num_universal_regions: usize,
placeholder_indices: Rc<PlaceholderIndices>, placeholder_indices: PlaceholderIndices,
) -> Self { ) -> Self {
let num_points = elements.num_points(); let num_points = elements.num_points();
let num_placeholders = placeholder_indices.len(); let num_placeholders = placeholder_indices.len();

View File

@ -132,7 +132,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
locations: Locations, locations: Locations,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
) { ) {
let param_env = self.param_env; let param_env = self.infcx.param_env;
let predicate = predicate.upcast(self.tcx()); let predicate = predicate.upcast(self.tcx());
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
locations, locations,
@ -158,7 +158,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
where where
T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx, T: type_op::normalize::Normalizable<'tcx> + fmt::Display + Copy + 'tcx,
{ {
let param_env = self.param_env; let param_env = self.infcx.param_env;
let result: Result<_, ErrorGuaranteed> = self.fully_perform_op( let result: Result<_, ErrorGuaranteed> = self.fully_perform_op(
location.to_locations(), location.to_locations(),
category, category,
@ -176,7 +176,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let tcx = self.tcx(); let tcx = self.tcx();
if self.infcx.next_trait_solver() { if self.infcx.next_trait_solver() {
let body = self.body; let body = self.body;
let param_env = self.param_env; let param_env = self.infcx.param_env;
self.fully_perform_op( self.fully_perform_op(
location.to_locations(), location.to_locations(),
ConstraintCategory::Boring, ConstraintCategory::Boring,
@ -223,7 +223,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
Locations::All(span), Locations::All(span),
ConstraintCategory::Boring, ConstraintCategory::Boring,
self.param_env.and(type_op::ascribe_user_type::AscribeUserType { mir_ty, user_ty }), self.infcx
.param_env
.and(type_op::ascribe_user_type::AscribeUserType { mir_ty, user_ty }),
); );
} }
@ -250,7 +252,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let mir_ty = self.normalize(mir_ty, Locations::All(span)); let mir_ty = self.normalize(mir_ty, Locations::All(span));
let cause = ObligationCause::dummy_with_span(span); let cause = ObligationCause::dummy_with_span(span);
let param_env = self.param_env; let param_env = self.infcx.param_env;
let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(
Locations::All(span), Locations::All(span),
ConstraintCategory::Boring, ConstraintCategory::Boring,

View File

@ -37,7 +37,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> {
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,
@ -52,7 +52,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: &'a RegionBoundPairs<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>],
locations: Locations, locations: Locations,
span: Span, span: Span,
category: ConstraintCategory<'tcx>, category: ConstraintCategory<'tcx>,

View File

@ -1,5 +1,3 @@
use std::rc::Rc;
use rustc_data_structures::frozen::Frozen; use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder}; use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder};
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -23,7 +21,7 @@ use crate::universal_regions::UniversalRegions;
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct UniversalRegionRelations<'tcx> { pub(crate) struct UniversalRegionRelations<'tcx> {
universal_regions: Rc<UniversalRegions<'tcx>>, pub(crate) universal_regions: UniversalRegions<'tcx>,
/// Stores the outlives relations that are known to hold from the /// Stores the outlives relations that are known to hold from the
/// implied bounds, in-scope where-clauses, and that sort of /// implied bounds, in-scope where-clauses, and that sort of
@ -46,7 +44,7 @@ type NormalizedInputsAndOutput<'tcx> = Vec<Ty<'tcx>>;
pub(crate) struct CreateResult<'tcx> { pub(crate) struct CreateResult<'tcx> {
pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>, pub(crate) universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>,
pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], pub(crate) known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>,
} }
@ -54,7 +52,7 @@ pub(crate) fn create<'tcx>(
infcx: &InferCtxt<'tcx>, infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
universal_regions: Rc<UniversalRegions<'tcx>>, universal_regions: UniversalRegions<'tcx>,
constraints: &mut MirTypeckRegionConstraints<'tcx>, constraints: &mut MirTypeckRegionConstraints<'tcx>,
) -> CreateResult<'tcx> { ) -> CreateResult<'tcx> {
UniversalRegionRelationsBuilder { UniversalRegionRelationsBuilder {
@ -184,7 +182,7 @@ impl UniversalRegionRelations<'_> {
struct UniversalRegionRelationsBuilder<'a, 'tcx> { struct UniversalRegionRelationsBuilder<'a, 'tcx> {
infcx: &'a InferCtxt<'tcx>, infcx: &'a InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
universal_regions: Rc<UniversalRegions<'tcx>>, universal_regions: UniversalRegions<'tcx>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
@ -220,7 +218,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// region `'r`, all of which are provided by our caller // region `'r`, all of which are provided by our caller
let fr_static = self.universal_regions.fr_static; let fr_static = self.universal_regions.fr_static;
let fr_fn_body = self.universal_regions.fr_fn_body; let fr_fn_body = self.universal_regions.fr_fn_body;
for fr in self.universal_regions.universal_regions() { for fr in self.universal_regions.universal_regions_iter() {
debug!("build: relating free region {:?} to itself and to 'static", fr); debug!("build: relating free region {:?} to itself and to 'static", fr);
self.relate_universal_regions(fr, fr); self.relate_universal_regions(fr, fr);
self.relate_universal_regions(fr_static, fr); self.relate_universal_regions(fr_static, fr);
@ -236,7 +234,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// In the new solver, normalize the type-outlives obligation assumptions. // In the new solver, normalize the type-outlives obligation assumptions.
if self.infcx.next_trait_solver() { if self.infcx.next_trait_solver() {
match deeply_normalize( match deeply_normalize(
self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env), self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), param_env),
outlives, outlives,
) { ) {
Ok(normalized_outlives) => { Ok(normalized_outlives) => {
@ -250,8 +248,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
known_type_outlives_obligations.push(outlives); known_type_outlives_obligations.push(outlives);
} }
let known_type_outlives_obligations =
self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
let unnormalized_input_output_tys = self let unnormalized_input_output_tys = self
.universal_regions .universal_regions
@ -278,15 +274,15 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
if let Some(c) = constraints_unnorm { if let Some(c) = constraints_unnorm {
constraints.push(c) constraints.push(c)
} }
let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } =
.param_env param_env
.and(type_op::normalize::Normalize { value: ty }) .and(type_op::normalize::Normalize { value: ty })
.fully_perform(self.infcx, span) .fully_perform(self.infcx, span)
.unwrap_or_else(|guar| TypeOpOutput { .unwrap_or_else(|guar| TypeOpOutput {
output: Ty::new_error(self.infcx.tcx, guar), output: Ty::new_error(self.infcx.tcx, guar),
constraints: None, constraints: None,
error_info: None, error_info: None,
}); });
if let Some(c) = constraints_normalize { if let Some(c) = constraints_normalize {
constraints.push(c) constraints.push(c)
} }
@ -316,8 +312,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
// Add implied bounds from impl header. // Add implied bounds from impl header.
if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) { if matches!(tcx.def_kind(defining_ty_def_id), DefKind::AssocFn | DefKind::AssocConst) {
for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) { for &(ty, _) in tcx.assumed_wf_types(tcx.local_parent(defining_ty_def_id)) {
let result: Result<_, ErrorGuaranteed> = self let result: Result<_, ErrorGuaranteed> = param_env
.param_env
.and(type_op::normalize::Normalize { value: ty }) .and(type_op::normalize::Normalize { value: ty })
.fully_perform(self.infcx, span); .fully_perform(self.infcx, span);
let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else { let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else {
@ -340,7 +335,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
&self.region_bound_pairs, &self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
param_env, param_env,
known_type_outlives_obligations, &known_type_outlives_obligations,
Locations::All(span), Locations::All(span),
span, span,
ConstraintCategory::Internal, ConstraintCategory::Internal,

View File

@ -19,7 +19,7 @@ use tracing::{debug, instrument};
use super::{Locations, TypeChecker}; use super::{Locations, TypeChecker};
use crate::renumber::RegionCtxt; use crate::renumber::RegionCtxt;
use crate::universal_regions::{DefiningTy, UniversalRegions}; use crate::universal_regions::DefiningTy;
impl<'a, 'tcx> TypeChecker<'a, 'tcx> { impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
/// Check explicit closure signature annotation, /// Check explicit closure signature annotation,
@ -124,11 +124,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
); );
} }
#[instrument(skip(self, body, universal_regions), level = "debug")] #[instrument(skip(self, body), level = "debug")]
pub(super) fn equate_inputs_and_outputs( pub(super) fn equate_inputs_and_outputs(
&mut self, &mut self,
body: &Body<'tcx>, body: &Body<'tcx>,
universal_regions: &UniversalRegions<'tcx>,
normalized_inputs_and_output: &[Ty<'tcx>], normalized_inputs_and_output: &[Ty<'tcx>],
) { ) {
let (&normalized_output_ty, normalized_input_tys) = let (&normalized_output_ty, normalized_input_tys) =
@ -161,7 +160,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Some(mir_yield_ty) = body.yield_ty() { if let Some(mir_yield_ty) = body.yield_ty() {
let yield_span = body.local_decls[RETURN_PLACE].source_info.span; let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output( self.equate_normalized_input_or_output(
universal_regions.yield_ty.unwrap(), self.universal_regions.yield_ty.unwrap(),
mir_yield_ty, mir_yield_ty,
yield_span, yield_span,
); );
@ -170,7 +169,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
if let Some(mir_resume_ty) = body.resume_ty() { if let Some(mir_resume_ty) = body.resume_ty() {
let yield_span = body.local_decls[RETURN_PLACE].source_info.span; let yield_span = body.local_decls[RETURN_PLACE].source_info.span;
self.equate_normalized_input_or_output( self.equate_normalized_input_or_output(
universal_regions.resume_ty.unwrap(), self.universal_regions.resume_ty.unwrap(),
mir_resume_ty, mir_resume_ty,
yield_span, yield_span,
); );

View File

@ -32,14 +32,14 @@ pub(super) fn generate<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &DenseLocationMap, elements: &DenseLocationMap,
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
) { ) {
debug!("liveness::generate"); debug!("liveness::generate");
let free_regions = regions_that_outlive_free_regions( let free_regions = regions_that_outlive_free_regions(
typeck.infcx.num_region_vars(), typeck.infcx.num_region_vars(),
typeck.universal_regions, &typeck.universal_regions,
&typeck.constraints.outlives_constraints, &typeck.constraints.outlives_constraints,
); );
let (relevant_live_locals, boring_locals) = let (relevant_live_locals, boring_locals) =
@ -107,7 +107,7 @@ fn regions_that_outlive_free_regions<'tcx>(
let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static); let rev_region_graph = rev_constraint_graph.region_graph(constraint_set, fr_static);
// Stack for the depth-first search. Start out with all the free regions. // Stack for the depth-first search. Start out with all the free regions.
let mut stack: Vec<_> = universal_regions.universal_regions().collect(); let mut stack: Vec<_> = universal_regions.universal_regions_iter().collect();
// Set of all free regions, plus anything that outlives them. Initially // Set of all free regions, plus anything that outlives them. Initially
// just contains the free regions. // just contains the free regions.

View File

@ -38,7 +38,7 @@ pub(super) fn trace<'a, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>, typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
elements: &DenseLocationMap, elements: &DenseLocationMap,
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>, relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>, boring_locals: Vec<Local>,
@ -113,7 +113,7 @@ struct LivenessContext<'a, 'typeck, 'b, 'tcx> {
/// Results of dataflow tracking which variables (and paths) have been /// Results of dataflow tracking which variables (and paths) have been
/// initialized. /// initialized.
flow_inits: &'a mut ResultsCursor<'b, 'tcx, MaybeInitializedPlaces<'b, 'tcx>>, flow_inits: ResultsCursor<'b, 'tcx, MaybeInitializedPlaces<'b, 'tcx>>,
/// Index indicating where each variable is assigned, used, or /// Index indicating where each variable is assigned, used, or
/// dropped. /// dropped.
@ -608,7 +608,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
value.visit_with(&mut for_liveness::FreeRegionsVisitor { value.visit_with(&mut for_liveness::FreeRegionsVisitor {
tcx: typeck.tcx(), tcx: typeck.tcx(),
param_env: typeck.param_env, param_env: typeck.infcx.param_env,
op: |r| { op: |r| {
let live_region_vid = typeck.universal_regions.to_region_vid(r); let live_region_vid = typeck.universal_regions.to_region_vid(r);
@ -621,6 +621,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,); debug!("compute_drop_data(dropped_ty={:?})", dropped_ty,);
match typeck match typeck
.infcx
.param_env .param_env
.and(DropckOutlives { dropped_ty }) .and(DropckOutlives { dropped_ty })
.fully_perform(typeck.infcx, DUMMY_SP) .fully_perform(typeck.infcx, DUMMY_SP)

View File

@ -118,17 +118,15 @@ mod relate_tys;
/// - `elements` -- MIR region map /// - `elements` -- MIR region map
pub(crate) fn type_check<'a, 'tcx>( pub(crate) fn type_check<'a, 'tcx>(
infcx: &BorrowckInferCtxt<'tcx>, infcx: &BorrowckInferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
promoted: &IndexSlice<Promoted, Body<'tcx>>, promoted: &IndexSlice<Promoted, Body<'tcx>>,
universal_regions: Rc<UniversalRegions<'tcx>>, universal_regions: UniversalRegions<'tcx>,
location_table: &LocationTable, location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>, all_facts: &mut Option<AllFacts>,
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
move_data: &MoveData<'tcx>, move_data: &MoveData<'tcx>,
elements: Rc<DenseLocationMap>, elements: Rc<DenseLocationMap>,
upvars: &[&ty::CapturedPlace<'tcx>],
) -> MirTypeckResults<'tcx> { ) -> MirTypeckResults<'tcx> {
let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body); let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body);
let mut constraints = MirTypeckRegionConstraints { let mut constraints = MirTypeckRegionConstraints {
@ -148,9 +146,9 @@ pub(crate) fn type_check<'a, 'tcx>(
known_type_outlives_obligations, known_type_outlives_obligations,
} = free_region_relations::create( } = free_region_relations::create(
infcx, infcx,
param_env, infcx.param_env,
implicit_region_bound, implicit_region_bound,
Rc::clone(&universal_regions), universal_regions,
&mut constraints, &mut constraints,
); );
@ -158,29 +156,27 @@ pub(crate) fn type_check<'a, 'tcx>(
let mut checker = TypeChecker { let mut checker = TypeChecker {
infcx, infcx,
param_env,
last_span: body.span, last_span: body.span,
body, body,
user_type_annotations: &body.user_type_annotations, user_type_annotations: &body.user_type_annotations,
region_bound_pairs: &region_bound_pairs, region_bound_pairs,
known_type_outlives_obligations, known_type_outlives_obligations,
implicit_region_bound, implicit_region_bound,
reported_errors: Default::default(), reported_errors: Default::default(),
universal_regions: &universal_regions, universal_regions: &universal_region_relations.universal_regions,
location_table, location_table,
all_facts, all_facts,
borrow_set, borrow_set,
constraints: &mut constraints, constraints: &mut constraints,
upvars,
}; };
checker.check_user_type_annotations(); checker.check_user_type_annotations();
let mut verifier = TypeVerifier::new(&mut checker, promoted); let mut verifier = TypeVerifier { cx: &mut checker, promoted, last_span: body.span };
verifier.visit_body(body); verifier.visit_body(body);
checker.typeck_mir(body); checker.typeck_mir(body);
checker.equate_inputs_and_outputs(body, &universal_regions, &normalized_inputs_and_output); checker.equate_inputs_and_outputs(body, &normalized_inputs_and_output);
checker.check_signature_annotation(body); checker.check_signature_annotation(body);
liveness::generate(&mut checker, body, &elements, flow_inits, move_data); liveness::generate(&mut checker, body, &elements, flow_inits, move_data);
@ -467,13 +463,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
} }
impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
fn new(
cx: &'a mut TypeChecker<'b, 'tcx>,
promoted: &'b IndexSlice<Promoted, Body<'tcx>>,
) -> Self {
TypeVerifier { promoted, last_span: cx.body.span, cx }
}
fn body(&self) -> &Body<'tcx> { fn body(&self) -> &Body<'tcx> {
self.cx.body self.cx.body
} }
@ -837,14 +826,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
/// NLL region checking. /// NLL region checking.
struct TypeChecker<'a, 'tcx> { struct TypeChecker<'a, 'tcx> {
infcx: &'a BorrowckInferCtxt<'tcx>, infcx: &'a BorrowckInferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
last_span: Span, last_span: Span,
body: &'a Body<'tcx>, body: &'a Body<'tcx>,
/// User type annotations are shared between the main MIR and the MIR of /// User type annotations are shared between the main MIR and the MIR of
/// all of the promoted items. /// all of the promoted items.
user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>,
region_bound_pairs: &'a RegionBoundPairs<'tcx>, region_bound_pairs: RegionBoundPairs<'tcx>,
known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], known_type_outlives_obligations: Vec<ty::PolyTypeOutlivesPredicate<'tcx>>,
implicit_region_bound: ty::Region<'tcx>, implicit_region_bound: ty::Region<'tcx>,
reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, reported_errors: FxIndexSet<(Ty<'tcx>, Span)>,
universal_regions: &'a UniversalRegions<'tcx>, universal_regions: &'a UniversalRegions<'tcx>,
@ -852,7 +840,6 @@ struct TypeChecker<'a, 'tcx> {
all_facts: &'a mut Option<AllFacts>, all_facts: &'a mut Option<AllFacts>,
borrow_set: &'a BorrowSet<'tcx>, borrow_set: &'a BorrowSet<'tcx>,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
upvars: &'a [&'a ty::CapturedPlace<'tcx>],
} }
/// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions /// Holder struct for passing results from MIR typeck to the rest of the non-lexical regions
@ -1025,10 +1012,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
constraint_conversion::ConstraintConversion::new( constraint_conversion::ConstraintConversion::new(
self.infcx, self.infcx,
self.universal_regions, self.universal_regions,
self.region_bound_pairs, &self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.infcx.param_env,
self.known_type_outlives_obligations, &self.known_type_outlives_obligations,
locations, locations,
locations.span(self.body), locations.span(self.body),
category, category,
@ -1527,9 +1514,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// The signature in this call can reference region variables, // The signature in this call can reference region variables,
// so erase them before calling a query. // so erase them before calling a query.
let output_ty = self.tcx().erase_regions(sig.output()); let output_ty = self.tcx().erase_regions(sig.output());
if !output_ty if !output_ty.is_privately_uninhabited(
.is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.param_env)) self.tcx(),
{ self.infcx.typing_env(self.infcx.param_env),
) {
span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig); span_mirbug!(self, term, "call to converging function {:?} w/o dest", sig);
} }
} }
@ -1739,7 +1727,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// `Sized` bound in no way depends on precise regions, so this // `Sized` bound in no way depends on precise regions, so this
// shouldn't affect `is_sized`. // shouldn't affect `is_sized`.
let erased_ty = tcx.erase_regions(ty); let erased_ty = tcx.erase_regions(ty);
if !erased_ty.is_sized(tcx, self.param_env) { if !erased_ty.is_sized(tcx, self.infcx.param_env) {
// in current MIR construction, all non-control-flow rvalue // in current MIR construction, all non-control-flow rvalue
// expressions evaluate through `as_temp` or `into` a return // expressions evaluate through `as_temp` or `into` a return
// slot or local, so to find all unsized rvalues it is enough // slot or local, so to find all unsized rvalues it is enough
@ -2631,8 +2619,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
); );
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let def = self.body.source.def_id().expect_local();
let upvars = tcx.closure_captures(def);
let field = let field =
path_utils::is_upvar_field_projection(tcx, self.upvars, borrowed_place.as_ref(), body); path_utils::is_upvar_field_projection(tcx, upvars, borrowed_place.as_ref(), body);
let category = if let Some(field) = field { let category = if let Some(field) = field {
ConstraintCategory::ClosureUpvar(field) ConstraintCategory::ClosureUpvar(field)
} else { } else {
@ -2787,10 +2777,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
constraint_conversion::ConstraintConversion::new( constraint_conversion::ConstraintConversion::new(
self.infcx, self.infcx,
self.universal_regions, self.universal_regions,
self.region_bound_pairs, &self.region_bound_pairs,
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.infcx.param_env,
self.known_type_outlives_obligations, &self.known_type_outlives_obligations,
locations, locations,
self.body.span, // irrelevant; will be overridden. self.body.span, // irrelevant; will be overridden.
ConstraintCategory::Boring, // same as above. ConstraintCategory::Boring, // same as above.

View File

@ -522,7 +522,7 @@ impl<'b, 'tcx> PredicateEmittingRelation<InferCtxt<'tcx>> for NllTypeRelating<'_
} }
fn param_env(&self) -> ty::ParamEnv<'tcx> { fn param_env(&self) -> ty::ParamEnv<'tcx> {
self.type_checker.param_env self.type_checker.infcx.param_env
} }
fn register_predicates( fn register_predicates(

View File

@ -248,12 +248,8 @@ impl<'tcx> UniversalRegions<'tcx> {
/// MIR -- that is, all the regions that appear in the function's /// MIR -- that is, all the regions that appear in the function's
/// signature. This will also compute the relationships that are /// signature. This will also compute the relationships that are
/// known between those regions. /// known between those regions.
pub(crate) fn new( pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self {
infcx: &BorrowckInferCtxt<'tcx>, UniversalRegionsBuilder { infcx, mir_def }.build()
mir_def: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
) -> Self {
UniversalRegionsBuilder { infcx, mir_def, param_env }.build()
} }
/// Given a reference to a closure type, extracts all the values /// Given a reference to a closure type, extracts all the values
@ -312,7 +308,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// Returns an iterator over all the RegionVids corresponding to /// Returns an iterator over all the RegionVids corresponding to
/// universally quantified free regions. /// universally quantified free regions.
pub(crate) fn universal_regions(&self) -> impl Iterator<Item = RegionVid> { pub(crate) fn universal_regions_iter(&self) -> impl Iterator<Item = RegionVid> {
(FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize) (FIRST_GLOBAL_INDEX..self.num_universals).map(RegionVid::from_usize)
} }
@ -336,7 +332,7 @@ impl<'tcx> UniversalRegions<'tcx> {
} }
/// Gets an iterator over all the early-bound regions that have names. /// Gets an iterator over all the early-bound regions that have names.
pub(crate) fn named_universal_regions<'s>( pub(crate) fn named_universal_regions_iter<'s>(
&'s self, &'s self,
) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's { ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's {
self.indices.indices.iter().map(|(&r, &v)| (r, v)) self.indices.indices.iter().map(|(&r, &v)| (r, v))
@ -426,7 +422,6 @@ impl<'tcx> UniversalRegions<'tcx> {
struct UniversalRegionsBuilder<'infcx, 'tcx> { struct UniversalRegionsBuilder<'infcx, 'tcx> {
infcx: &'infcx BorrowckInferCtxt<'tcx>, infcx: &'infcx BorrowckInferCtxt<'tcx>,
mir_def: LocalDefId, mir_def: LocalDefId,
param_env: ty::ParamEnv<'tcx>,
} }
const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion; const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion;
@ -435,7 +430,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
fn build(self) -> UniversalRegions<'tcx> { fn build(self) -> UniversalRegions<'tcx> {
debug!("build(mir_def={:?})", self.mir_def); debug!("build(mir_def={:?})", self.mir_def);
let param_env = self.param_env; let param_env = self.infcx.param_env;
debug!("build: param_env={:?}", param_env); debug!("build: param_env={:?}", param_env);
assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars()); assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());