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