1
Fork 0

Remove lifetimes from BorrowckDomain.

They are only present because it's currently defined in terms of the
domains of `Borrows` and `MaybeUninitializedPlaces` and
`EverInitializedPlaces` via associated types. This commit introduces
typedefs for those domains, avoiding the lifetimes.
This commit is contained in:
Nicholas Nethercote 2024-11-26 14:02:10 +11:00
parent 83f67c5915
commit d490ea1f39
4 changed files with 42 additions and 41 deletions

View file

@ -8,7 +8,10 @@ use rustc_middle::mir::{
}; };
use rustc_middle::ty::{RegionVid, TyCtxt}; use rustc_middle::ty::{RegionVid, TyCtxt};
use rustc_mir_dataflow::fmt::DebugWithContext; use rustc_mir_dataflow::fmt::DebugWithContext;
use rustc_mir_dataflow::impls::{EverInitializedPlaces, MaybeUninitializedPlaces}; use rustc_mir_dataflow::impls::{
EverInitializedPlaces, EverInitializedPlacesDomain, MaybeUninitializedPlaces,
MaybeUninitializedPlacesDomain,
};
use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice, SwitchIntEdgeEffects}; use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice, SwitchIntEdgeEffects};
use tracing::debug; use tracing::debug;
@ -24,7 +27,7 @@ pub(crate) struct Borrowck<'a, 'tcx> {
} }
impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> { impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
type Domain = BorrowckDomain<'a, 'tcx>; type Domain = BorrowckDomain;
const NAME: &'static str = "borrowck"; const NAME: &'static str = "borrowck";
@ -110,14 +113,14 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
} }
} }
impl JoinSemiLattice for BorrowckDomain<'_, '_> { impl JoinSemiLattice for BorrowckDomain {
fn join(&mut self, _other: &Self) -> bool { fn join(&mut self, _other: &Self) -> bool {
// This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use. // This is only reachable from `iterate_to_fixpoint`, which this analysis doesn't use.
unreachable!(); unreachable!();
} }
} }
impl<'tcx, C> DebugWithContext<C> for BorrowckDomain<'_, 'tcx> impl<'tcx, C> DebugWithContext<C> for BorrowckDomain
where where
C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>, C: rustc_mir_dataflow::move_paths::HasMoveData<'tcx>,
{ {
@ -160,10 +163,10 @@ where
/// The transient state of the dataflow analyses used by the borrow checker. /// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct BorrowckDomain<'a, 'tcx> { pub(crate) struct BorrowckDomain {
pub(crate) borrows: <Borrows<'a, 'tcx> as Analysis<'tcx>>::Domain, pub(crate) borrows: BorrowsDomain,
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain, pub(crate) uninits: MaybeUninitializedPlacesDomain,
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as Analysis<'tcx>>::Domain, pub(crate) ever_inits: EverInitializedPlacesDomain,
} }
rustc_index::newtype_index! { rustc_index::newtype_index! {
@ -566,6 +569,8 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
} }
} }
type BorrowsDomain = BitSet<BorrowIndex>;
/// Forward dataflow computation of the set of borrows that are in scope at a particular location. /// Forward dataflow computation of the set of borrows that are in scope at a particular location.
/// - we gen the introduced loans /// - we gen the introduced loans
/// - we kill loans on locals going out of (regular) scope /// - we kill loans on locals going out of (regular) scope
@ -574,7 +579,7 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of /// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `a.b.c` when `a` is overwritten. /// `a.b.c` when `a` is overwritten.
impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> { impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
type Domain = BitSet<BorrowIndex>; type Domain = BorrowsDomain;
const NAME: &'static str = "borrows"; const NAME: &'static str = "borrows";

View file

@ -603,7 +603,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
fn visit_statement_before_primary_effect( fn visit_statement_before_primary_effect(
&mut self, &mut self,
_results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
stmt: &'a Statement<'tcx>, stmt: &'a Statement<'tcx>,
location: Location, location: Location,
) { ) {
@ -677,7 +677,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
fn visit_terminator_before_primary_effect( fn visit_terminator_before_primary_effect(
&mut self, &mut self,
_results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
term: &'a Terminator<'tcx>, term: &'a Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
@ -790,7 +790,7 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
fn visit_terminator_after_primary_effect( fn visit_terminator_after_primary_effect(
&mut self, &mut self,
_results: &mut Results<'tcx, Borrowck<'a, 'tcx>>, _results: &mut Results<'tcx, Borrowck<'a, 'tcx>>,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
term: &'a Terminator<'tcx>, term: &'a Terminator<'tcx>,
loc: Location, loc: Location,
) { ) {
@ -983,7 +983,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite), kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
let (sd, rw) = kind; let (sd, rw) = kind;
@ -1032,7 +1032,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
sd: AccessDepth, sd: AccessDepth,
rw: ReadOrWrite, rw: ReadOrWrite,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) -> bool { ) -> bool {
let mut error_reported = false; let mut error_reported = false;
@ -1172,7 +1172,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
location: Location, location: Location,
place_span: (Place<'tcx>, Span), place_span: (Place<'tcx>, Span),
kind: AccessDepth, kind: AccessDepth,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
// Write of P[i] or *P requires P init'd. // Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, state); self.check_if_assigned_path_is_moved(location, place_span, state);
@ -1190,7 +1190,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(rvalue, span): (&'a Rvalue<'tcx>, Span), (rvalue, span): (&'a Rvalue<'tcx>, Span),
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
match rvalue { match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => { &Rvalue::Ref(_ /*rgn*/, bk, place) => {
@ -1448,7 +1448,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(operand, span): (&'a Operand<'tcx>, Span), (operand, span): (&'a Operand<'tcx>, Span),
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
match *operand { match *operand {
Operand::Copy(place) => { Operand::Copy(place) => {
@ -1568,12 +1568,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
} }
} }
fn check_activations( fn check_activations(&mut self, location: Location, span: Span, state: &BorrowckDomain) {
&mut self,
location: Location,
span: Span,
state: &BorrowckDomain<'a, 'tcx>,
) {
// Two-phase borrow support: For each activation that is newly // Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with // generated at this statement, check if it interferes with
// another borrow. // another borrow.
@ -1731,7 +1726,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
let maybe_uninits = &state.uninits; let maybe_uninits = &state.uninits;
@ -1836,7 +1831,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
location: Location, location: Location,
desired_action: InitializationRequiringAction, desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span), place_span: (PlaceRef<'tcx>, Span),
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
let maybe_uninits = &state.uninits; let maybe_uninits = &state.uninits;
@ -1935,7 +1930,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
&mut self, &mut self,
location: Location, location: Location,
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
debug!("check_if_assigned_path_is_moved place: {:?}", place); debug!("check_if_assigned_path_is_moved place: {:?}", place);
@ -2001,7 +1996,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
location: Location, location: Location,
base: PlaceRef<'tcx>, base: PlaceRef<'tcx>,
span: Span, span: Span,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
) { ) {
// rust-lang/rust#21232: Until Rust allows reads from the // rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we // initialized parts of partially initialized structs, we
@ -2092,7 +2087,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
(place, span): (Place<'tcx>, Span), (place, span): (Place<'tcx>, Span),
kind: ReadOrWrite, kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed, is_local_mutation_allowed: LocalMutationIsAllowed,
state: &BorrowckDomain<'a, 'tcx>, state: &BorrowckDomain,
location: Location, location: Location,
) -> bool { ) -> bool {
debug!( debug!(
@ -2206,18 +2201,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
} }
} }
fn is_local_ever_initialized( fn is_local_ever_initialized(&self, local: Local, state: &BorrowckDomain) -> Option<InitIndex> {
&self,
local: Local,
state: &BorrowckDomain<'a, 'tcx>,
) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?; let mpi = self.move_data.rev_lookup.find_local(local)?;
let ii = &self.move_data.init_path_map[mpi]; let ii = &self.move_data.init_path_map[mpi];
ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied() ii.into_iter().find(|&&index| state.ever_inits.contains(index)).copied()
} }
/// Adds the place into the used mutable variables set /// Adds the place into the used mutable variables set
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain<'a, 'tcx>) { fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, state: &BorrowckDomain) {
match root_place { match root_place {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => { RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being // If the local may have been initialized, and it is now currently being

View file

@ -369,10 +369,12 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
} }
} }
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
/// We use a mixed bitset to avoid paying too high a memory footprint.
pub type MaybeUninitializedPlacesDomain = MixedBitSet<MovePathIndex>;
impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> { impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
/// There can be many more `MovePathIndex` than there are locals in a MIR body. type Domain = MaybeUninitializedPlacesDomain;
/// We use a mixed bitset to avoid paying too high a memory footprint.
type Domain = MixedBitSet<MovePathIndex>;
const NAME: &'static str = "maybe_uninit"; const NAME: &'static str = "maybe_uninit";
@ -490,10 +492,12 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
} }
} }
/// There can be many more `InitIndex` than there are locals in a MIR body.
/// We use a mixed bitset to avoid paying too high a memory footprint.
pub type EverInitializedPlacesDomain = MixedBitSet<InitIndex>;
impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> { impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
/// There can be many more `InitIndex` than there are locals in a MIR body. type Domain = EverInitializedPlacesDomain;
/// We use a mixed bitset to avoid paying too high a memory footprint.
type Domain = MixedBitSet<InitIndex>;
const NAME: &'static str = "ever_init"; const NAME: &'static str = "ever_init";

View file

@ -9,7 +9,8 @@ mod storage_liveness;
pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals}; pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals};
pub use self::initialized::{ pub use self::initialized::{
EverInitializedPlaces, MaybeInitializedPlaces, MaybeUninitializedPlaces, EverInitializedPlaces, EverInitializedPlacesDomain, MaybeInitializedPlaces,
MaybeUninitializedPlaces, MaybeUninitializedPlacesDomain,
}; };
pub use self::liveness::{ pub use self::liveness::{
MaybeLiveLocals, MaybeTransitiveLiveLocals, TransferFunction as LivenessTransferFunction, MaybeLiveLocals, MaybeTransitiveLiveLocals, TransferFunction as LivenessTransferFunction,