diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs index 0897d140d60..90d12ea8328 100644 --- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs @@ -60,7 +60,7 @@ impl<'tcx> UniverseInfo<'tcx> { UniverseInfo::RelateTys { expected, found } => { let err = mbcx.infcx.err_ctxt().report_mismatched_types( &cause, - mbcx.param_env, + mbcx.infcx.param_env, expected, found, TypeError::RegionsPlaceholderMismatch, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 129a30661d6..c11103af476 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -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| { 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. let old_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, generic_args); let new_ty = ty::EarlyBinder::bind(ty).instantiate(tcx, new_args); - if let Ok(old_ty) = - tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), old_ty) - && let Ok(new_ty) = tcx.try_normalize_erasing_regions( - self.infcx.typing_env(self.param_env), - new_ty, - ) - { + if let Ok(old_ty) = tcx.try_normalize_erasing_regions( + self.infcx.typing_env(self.infcx.param_env), + old_ty, + ) && let Ok(new_ty) = tcx.try_normalize_erasing_regions( + self.infcx.typing_env(self.infcx.param_env), + new_ty, + ) { old_ty == new_ty } else { 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. clauses.instantiate(tcx, new_args).predicates.iter().all(|&(mut clause)| { // Normalize before testing to see through type aliases and projections. - if let Ok(normalized) = - tcx.try_normalize_erasing_regions(self.infcx.typing_env(self.param_env), clause) - { + if let Ok(normalized) = tcx.try_normalize_erasing_regions( + self.infcx.typing_env(self.infcx.param_env), + clause, + ) { clause = normalized; } self.infcx.predicate_must_hold_modulo_regions(&Obligation::new( tcx, ObligationCause::dummy(), - self.param_env, + self.infcx.param_env, clause, )) }) @@ -904,7 +905,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let ty = moved_place.ty(self.body, self.infcx.tcx).ty; 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 { return; }; @@ -1304,7 +1305,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { 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 }; 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() } @@ -1437,7 +1438,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let ocx = ObligationCtxt::new_with_diagnostics(self.infcx); 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(); // 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 inner = inner.peel_refs() && (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( span, @@ -1989,7 +1991,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let obligation = Obligation::new( self.infcx.tcx, ObligationCause::dummy(), - self.param_env, + self.infcx.param_env, trait_ref, ); 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) && self .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() { 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| { Instance::try_resolve( tcx, - self.infcx.typing_env(self.param_env), + self.infcx.typing_env(self.infcx.param_env), deref_target, method_args, ) .transpose() }); 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.span_note(tcx.def_span(instance.def_id()), "deref defined here"); } diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index 6c63da819c7..bda96726738 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -864,7 +864,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let kind = call_kind( self.infcx.tcx, - self.infcx.typing_env(self.param_env), + self.infcx.typing_env(self.infcx.param_env), method_did, method_args, *fn_span, @@ -1160,7 +1160,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let suggest = match tcx.get_diagnostic_item(sym::IntoIterator) { Some(def_id) => type_known_to_meet_bound_modulo_regions( self.infcx, - self.param_env, + self.infcx.param_env, Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, ty), def_id, ), @@ -1224,7 +1224,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { BoundRegionConversionTime::FnCall, 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 { 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( clone_trait, ty, - self.param_env, + self.infcx.param_env, ) && !has_sugg { let msg = match &errors[..] { diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index 15cc9c20ab7..4ba6b2e94ec 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -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 }; // This is only going to be ambiguous if there are incoherent impls, because otherwise // 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> { diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs index d064bf098e4..c5ebf3c547e 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs @@ -1242,7 +1242,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { .type_implements_trait_shallow( clone_trait, ty.peel_refs(), - self.param_env, + self.infcx.param_env, ) .as_deref() { @@ -1279,7 +1279,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let obligation = traits::Obligation::new( self.infcx.tcx, traits::ObligationCause::dummy(), - self.param_env, + self.infcx.param_env, trait_ref, ); self.infcx.err_ctxt().suggest_derive( diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs index d4660d8af43..c38747f6675 100644 --- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs @@ -952,7 +952,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { if let Ok(Some(instance)) = ty::Instance::try_resolve( tcx, - self.infcx.typing_env(self.param_env), + self.infcx.typing_env(self.infcx.param_env), *fn_did, self.infcx.resolve_vars_if_possible(args), ) { @@ -1091,7 +1091,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { peeled_ty = ref_ty; 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; } @@ -1160,7 +1160,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> { let ocx = ObligationCtxt::new(&self.infcx); ocx.register_obligations(preds.iter().map(|(pred, span)| { 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 { diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 7eaf265d410..03f7b05d1e3 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -140,7 +140,6 @@ fn do_mir_borrowck<'tcx>( ) -> (BorrowCheckResult<'tcx>, Option>>) { let def = input_body.source.def_id().expect_local(); 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); 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. let mut body_owned = input_body.clone(); let mut promoted = input_promoted.to_owned(); - let free_regions = - nll::replace_regions_in_mir(&infcx, param_env, &mut body_owned, &mut promoted); + let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted); let body = &body_owned; // no further changes // FIXME(-Znext-solver): A bit dubious that we're only registering @@ -192,7 +190,7 @@ fn do_mir_borrowck<'tcx>( .iter_enumerated() .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")) .into_results_cursor(body); @@ -213,18 +211,12 @@ fn do_mir_borrowck<'tcx>( body, &promoted, &location_table, - param_env, - &mut flow_inits, + flow_inits, &move_data, &borrow_set, - tcx.closure_captures(def), 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 // write unit-tests, as well as helping with debugging. nll::dump_nll_mir(&infcx, body, ®ioncx, &opt_closure_req, &borrow_set); @@ -251,7 +243,6 @@ fn do_mir_borrowck<'tcx>( let promoted_body = &promoted[idx]; let mut promoted_mbcx = MirBorrowckCtxt { infcx: &infcx, - param_env, body: promoted_body, move_data: &move_data, 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 { infcx: &infcx, - param_env, body, move_data: &move_data, location_table: &location_table, @@ -448,12 +438,14 @@ fn get_flow_results<'a, 'tcx>( pub(crate) struct BorrowckInferCtxt<'tcx> { pub(crate) infcx: InferCtxt<'tcx>, pub(crate) reg_var_to_origin: RefCell>, + pub(crate) param_env: ParamEnv<'tcx>, } impl<'tcx> BorrowckInferCtxt<'tcx> { pub(crate) fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self { 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( @@ -532,7 +524,6 @@ impl<'tcx> Deref for BorrowckInferCtxt<'tcx> { struct MirBorrowckCtxt<'a, 'infcx, 'tcx> { infcx: &'infcx BorrowckInferCtxt<'tcx>, - param_env: ParamEnv<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index f76603d5679..be02e2f48df 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -30,7 +30,7 @@ use crate::diagnostics::RegionErrors; use crate::facts::{AllFacts, AllFactsExt, RustcFacts}; use crate::location::LocationTable; 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::{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 /// regions (e.g., region parameters) declared on the function. That set will need to be given to /// `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>( infcx: &BorrowckInferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &mut Body<'tcx>, promoted: &mut IndexSlice>, ) -> UniversalRegions<'tcx> { @@ -62,7 +61,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>( debug!(?def); // 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. renumber::renumber_mir(infcx, body, promoted); @@ -81,11 +80,9 @@ pub(crate) fn compute_regions<'a, 'tcx>( body: &Body<'tcx>, promoted: &IndexSlice>, location_table: &LocationTable, - param_env: ty::ParamEnv<'tcx>, - flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, + flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, - upvars: &[&ty::CapturedPlace<'tcx>], consumer_options: Option, ) -> NllOutput<'tcx> { 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 = (polonius_input || AllFacts::enabled(infcx.tcx)).then_some(AllFacts::default()); - let universal_regions = Rc::new(universal_regions); - let elements = Rc::new(DenseLocationMap::new(body)); // Run the MIR type-checker. let MirTypeckResults { constraints, universal_region_relations, opaque_type_values } = type_check::type_check( infcx, - param_env, body, promoted, - Rc::clone(&universal_regions), + universal_regions, location_table, borrow_set, &mut all_facts, flow_inits, move_data, Rc::clone(&elements), - upvars, ); // Create the region inference context, taking ownership of the // region inference data that was contained in `infcx`, and the // base constraints generated by the type-check. 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. polonius::emit_facts( @@ -140,31 +123,14 @@ pub(crate) fn compute_regions<'a, 'tcx>( body, borrow_set, move_data, - &universal_regions, &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( infcx, var_origins, - universal_regions, - placeholder_indices, + constraints, universal_region_relations, - outlives_constraints, - member_constraints, - universe_causes, - type_tests, - liveness_constraints, elements, ); diff --git a/compiler/rustc_borrowck/src/polonius/mod.rs b/compiler/rustc_borrowck/src/polonius/mod.rs index 6862eb13427..9fccc00bdaf 100644 --- a/compiler/rustc_borrowck/src/polonius/mod.rs +++ b/compiler/rustc_borrowck/src/polonius/mod.rs @@ -12,7 +12,6 @@ use crate::borrow_set::BorrowSet; use crate::facts::{AllFacts, PoloniusRegionVid}; use crate::location::LocationTable; use crate::type_check::free_region_relations::UniversalRegionRelations; -use crate::universal_regions::UniversalRegions; mod loan_invalidations; mod loan_kills; @@ -32,7 +31,6 @@ pub(crate) fn emit_facts<'tcx>( body: &Body<'tcx>, borrow_set: &BorrowSet<'tcx>, move_data: &MoveData<'_>, - universal_regions: &UniversalRegions<'_>, universal_region_relations: &UniversalRegionRelations<'_>, ) { 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"); emit_move_facts(all_facts, move_data, location_table, body); - emit_universal_region_facts( - all_facts, - borrow_set, - universal_regions, - universal_region_relations, - ); + emit_universal_region_facts(all_facts, borrow_set, universal_region_relations); 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); } @@ -129,7 +122,6 @@ fn emit_move_facts( fn emit_universal_region_facts( all_facts: &mut AllFacts, borrow_set: &BorrowSet<'_>, - universal_regions: &UniversalRegions<'_>, universal_region_relations: &UniversalRegionRelations<'_>, ) { // 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 // 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 .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(); debug!( "emit_universal_region_facts: polonius placeholders, num_universals={}, borrow_count={}", @@ -148,7 +141,7 @@ fn emit_universal_region_facts( 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 placeholder_loan_idx = borrow_count + universal_region_idx; all_facts.placeholder.push((universal_region.into(), placeholder_loan_idx.into())); diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs index 6b8dd1a49e7..ef3d6309c19 100644 --- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs +++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs @@ -23,7 +23,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { for region in self.regions() { 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); writeln!( out, diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 7e317ea6554..0ddb4e110e3 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -31,11 +31,9 @@ use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo}; use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex}; use crate::nll::PoloniusOutput; use crate::region_infer::reverse_sccs::ReverseSccGraph; -use crate::region_infer::values::{ - LivenessValues, PlaceholderIndices, RegionElement, RegionValues, ToElementIndex, -}; -use crate::type_check::Locations; +use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues, ToElementIndex}; use crate::type_check::free_region_relations::UniversalRegionRelations; +use crate::type_check::{Locations, MirTypeckRegionConstraints}; use crate::universal_regions::UniversalRegions; mod dump_mir; @@ -191,10 +189,6 @@ pub struct RegionInferenceContext<'tcx> { /// Type constraints that we check after solving. type_tests: Vec>, - /// Information about the universally quantified regions in scope - /// on this function. - universal_regions: Rc>, - /// Information about how the universally quantified regions in /// scope on this function relate to one another. universal_region_relations: Frozen>, @@ -399,21 +393,36 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn new( infcx: &BorrowckInferCtxt<'tcx>, var_infos: VarInfos, - universal_regions: Rc>, - placeholder_indices: Rc, + constraints: MirTypeckRegionConstraints<'tcx>, universal_region_relations: Frozen>, - mut outlives_constraints: OutlivesConstraintSet<'tcx>, - member_constraints_in: MemberConstraintSet<'tcx, RegionVid>, - universe_causes: FxIndexMap>, - type_tests: Vec>, - liveness_constraints: LivenessValues, elements: Rc, ) -> 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!("placeholder_indices: {:#?}", placeholder_indices); 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. let definitions: IndexVec<_, _> = var_infos .iter() @@ -438,7 +447,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } 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 { var_infos, @@ -453,7 +462,6 @@ impl<'tcx> RegionInferenceContext<'tcx> { universe_causes, scc_values, type_tests, - universal_regions, universal_region_relations, }; @@ -518,7 +526,9 @@ impl<'tcx> RegionInferenceContext<'tcx> { fn init_free_and_bound_regions(&mut self) { // Update the names (if any) // 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!( "init_free_and_bound_regions: region {:?} has external name {:?}", variable, external_name @@ -562,7 +572,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// /// (Panics if `r` is not a registered universal region.) 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. @@ -574,7 +584,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`. 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`. @@ -686,7 +696,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { if outlives_requirements.is_empty() { (None, errors_buffer) } 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 }), errors_buffer, @@ -989,7 +999,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // always be in the root universe. if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() { 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 { subject, outlived_free_region: static_r, @@ -1032,8 +1042,8 @@ impl<'tcx> RegionInferenceContext<'tcx> { // avoid potential non-determinism we approximate this by requiring // T: '1 and T: '2. for upper_bound in non_local_ub { - 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_universal_region(upper_bound)); + debug_assert!(!self.universal_regions().is_local_free_region(upper_bound)); let requirement = ClosureOutlivesRequirement { subject, @@ -1101,7 +1111,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // To do so, we simply check every candidate `u_r` for equality. self.scc_values .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)) .map(|u_r| ty::Region::new_var(tcx, u_r)) // 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 // 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 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) { let new_lub = self.universal_region_relations.postdom_upper_bound(lub, ur); debug!(?ur, ?lub, ?new_lub); @@ -1288,12 +1298,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!( "sup_region's value = {:?} universal={:?}", self.region_value_str(sup_region), - self.universal_regions.is_universal_region(sup_region), + self.universal_regions().is_universal_region(sup_region), ); debug!( "sub_region's value = {:?} universal={:?}", 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); @@ -1308,7 +1318,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { 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 @@ -1332,7 +1342,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // Now we have to compare all the points in the sub region and make // 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. debug!("super is universal and hence contains all points"); return true; @@ -1736,7 +1746,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!("provides_universal_region(r={:?}, fr1={:?}, fr2={:?})", r, fr1, fr2); let result = { 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); @@ -1837,7 +1847,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { // A constraint like `'r: 'x` can come from our constraint // graph. - let fr_static = self.universal_regions.fr_static; + let fr_static = self.universal_regions().fr_static; let outgoing_edges_from_graph = 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> { - self.universal_regions.as_ref() + &self.universal_region_relations.universal_regions } /// 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. 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 diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index d676ce59cfe..993d5d86333 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -74,7 +74,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { debug!(?opaque_type_key, ?concrete_type); 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 = 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. // See [rustc-dev-guide chapter] § "Semantic lifetime equality". NllRegionVariableOrigin::FreeRegion => self - .universal_regions .universal_regions() + .universal_regions_iter() .filter(|&ur| { // See [rustc-dev-guide chapter] § "Closure restrictions". !matches!( - self.universal_regions.region_classification(ur), + self.universal_regions().region_classification(ur), Some(RegionClassification::External) ) }) diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs index cfd5a92787e..d0cfe572d08 100644 --- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs +++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs @@ -45,8 +45,8 @@ impl RegionInferenceContext<'_> { let graph = self.constraint_sccs.reverse(); let mut paired_scc_regions = self - .universal_regions .universal_regions() + .universal_regions_iter() .map(|region| (self.constraint_sccs.scc(region), region)) .collect::>(); paired_scc_regions.sort(); diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 519edfafda5..a16bce63839 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -258,10 +258,9 @@ impl PlaceholderIndices { /// Here, the variable `'0` would contain the free region `'a`, /// because (since it is returned) it must live for at least `'a`. But /// it would also contain various points from within the function. -#[derive(Clone)] pub(crate) struct RegionValues { elements: Rc, - placeholder_indices: Rc, + placeholder_indices: PlaceholderIndices, points: SparseIntervalMatrix, free_regions: SparseBitMatrix, @@ -277,7 +276,7 @@ impl RegionValues { pub(crate) fn new( elements: Rc, num_universal_regions: usize, - placeholder_indices: Rc, + placeholder_indices: PlaceholderIndices, ) -> Self { let num_points = elements.num_points(); let num_placeholders = placeholder_indices.len(); diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index aee13ca8cd7..68b843d4d0d 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -132,7 +132,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { locations: Locations, category: ConstraintCategory<'tcx>, ) { - let param_env = self.param_env; + let param_env = self.infcx.param_env; let predicate = predicate.upcast(self.tcx()); let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( locations, @@ -158,7 +158,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { where 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( location.to_locations(), category, @@ -176,7 +176,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let tcx = self.tcx(); if self.infcx.next_trait_solver() { let body = self.body; - let param_env = self.param_env; + let param_env = self.infcx.param_env; self.fully_perform_op( location.to_locations(), ConstraintCategory::Boring, @@ -223,7 +223,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { let _: Result<_, ErrorGuaranteed> = self.fully_perform_op( Locations::All(span), 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 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( Locations::All(span), ConstraintCategory::Boring, diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs index 6c86968389a..67915371b1f 100644 --- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs +++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs @@ -37,7 +37,7 @@ pub(crate) struct ConstraintConversion<'a, 'tcx> { region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, param_env: ty::ParamEnv<'tcx>, - known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], + known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>], locations: Locations, span: Span, category: ConstraintCategory<'tcx>, @@ -52,7 +52,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> { region_bound_pairs: &'a RegionBoundPairs<'tcx>, implicit_region_bound: ty::Region<'tcx>, param_env: ty::ParamEnv<'tcx>, - known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], + known_type_outlives_obligations: &'a [ty::PolyTypeOutlivesPredicate<'tcx>], locations: Locations, span: Span, category: ConstraintCategory<'tcx>, diff --git a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs index 8e1faf025e2..ea965eb6545 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use rustc_data_structures::frozen::Frozen; use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder}; use rustc_hir::def::DefKind; @@ -23,7 +21,7 @@ use crate::universal_regions::UniversalRegions; #[derive(Debug)] pub(crate) struct UniversalRegionRelations<'tcx> { - universal_regions: Rc>, + pub(crate) universal_regions: UniversalRegions<'tcx>, /// Stores the outlives relations that are known to hold from the /// implied bounds, in-scope where-clauses, and that sort of @@ -46,7 +44,7 @@ type NormalizedInputsAndOutput<'tcx> = Vec>; pub(crate) struct CreateResult<'tcx> { pub(crate) universal_region_relations: Frozen>, pub(crate) region_bound_pairs: RegionBoundPairs<'tcx>, - pub(crate) known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], + pub(crate) known_type_outlives_obligations: Vec>, pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, } @@ -54,7 +52,7 @@ pub(crate) fn create<'tcx>( infcx: &InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, implicit_region_bound: ty::Region<'tcx>, - universal_regions: Rc>, + universal_regions: UniversalRegions<'tcx>, constraints: &mut MirTypeckRegionConstraints<'tcx>, ) -> CreateResult<'tcx> { UniversalRegionRelationsBuilder { @@ -184,7 +182,7 @@ impl UniversalRegionRelations<'_> { struct UniversalRegionRelationsBuilder<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - universal_regions: Rc>, + universal_regions: UniversalRegions<'tcx>, implicit_region_bound: ty::Region<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>, @@ -220,7 +218,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // region `'r`, all of which are provided by our caller let fr_static = self.universal_regions.fr_static; 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); self.relate_universal_regions(fr, 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. if self.infcx.next_trait_solver() { 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, ) { Ok(normalized_outlives) => { @@ -250,8 +248,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { 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 .universal_regions @@ -278,15 +274,15 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { if let Some(c) = constraints_unnorm { constraints.push(c) } - let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = self - .param_env - .and(type_op::normalize::Normalize { value: ty }) - .fully_perform(self.infcx, span) - .unwrap_or_else(|guar| TypeOpOutput { - output: Ty::new_error(self.infcx.tcx, guar), - constraints: None, - error_info: None, - }); + let TypeOpOutput { output: norm_ty, constraints: constraints_normalize, .. } = + param_env + .and(type_op::normalize::Normalize { value: ty }) + .fully_perform(self.infcx, span) + .unwrap_or_else(|guar| TypeOpOutput { + output: Ty::new_error(self.infcx.tcx, guar), + constraints: None, + error_info: None, + }); if let Some(c) = constraints_normalize { constraints.push(c) } @@ -316,8 +312,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { // Add implied bounds from impl header. 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)) { - let result: Result<_, ErrorGuaranteed> = self - .param_env + let result: Result<_, ErrorGuaranteed> = param_env .and(type_op::normalize::Normalize { value: ty }) .fully_perform(self.infcx, span); let Ok(TypeOpOutput { output: norm_ty, constraints: c, .. }) = result else { @@ -340,7 +335,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { &self.region_bound_pairs, self.implicit_region_bound, param_env, - known_type_outlives_obligations, + &known_type_outlives_obligations, Locations::All(span), span, ConstraintCategory::Internal, diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs index 7effd5c5a68..bbe2b55d8c4 100644 --- a/compiler/rustc_borrowck/src/type_check/input_output.rs +++ b/compiler/rustc_borrowck/src/type_check/input_output.rs @@ -19,7 +19,7 @@ use tracing::{debug, instrument}; use super::{Locations, TypeChecker}; use crate::renumber::RegionCtxt; -use crate::universal_regions::{DefiningTy, UniversalRegions}; +use crate::universal_regions::DefiningTy; impl<'a, 'tcx> TypeChecker<'a, 'tcx> { /// 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( &mut self, body: &Body<'tcx>, - universal_regions: &UniversalRegions<'tcx>, normalized_inputs_and_output: &[Ty<'tcx>], ) { 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() { let yield_span = body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output( - universal_regions.yield_ty.unwrap(), + self.universal_regions.yield_ty.unwrap(), mir_yield_ty, yield_span, ); @@ -170,7 +169,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { if let Some(mir_resume_ty) = body.resume_ty() { let yield_span = body.local_decls[RETURN_PLACE].source_info.span; self.equate_normalized_input_or_output( - universal_regions.resume_ty.unwrap(), + self.universal_regions.resume_ty.unwrap(), mir_resume_ty, yield_span, ); diff --git a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs index 84fb36dd32a..20d19a53752 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/mod.rs @@ -32,14 +32,14 @@ pub(super) fn generate<'a, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &DenseLocationMap, - flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, + flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, ) { debug!("liveness::generate"); let free_regions = regions_that_outlive_free_regions( typeck.infcx.num_region_vars(), - typeck.universal_regions, + &typeck.universal_regions, &typeck.constraints.outlives_constraints, ); 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); // 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 // just contains the free regions. diff --git a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs index 72f6a605279..3ec36c16cbf 100644 --- a/compiler/rustc_borrowck/src/type_check/liveness/trace.rs +++ b/compiler/rustc_borrowck/src/type_check/liveness/trace.rs @@ -38,7 +38,7 @@ pub(super) fn trace<'a, 'tcx>( typeck: &mut TypeChecker<'_, 'tcx>, body: &Body<'tcx>, elements: &DenseLocationMap, - flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, + flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, relevant_live_locals: Vec, boring_locals: Vec, @@ -113,7 +113,7 @@ struct LivenessContext<'a, 'typeck, 'b, 'tcx> { /// Results of dataflow tracking which variables (and paths) have been /// 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 /// dropped. @@ -608,7 +608,7 @@ impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> { value.visit_with(&mut for_liveness::FreeRegionsVisitor { tcx: typeck.tcx(), - param_env: typeck.param_env, + param_env: typeck.infcx.param_env, op: |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,); match typeck + .infcx .param_env .and(DropckOutlives { dropped_ty }) .fully_perform(typeck.infcx, DUMMY_SP) diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index ac0219684d8..58a23b9e558 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -118,17 +118,15 @@ mod relate_tys; /// - `elements` -- MIR region map pub(crate) fn type_check<'a, 'tcx>( infcx: &BorrowckInferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, body: &Body<'tcx>, promoted: &IndexSlice>, - universal_regions: Rc>, + universal_regions: UniversalRegions<'tcx>, location_table: &LocationTable, borrow_set: &BorrowSet<'tcx>, all_facts: &mut Option, - flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, + flow_inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>, move_data: &MoveData<'tcx>, elements: Rc, - upvars: &[&ty::CapturedPlace<'tcx>], ) -> MirTypeckResults<'tcx> { let implicit_region_bound = ty::Region::new_var(infcx.tcx, universal_regions.fr_fn_body); let mut constraints = MirTypeckRegionConstraints { @@ -148,9 +146,9 @@ pub(crate) fn type_check<'a, 'tcx>( known_type_outlives_obligations, } = free_region_relations::create( infcx, - param_env, + infcx.param_env, implicit_region_bound, - Rc::clone(&universal_regions), + universal_regions, &mut constraints, ); @@ -158,29 +156,27 @@ pub(crate) fn type_check<'a, 'tcx>( let mut checker = TypeChecker { infcx, - param_env, last_span: body.span, body, user_type_annotations: &body.user_type_annotations, - region_bound_pairs: ®ion_bound_pairs, + region_bound_pairs, known_type_outlives_obligations, implicit_region_bound, reported_errors: Default::default(), - universal_regions: &universal_regions, + universal_regions: &universal_region_relations.universal_regions, location_table, all_facts, borrow_set, constraints: &mut constraints, - upvars, }; 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); 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); 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> { - fn new( - cx: &'a mut TypeChecker<'b, 'tcx>, - promoted: &'b IndexSlice>, - ) -> Self { - TypeVerifier { promoted, last_span: cx.body.span, cx } - } - fn body(&self) -> &Body<'tcx> { self.cx.body } @@ -837,14 +826,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> { /// NLL region checking. struct TypeChecker<'a, 'tcx> { infcx: &'a BorrowckInferCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, last_span: Span, body: &'a Body<'tcx>, /// User type annotations are shared between the main MIR and the MIR of /// all of the promoted items. user_type_annotations: &'a CanonicalUserTypeAnnotations<'tcx>, - region_bound_pairs: &'a RegionBoundPairs<'tcx>, - known_type_outlives_obligations: &'tcx [ty::PolyTypeOutlivesPredicate<'tcx>], + region_bound_pairs: RegionBoundPairs<'tcx>, + known_type_outlives_obligations: Vec>, implicit_region_bound: ty::Region<'tcx>, reported_errors: FxIndexSet<(Ty<'tcx>, Span)>, universal_regions: &'a UniversalRegions<'tcx>, @@ -852,7 +840,6 @@ struct TypeChecker<'a, 'tcx> { all_facts: &'a mut Option, borrow_set: &'a BorrowSet<'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 @@ -1025,10 +1012,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, - self.region_bound_pairs, + &self.region_bound_pairs, self.implicit_region_bound, - self.param_env, - self.known_type_outlives_obligations, + self.infcx.param_env, + &self.known_type_outlives_obligations, locations, locations.span(self.body), category, @@ -1527,9 +1514,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { // The signature in this call can reference region variables, // so erase them before calling a query. let output_ty = self.tcx().erase_regions(sig.output()); - if !output_ty - .is_privately_uninhabited(self.tcx(), self.infcx.typing_env(self.param_env)) - { + if !output_ty.is_privately_uninhabited( + self.tcx(), + self.infcx.typing_env(self.infcx.param_env), + ) { 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 // shouldn't affect `is_sized`. 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 // expressions evaluate through `as_temp` or `into` a return // 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 def = self.body.source.def_id().expect_local(); + let upvars = tcx.closure_captures(def); 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 { ConstraintCategory::ClosureUpvar(field) } else { @@ -2787,10 +2777,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { constraint_conversion::ConstraintConversion::new( self.infcx, self.universal_regions, - self.region_bound_pairs, + &self.region_bound_pairs, self.implicit_region_bound, - self.param_env, - self.known_type_outlives_obligations, + self.infcx.param_env, + &self.known_type_outlives_obligations, locations, self.body.span, // irrelevant; will be overridden. ConstraintCategory::Boring, // same as above. diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs index e2f3e065bc0..752b2bf1a24 100644 --- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs +++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs @@ -522,7 +522,7 @@ impl<'b, 'tcx> PredicateEmittingRelation> for NllTypeRelating<'_ } fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.type_checker.param_env + self.type_checker.infcx.param_env } fn register_predicates( diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index b63144f560f..f1c23aa26a9 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -248,12 +248,8 @@ impl<'tcx> UniversalRegions<'tcx> { /// MIR -- that is, all the regions that appear in the function's /// signature. This will also compute the relationships that are /// known between those regions. - pub(crate) fn new( - infcx: &BorrowckInferCtxt<'tcx>, - mir_def: LocalDefId, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { - UniversalRegionsBuilder { infcx, mir_def, param_env }.build() + pub(crate) fn new(infcx: &BorrowckInferCtxt<'tcx>, mir_def: LocalDefId) -> Self { + UniversalRegionsBuilder { infcx, mir_def }.build() } /// 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 /// universally quantified free regions. - pub(crate) fn universal_regions(&self) -> impl Iterator { + pub(crate) fn universal_regions_iter(&self) -> impl Iterator { (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. - pub(crate) fn named_universal_regions<'s>( + pub(crate) fn named_universal_regions_iter<'s>( &'s self, ) -> impl Iterator, ty::RegionVid)> + 's { self.indices.indices.iter().map(|(&r, &v)| (r, v)) @@ -426,7 +422,6 @@ impl<'tcx> UniversalRegions<'tcx> { struct UniversalRegionsBuilder<'infcx, 'tcx> { infcx: &'infcx BorrowckInferCtxt<'tcx>, mir_def: LocalDefId, - param_env: ty::ParamEnv<'tcx>, } const FR: NllRegionVariableOrigin = NllRegionVariableOrigin::FreeRegion; @@ -435,7 +430,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { fn build(self) -> UniversalRegions<'tcx> { 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); assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());