Skip to content

Commit

Permalink
Split lifetimes on mir borrowck dataflow
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Jun 26, 2024
1 parent 4bdf8d2 commit 81695a1
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 86 deletions.
40 changes: 20 additions & 20 deletions compiler/rustc_borrowck/src/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,24 @@ use std::fmt;
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};

/// The results of the dataflow analyses used by the borrow checker.
pub struct BorrowckResults<'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
pub struct BorrowckResults<'a, 'mir, 'tcx> {
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
}

/// The transient state of the dataflow analyses used by the borrow checker.
#[derive(Debug)]
pub struct BorrowckFlowState<'mir, 'tcx> {
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
}

impl<'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'mir, 'tcx> {
impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> {
// All three analyses are forward, but we have to use just one here.
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'mir, 'tcx>;
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;

fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
BorrowckFlowState {
Expand Down Expand Up @@ -106,11 +106,11 @@ rustc_index::newtype_index! {
/// `BorrowIndex`, and maps each such index to a `BorrowData`
/// describing the borrow. These indexes are used for representing the
/// borrows in compact bitvectors.
pub struct Borrows<'mir, 'tcx> {
pub struct Borrows<'a, 'mir, 'tcx> {
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,

borrow_set: &'mir BorrowSet<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
}

Expand Down Expand Up @@ -389,12 +389,12 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
}
}

impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> {
pub fn new(
tcx: TyCtxt<'tcx>,
body: &'mir Body<'tcx>,
regioncx: &'mir RegionInferenceContext<'tcx>,
borrow_set: &'mir BorrowSet<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
borrow_set: &'a BorrowSet<'tcx>,
) -> Self {
let mut borrows_out_of_scope_at_location =
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
Expand Down Expand Up @@ -494,7 +494,7 @@ impl<'mir, 'tcx> Borrows<'mir, 'tcx> {
}
}

impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, '_, 'tcx> {
type Domain = BitSet<BorrowIndex>;

const NAME: &'static str = "borrows";
Expand All @@ -517,7 +517,7 @@ impl<'tcx> rustc_mir_dataflow::AnalysisDomain<'tcx> for Borrows<'_, 'tcx> {
/// region stops containing the CFG points reachable from the issuing location.
/// - we also kill loans of conflicting places when overwriting a shared path: e.g. borrows of
/// `a.b.c` when `a` is overwritten.
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
type Idx = BorrowIndex;

fn domain_size(&self, _: &mir::Body<'tcx>) -> usize {
Expand Down Expand Up @@ -617,8 +617,8 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
}
}

impl DebugWithContext<Borrows<'_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex {
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", ctxt.location(*self))
}
}
38 changes: 19 additions & 19 deletions compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,15 +605,15 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
// 2. loans made in overlapping scopes do not conflict
// 3. assignments do not affect things loaned out as immutable
// 4. moves do not affect things loaned out in any way
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'_, 'mir, '_, 'tcx>
impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
{
type FlowState = Flows<'mir, 'tcx>;
type FlowState = Flows<'a, 'mir, 'tcx>;

fn visit_statement_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
stmt: &'mir Statement<'tcx>,
location: Location,
) {
Expand Down Expand Up @@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_before_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
Expand Down Expand Up @@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
fn visit_terminator_after_primary_effect(
&mut self,
_results: &mut R,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
term: &'mir Terminator<'tcx>,
loc: Location,
) {
Expand Down Expand Up @@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span),
kind: (AccessDepth, ReadOrWrite),
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let (sd, rw) = kind;

Expand Down Expand Up @@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
place_span: (Place<'tcx>, Span),
sd: AccessDepth,
rw: ReadOrWrite,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) -> bool {
let mut error_reported = false;
let borrow_set = Rc::clone(&self.borrow_set);
Expand Down Expand Up @@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
place_span: (Place<'tcx>, Span),
kind: AccessDepth,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// Write of P[i] or *P requires P init'd.
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
Expand All @@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
match rvalue {
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
Expand Down Expand Up @@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(operand, span): (&'mir Operand<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
match *operand {
Operand::Copy(place) => {
Expand Down Expand Up @@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
span: Span,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
Expand Down Expand Up @@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;

Expand Down Expand Up @@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
desired_action: InitializationRequiringAction,
place_span: (PlaceRef<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
let maybe_uninits = &flow_state.uninits;

Expand Down Expand Up @@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
&mut self,
location: Location,
(place, span): (Place<'tcx>, Span),
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
debug!("check_if_assigned_path_is_moved place: {:?}", place);

Expand Down Expand Up @@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
location: Location,
base: PlaceRef<'tcx>,
span: Span,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) {
// rust-lang/rust#21232: Until Rust allows reads from the
// initialized parts of partially initialized structs, we
Expand Down Expand Up @@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
(place, span): (Place<'tcx>, Span),
kind: ReadOrWrite,
is_local_mutation_allowed: LocalMutationIsAllowed,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
location: Location,
) -> bool {
debug!(
Expand Down Expand Up @@ -2220,15 +2220,15 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
fn is_local_ever_initialized(
&self,
local: Local,
flow_state: &Flows<'mir, 'tcx>,
flow_state: &Flows<'_, 'mir, 'tcx>,
) -> Option<InitIndex> {
let mpi = self.move_data.rev_lookup.find_local(local)?;
let ii = &self.move_data.init_path_map[mpi];
ii.into_iter().find(|&&index| flow_state.ever_inits.contains(index)).copied()
}

/// Adds the place into the used mutable variables set
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'mir, 'tcx>) {
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) {
match root_place {
RootPlace { place_local: local, place_projection: [], is_local_mutation_allowed } => {
// If the local may have been initialized, and it is now currently being
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
promoted: &IndexSlice<Promoted, Body<'tcx>>,
location_table: &LocationTable,
param_env: ty::ParamEnv<'tcx>,
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'_, 'cx, 'tcx>>,
move_data: &MoveData<'tcx>,
borrow_set: &BorrowSet<'tcx>,
upvars: &[&ty::CapturedPlace<'tcx>],
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/liveness/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub(super) fn generate<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>,
) {
debug!("liveness::generate");
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_borrowck/src/type_check/liveness/trace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>(
typeck: &mut TypeChecker<'_, 'tcx>,
body: &Body<'tcx>,
elements: &Rc<DenseLocationMap>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>,
relevant_live_locals: Vec<Local>,
boring_locals: Vec<Local>,
Expand Down Expand Up @@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>(
}

/// Contextual state for the type-liveness coroutine.
struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> {
/// Current type-checker, giving us our inference context etc.
typeck: &'me mut TypeChecker<'typeck, 'tcx>,

Expand All @@ -119,7 +119,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {

/// Results of dataflow tracking which variables (and paths) have been
/// initialized.
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>,
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>,

/// Index indicating where each variable is assigned, used, or
/// dropped.
Expand All @@ -131,8 +131,8 @@ struct DropData<'tcx> {
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
}

struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>,
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,

/// Set of points that define the current local.
defs: BitSet<PointIndex>,
Expand All @@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
stack: Vec<PointIndex>,
}

impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self {
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
let num_points = cx.elements.num_points();
LivenessResults {
cx,
Expand Down Expand Up @@ -507,7 +507,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
}
}

impl<'tcx> LivenessContext<'_, '_, '_, 'tcx> {
impl<'tcx> LivenessContext<'_, '_, '_, '_, 'tcx> {
/// Returns `true` if the local variable (or some part of it) is initialized at the current
/// cursor position. Callers should call one of the `seek` methods immediately before to point
/// the cursor to the desired location.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
location_table: &LocationTable,
borrow_set: &BorrowSet<'tcx>,
all_facts: &mut Option<AllFacts>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
move_data: &MoveData<'tcx>,
elements: &Rc<DenseLocationMap>,
upvars: &[&ty::CapturedPlace<'tcx>],
Expand Down
Loading

0 comments on commit 81695a1

Please sign in to comment.