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:
Matthias Krüger 2024-09-09 20:20:17 +02:00 committed by GitHub
commit ee8fd33f60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 209 additions and 248 deletions

View File

@ -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()
}

View File

@ -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))
}
}

View File

@ -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>>,

View File

@ -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(

View File

@ -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,

View File

@ -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,

View File

@ -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 {

View File

@ -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>,

View File

@ -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.");

View File

@ -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

View File

@ -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()
}

View File

@ -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);
}

View File

@ -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());

View File

@ -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`.

View File

@ -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");

View File

@ -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.

View File

@ -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>],

View File

@ -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>,
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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);
}
}
}

View File

@ -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() {

View File

@ -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 {

View File

@ -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>,

View File

@ -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(_)) => {