mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-24 05:33:41 +00:00
Split lifetimes on mir borrowck dataflow
This commit is contained in:
parent
4bdf8d2d58
commit
81695a147a
@ -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 {
|
||||
@ -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>>,
|
||||
}
|
||||
|
||||
@ -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);
|
||||
@ -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";
|
||||
@ -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 {
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
) {
|
||||
@ -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,
|
||||
) {
|
||||
@ -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,
|
||||
) {
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
@ -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);
|
||||
@ -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) => {
|
||||
@ -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) => {
|
||||
@ -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
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
@ -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!(
|
||||
@ -2220,7 +2220,7 @@ 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];
|
||||
@ -2228,7 +2228,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
}
|
||||
|
||||
/// 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
|
||||
|
@ -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>],
|
||||
|
@ -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");
|
||||
|
@ -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>,
|
||||
@ -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>,
|
||||
|
||||
@ -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.
|
||||
@ -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>,
|
||||
@ -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,
|
||||
@ -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.
|
||||
|
@ -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>],
|
||||
|
@ -50,15 +50,19 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable};
|
||||
/// Similarly, at a given `drop` statement, the set-intersection
|
||||
/// between this data and `MaybeUninitializedPlaces` yields the set of
|
||||
/// places that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeInitializedPlaces<'a, 'tcx> {
|
||||
pub struct MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
skip_unreachable_unwind: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false }
|
||||
}
|
||||
|
||||
@ -84,7 +88,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
|
||||
impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
&self.mdpe.move_data
|
||||
}
|
||||
@ -125,17 +129,21 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
|
||||
/// Similarly, at a given `drop` statement, the set-intersection
|
||||
/// between this data and `MaybeInitializedPlaces` yields the set of
|
||||
/// places that would require a dynamic drop-flag at that statement.
|
||||
pub struct MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
pub struct MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
|
||||
mark_inactive_variants_as_uninit: bool,
|
||||
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
||||
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
) -> Self {
|
||||
MaybeUninitializedPlaces {
|
||||
tcx,
|
||||
body,
|
||||
@ -164,7 +172,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
&self.mdpe.move_data
|
||||
}
|
||||
@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
|
||||
/// c = S; // {a, b, c, d }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct EverInitializedPlaces<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
body: &'mir Body<'tcx>,
|
||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
||||
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
||||
EverInitializedPlaces { body, mdpe }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> {
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
&self.mdpe.move_data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
fn update_bits(
|
||||
trans: &mut impl GenKill<MovePathIndex>,
|
||||
path: MovePathIndex,
|
||||
@ -280,7 +288,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> {
|
||||
fn update_bits(
|
||||
trans: &mut impl GenKill<MovePathIndex>,
|
||||
path: MovePathIndex,
|
||||
@ -306,7 +314,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
|
||||
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
|
||||
@ -328,7 +336,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
@ -441,7 +449,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
|
||||
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
type Domain = ChunkedBitSet<MovePathIndex>;
|
||||
@ -465,7 +473,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
@ -642,7 +650,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
|
||||
/// There can be many more `InitIndex` than there are locals in a MIR body.
|
||||
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||
type Domain = ChunkedBitSet<InitIndex>;
|
||||
@ -661,7 +669,7 @@ impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
|
||||
type Idx = InitIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
|
@ -97,7 +97,7 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||
#[instrument(level = "trace", skip(body, flow_inits), ret)]
|
||||
fn compute_dead_unwinds<'mir, 'tcx>(
|
||||
body: &'mir Body<'tcx>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
|
||||
) -> BitSet<BasicBlock> {
|
||||
// We only need to do this pass once, because unwind edges can only
|
||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||
@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
|
||||
dead_unwinds
|
||||
}
|
||||
|
||||
struct InitializationData<'mir, 'tcx> {
|
||||
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
||||
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
|
||||
struct InitializationData<'a, 'mir, 'tcx> {
|
||||
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
}
|
||||
|
||||
impl InitializationData<'_, '_> {
|
||||
impl InitializationData<'_, '_, '_> {
|
||||
fn seek_before(&mut self, loc: Location) {
|
||||
self.inits.seek_before_primary_effect(loc);
|
||||
self.uninits.seek_before_primary_effect(loc);
|
||||
@ -134,17 +134,17 @@ impl InitializationData<'_, '_> {
|
||||
}
|
||||
}
|
||||
|
||||
struct Elaborator<'a, 'b, 'tcx> {
|
||||
ctxt: &'a mut ElaborateDropsCtxt<'b, 'tcx>,
|
||||
struct Elaborator<'a, 'b, 'mir, 'tcx> {
|
||||
ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Elaborator<'_, '_, '_> {
|
||||
impl fmt::Debug for Elaborator<'_, '_, '_, '_> {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
|
||||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
|
||||
type Path = MovePathIndex;
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
||||
@ -238,16 +238,16 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
struct ElaborateDropsCtxt<'a, 'tcx> {
|
||||
struct ElaborateDropsCtxt<'a, 'mir, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
env: &'a MoveDataParamEnv<'tcx>,
|
||||
init_data: InitializationData<'a, 'tcx>,
|
||||
init_data: InitializationData<'a, 'mir, 'tcx>,
|
||||
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
|
||||
patch: MirPatch<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
||||
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
|
||||
fn move_data(&self) -> &'b MoveData<'tcx> {
|
||||
&self.env.move_data
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user