Split lifetimes on mir borrowck dataflow
This commit is contained in:
parent
4bdf8d2d58
commit
81695a147a
8 changed files with 94 additions and 86 deletions
|
@ -15,24 +15,24 @@ use std::fmt;
|
||||||
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
||||||
|
|
||||||
/// The results of the dataflow analyses used by the borrow checker.
|
/// The results of the dataflow analyses used by the borrow checker.
|
||||||
pub struct BorrowckResults<'mir, 'tcx> {
|
pub struct BorrowckResults<'a, 'mir, 'tcx> {
|
||||||
pub(crate) borrows: Results<'tcx, Borrows<'mir, 'tcx>>,
|
pub(crate) borrows: Results<'tcx, Borrows<'a, 'mir, 'tcx>>,
|
||||||
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
|
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'mir, 'tcx>>,
|
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BorrowckFlowState<'mir, 'tcx> {
|
pub struct BorrowckFlowState<'a, 'mir, 'tcx> {
|
||||||
pub(crate) borrows: <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
pub(crate) borrows: <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||||
pub(crate) uninits: <MaybeUninitializedPlaces<'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||||
pub(crate) ever_inits: <EverInitializedPlaces<'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.
|
// All three analyses are forward, but we have to use just one here.
|
||||||
type Direction = <Borrows<'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
||||||
type FlowState = BorrowckFlowState<'mir, 'tcx>;
|
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;
|
||||||
|
|
||||||
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
|
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
|
||||||
BorrowckFlowState {
|
BorrowckFlowState {
|
||||||
|
@ -106,11 +106,11 @@ rustc_index::newtype_index! {
|
||||||
/// `BorrowIndex`, and maps each such index to a `BorrowData`
|
/// `BorrowIndex`, and maps each such index to a `BorrowData`
|
||||||
/// describing the borrow. These indexes are used for representing the
|
/// describing the borrow. These indexes are used for representing the
|
||||||
/// borrows in compact bitvectors.
|
/// borrows in compact bitvectors.
|
||||||
pub struct Borrows<'mir, 'tcx> {
|
pub struct Borrows<'a, 'mir, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'mir Body<'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>>,
|
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(
|
pub fn new(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'mir Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
regioncx: &'mir RegionInferenceContext<'tcx>,
|
regioncx: &RegionInferenceContext<'tcx>,
|
||||||
borrow_set: &'mir BorrowSet<'tcx>,
|
borrow_set: &'a BorrowSet<'tcx>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let mut borrows_out_of_scope_at_location =
|
let mut borrows_out_of_scope_at_location =
|
||||||
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
|
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>;
|
type Domain = BitSet<BorrowIndex>;
|
||||||
|
|
||||||
const NAME: &'static str = "borrows";
|
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.
|
/// 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
|
/// - 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::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
|
impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, '_, 'tcx> {
|
||||||
type Idx = BorrowIndex;
|
type Idx = BorrowIndex;
|
||||||
|
|
||||||
fn domain_size(&self, _: &mir::Body<'tcx>) -> usize {
|
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 {
|
impl DebugWithContext<Borrows<'_, '_, '_>> for BorrowIndex {
|
||||||
fn fmt_with(&self, ctxt: &Borrows<'_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt_with(&self, ctxt: &Borrows<'_, '_, '_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{:?}", ctxt.location(*self))
|
write!(f, "{:?}", ctxt.location(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -605,15 +605,15 @@ struct MirBorrowckCtxt<'a, 'mir, 'cx, 'tcx> {
|
||||||
// 2. loans made in overlapping scopes do not conflict
|
// 2. loans made in overlapping scopes do not conflict
|
||||||
// 3. assignments do not affect things loaned out as immutable
|
// 3. assignments do not affect things loaned out as immutable
|
||||||
// 4. moves do not affect things loaned out in any way
|
// 4. moves do not affect things loaned out in any way
|
||||||
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
impl<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||||
for MirBorrowckCtxt<'_, 'mir, '_, 'tcx>
|
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
|
||||||
{
|
{
|
||||||
type FlowState = Flows<'mir, 'tcx>;
|
type FlowState = Flows<'a, 'mir, 'tcx>;
|
||||||
|
|
||||||
fn visit_statement_before_primary_effect(
|
fn visit_statement_before_primary_effect(
|
||||||
&mut self,
|
&mut self,
|
||||||
_results: &mut R,
|
_results: &mut R,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
stmt: &'mir Statement<'tcx>,
|
stmt: &'mir Statement<'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) {
|
) {
|
||||||
|
@ -683,7 +683,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||||
fn visit_terminator_before_primary_effect(
|
fn visit_terminator_before_primary_effect(
|
||||||
&mut self,
|
&mut self,
|
||||||
_results: &mut R,
|
_results: &mut R,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
term: &'mir Terminator<'tcx>,
|
term: &'mir Terminator<'tcx>,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
) {
|
) {
|
||||||
|
@ -794,7 +794,7 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||||
fn visit_terminator_after_primary_effect(
|
fn visit_terminator_after_primary_effect(
|
||||||
&mut self,
|
&mut self,
|
||||||
_results: &mut R,
|
_results: &mut R,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
term: &'mir Terminator<'tcx>,
|
term: &'mir Terminator<'tcx>,
|
||||||
loc: Location,
|
loc: Location,
|
||||||
) {
|
) {
|
||||||
|
@ -988,7 +988,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, '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,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
let (sd, rw) = kind;
|
let (sd, rw) = kind;
|
||||||
|
|
||||||
|
@ -1038,7 +1038,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
place_span: (Place<'tcx>, Span),
|
place_span: (Place<'tcx>, Span),
|
||||||
sd: AccessDepth,
|
sd: AccessDepth,
|
||||||
rw: ReadOrWrite,
|
rw: ReadOrWrite,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let mut error_reported = false;
|
let mut error_reported = false;
|
||||||
let borrow_set = Rc::clone(&self.borrow_set);
|
let borrow_set = Rc::clone(&self.borrow_set);
|
||||||
|
@ -1179,7 +1179,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
location: Location,
|
location: Location,
|
||||||
place_span: (Place<'tcx>, Span),
|
place_span: (Place<'tcx>, Span),
|
||||||
kind: AccessDepth,
|
kind: AccessDepth,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
// 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, flow_state);
|
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
|
||||||
|
@ -1197,7 +1197,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
|
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
match rvalue {
|
match rvalue {
|
||||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||||
|
@ -1455,7 +1455,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(operand, span): (&'mir Operand<'tcx>, Span),
|
(operand, span): (&'mir Operand<'tcx>, Span),
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
match *operand {
|
match *operand {
|
||||||
Operand::Copy(place) => {
|
Operand::Copy(place) => {
|
||||||
|
@ -1579,7 +1579,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
span: Span,
|
span: Span,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, '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
|
||||||
|
@ -1743,7 +1743,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
location: Location,
|
location: Location,
|
||||||
desired_action: InitializationRequiringAction,
|
desired_action: InitializationRequiringAction,
|
||||||
place_span: (PlaceRef<'tcx>, Span),
|
place_span: (PlaceRef<'tcx>, Span),
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
let maybe_uninits = &flow_state.uninits;
|
let maybe_uninits = &flow_state.uninits;
|
||||||
|
|
||||||
|
@ -1848,7 +1848,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
location: Location,
|
location: Location,
|
||||||
desired_action: InitializationRequiringAction,
|
desired_action: InitializationRequiringAction,
|
||||||
place_span: (PlaceRef<'tcx>, Span),
|
place_span: (PlaceRef<'tcx>, Span),
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
let maybe_uninits = &flow_state.uninits;
|
let maybe_uninits = &flow_state.uninits;
|
||||||
|
|
||||||
|
@ -1947,7 +1947,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
location: Location,
|
location: Location,
|
||||||
(place, span): (Place<'tcx>, Span),
|
(place, span): (Place<'tcx>, Span),
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
debug!("check_if_assigned_path_is_moved place: {:?}", place);
|
debug!("check_if_assigned_path_is_moved place: {:?}", place);
|
||||||
|
|
||||||
|
@ -2013,7 +2013,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
location: Location,
|
location: Location,
|
||||||
base: PlaceRef<'tcx>,
|
base: PlaceRef<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) {
|
) {
|
||||||
// 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
|
||||||
|
@ -2104,7 +2104,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, '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,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -2220,7 +2220,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
fn is_local_ever_initialized(
|
fn is_local_ever_initialized(
|
||||||
&self,
|
&self,
|
||||||
local: Local,
|
local: Local,
|
||||||
flow_state: &Flows<'mir, 'tcx>,
|
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||||
) -> Option<InitIndex> {
|
) -> 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];
|
||||||
|
@ -2228,7 +2228,7 @@ impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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>, flow_state: &Flows<'mir, 'tcx>) {
|
fn add_used_mut(&mut self, root_place: RootPlace<'tcx>, flow_state: &Flows<'_, 'mir, 'tcx>) {
|
||||||
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
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||||
promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
promoted: &IndexSlice<Promoted, Body<'tcx>>,
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
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>,
|
move_data: &MoveData<'tcx>,
|
||||||
borrow_set: &BorrowSet<'tcx>,
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub(super) fn generate<'mir, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
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>,
|
move_data: &MoveData<'tcx>,
|
||||||
) {
|
) {
|
||||||
debug!("liveness::generate");
|
debug!("liveness::generate");
|
||||||
|
|
|
@ -43,7 +43,7 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
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>,
|
move_data: &MoveData<'tcx>,
|
||||||
relevant_live_locals: Vec<Local>,
|
relevant_live_locals: Vec<Local>,
|
||||||
boring_locals: Vec<Local>,
|
boring_locals: Vec<Local>,
|
||||||
|
@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Contextual state for the type-liveness coroutine.
|
/// 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.
|
/// Current type-checker, giving us our inference context etc.
|
||||||
typeck: &'me mut TypeChecker<'typeck, 'tcx>,
|
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
|
/// Results of dataflow tracking which variables (and paths) have been
|
||||||
/// initialized.
|
/// 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
|
/// Index indicating where each variable is assigned, used, or
|
||||||
/// dropped.
|
/// dropped.
|
||||||
|
@ -131,8 +131,8 @@ struct DropData<'tcx> {
|
||||||
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
|
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||||
cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>,
|
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,
|
||||||
|
|
||||||
/// Set of points that define the current local.
|
/// Set of points that define the current local.
|
||||||
defs: BitSet<PointIndex>,
|
defs: BitSet<PointIndex>,
|
||||||
|
@ -153,8 +153,8 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
||||||
stack: Vec<PointIndex>,
|
stack: Vec<PointIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
|
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||||
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>) -> Self {
|
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
|
||||||
let num_points = cx.elements.num_points();
|
let num_points = cx.elements.num_points();
|
||||||
LivenessResults {
|
LivenessResults {
|
||||||
cx,
|
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
|
/// 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
|
/// cursor position. Callers should call one of the `seek` methods immediately before to point
|
||||||
/// the cursor to the desired location.
|
/// the cursor to the desired location.
|
||||||
|
|
|
@ -129,7 +129,7 @@ pub(crate) fn type_check<'mir, 'tcx>(
|
||||||
location_table: &LocationTable,
|
location_table: &LocationTable,
|
||||||
borrow_set: &BorrowSet<'tcx>,
|
borrow_set: &BorrowSet<'tcx>,
|
||||||
all_facts: &mut Option<AllFacts>,
|
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>,
|
move_data: &MoveData<'tcx>,
|
||||||
elements: &Rc<DenseLocationMap>,
|
elements: &Rc<DenseLocationMap>,
|
||||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||||
|
|
|
@ -50,15 +50,19 @@ use crate::{lattice, AnalysisDomain, GenKill, GenKillAnalysis, MaybeReachable};
|
||||||
/// Similarly, at a given `drop` statement, the set-intersection
|
/// Similarly, at a given `drop` statement, the set-intersection
|
||||||
/// between this data and `MaybeUninitializedPlaces` yields the set of
|
/// between this data and `MaybeUninitializedPlaces` yields the set of
|
||||||
/// places that would require a dynamic drop-flag at that statement.
|
/// 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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||||
skip_unreachable_unwind: bool,
|
skip_unreachable_unwind: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
pub fn new(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
body: &'mir Body<'tcx>,
|
||||||
|
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||||
|
) -> Self {
|
||||||
MaybeInitializedPlaces { tcx, body, mdpe, skip_unreachable_unwind: false }
|
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> {
|
fn move_data(&self) -> &MoveData<'tcx> {
|
||||||
&self.mdpe.move_data
|
&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
|
/// Similarly, at a given `drop` statement, the set-intersection
|
||||||
/// between this data and `MaybeInitializedPlaces` yields the set of
|
/// between this data and `MaybeInitializedPlaces` yields the set of
|
||||||
/// places that would require a dynamic drop-flag at that statement.
|
/// 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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||||
|
|
||||||
mark_inactive_variants_as_uninit: bool,
|
mark_inactive_variants_as_uninit: bool,
|
||||||
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
|
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
|
||||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
pub fn new(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
body: &'mir Body<'tcx>,
|
||||||
|
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||||
|
) -> Self {
|
||||||
MaybeUninitializedPlaces {
|
MaybeUninitializedPlaces {
|
||||||
tcx,
|
tcx,
|
||||||
body,
|
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> {
|
fn move_data(&self) -> &MoveData<'tcx> {
|
||||||
&self.mdpe.move_data
|
&self.mdpe.move_data
|
||||||
}
|
}
|
||||||
|
@ -250,24 +258,24 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
|
||||||
/// c = S; // {a, b, c, d }
|
/// c = S; // {a, b, c, d }
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct EverInitializedPlaces<'a, 'tcx> {
|
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||||
body: &'a Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
mdpe: &'a MoveDataParamEnv<'tcx>,
|
mdpe: &'a MoveDataParamEnv<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
|
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||||
pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
pub fn new(body: &'mir Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
|
||||||
EverInitializedPlaces { body, mdpe }
|
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> {
|
fn move_data(&self) -> &MoveData<'tcx> {
|
||||||
&self.mdpe.move_data
|
&self.mdpe.move_data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||||
fn update_bits(
|
fn update_bits(
|
||||||
trans: &mut impl GenKill<MovePathIndex>,
|
trans: &mut impl GenKill<MovePathIndex>,
|
||||||
path: 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(
|
fn update_bits(
|
||||||
trans: &mut impl GenKill<MovePathIndex>,
|
trans: &mut impl GenKill<MovePathIndex>,
|
||||||
path: 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.
|
/// 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.
|
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||||
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
|
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;
|
type Idx = MovePathIndex;
|
||||||
|
|
||||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
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.
|
/// 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.
|
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||||
type Domain = ChunkedBitSet<MovePathIndex>;
|
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;
|
type Idx = MovePathIndex;
|
||||||
|
|
||||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
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.
|
/// 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.
|
/// We use a chunked bitset to avoid paying too high a memory footprint.
|
||||||
type Domain = ChunkedBitSet<InitIndex>;
|
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;
|
type Idx = InitIndex;
|
||||||
|
|
||||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
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)]
|
#[instrument(level = "trace", skip(body, flow_inits), ret)]
|
||||||
fn compute_dead_unwinds<'mir, 'tcx>(
|
fn compute_dead_unwinds<'mir, 'tcx>(
|
||||||
body: &'mir Body<'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> {
|
) -> BitSet<BasicBlock> {
|
||||||
// We only need to do this pass once, because unwind edges can only
|
// We only need to do this pass once, because unwind edges can only
|
||||||
// reach cleanup blocks, which can't have unwind edges themselves.
|
// reach cleanup blocks, which can't have unwind edges themselves.
|
||||||
|
@ -118,12 +118,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
|
||||||
dead_unwinds
|
dead_unwinds
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InitializationData<'mir, 'tcx> {
|
struct InitializationData<'a, 'mir, 'tcx> {
|
||||||
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
|
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'mir, 'tcx>>,
|
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InitializationData<'_, '_> {
|
impl InitializationData<'_, '_, '_> {
|
||||||
fn seek_before(&mut self, loc: Location) {
|
fn seek_before(&mut self, loc: Location) {
|
||||||
self.inits.seek_before_primary_effect(loc);
|
self.inits.seek_before_primary_effect(loc);
|
||||||
self.uninits.seek_before_primary_effect(loc);
|
self.uninits.seek_before_primary_effect(loc);
|
||||||
|
@ -134,17 +134,17 @@ impl InitializationData<'_, '_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Elaborator<'a, 'b, 'tcx> {
|
struct Elaborator<'a, 'b, 'mir, 'tcx> {
|
||||||
ctxt: &'a mut ElaborateDropsCtxt<'b, '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 {
|
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
|
impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, '_, 'tcx> {
|
||||||
type Path = MovePathIndex;
|
type Path = MovePathIndex;
|
||||||
|
|
||||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
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>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &'a Body<'tcx>,
|
body: &'mir Body<'tcx>,
|
||||||
env: &'a MoveDataParamEnv<'tcx>,
|
env: &'a MoveDataParamEnv<'tcx>,
|
||||||
init_data: InitializationData<'a, 'tcx>,
|
init_data: InitializationData<'a, 'mir, 'tcx>,
|
||||||
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
|
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
|
||||||
patch: MirPatch<'tcx>,
|
patch: MirPatch<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
|
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
|
||||||
fn move_data(&self) -> &'b MoveData<'tcx> {
|
fn move_data(&self) -> &'b MoveData<'tcx> {
|
||||||
&self.env.move_data
|
&self.env.move_data
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue