diff --git a/compiler/rustc_borrowck/src/handle_placeholders.rs b/compiler/rustc_borrowck/src/handle_placeholders.rs index 60be521c29af0..4043e045eac05 100644 --- a/compiler/rustc_borrowck/src/handle_placeholders.rs +++ b/compiler/rustc_borrowck/src/handle_placeholders.rs @@ -8,7 +8,7 @@ use rustc_data_structures::graph::scc::Sccs; use rustc_index::IndexVec; use rustc_infer::infer::RegionVariableOrigin; use rustc_middle::mir::ConstraintCategory; -use rustc_middle::ty::{RegionVid, UniverseIndex}; +use rustc_middle::ty::{self, RegionVid, UniverseIndex}; use tracing::{debug, trace}; use crate::constraints::{ConstraintSccIndex, OutlivesConstraintSet}; @@ -17,8 +17,8 @@ use crate::diagnostics::UniverseInfo; use crate::region_infer::values::{LivenessValues, PlaceholderIndices}; use crate::region_infer::{ConstraintSccs, RegionDefinition, Representative, TypeTest}; use crate::ty::VarianceDiagInfo; +use crate::type_check::Locations; use crate::type_check::free_region_relations::UniversalRegionRelations; -use crate::type_check::{Locations, MirTypeckRegionConstraints}; use crate::universal_regions::UniversalRegions; use crate::{BorrowckInferCtxt, NllRegionVariableOrigin}; @@ -263,22 +263,17 @@ pub(super) fn region_definitions<'tcx>( /// /// Every constraint added by this method is an internal `IllegalUniverse` constraint. pub(crate) fn compute_sccs_applying_placeholder_outlives_constraints<'tcx>( - constraints: MirTypeckRegionConstraints<'tcx>, - universal_region_relations: &Frozen>, + placeholder_indices: PlaceholderIndices<'tcx>, + liveness_constraints: LivenessValues, + mut outlives_constraints: OutlivesConstraintSet<'tcx>, + universe_causes: FxIndexMap>, + type_tests: Vec>, + universal_region_relations: &UniversalRegionRelations<'tcx>, infcx: &BorrowckInferCtxt<'tcx>, ) -> LoweredConstraints<'tcx> { let universal_regions = &universal_region_relations.universal_regions; let (definitions, has_placeholders) = region_definitions(infcx, universal_regions); - let MirTypeckRegionConstraints { - placeholder_indices, - placeholder_index_to_region: _, - liveness_constraints, - mut outlives_constraints, - universe_causes, - type_tests, - } = constraints; - let fr_static = universal_regions.fr_static; let compute_sccs = |constraints: &OutlivesConstraintSet<'tcx>, diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 91defbad0a0e0..3977688e78506 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -293,7 +293,7 @@ struct CollectRegionConstraintsResult<'tcx> { borrow_set: BorrowSet<'tcx>, location_table: PoloniusLocationTable, location_map: Rc, - universal_region_relations: Frozen>, + universal_region_relations: Rc>, region_bound_pairs: Frozen>, known_type_outlives_obligations: Frozen>>, constraints: MirTypeckRegionConstraints<'tcx>, diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 5537d90e297aa..407c56b2440e3 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -6,7 +6,6 @@ use std::rc::Rc; use std::str::FromStr; use polonius_engine::{Algorithm, AllFacts, Output}; -use rustc_data_structures::frozen::Frozen; use rustc_index::IndexSlice; use rustc_middle::mir::pretty::PrettyPrintMirOptions; use rustc_middle::mir::{Body, MirDumper, PassWhere, Promoted}; @@ -86,25 +85,39 @@ pub(crate) fn compute_closure_requirements_modulo_opaques<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, body: &Body<'tcx>, location_map: Rc, - universal_region_relations: &Frozen>, - constraints: &MirTypeckRegionConstraints<'tcx>, -) -> Option> { - // FIXME(#146079): we shouldn't have to clone all this stuff here. - // Computing the region graph should take at least some of it by reference/`Rc`. + universal_region_relations: Rc>, + constraints: MirTypeckRegionConstraints<'tcx>, +) -> (MirTypeckRegionConstraints<'tcx>, Option>) { + let outlives_constraints = constraints.outlives_constraints.clone(); + let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( - constraints.clone(), + constraints.placeholder_indices, + constraints.liveness_constraints, + outlives_constraints, + constraints.universe_causes, + constraints.type_tests, &universal_region_relations, infcx, ); let mut regioncx = RegionInferenceContext::new( &infcx, lowered_constraints, - universal_region_relations.clone(), + universal_region_relations, location_map, ); let (closure_region_requirements, _nll_errors) = regioncx.solve(infcx, body, None); - closure_region_requirements + ( + MirTypeckRegionConstraints { + placeholder_indices: regioncx.scc_values.placeholder_indices, + placeholder_index_to_region: constraints.placeholder_index_to_region, + liveness_constraints: regioncx.liveness_constraints, + outlives_constraints: constraints.outlives_constraints, + universe_causes: regioncx.universe_causes, + type_tests: regioncx.type_tests, + }, + closure_region_requirements, + ) } /// Computes the (non-lexical) regions from the input MIR. @@ -118,7 +131,7 @@ pub(crate) fn compute_regions<'tcx>( move_data: &MoveData<'tcx>, borrow_set: &BorrowSet<'tcx>, location_map: Rc, - universal_region_relations: Frozen>, + universal_region_relations: Rc>, constraints: MirTypeckRegionConstraints<'tcx>, mut polonius_facts: Option>, polonius_context: Option, @@ -127,7 +140,11 @@ pub(crate) fn compute_regions<'tcx>( || infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled(); let lowered_constraints = compute_sccs_applying_placeholder_outlives_constraints( - constraints, + constraints.placeholder_indices, + constraints.liveness_constraints, + constraints.outlives_constraints, + constraints.universe_causes, + constraints.type_tests, &universal_region_relations, infcx, ); diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 6ed70b39c5b7f..529255e7fc683 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -87,7 +87,7 @@ pub struct RegionInferenceContext<'tcx> { /// regions, these start out empty and steadily grow, though for /// each universally quantified region R they start out containing /// the entire CFG and `end(R)`. - liveness_constraints: LivenessValues, + pub(crate) liveness_constraints: LivenessValues, /// The outlives constraints computed by the type-check. constraints: Frozen>, @@ -105,19 +105,19 @@ pub struct RegionInferenceContext<'tcx> { scc_annotations: IndexVec, /// Map universe indexes to information on why we created it. - universe_causes: FxIndexMap>, + pub(crate) universe_causes: FxIndexMap>, /// The final inferred values of the region variables; we compute /// one value per SCC. To get the value for any given *region*, /// you first find which scc it is a part of. - scc_values: RegionValues<'tcx, ConstraintSccIndex>, + pub(crate) scc_values: RegionValues<'tcx, ConstraintSccIndex>, /// Type constraints that we check after solving. - type_tests: Vec>, + pub(crate) type_tests: Vec>, /// Information about how the universally quantified regions in /// scope on this function relate to one another. - universal_region_relations: Frozen>, + universal_region_relations: Rc>, } #[derive(Debug)] @@ -292,7 +292,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { pub(crate) fn new( infcx: &BorrowckInferCtxt<'tcx>, lowered_constraints: LoweredConstraints<'tcx>, - universal_region_relations: Frozen>, + universal_region_relations: Rc>, location_map: Rc, ) -> Self { let universal_regions = &universal_region_relations.universal_regions; diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs index 0c4a82f3d2f36..55d45ddbeeee7 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/mod.rs @@ -1,7 +1,6 @@ use std::iter; use std::rc::Rc; -use rustc_data_structures::frozen::Frozen; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_infer::infer::outlives::env::RegionBoundPairs; @@ -65,7 +64,7 @@ pub(crate) enum DeferredOpaqueTypeError<'tcx> { /// encounter inference variables, e.g. when checking user types. pub(crate) fn clone_and_resolve_opaque_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, - universal_region_relations: &Frozen>, + universal_region_relations: &UniversalRegionRelations<'tcx>, constraints: &mut MirTypeckRegionConstraints<'tcx>, ) -> (OpaqueTypeStorageEntries, Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>) { let opaque_types = infcx.clone_opaque_types(); @@ -177,7 +176,7 @@ struct DefiningUse<'tcx> { /// recheck all uses of the opaques regardless. pub(crate) fn compute_definition_site_hidden_types<'tcx>( infcx: &BorrowckInferCtxt<'tcx>, - universal_region_relations: &Frozen>, + universal_region_relations: &UniversalRegionRelations<'tcx>, constraints: &MirTypeckRegionConstraints<'tcx>, location_map: Rc, hidden_types: &mut FxIndexMap>, diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs index ada8908e220ac..320bfa1f83fcc 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs @@ -37,7 +37,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { /// when applying member constraints. pub(super) fn new( infcx: &'a BorrowckInferCtxt<'tcx>, - universal_region_relations: &'a Frozen>, + universal_region_relations: &'a UniversalRegionRelations<'tcx>, location_map: Rc, constraints: &MirTypeckRegionConstraints<'tcx>, ) -> RegionCtxt<'a, 'tcx> { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 0063af25d781a..681cfbd1c5fc5 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -37,7 +37,6 @@ pub(crate) enum RegionElement<'tcx> { /// Records the CFG locations where each region is live. When we initially compute liveness, we use /// an interval matrix storing liveness ranges for each region-vid. -#[derive(Clone)] // FIXME(#146079) pub(crate) struct LivenessValues { /// The map from locations to points. location_map: Rc, @@ -195,7 +194,6 @@ impl LivenessValues { /// rustc to the internal `PlaceholderIndex` values that are used in /// NLL. #[derive(Debug, Default)] -#[derive(Clone)] // FIXME(#146079) pub(crate) struct PlaceholderIndices<'tcx> { indices: FxIndexSet>, } @@ -246,7 +244,7 @@ impl<'tcx> PlaceholderIndices<'tcx> { /// it would also contain various points from within the function. pub(crate) struct RegionValues<'tcx, N: Idx> { location_map: Rc, - placeholder_indices: PlaceholderIndices<'tcx>, + pub(crate) placeholder_indices: PlaceholderIndices<'tcx>, points: SparseIntervalMatrix, free_regions: SparseBitMatrix, diff --git a/compiler/rustc_borrowck/src/root_cx.rs b/compiler/rustc_borrowck/src/root_cx.rs index 4d42055df1687..d2b7914eb07c0 100644 --- a/compiler/rustc_borrowck/src/root_cx.rs +++ b/compiler/rustc_borrowck/src/root_cx.rs @@ -193,7 +193,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { // and write its result into `propagated_borrowck_results`. if depends_on_opaques { if def_id != self.root_def_id { - let req = Self::compute_closure_requirements_modulo_opaques(&input); + let (constraints, req) = compute_closure_requirements_modulo_opaques( + &input.infcx, + &input.body_owned, + Rc::clone(&input.location_map), + Rc::clone(&input.universal_region_relations), + input.constraints, + ); + input.constraints = constraints; closure_requirements_modulo_opaques.insert(def_id, req); } self.collect_region_constraints_results.insert(def_id, input); @@ -205,18 +212,6 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> { } } - fn compute_closure_requirements_modulo_opaques( - input: &CollectRegionConstraintsResult<'tcx>, - ) -> Option> { - compute_closure_requirements_modulo_opaques( - &input.infcx, - &input.body_owned, - Rc::clone(&input.location_map), - &input.universal_region_relations, - &input.constraints, - ) - } - fn apply_closure_requirements( input: &mut CollectRegionConstraintsResult<'tcx>, closure_requirements: &Option>, 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 279625cb87c9c..48871e93236f5 100644 --- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs +++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs @@ -1,3 +1,5 @@ +use std::rc::Rc; + use rustc_data_structures::frozen::Frozen; use rustc_data_structures::transitive_relation::{TransitiveRelation, TransitiveRelationBuilder}; use rustc_hir::def::DefKind; @@ -19,7 +21,6 @@ use crate::type_check::{Locations, MirTypeckRegionConstraints, constraint_conver use crate::universal_regions::UniversalRegions; #[derive(Debug)] -#[derive(Clone)] // FIXME(#146079) pub(crate) struct UniversalRegionRelations<'tcx> { pub(crate) universal_regions: UniversalRegions<'tcx>, @@ -42,7 +43,7 @@ pub(crate) struct UniversalRegionRelations<'tcx> { type NormalizedInputsAndOutput<'tcx> = Vec>; pub(crate) struct CreateResult<'tcx> { - pub(crate) universal_region_relations: Frozen>, + pub(crate) universal_region_relations: Rc>, pub(crate) region_bound_pairs: Frozen>, pub(crate) known_type_outlives_obligations: Frozen>>, pub(crate) normalized_inputs_and_output: NormalizedInputsAndOutput<'tcx>, @@ -310,7 +311,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> { } CreateResult { - universal_region_relations: Frozen::freeze(UniversalRegionRelations { + universal_region_relations: Rc::new(UniversalRegionRelations { universal_regions: self.universal_regions, outlives: self.outlives.freeze(), inverse_outlives: self.inverse_outlives.freeze(), diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 097416b4f2804..224f06f086738 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -242,7 +242,7 @@ struct TypeChecker<'a, 'tcx> { /// inference computation. pub(crate) struct MirTypeckResults<'tcx> { pub(crate) constraints: MirTypeckRegionConstraints<'tcx>, - pub(crate) universal_region_relations: Frozen>, + pub(crate) universal_region_relations: Rc>, pub(crate) region_bound_pairs: Frozen>, pub(crate) known_type_outlives_obligations: Frozen>>, pub(crate) deferred_closure_requirements: DeferredClosureRequirements<'tcx>, @@ -251,7 +251,6 @@ pub(crate) struct MirTypeckResults<'tcx> { /// A collection of region constraints that must be satisfied for the /// program to be considered well-typed. -#[derive(Clone)] // FIXME(#146079) pub(crate) struct MirTypeckRegionConstraints<'tcx> { /// Maps from a `ty::Placeholder` to the corresponding /// `PlaceholderIndex` bit that we will use for it. diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index fda4719fc3f5e..e0e5ea93742e1 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -39,7 +39,6 @@ use crate::BorrowckInferCtxt; use crate::renumber::RegionCtxt; #[derive(Debug)] -#[derive(Clone)] // FIXME(#146079) pub(crate) struct UniversalRegions<'tcx> { indices: UniversalRegionIndices<'tcx>, @@ -200,7 +199,6 @@ impl<'tcx> DefiningTy<'tcx> { } #[derive(Debug)] -#[derive(Clone)] // FIXME(#146079) struct UniversalRegionIndices<'tcx> { /// For those regions that may appear in the parameter environment /// ('static and early-bound regions), we maintain a map from the