Rollup merge of #130022 - nnethercote:dataflow-borrowck-lifetimes, r=oli-obk
Dataflow/borrowck lifetime cleanups These commits remove a bunch of unnecessary lifetimes from structs involved in dataflow/borrowck. r? ``@lqd``
This commit is contained in:
commit
ee8fd33f60
@ -8,7 +8,7 @@
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn dcx(&self) -> DiagCtxtHandle<'infcx> {
|
||||
self.infcx.dcx()
|
||||
}
|
||||
|
@ -15,24 +15,24 @@
|
||||
use crate::{places_conflict, BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext};
|
||||
|
||||
/// The results of the dataflow analyses used by the borrow checker.
|
||||
pub(crate) 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>>,
|
||||
pub(crate) struct BorrowckResults<'a, 'tcx> {
|
||||
pub(crate) borrows: Results<'tcx, Borrows<'a, 'tcx>>,
|
||||
pub(crate) uninits: Results<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
|
||||
pub(crate) ever_inits: Results<'tcx, EverInitializedPlaces<'a, 'tcx>>,
|
||||
}
|
||||
|
||||
/// The transient state of the dataflow analyses used by the borrow checker.
|
||||
#[derive(Debug)]
|
||||
pub(crate) 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,
|
||||
pub(crate) struct BorrowckFlowState<'a, 'tcx> {
|
||||
pub(crate) borrows: <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) uninits: <MaybeUninitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
pub(crate) ever_inits: <EverInitializedPlaces<'a, 'tcx> as AnalysisDomain<'tcx>>::Domain,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'mir, 'tcx> {
|
||||
impl<'a, 'tcx> ResultsVisitable<'tcx> for BorrowckResults<'a, 'tcx> {
|
||||
// All three analyses are forward, but we have to use just one here.
|
||||
type Direction = <Borrows<'a, 'mir, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
||||
type FlowState = BorrowckFlowState<'a, 'mir, 'tcx>;
|
||||
type Direction = <Borrows<'a, 'tcx> as AnalysisDomain<'tcx>>::Direction;
|
||||
type FlowState = BorrowckFlowState<'a, 'tcx>;
|
||||
|
||||
fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
|
||||
BorrowckFlowState {
|
||||
@ -106,10 +106,9 @@ pub struct BorrowIndex {}
|
||||
/// `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<'a, 'mir, 'tcx> {
|
||||
pub struct Borrows<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
|
||||
body: &'a Body<'tcx>,
|
||||
borrow_set: &'a BorrowSet<'tcx>,
|
||||
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
|
||||
}
|
||||
@ -389,10 +388,10 @@ fn loan_kill_location(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> Borrows<'a, 'mir, 'tcx> {
|
||||
impl<'a, 'tcx> Borrows<'a, 'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
borrow_set: &'a BorrowSet<'tcx>,
|
||||
) -> Self {
|
||||
@ -494,7 +493,7 @@ fn kill_borrows_on_place(&self, trans: &mut impl GenKill<BorrowIndex>, place: Pl
|
||||
}
|
||||
}
|
||||
|
||||
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 +516,7 @@ fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
|
||||
/// 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 +616,8 @@ fn call_return_effect(
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub(crate) fn relate(expected: Ty<'tcx>, found: Ty<'tcx>) -> UniverseInfo<'tcx>
|
||||
|
||||
pub(crate) fn report_error(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
cause: ObligationCause<'tcx>,
|
||||
@ -151,7 +151,7 @@ trait TypeOpInfo<'tcx> {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -160,7 +160,7 @@ fn nice_error<'infcx>(
|
||||
#[instrument(level = "debug", skip(self, mbcx))]
|
||||
fn report_error(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'tcx>,
|
||||
placeholder: ty::PlaceholderRegion,
|
||||
error_element: RegionElement,
|
||||
cause: ObligationCause<'tcx>,
|
||||
@ -233,7 +233,7 @@ fn base_universe(&self) -> ty::UniverseIndex {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -277,7 +277,7 @@ fn base_universe(&self) -> ty::UniverseIndex {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -324,7 +324,7 @@ fn base_universe(&self) -> ty::UniverseIndex {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
@ -357,7 +357,7 @@ fn base_universe(&self) -> ty::UniverseIndex {
|
||||
|
||||
fn nice_error<'infcx>(
|
||||
&self,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, '_, 'infcx, 'tcx>,
|
||||
mbcx: &mut MirBorrowckCtxt<'_, 'infcx, 'tcx>,
|
||||
_cause: ObligationCause<'tcx>,
|
||||
placeholder_region: ty::Region<'tcx>,
|
||||
error_region: Option<ty::Region<'tcx>>,
|
||||
|
@ -69,7 +69,7 @@ enum StorageDeadOrDrop<'tcx> {
|
||||
Destructor(Ty<'tcx>),
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn report_use_of_moved_or_uninitialized(
|
||||
&mut self,
|
||||
location: Location,
|
||||
@ -4358,11 +4358,7 @@ enum AnnotatedBorrowFnSignature<'tcx> {
|
||||
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
|
||||
/// Annotate the provided diagnostic with information about borrow from the fn signature that
|
||||
/// helps explain.
|
||||
pub(crate) fn emit(
|
||||
&self,
|
||||
cx: &MirBorrowckCtxt<'_, '_, '_, 'tcx>,
|
||||
diag: &mut Diag<'_>,
|
||||
) -> String {
|
||||
pub(crate) fn emit(&self, cx: &MirBorrowckCtxt<'_, '_, 'tcx>, diag: &mut Diag<'_>) -> String {
|
||||
match self {
|
||||
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
|
||||
diag.span_label(
|
||||
|
@ -390,7 +390,7 @@ fn add_lifetime_bound_suggestion_to_diagnostic(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
fn free_region_constraint_info(
|
||||
&self,
|
||||
borrow_region: RegionVid,
|
||||
|
@ -68,7 +68,7 @@ pub(super) struct DescribePlaceOpt {
|
||||
|
||||
pub(super) struct IncludingTupleField(pub(super) bool);
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
/// Adds a suggestion when a closure is invoked twice with a moved variable or when a closure
|
||||
/// is moved after being invoked.
|
||||
///
|
||||
@ -772,7 +772,7 @@ struct CapturedMessageOpt {
|
||||
maybe_reinitialized_locations_is_empty: bool,
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
/// Finds the spans associated to a move or copy of move_place at location.
|
||||
pub(super) fn move_spans(
|
||||
&self,
|
||||
|
@ -93,7 +93,7 @@ enum GroupedMoveError<'tcx> {
|
||||
},
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn report_move_errors(&mut self) {
|
||||
let grouped_errors = self.group_move_errors();
|
||||
for error in grouped_errors {
|
||||
|
@ -32,7 +32,7 @@ pub(crate) enum AccessKind {
|
||||
Mutate,
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn report_mutability_error(
|
||||
&mut self,
|
||||
access_place: Place<'tcx>,
|
||||
|
@ -76,7 +76,7 @@ fn region_name_is_suggestable(name: &RegionName) -> bool {
|
||||
/// Returns a name for the region if it is suggestable. See `region_name_is_suggestable`.
|
||||
fn region_vid_to_name(
|
||||
&self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
region: RegionVid,
|
||||
) -> Option<RegionName> {
|
||||
mbcx.give_region_a_name(region).filter(Self::region_name_is_suggestable)
|
||||
@ -85,7 +85,7 @@ fn region_vid_to_name(
|
||||
/// Compiles a list of all suggestions to be printed in the final big suggestion.
|
||||
fn compile_all_suggestions(
|
||||
&self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
) -> SmallVec<[SuggestedConstraint; 2]> {
|
||||
let mut suggested = SmallVec::new();
|
||||
|
||||
@ -161,7 +161,7 @@ pub(crate) fn collect_constraint(&mut self, fr: RegionVid, outlived_fr: RegionVi
|
||||
/// Emit an intermediate note on the given `Diag` if the involved regions are suggestable.
|
||||
pub(crate) fn intermediate_suggestion(
|
||||
&mut self,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_, '_>,
|
||||
mbcx: &MirBorrowckCtxt<'_, '_, '_>,
|
||||
errci: &ErrorConstraintInfo<'_>,
|
||||
diag: &mut Diag<'_>,
|
||||
) {
|
||||
@ -180,7 +180,7 @@ pub(crate) fn intermediate_suggestion(
|
||||
|
||||
/// If there is a suggestion to emit, add a diagnostic to the buffer. This is the final
|
||||
/// suggestion including all collected constraints.
|
||||
pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_, '_>) {
|
||||
pub(crate) fn add_suggestion(&self, mbcx: &mut MirBorrowckCtxt<'_, '_, '_>) {
|
||||
// No constraints to add? Done.
|
||||
if self.constraints_to_add.is_empty() {
|
||||
debug!("No constraints to suggest.");
|
||||
|
@ -156,7 +156,7 @@ pub(crate) struct ErrorConstraintInfo<'tcx> {
|
||||
pub(super) span: Span,
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
/// Converts a region inference variable into a `ty::Region` that
|
||||
/// we can use for error reporting. If `r` is universally bound,
|
||||
/// then we use the name that we have on record for it. If `r` is
|
||||
|
@ -200,7 +200,7 @@ fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
pub(crate) fn mir_def_id(&self) -> hir::def_id::LocalDefId {
|
||||
self.body.source.def_id().expect_local()
|
||||
}
|
||||
|
@ -304,11 +304,11 @@ fn do_mir_borrowck<'tcx>(
|
||||
promoted_mbcx.report_move_errors();
|
||||
diags = promoted_mbcx.diags;
|
||||
|
||||
struct MoveVisitor<'a, 'b, 'mir, 'infcx, 'tcx> {
|
||||
ctxt: &'a mut MirBorrowckCtxt<'b, 'mir, 'infcx, 'tcx>,
|
||||
struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
|
||||
ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, '_, 'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> {
|
||||
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
|
||||
if let Operand::Move(place) = operand {
|
||||
self.ctxt.check_movable_place(location, *place);
|
||||
@ -522,10 +522,10 @@ fn deref(&self) -> &Self::Target {
|
||||
}
|
||||
}
|
||||
|
||||
struct MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx> {
|
||||
struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
|
||||
/// Map from MIR `Location` to `LocationIndex`; created
|
||||
@ -599,16 +599,16 @@ struct MirBorrowckCtxt<'a, 'mir, 'infcx, '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<'a, 'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
for MirBorrowckCtxt<'a, 'mir, '_, 'tcx>
|
||||
impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
|
||||
for MirBorrowckCtxt<'a, '_, 'tcx>
|
||||
{
|
||||
type FlowState = Flows<'a, 'mir, 'tcx>;
|
||||
type FlowState = Flows<'a, 'tcx>;
|
||||
|
||||
fn visit_statement_before_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
stmt: &'mir Statement<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
stmt: &'a Statement<'tcx>,
|
||||
location: Location,
|
||||
) {
|
||||
debug!("MirBorrowckCtxt::process_statement({:?}, {:?}): {:?}", location, stmt, flow_state);
|
||||
@ -677,8 +677,8 @@ fn visit_statement_before_primary_effect(
|
||||
fn visit_terminator_before_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
term: &'mir Terminator<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
term: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
debug!("MirBorrowckCtxt::process_terminator({:?}, {:?}): {:?}", loc, term, flow_state);
|
||||
@ -794,8 +794,8 @@ fn visit_terminator_before_primary_effect(
|
||||
fn visit_terminator_after_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
term: &'mir Terminator<'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
term: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
let span = term.source_info.span;
|
||||
@ -972,8 +972,8 @@ fn as_general_verb_in_past_tense(self) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> MirBorrowckCtxt<'_, 'mir, '_, 'tcx> {
|
||||
fn body(&self) -> &'mir Body<'tcx> {
|
||||
impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
|
||||
fn body(&self) -> &'a Body<'tcx> {
|
||||
self.body
|
||||
}
|
||||
|
||||
@ -989,7 +989,7 @@ fn access_place(
|
||||
place_span: (Place<'tcx>, Span),
|
||||
kind: (AccessDepth, ReadOrWrite),
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let (sd, rw) = kind;
|
||||
|
||||
@ -1039,7 +1039,7 @@ fn check_access_for_conflict(
|
||||
place_span: (Place<'tcx>, Span),
|
||||
sd: AccessDepth,
|
||||
rw: ReadOrWrite,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) -> bool {
|
||||
let mut error_reported = false;
|
||||
let borrow_set = Rc::clone(&self.borrow_set);
|
||||
@ -1180,7 +1180,7 @@ fn mutate_place(
|
||||
location: Location,
|
||||
place_span: (Place<'tcx>, Span),
|
||||
kind: AccessDepth,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
// Write of P[i] or *P requires P init'd.
|
||||
self.check_if_assigned_path_is_moved(location, place_span, flow_state);
|
||||
@ -1197,8 +1197,8 @@ fn mutate_place(
|
||||
fn consume_rvalue(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(rvalue, span): (&'mir Rvalue<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
(rvalue, span): (&'a Rvalue<'tcx>, Span),
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
match rvalue {
|
||||
&Rvalue::Ref(_ /*rgn*/, bk, place) => {
|
||||
@ -1455,8 +1455,8 @@ fn propagate_closure_used_mut_upvar(&mut self, operand: &Operand<'tcx>) {
|
||||
fn consume_operand(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(operand, span): (&'mir Operand<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
(operand, span): (&'a Operand<'tcx>, Span),
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
match *operand {
|
||||
Operand::Copy(place) => {
|
||||
@ -1576,12 +1576,7 @@ fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span
|
||||
}
|
||||
}
|
||||
|
||||
fn check_activations(
|
||||
&mut self,
|
||||
location: Location,
|
||||
span: Span,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
) {
|
||||
fn check_activations(&mut self, location: Location, span: Span, flow_state: &Flows<'a, 'tcx>) {
|
||||
// Two-phase borrow support: For each activation that is newly
|
||||
// generated at this statement, check if it interferes with
|
||||
// another borrow.
|
||||
@ -1744,7 +1739,7 @@ fn check_if_full_path_is_moved(
|
||||
location: Location,
|
||||
desired_action: InitializationRequiringAction,
|
||||
place_span: (PlaceRef<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let maybe_uninits = &flow_state.uninits;
|
||||
|
||||
@ -1849,7 +1844,7 @@ fn check_if_path_or_subpath_is_moved(
|
||||
location: Location,
|
||||
desired_action: InitializationRequiringAction,
|
||||
place_span: (PlaceRef<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
let maybe_uninits = &flow_state.uninits;
|
||||
|
||||
@ -1948,7 +1943,7 @@ fn check_if_assigned_path_is_moved(
|
||||
&mut self,
|
||||
location: Location,
|
||||
(place, span): (Place<'tcx>, Span),
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
debug!("check_if_assigned_path_is_moved place: {:?}", place);
|
||||
|
||||
@ -2009,12 +2004,12 @@ fn check_if_assigned_path_is_moved(
|
||||
}
|
||||
}
|
||||
|
||||
fn check_parent_of_field<'mir, 'tcx>(
|
||||
this: &mut MirBorrowckCtxt<'_, 'mir, '_, 'tcx>,
|
||||
fn check_parent_of_field<'a, 'tcx>(
|
||||
this: &mut MirBorrowckCtxt<'a, '_, 'tcx>,
|
||||
location: Location,
|
||||
base: PlaceRef<'tcx>,
|
||||
span: Span,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) {
|
||||
// rust-lang/rust#21232: Until Rust allows reads from the
|
||||
// initialized parts of partially initialized structs, we
|
||||
@ -2105,7 +2100,7 @@ fn check_access_permissions(
|
||||
(place, span): (Place<'tcx>, Span),
|
||||
kind: ReadOrWrite,
|
||||
is_local_mutation_allowed: LocalMutationIsAllowed,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
location: Location,
|
||||
) -> bool {
|
||||
debug!(
|
||||
@ -2221,7 +2216,7 @@ fn check_access_permissions(
|
||||
fn is_local_ever_initialized(
|
||||
&self,
|
||||
local: Local,
|
||||
flow_state: &Flows<'_, 'mir, 'tcx>,
|
||||
flow_state: &Flows<'a, 'tcx>,
|
||||
) -> Option<InitIndex> {
|
||||
let mpi = self.move_data.rev_lookup.find_local(local)?;
|
||||
let ii = &self.move_data.init_path_map[mpi];
|
||||
@ -2229,7 +2224,7 @@ fn is_local_ever_initialized(
|
||||
}
|
||||
|
||||
/// 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<'a, '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
|
||||
@ -2484,7 +2479,7 @@ pub(crate) fn buffer_non_error(&mut self, diag: Diag<'infcx, ()>) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
|
||||
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||
pub(crate) fn buffer_error(&mut self, diag: Diag<'infcx>) {
|
||||
self.diags.buffer_error(diag);
|
||||
}
|
||||
|
@ -75,14 +75,14 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
|
||||
/// Computes the (non-lexical) regions from the input MIR.
|
||||
///
|
||||
/// This may result in errors being reported.
|
||||
pub(crate) fn compute_regions<'cx, 'tcx>(
|
||||
pub(crate) fn compute_regions<'a, 'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
universal_regions: UniversalRegions<'tcx>,
|
||||
body: &Body<'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<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||
@ -301,13 +301,13 @@ pub(super) fn dump_nll_mir<'tcx>(
|
||||
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
pub(super) fn dump_annotation<'tcx, 'cx>(
|
||||
infcx: &'cx BorrowckInferCtxt<'tcx>,
|
||||
pub(super) fn dump_annotation<'tcx, 'infcx>(
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
regioncx: &RegionInferenceContext<'tcx>,
|
||||
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
|
||||
opaque_type_values: &FxIndexMap<LocalDefId, OpaqueHiddenType<'tcx>>,
|
||||
diags: &mut crate::diags::BorrowckDiags<'cx, 'tcx>,
|
||||
diags: &mut crate::diags::BorrowckDiags<'infcx, 'tcx>,
|
||||
) {
|
||||
let tcx = infcx.tcx;
|
||||
let base_def_id = tcx.typeck_root_def_id(body.source.def_id());
|
||||
|
@ -34,7 +34,7 @@ pub(super) enum PrefixSet {
|
||||
Shallow,
|
||||
}
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
/// Returns an iterator over the prefixes of `place`
|
||||
/// (inclusive) from longest to smallest, potentially
|
||||
/// terminating the iteration early based on `kind`.
|
||||
|
@ -30,11 +30,11 @@
|
||||
///
|
||||
/// N.B., this computation requires normalization; therefore, it must be
|
||||
/// performed before
|
||||
pub(super) fn generate<'mir, 'tcx>(
|
||||
pub(super) fn generate<'a, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
elements: &Rc<DenseLocationMap>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
|
||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
) {
|
||||
debug!("liveness::generate");
|
||||
|
@ -37,11 +37,11 @@
|
||||
/// DROP-LIVE set are to the liveness sets for regions found in the
|
||||
/// `dropck_outlives` result of the variable's type (in particular,
|
||||
/// this respects `#[may_dangle]` annotations).
|
||||
pub(super) fn trace<'mir, 'tcx>(
|
||||
pub(super) fn trace<'a, 'tcx>(
|
||||
typeck: &mut TypeChecker<'_, 'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
elements: &Rc<DenseLocationMap>,
|
||||
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'_, 'mir, 'tcx>>,
|
||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
relevant_live_locals: Vec<Local>,
|
||||
boring_locals: Vec<Local>,
|
||||
@ -99,29 +99,29 @@ pub(super) fn trace<'mir, 'tcx>(
|
||||
}
|
||||
|
||||
/// Contextual state for the type-liveness coroutine.
|
||||
struct LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
struct LivenessContext<'a, 'typeck, 'b, 'tcx> {
|
||||
/// Current type-checker, giving us our inference context etc.
|
||||
typeck: &'me mut TypeChecker<'typeck, 'tcx>,
|
||||
typeck: &'a mut TypeChecker<'typeck, 'tcx>,
|
||||
|
||||
/// Defines the `PointIndex` mapping
|
||||
elements: &'me DenseLocationMap,
|
||||
elements: &'a DenseLocationMap,
|
||||
|
||||
/// MIR we are analyzing.
|
||||
body: &'me Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
|
||||
/// Mapping to/from the various indices used for initialization tracking.
|
||||
move_data: &'me MoveData<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
|
||||
/// Cache for the results of `dropck_outlives` query.
|
||||
drop_data: FxIndexMap<Ty<'tcx>, DropData<'tcx>>,
|
||||
|
||||
/// Results of dataflow tracking which variables (and paths) have been
|
||||
/// initialized.
|
||||
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'a, 'flow, 'tcx>>,
|
||||
flow_inits: &'a mut ResultsCursor<'b, 'tcx, MaybeInitializedPlaces<'b, 'tcx>>,
|
||||
|
||||
/// Index indicating where each variable is assigned, used, or
|
||||
/// dropped.
|
||||
local_use_map: &'me LocalUseMap,
|
||||
local_use_map: &'a LocalUseMap,
|
||||
}
|
||||
|
||||
struct DropData<'tcx> {
|
||||
@ -129,8 +129,8 @@ struct DropData<'tcx> {
|
||||
region_constraint_data: Option<&'tcx QueryRegionConstraints<'tcx>>,
|
||||
}
|
||||
|
||||
struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>,
|
||||
struct LivenessResults<'a, 'typeck, 'b, 'tcx> {
|
||||
cx: LivenessContext<'a, 'typeck, 'b, 'tcx>,
|
||||
|
||||
/// Set of points that define the current local.
|
||||
defs: BitSet<PointIndex>,
|
||||
@ -151,8 +151,8 @@ struct LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
stack: Vec<PointIndex>,
|
||||
}
|
||||
|
||||
impl<'a, 'me, 'typeck, 'flow, 'tcx> LivenessResults<'a, 'me, 'typeck, 'flow, 'tcx> {
|
||||
fn new(cx: LivenessContext<'a, 'me, 'typeck, 'flow, 'tcx>) -> Self {
|
||||
impl<'a, 'typeck, 'b, 'tcx> LivenessResults<'a, 'typeck, 'b, 'tcx> {
|
||||
fn new(cx: LivenessContext<'a, 'typeck, 'b, 'tcx>) -> Self {
|
||||
let num_points = cx.elements.num_points();
|
||||
LivenessResults {
|
||||
cx,
|
||||
@ -505,7 +505,7 @@ fn compute_drop_live_points_for_block(&mut self, mpi: MovePathIndex, term_point:
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -116,7 +116,7 @@ macro_rules! span_mirbug_and_err {
|
||||
/// - `flow_inits` -- results of a maybe-init dataflow analysis
|
||||
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
|
||||
/// - `elements` -- MIR region map
|
||||
pub(crate) fn type_check<'mir, 'tcx>(
|
||||
pub(crate) fn type_check<'a, 'tcx>(
|
||||
infcx: &BorrowckInferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
@ -125,7 +125,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<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
elements: &Rc<DenseLocationMap>,
|
||||
upvars: &[&ty::CapturedPlace<'tcx>],
|
||||
|
@ -423,8 +423,8 @@ pub(crate) fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
|
||||
}
|
||||
}
|
||||
|
||||
struct UniversalRegionsBuilder<'cx, 'tcx> {
|
||||
infcx: &'cx BorrowckInferCtxt<'tcx>,
|
||||
struct UniversalRegionsBuilder<'infcx, 'tcx> {
|
||||
infcx: &'infcx BorrowckInferCtxt<'tcx>,
|
||||
mir_def: LocalDefId,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
use crate::MirBorrowckCtxt;
|
||||
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
|
||||
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
|
||||
/// Walks the MIR adding to the set of `used_mut` locals that will be ignored for the purposes
|
||||
/// of the `unused_mut` lint.
|
||||
///
|
||||
@ -46,13 +46,13 @@ pub(crate) fn gather_used_muts(
|
||||
|
||||
/// MIR visitor for collecting used mutable variables.
|
||||
/// The 'visit lifetime represents the duration of the MIR walk.
|
||||
struct GatherUsedMutsVisitor<'visit, 'a, 'mir, 'infcx, 'tcx> {
|
||||
struct GatherUsedMutsVisitor<'a, 'b, 'infcx, 'tcx> {
|
||||
temporary_used_locals: FxIndexSet<Local>,
|
||||
never_initialized_mut_locals: &'visit mut FxIndexSet<Local>,
|
||||
mbcx: &'visit mut MirBorrowckCtxt<'a, 'mir, 'infcx, 'tcx>,
|
||||
never_initialized_mut_locals: &'a mut FxIndexSet<Local>,
|
||||
mbcx: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
|
||||
}
|
||||
|
||||
impl GatherUsedMutsVisitor<'_, '_, '_, '_, '_> {
|
||||
impl GatherUsedMutsVisitor<'_, '_, '_, '_> {
|
||||
fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
|
||||
// Remove any locals that we found were initialized from the
|
||||
// `never_initialized_mut_locals` set. At the end, the only remaining locals will
|
||||
@ -64,7 +64,7 @@ fn remove_never_initialized_mut_locals(&mut self, into: Place<'_>) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, '_, 'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'_, '_, '_, 'tcx> {
|
||||
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
|
||||
debug!("visit_terminator: terminator={:?}", terminator);
|
||||
match &terminator.kind {
|
||||
|
@ -51,15 +51,15 @@
|
||||
/// 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, 'mir, 'tcx> {
|
||||
pub struct MaybeInitializedPlaces<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
skip_unreachable_unwind: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
MaybeInitializedPlaces { tcx, body, move_data, skip_unreachable_unwind: false }
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ pub fn is_unwind_dead(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
self.move_data
|
||||
}
|
||||
@ -126,17 +126,17 @@ fn move_data(&self) -> &MoveData<'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, 'mir, 'tcx> {
|
||||
pub struct MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
|
||||
mark_inactive_variants_as_uninit: bool,
|
||||
skip_unreachable_unwind: BitSet<mir::BasicBlock>,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeUninitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
MaybeUninitializedPlaces {
|
||||
tcx,
|
||||
body,
|
||||
@ -165,7 +165,7 @@ pub fn skipping_unreachable_unwind(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, '_, 'tcx> {
|
||||
impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
self.move_data
|
||||
}
|
||||
@ -251,24 +251,24 @@ fn move_data(&self) -> &MoveData<'tcx> {
|
||||
/// c = S; // {a, b, c, d }
|
||||
/// }
|
||||
/// ```
|
||||
pub struct EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
body: &'mir Body<'tcx>,
|
||||
pub struct EverInitializedPlaces<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
move_data: &'a MoveData<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> EverInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
pub fn new(body: &'mir Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
|
||||
pub fn new(body: &'a Body<'tcx>, move_data: &'a MoveData<'tcx>) -> Self {
|
||||
EverInitializedPlaces { body, move_data }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, '_, 'tcx> {
|
||||
impl<'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
||||
fn move_data(&self) -> &MoveData<'tcx> {
|
||||
self.move_data
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'mir, 'tcx> MaybeInitializedPlaces<'a, 'mir, 'tcx> {
|
||||
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
|
||||
fn update_bits(
|
||||
trans: &mut impl GenKill<MovePathIndex>,
|
||||
path: MovePathIndex,
|
||||
@ -281,7 +281,7 @@ fn update_bits(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, '_, 'tcx> {
|
||||
impl<'tcx> MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
fn update_bits(
|
||||
trans: &mut impl GenKill<MovePathIndex>,
|
||||
path: MovePathIndex,
|
||||
@ -307,7 +307,7 @@ fn update_bits(
|
||||
}
|
||||
}
|
||||
|
||||
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>>;
|
||||
@ -329,7 +329,7 @@ fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, '_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
@ -442,7 +442,7 @@ fn switch_int_edge_effects<G: GenKill<Self::Idx>>(
|
||||
}
|
||||
}
|
||||
|
||||
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>;
|
||||
@ -466,7 +466,7 @@ fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, '_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
||||
type Idx = MovePathIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
@ -643,7 +643,7 @@ fn call_return_effect(
|
||||
}
|
||||
}
|
||||
|
||||
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>;
|
||||
@ -662,7 +662,7 @@ fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domai
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, '_, 'tcx> {
|
||||
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
||||
type Idx = InitIndex;
|
||||
|
||||
fn domain_size(&self, _: &Body<'tcx>) -> usize {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
struct MoveDataBuilder<'a, 'tcx, F> {
|
||||
body: &'a Body<'tcx>,
|
||||
loc: Location,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
data: MoveData<'tcx>,
|
||||
@ -56,6 +57,7 @@ fn new(
|
||||
|
||||
MoveDataBuilder {
|
||||
body,
|
||||
loc: Location::START,
|
||||
tcx,
|
||||
param_env,
|
||||
data: MoveData {
|
||||
@ -107,7 +109,7 @@ enum MovePathResult {
|
||||
Error,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
impl<'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> MoveDataBuilder<'a, 'tcx, F> {
|
||||
/// This creates a MovePath for a given place, returning an `MovePathError`
|
||||
/// if that place can't be moved from.
|
||||
///
|
||||
@ -116,7 +118,7 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
///
|
||||
/// Maybe we should have separate "borrowck" and "moveck" modes.
|
||||
fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
|
||||
let data = &mut self.builder.data;
|
||||
let data = &mut self.data;
|
||||
|
||||
debug!("lookup({:?})", place);
|
||||
let Some(mut base) = data.rev_lookup.find_local(place.local) else {
|
||||
@ -131,8 +133,8 @@ fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
|
||||
let mut union_path = None;
|
||||
|
||||
for (place_ref, elem) in data.rev_lookup.un_derefer.iter_projections(place.as_ref()) {
|
||||
let body = self.builder.body;
|
||||
let tcx = self.builder.tcx;
|
||||
let body = self.body;
|
||||
let tcx = self.tcx;
|
||||
let place_ty = place_ref.ty(body, tcx).ty;
|
||||
if place_ty.references_error() {
|
||||
return MovePathResult::Error;
|
||||
@ -238,7 +240,7 @@ fn move_path_for(&mut self, place: Place<'tcx>) -> MovePathResult {
|
||||
| ProjectionElem::Downcast(_, _) => (),
|
||||
}
|
||||
let elem_ty = PlaceTy::from_ty(place_ty).projection_ty(tcx, elem).ty;
|
||||
if !(self.builder.filter)(elem_ty) {
|
||||
if !(self.filter)(elem_ty) {
|
||||
return MovePathResult::Error;
|
||||
}
|
||||
if union_path.is_none() {
|
||||
@ -274,7 +276,7 @@ fn add_move_path(
|
||||
data: MoveData { rev_lookup, move_paths, path_map, init_path_map, .. },
|
||||
tcx,
|
||||
..
|
||||
} = self.builder;
|
||||
} = self;
|
||||
*rev_lookup.projections.entry((base, elem.lift())).or_insert_with(move || {
|
||||
new_move_path(move_paths, path_map, init_path_map, Some(base), mk_place(*tcx))
|
||||
})
|
||||
@ -285,9 +287,7 @@ fn create_move_path(&mut self, place: Place<'tcx>) {
|
||||
// drop), so this not being a valid move path is OK.
|
||||
let _ = self.move_path_for(place);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx, F> MoveDataBuilder<'a, 'tcx, F> {
|
||||
fn finalize(self) -> MoveData<'tcx> {
|
||||
debug!("{}", {
|
||||
debug!("moves for {:?}:", self.body.span);
|
||||
@ -317,12 +317,12 @@ pub(super) fn gather_moves<'tcx>(
|
||||
|
||||
for (bb, block) in body.basic_blocks.iter_enumerated() {
|
||||
for (i, stmt) in block.statements.iter().enumerate() {
|
||||
let source = Location { block: bb, statement_index: i };
|
||||
builder.gather_statement(source, stmt);
|
||||
builder.loc = Location { block: bb, statement_index: i };
|
||||
builder.gather_statement(stmt);
|
||||
}
|
||||
|
||||
let terminator_loc = Location { block: bb, statement_index: block.statements.len() };
|
||||
builder.gather_terminator(terminator_loc, block.terminator());
|
||||
builder.loc = Location { block: bb, statement_index: block.statements.len() };
|
||||
builder.gather_terminator(block.terminator());
|
||||
}
|
||||
|
||||
builder.finalize()
|
||||
@ -345,30 +345,14 @@ fn gather_args(&mut self) {
|
||||
}
|
||||
}
|
||||
|
||||
fn gather_statement(&mut self, loc: Location, stmt: &Statement<'tcx>) {
|
||||
debug!("gather_statement({:?}, {:?})", loc, stmt);
|
||||
(Gatherer { builder: self, loc }).gather_statement(stmt);
|
||||
}
|
||||
|
||||
fn gather_terminator(&mut self, loc: Location, term: &Terminator<'tcx>) {
|
||||
debug!("gather_terminator({:?}, {:?})", loc, term);
|
||||
(Gatherer { builder: self, loc }).gather_terminator(term);
|
||||
}
|
||||
}
|
||||
|
||||
struct Gatherer<'b, 'a, 'tcx, F> {
|
||||
builder: &'b mut MoveDataBuilder<'a, 'tcx, F>,
|
||||
loc: Location,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
|
||||
fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||
debug!("gather_statement({:?}, {:?})", self.loc, stmt);
|
||||
match &stmt.kind {
|
||||
StatementKind::Assign(box (place, Rvalue::CopyForDeref(reffed))) => {
|
||||
let local = place.as_local().unwrap();
|
||||
assert!(self.builder.body.local_decls[local].is_deref_temp());
|
||||
assert!(self.body.local_decls[local].is_deref_temp());
|
||||
|
||||
let rev_lookup = &mut self.builder.data.rev_lookup;
|
||||
let rev_lookup = &mut self.data.rev_lookup;
|
||||
|
||||
rev_lookup.un_derefer.insert(local, reffed.as_ref());
|
||||
let base_local = rev_lookup.un_derefer.deref_chain(local).first().unwrap().local;
|
||||
@ -380,7 +364,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||
// Box starts out uninitialized - need to create a separate
|
||||
// move-path for the interior so it will be separate from
|
||||
// the exterior.
|
||||
self.create_move_path(self.builder.tcx.mk_place_deref(*place));
|
||||
self.create_move_path(self.tcx.mk_place_deref(*place));
|
||||
self.gather_init(place.as_ref(), InitKind::Shallow);
|
||||
} else {
|
||||
self.gather_init(place.as_ref(), InitKind::Deep);
|
||||
@ -393,7 +377,7 @@ fn gather_statement(&mut self, stmt: &Statement<'tcx>) {
|
||||
StatementKind::StorageLive(_) => {}
|
||||
StatementKind::StorageDead(local) => {
|
||||
// DerefTemp locals (results of CopyForDeref) don't actually move anything.
|
||||
if !self.builder.body.local_decls[*local].is_deref_temp() {
|
||||
if !self.body.local_decls[*local].is_deref_temp() {
|
||||
self.gather_move(Place::from(*local));
|
||||
}
|
||||
}
|
||||
@ -443,6 +427,7 @@ fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
|
||||
}
|
||||
|
||||
fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
|
||||
debug!("gather_terminator({:?}, {:?})", self.loc, term);
|
||||
match term.kind {
|
||||
TerminatorKind::Goto { target: _ }
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
@ -551,7 +536,7 @@ fn gather_move(&mut self, place: Place<'tcx>) {
|
||||
// `ConstIndex` patterns. This is done to ensure that all move paths
|
||||
// are disjoint, which is expected by drop elaboration.
|
||||
let base_place =
|
||||
Place { local: place.local, projection: self.builder.tcx.mk_place_elems(base) };
|
||||
Place { local: place.local, projection: self.tcx.mk_place_elems(base) };
|
||||
let base_path = match self.move_path_for(base_place) {
|
||||
MovePathResult::Path(path) => path,
|
||||
MovePathResult::Union(path) => {
|
||||
@ -562,11 +547,9 @@ fn gather_move(&mut self, place: Place<'tcx>) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
let base_ty = base_place.ty(self.builder.body, self.builder.tcx).ty;
|
||||
let base_ty = base_place.ty(self.body, self.tcx).ty;
|
||||
let len: u64 = match base_ty.kind() {
|
||||
ty::Array(_, size) => {
|
||||
size.eval_target_usize(self.builder.tcx, self.builder.param_env)
|
||||
}
|
||||
ty::Array(_, size) => size.eval_target_usize(self.tcx, self.param_env),
|
||||
_ => bug!("from_end: false slice pattern of non-array type"),
|
||||
};
|
||||
for offset in from..to {
|
||||
@ -587,13 +570,13 @@ fn gather_move(&mut self, place: Place<'tcx>) {
|
||||
}
|
||||
|
||||
fn record_move(&mut self, place: Place<'tcx>, path: MovePathIndex) {
|
||||
let move_out = self.builder.data.moves.push(MoveOut { path, source: self.loc });
|
||||
let move_out = self.data.moves.push(MoveOut { path, source: self.loc });
|
||||
debug!(
|
||||
"gather_move({:?}, {:?}): adding move {:?} of {:?}",
|
||||
self.loc, place, move_out, path
|
||||
);
|
||||
self.builder.data.path_map[path].push(move_out);
|
||||
self.builder.data.loc_map[self.loc].push(move_out);
|
||||
self.data.path_map[path].push(move_out);
|
||||
self.data.loc_map[self.loc].push(move_out);
|
||||
}
|
||||
|
||||
fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
|
||||
@ -604,13 +587,13 @@ fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
|
||||
// Check if we are assigning into a field of a union, if so, lookup the place
|
||||
// of the union so it is marked as initialized again.
|
||||
if let Some((place_base, ProjectionElem::Field(_, _))) = place.last_projection() {
|
||||
if place_base.ty(self.builder.body, self.builder.tcx).ty.is_union() {
|
||||
if place_base.ty(self.body, self.tcx).ty.is_union() {
|
||||
place = place_base;
|
||||
}
|
||||
}
|
||||
|
||||
if let LookupResult::Exact(path) = self.builder.data.rev_lookup.find(place) {
|
||||
let init = self.builder.data.inits.push(Init {
|
||||
if let LookupResult::Exact(path) = self.data.rev_lookup.find(place) {
|
||||
let init = self.data.inits.push(Init {
|
||||
location: InitLocation::Statement(self.loc),
|
||||
path,
|
||||
kind,
|
||||
@ -621,8 +604,8 @@ fn gather_init(&mut self, place: PlaceRef<'tcx>, kind: InitKind) {
|
||||
self.loc, place, init, path
|
||||
);
|
||||
|
||||
self.builder.data.init_path_map[path].push(init);
|
||||
self.builder.data.init_loc_map[self.loc].push(init);
|
||||
self.data.init_path_map[path].push(init);
|
||||
self.data.init_loc_map[self.loc].push(init);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -923,14 +923,14 @@ fn cache_preorder_invoke(&mut self, root: PlaceIndex) {
|
||||
}
|
||||
}
|
||||
|
||||
struct PlaceCollector<'a, 'b, 'tcx> {
|
||||
struct PlaceCollector<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'b Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
map: &'a mut Map<'tcx>,
|
||||
assignments: FxIndexSet<(PlaceIndex, PlaceIndex)>,
|
||||
}
|
||||
|
||||
impl<'tcx> PlaceCollector<'_, '_, 'tcx> {
|
||||
impl<'tcx> PlaceCollector<'_, 'tcx> {
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
fn register_place(&mut self, place: Place<'tcx>) -> Option<PlaceIndex> {
|
||||
// Create a place for this projection.
|
||||
@ -967,7 +967,7 @@ fn register_place(&mut self, place: Place<'tcx>) -> Option<PlaceIndex> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for PlaceCollector<'_, '_, 'tcx> {
|
||||
impl<'tcx> Visitor<'tcx> for PlaceCollector<'_, 'tcx> {
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, _: Location) {
|
||||
if !ctxt.is_use() {
|
||||
|
@ -872,9 +872,9 @@ fn compute_storage_conflicts<'mir, 'tcx>(
|
||||
storage_conflicts
|
||||
}
|
||||
|
||||
struct StorageConflictVisitor<'mir, 'tcx, 's> {
|
||||
body: &'mir Body<'tcx>,
|
||||
saved_locals: &'s CoroutineSavedLocals,
|
||||
struct StorageConflictVisitor<'a, 'tcx> {
|
||||
body: &'a Body<'tcx>,
|
||||
saved_locals: &'a CoroutineSavedLocals,
|
||||
// FIXME(tmandry): Consider using sparse bitsets here once we have good
|
||||
// benchmarks for coroutines.
|
||||
local_conflicts: BitMatrix<Local, Local>,
|
||||
@ -882,8 +882,8 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> {
|
||||
eligible_storage_live: BitSet<Local>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R>
|
||||
for StorageConflictVisitor<'mir, 'tcx, '_>
|
||||
impl<'a, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'a, 'tcx, R>
|
||||
for StorageConflictVisitor<'a, 'tcx>
|
||||
{
|
||||
type FlowState = BitSet<Local>;
|
||||
|
||||
@ -891,7 +891,7 @@ fn visit_statement_before_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
state: &Self::FlowState,
|
||||
_statement: &'mir Statement<'tcx>,
|
||||
_statement: &'a Statement<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
self.apply_state(state, loc);
|
||||
@ -901,14 +901,14 @@ fn visit_terminator_before_primary_effect(
|
||||
&mut self,
|
||||
_results: &mut R,
|
||||
state: &Self::FlowState,
|
||||
_terminator: &'mir Terminator<'tcx>,
|
||||
_terminator: &'a Terminator<'tcx>,
|
||||
loc: Location,
|
||||
) {
|
||||
self.apply_state(state, loc);
|
||||
}
|
||||
}
|
||||
|
||||
impl StorageConflictVisitor<'_, '_, '_> {
|
||||
impl StorageConflictVisitor<'_, '_> {
|
||||
fn apply_state(&mut self, flow_state: &BitSet<Local>, loc: Location) {
|
||||
// Ignore unreachable blocks.
|
||||
if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind {
|
||||
|
@ -838,14 +838,14 @@ fn process_projection_elem(
|
||||
}
|
||||
}
|
||||
|
||||
struct OperandCollector<'tcx, 'map, 'locals, 'a> {
|
||||
struct OperandCollector<'a, 'locals, 'tcx> {
|
||||
state: &'a State<FlatSet<Scalar>>,
|
||||
visitor: &'a mut Collector<'tcx, 'locals>,
|
||||
ecx: &'map mut InterpCx<'tcx, DummyMachine>,
|
||||
map: &'map Map<'tcx>,
|
||||
ecx: &'a mut InterpCx<'tcx, DummyMachine>,
|
||||
map: &'a Map<'tcx>,
|
||||
}
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
|
||||
impl<'tcx> Visitor<'tcx> for OperandCollector<'_, '_, 'tcx> {
|
||||
fn visit_projection_elem(
|
||||
&mut self,
|
||||
_: PlaceRef<'tcx>,
|
||||
|
@ -98,9 +98,9 @@ fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||
/// Records unwind edges which are known to be unreachable, because they are in `drop` terminators
|
||||
/// that can't drop anything.
|
||||
#[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>>,
|
||||
fn compute_dead_unwinds<'a, 'tcx>(
|
||||
body: &'a Body<'tcx>,
|
||||
flow_inits: &mut ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, '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.
|
||||
@ -121,12 +121,12 @@ fn compute_dead_unwinds<'mir, 'tcx>(
|
||||
dead_unwinds
|
||||
}
|
||||
|
||||
struct InitializationData<'a, 'mir, 'tcx> {
|
||||
inits: ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
uninits: ResultsCursor<'mir, 'tcx, MaybeUninitializedPlaces<'a, 'mir, 'tcx>>,
|
||||
struct InitializationData<'a, 'tcx> {
|
||||
inits: ResultsCursor<'a, 'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
|
||||
uninits: ResultsCursor<'a, 'tcx, MaybeUninitializedPlaces<'a, '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);
|
||||
@ -137,45 +137,35 @@ fn maybe_live_dead(&self, path: MovePathIndex) -> (bool, bool) {
|
||||
}
|
||||
}
|
||||
|
||||
struct Elaborator<'a, 'b, 'mir, 'tcx> {
|
||||
ctxt: &'a mut ElaborateDropsCtxt<'b, 'mir, 'tcx>,
|
||||
}
|
||||
|
||||
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 ElaborateDropsCtxt<'a, 'tcx> {
|
||||
type Path = MovePathIndex;
|
||||
|
||||
fn patch(&mut self) -> &mut MirPatch<'tcx> {
|
||||
&mut self.ctxt.patch
|
||||
&mut self.patch
|
||||
}
|
||||
|
||||
fn body(&self) -> &'a Body<'tcx> {
|
||||
self.ctxt.body
|
||||
self.body
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.ctxt.tcx
|
||||
self.tcx
|
||||
}
|
||||
|
||||
fn param_env(&self) -> ty::ParamEnv<'tcx> {
|
||||
self.ctxt.param_env()
|
||||
self.param_env()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
|
||||
let ((maybe_live, maybe_dead), multipart) = match mode {
|
||||
DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false),
|
||||
DropFlagMode::Shallow => (self.init_data.maybe_live_dead(path), false),
|
||||
DropFlagMode::Deep => {
|
||||
let mut some_live = false;
|
||||
let mut some_dead = false;
|
||||
let mut children_count = 0;
|
||||
on_all_children_bits(self.ctxt.move_data(), path, |child| {
|
||||
let (live, dead) = self.ctxt.init_data.maybe_live_dead(child);
|
||||
on_all_children_bits(self.move_data(), path, |child| {
|
||||
let (live, dead) = self.init_data.maybe_live_dead(child);
|
||||
debug!("elaborate_drop: state({:?}) = {:?}", child, (live, dead));
|
||||
some_live |= live;
|
||||
some_dead |= dead;
|
||||
@ -195,25 +185,25 @@ fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
|
||||
fn clear_drop_flag(&mut self, loc: Location, path: Self::Path, mode: DropFlagMode) {
|
||||
match mode {
|
||||
DropFlagMode::Shallow => {
|
||||
self.ctxt.set_drop_flag(loc, path, DropFlagState::Absent);
|
||||
self.set_drop_flag(loc, path, DropFlagState::Absent);
|
||||
}
|
||||
DropFlagMode::Deep => {
|
||||
on_all_children_bits(self.ctxt.move_data(), path, |child| {
|
||||
self.ctxt.set_drop_flag(loc, child, DropFlagState::Absent)
|
||||
on_all_children_bits(self.move_data(), path, |child| {
|
||||
self.set_drop_flag(loc, child, DropFlagState::Absent)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn field_subpath(&self, path: Self::Path, field: FieldIdx) -> Option<Self::Path> {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
|
||||
ProjectionElem::Field(idx, _) => idx == field,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option<Self::Path> {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
|
||||
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
|
||||
debug_assert!(size == min_length, "min_length should be exact for arrays");
|
||||
assert!(!from_end, "from_end should not be used for array element ConstantIndex");
|
||||
@ -224,34 +214,40 @@ fn array_subpath(&self, path: Self::Path, index: u64, size: u64) -> Option<Self:
|
||||
}
|
||||
|
||||
fn deref_subpath(&self, path: Self::Path) -> Option<Self::Path> {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| {
|
||||
e == ProjectionElem::Deref
|
||||
})
|
||||
}
|
||||
|
||||
fn downcast_subpath(&self, path: Self::Path, variant: VariantIdx) -> Option<Self::Path> {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.ctxt.move_data(), path, |e| match e {
|
||||
rustc_mir_dataflow::move_path_children_matching(self.move_data(), path, |e| match e {
|
||||
ProjectionElem::Downcast(_, idx) => idx == variant,
|
||||
_ => false,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_drop_flag(&mut self, path: Self::Path) -> Option<Operand<'tcx>> {
|
||||
self.ctxt.drop_flag(path).map(Operand::Copy)
|
||||
self.drop_flag(path).map(Operand::Copy)
|
||||
}
|
||||
}
|
||||
|
||||
struct ElaborateDropsCtxt<'a, 'mir, 'tcx> {
|
||||
struct ElaborateDropsCtxt<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir Body<'tcx>,
|
||||
body: &'a Body<'tcx>,
|
||||
env: &'a MoveDataParamEnv<'tcx>,
|
||||
init_data: InitializationData<'a, 'mir, 'tcx>,
|
||||
init_data: InitializationData<'a, 'tcx>,
|
||||
drop_flags: IndexVec<MovePathIndex, Option<Local>>,
|
||||
patch: MirPatch<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'mir, 'tcx> ElaborateDropsCtxt<'b, 'mir, 'tcx> {
|
||||
fn move_data(&self) -> &'b MoveData<'tcx> {
|
||||
impl fmt::Debug for ElaborateDropsCtxt<'_, '_> {
|
||||
fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
|
||||
fn move_data(&self) -> &'a MoveData<'tcx> {
|
||||
&self.env.move_data
|
||||
}
|
||||
|
||||
@ -370,15 +366,7 @@ fn elaborate_drops(&mut self) {
|
||||
}
|
||||
};
|
||||
self.init_data.seek_before(self.body.terminator_loc(bb));
|
||||
elaborate_drop(
|
||||
&mut Elaborator { ctxt: self },
|
||||
terminator.source_info,
|
||||
place,
|
||||
path,
|
||||
target,
|
||||
unwind,
|
||||
bb,
|
||||
)
|
||||
elaborate_drop(self, terminator.source_info, place, path, target, unwind, bb)
|
||||
}
|
||||
LookupResult::Parent(None) => {}
|
||||
LookupResult::Parent(Some(_)) => {
|
||||
|
Loading…
Reference in New Issue
Block a user