summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_dataflow/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-19 09:26:03 +0000
commit9918693037dce8aa4bb6f08741b6812923486c18 (patch)
tree21d2b40bec7e6a7ea664acee056eb3d08e15a1cf /compiler/rustc_mir_dataflow/src
parentReleasing progress-linux version 1.75.0+dfsg1-5~progress7.99u1. (diff)
downloadrustc-9918693037dce8aa4bb6f08741b6812923486c18.tar.xz
rustc-9918693037dce8aa4bb6f08741b6812923486c18.zip
Merging upstream version 1.76.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_mir_dataflow/src')
-rw-r--r--compiler/rustc_mir_dataflow/src/drop_flag_effects.rs45
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs14
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/cursor.rs108
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/direction.rs22
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/engine.rs140
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/graphviz.rs67
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/lattice.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/mod.rs40
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/tests.rs5
-rw-r--r--compiler/rustc_mir_dataflow/src/framework/visitor.rs29
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs55
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs3
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs45
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs36
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/rustc_peek.rs47
-rw-r--r--compiler/rustc_mir_dataflow/src/un_derefer.rs8
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs41
19 files changed, 236 insertions, 475 deletions
diff --git a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
index 163d74cc9..de1ca8d82 100644
--- a/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
+++ b/compiler/rustc_mir_dataflow/src/drop_flag_effects.rs
@@ -1,10 +1,8 @@
use crate::elaborate_drops::DropFlagState;
use rustc_middle::mir::{self, Body, Location, Terminator, TerminatorKind};
-use rustc_middle::ty::TyCtxt;
use rustc_target::abi::VariantIdx;
-use super::indexes::MovePathIndex;
-use super::move_paths::{InitKind, LookupResult, MoveData};
+use super::move_paths::{InitKind, LookupResult, MoveData, MovePathIndex};
use super::MoveDataParamEnv;
pub fn move_path_children_matching<'tcx, F>(
@@ -30,8 +28,6 @@ where
}
pub fn on_lookup_result_bits<'tcx, F>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
move_data: &MoveData<'tcx>,
lookup_result: LookupResult,
each_child: F,
@@ -42,13 +38,11 @@ pub fn on_lookup_result_bits<'tcx, F>(
LookupResult::Parent(..) => {
// access to untracked value - do not touch children
}
- LookupResult::Exact(e) => on_all_children_bits(tcx, body, move_data, e, each_child),
+ LookupResult::Exact(e) => on_all_children_bits(move_data, e, each_child),
}
}
pub fn on_all_children_bits<'tcx, F>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
move_data: &MoveData<'tcx>,
move_path_index: MovePathIndex,
mut each_child: F,
@@ -56,8 +50,6 @@ pub fn on_all_children_bits<'tcx, F>(
F: FnMut(MovePathIndex),
{
fn on_all_children_bits<'tcx, F>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
move_data: &MoveData<'tcx>,
move_path_index: MovePathIndex,
each_child: &mut F,
@@ -68,15 +60,14 @@ pub fn on_all_children_bits<'tcx, F>(
let mut next_child_index = move_data.move_paths[move_path_index].first_child;
while let Some(child_index) = next_child_index {
- on_all_children_bits(tcx, body, move_data, child_index, each_child);
+ on_all_children_bits(move_data, child_index, each_child);
next_child_index = move_data.move_paths[child_index].next_sibling;
}
}
- on_all_children_bits(tcx, body, move_data, move_path_index, &mut each_child);
+ on_all_children_bits(move_data, move_path_index, &mut each_child);
}
pub fn drop_flag_effects_for_function_entry<'tcx, F>(
- tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
ctxt: &MoveDataParamEnv<'tcx>,
mut callback: F,
@@ -87,14 +78,13 @@ pub fn drop_flag_effects_for_function_entry<'tcx, F>(
for arg in body.args_iter() {
let place = mir::Place::from(arg);
let lookup_result = move_data.rev_lookup.find(place.as_ref());
- on_lookup_result_bits(tcx, body, move_data, lookup_result, |mpi| {
+ on_lookup_result_bits(move_data, lookup_result, |mpi| {
callback(mpi, DropFlagState::Present)
});
}
}
pub fn drop_flag_effects_for_location<'tcx, F>(
- tcx: TyCtxt<'tcx>,
body: &Body<'tcx>,
ctxt: &MoveDataParamEnv<'tcx>,
loc: Location,
@@ -110,7 +100,7 @@ pub fn drop_flag_effects_for_location<'tcx, F>(
let path = mi.move_path_index(move_data);
debug!("moving out of path {:?}", move_data.move_paths[path]);
- on_all_children_bits(tcx, body, move_data, path, |mpi| callback(mpi, DropFlagState::Absent))
+ on_all_children_bits(move_data, path, |mpi| callback(mpi, DropFlagState::Absent))
}
// Drop does not count as a move but we should still consider the variable uninitialized.
@@ -118,24 +108,17 @@ pub fn drop_flag_effects_for_location<'tcx, F>(
body.stmt_at(loc).right()
{
if let LookupResult::Exact(mpi) = move_data.rev_lookup.find(place.as_ref()) {
- on_all_children_bits(tcx, body, move_data, mpi, |mpi| {
- callback(mpi, DropFlagState::Absent)
- })
+ on_all_children_bits(move_data, mpi, |mpi| callback(mpi, DropFlagState::Absent))
}
}
debug!("drop_flag_effects: assignment for location({:?})", loc);
- for_location_inits(tcx, body, move_data, loc, |mpi| callback(mpi, DropFlagState::Present));
+ for_location_inits(move_data, loc, |mpi| callback(mpi, DropFlagState::Present));
}
-pub fn for_location_inits<'tcx, F>(
- tcx: TyCtxt<'tcx>,
- body: &Body<'tcx>,
- move_data: &MoveData<'tcx>,
- loc: Location,
- mut callback: F,
-) where
+fn for_location_inits<'tcx, F>(move_data: &MoveData<'tcx>, loc: Location, mut callback: F)
+where
F: FnMut(MovePathIndex),
{
for ii in &move_data.init_loc_map[loc] {
@@ -144,7 +127,7 @@ pub fn for_location_inits<'tcx, F>(
InitKind::Deep => {
let path = init.path;
- on_all_children_bits(tcx, body, move_data, path, &mut callback)
+ on_all_children_bits(move_data, path, &mut callback)
}
InitKind::Shallow => {
let mpi = init.path;
@@ -161,8 +144,6 @@ pub fn for_location_inits<'tcx, F>(
/// NOTE: If there are no move paths corresponding to an inactive variant,
/// `handle_inactive_variant` will not be called for that variant.
pub(crate) fn on_all_inactive_variants<'tcx>(
- tcx: TyCtxt<'tcx>,
- body: &mir::Body<'tcx>,
move_data: &MoveData<'tcx>,
enum_place: mir::Place<'tcx>,
active_variant: VariantIdx,
@@ -185,9 +166,7 @@ pub(crate) fn on_all_inactive_variants<'tcx>(
};
if variant_idx != active_variant {
- on_all_children_bits(tcx, body, move_data, variant_mpi, |mpi| {
- handle_inactive_variant(mpi)
- });
+ on_all_children_bits(move_data, variant_mpi, |mpi| handle_inactive_variant(mpi));
}
}
}
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 25ba67a63..958fa0d17 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -481,12 +481,8 @@ where
) -> (BasicBlock, Unwind) {
let (succ, unwind) = self.drop_ladder_bottom();
if !adt.is_enum() {
- let fields = self.move_paths_for_fields(
- self.place,
- self.path,
- &adt.variant(FIRST_VARIANT),
- args,
- );
+ let fields =
+ self.move_paths_for_fields(self.place, self.path, adt.variant(FIRST_VARIANT), args);
self.drop_ladder(fields, succ, unwind)
} else {
self.open_drop_for_multivariant(adt, args, succ, unwind)
@@ -518,7 +514,7 @@ where
self.place,
ProjectionElem::Downcast(Some(variant.name), variant_index),
);
- let fields = self.move_paths_for_fields(base_place, variant_path, &variant, args);
+ let fields = self.move_paths_for_fields(base_place, variant_path, variant, args);
values.push(discr.val);
if let Unwind::To(unwind) = unwind {
// We can't use the half-ladder from the original
@@ -859,14 +855,14 @@ where
fn open_drop(&mut self) -> BasicBlock {
let ty = self.place_ty(self.place);
match ty.kind() {
- ty::Closure(_, args) => self.open_drop_for_tuple(&args.as_closure().upvar_tys()),
+ ty::Closure(_, args) => self.open_drop_for_tuple(args.as_closure().upvar_tys()),
// Note that `elaborate_drops` only drops the upvars of a coroutine,
// and this is ok because `open_drop` here can only be reached
// within that own coroutine's resume function.
// This should only happen for the self argument on the resume function.
// It effectively only contains upvars until the coroutine transformation runs.
// See librustc_body/transform/coroutine.rs for more details.
- ty::Coroutine(_, args, _) => self.open_drop_for_tuple(&args.as_coroutine().upvar_tys()),
+ ty::Coroutine(_, args, _) => self.open_drop_for_tuple(args.as_coroutine().upvar_tys()),
ty::Tuple(fields) => self.open_drop_for_tuple(fields),
ty::Adt(def, args) => self.open_drop_for_adt(*def, args),
ty::Dynamic(..) => self.complete_drop(self.succ, self.unwind),
diff --git a/compiler/rustc_mir_dataflow/src/framework/cursor.rs b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
index c978bddfe..815f20459 100644
--- a/compiler/rustc_mir_dataflow/src/framework/cursor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/cursor.rs
@@ -1,60 +1,14 @@
//! Random access inspection of the results of a dataflow analysis.
-use crate::{framework::BitSetExt, CloneAnalysis};
+use crate::framework::BitSetExt;
-use std::borrow::{Borrow, BorrowMut};
use std::cmp::Ordering;
#[cfg(debug_assertions)]
use rustc_index::bit_set::BitSet;
use rustc_middle::mir::{self, BasicBlock, Location};
-use super::{Analysis, Direction, Effect, EffectIndex, EntrySets, Results, ResultsCloned};
-
-// `AnalysisResults` is needed as an impl such as the following has an unconstrained type
-// parameter:
-// ```
-// impl<'tcx, A, E, R> ResultsCursor<'_, 'tcx, A, R>
-// where
-// A: Analysis<'tcx>,
-// E: Borrow<EntrySets<'tcx, A>>,
-// R: Results<'tcx, A, E>,
-// {}
-// ```
-
-/// A type representing the analysis results consumed by a `ResultsCursor`.
-pub trait AnalysisResults<'tcx, A>: BorrowMut<Results<'tcx, A, Self::EntrySets>>
-where
- A: Analysis<'tcx>,
-{
- /// The type containing the entry sets for this `Results` type.
- ///
- /// Should be either `EntrySets<'tcx, A>` or `&EntrySets<'tcx, A>`.
- type EntrySets: Borrow<EntrySets<'tcx, A>>;
-}
-impl<'tcx, A, E> AnalysisResults<'tcx, A> for Results<'tcx, A, E>
-where
- A: Analysis<'tcx>,
- E: Borrow<EntrySets<'tcx, A>>,
-{
- type EntrySets = E;
-}
-impl<'a, 'tcx, A, E> AnalysisResults<'tcx, A> for &'a mut Results<'tcx, A, E>
-where
- A: Analysis<'tcx>,
- E: Borrow<EntrySets<'tcx, A>>,
-{
- type EntrySets = E;
-}
-
-/// A `ResultsCursor` that borrows the underlying `Results`.
-pub type ResultsRefCursor<'res, 'mir, 'tcx, A> =
- ResultsCursor<'mir, 'tcx, A, &'res mut Results<'tcx, A>>;
-
-/// A `ResultsCursor` which uses a cloned `Analysis` while borrowing the underlying `Results`. This
-/// allows multiple cursors over the same `Results`.
-pub type ResultsClonedCursor<'res, 'mir, 'tcx, A> =
- ResultsCursor<'mir, 'tcx, A, ResultsCloned<'res, 'tcx, A>>;
+use super::{Analysis, Direction, Effect, EffectIndex, Results};
/// Allows random access inspection of the results of a dataflow analysis.
///
@@ -62,15 +16,12 @@ pub type ResultsClonedCursor<'res, 'mir, 'tcx, A> =
/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are
/// visited in *reverse* order—performance will be quadratic in the number of statements in the
/// block. The order in which basic blocks are inspected has no impact on performance.
-///
-/// A `ResultsCursor` can either own (the default) or borrow the dataflow results it inspects. The
-/// type of ownership is determined by `R` (see `ResultsRefCursor` above).
-pub struct ResultsCursor<'mir, 'tcx, A, R = Results<'tcx, A>>
+pub struct ResultsCursor<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
body: &'mir mir::Body<'tcx>,
- results: R,
+ results: Results<'tcx, A>,
state: A::Domain,
pos: CursorPosition,
@@ -84,7 +35,7 @@ where
reachable_blocks: BitSet<BasicBlock>,
}
-impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
+impl<'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
@@ -99,30 +50,13 @@ where
}
/// Unwraps this cursor, returning the underlying `Results`.
- pub fn into_results(self) -> R {
+ pub fn into_results(self) -> Results<'tcx, A> {
self.results
}
-}
-impl<'res, 'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A, ResultsCloned<'res, 'tcx, A>>
-where
- A: Analysis<'tcx> + CloneAnalysis,
-{
- /// Creates a new cursor over the same `Results`. Note that the cursor's position is *not*
- /// copied.
- pub fn new_cursor(&self) -> Self {
- Self::new(self.body, self.results.reclone_analysis())
- }
-}
-
-impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
-where
- A: Analysis<'tcx>,
- R: AnalysisResults<'tcx, A>,
-{
/// Returns a new cursor that can inspect `results`.
- pub fn new(body: &'mir mir::Body<'tcx>, results: R) -> Self {
- let bottom_value = results.borrow().analysis.bottom_value(body);
+ pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
+ let bottom_value = results.analysis.bottom_value(body);
ResultsCursor {
body,
results,
@@ -147,28 +81,23 @@ where
}
/// Returns the underlying `Results`.
- pub fn results(&mut self) -> &Results<'tcx, A, R::EntrySets> {
- self.results.borrow()
+ pub fn results(&self) -> &Results<'tcx, A> {
+ &self.results
}
/// Returns the underlying `Results`.
- pub fn mut_results(&mut self) -> &mut Results<'tcx, A, R::EntrySets> {
- self.results.borrow_mut()
+ pub fn mut_results(&mut self) -> &mut Results<'tcx, A> {
+ &mut self.results
}
/// Returns the `Analysis` used to generate the underlying `Results`.
pub fn analysis(&self) -> &A {
- &self.results.borrow().analysis
+ &self.results.analysis
}
/// Returns the `Analysis` used to generate the underlying `Results`.
pub fn mut_analysis(&mut self) -> &mut A {
- &mut self.results.borrow_mut().analysis
- }
-
- /// Returns both the dataflow state at the current location and the `Analysis`.
- pub fn get_with_analysis(&mut self) -> (&A::Domain, &mut A) {
- (&self.state, &mut self.results.borrow_mut().analysis)
+ &mut self.results.analysis
}
/// Resets the cursor to hold the entry set for the given basic block.
@@ -180,7 +109,7 @@ where
#[cfg(debug_assertions)]
assert!(self.reachable_blocks.contains(block));
- self.state.clone_from(self.results.borrow().entry_set_for_block(block));
+ self.state.clone_from(self.results.entry_set_for_block(block));
self.pos = CursorPosition::block_entry(block);
self.state_needs_reset = false;
}
@@ -269,11 +198,10 @@ where
)
};
- let analysis = &mut self.results.borrow_mut().analysis;
let target_effect_index = effect.at_index(target.statement_index);
A::Direction::apply_effects_in_range(
- analysis,
+ &mut self.results.analysis,
&mut self.state,
target.block,
block_data,
@@ -289,12 +217,12 @@ where
/// This can be used, e.g., to apply the call return effect directly to the cursor without
/// creating an extra copy of the dataflow state.
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
- f(&mut self.results.borrow_mut().analysis, &mut self.state);
+ f(&mut self.results.analysis, &mut self.state);
self.state_needs_reset = true;
}
}
-impl<'mir, 'tcx, A, R> ResultsCursor<'mir, 'tcx, A, R>
+impl<'mir, 'tcx, A> ResultsCursor<'mir, 'tcx, A>
where
A: crate::GenKillAnalysis<'tcx>,
A::Domain: BitSetExt<A::Idx>,
diff --git a/compiler/rustc_mir_dataflow/src/framework/direction.rs b/compiler/rustc_mir_dataflow/src/framework/direction.rs
index 70451edd5..4c3fadf48 100644
--- a/compiler/rustc_mir_dataflow/src/framework/direction.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/direction.rs
@@ -196,7 +196,7 @@ impl Direction for Backward {
{
results.reset_to_block_entry(state, block);
- vis.visit_block_end(results, &state, block_data, block);
+ vis.visit_block_end(state);
// Terminator
let loc = Location { block, statement_index: block_data.statements.len() };
@@ -214,7 +214,7 @@ impl Direction for Backward {
vis.visit_statement_after_primary_effect(results, state, stmt, loc);
}
- vis.visit_block_start(results, state, block_data, block);
+ vis.visit_block_start(state);
}
fn join_state_into_successors_of<'tcx, A>(
@@ -287,12 +287,12 @@ impl Direction for Backward {
}
}
-struct BackwardSwitchIntEdgeEffectsApplier<'a, 'tcx, D, F> {
- body: &'a mir::Body<'tcx>,
+struct BackwardSwitchIntEdgeEffectsApplier<'mir, 'tcx, D, F> {
+ body: &'mir mir::Body<'tcx>,
pred: BasicBlock,
- exit_state: &'a mut D,
+ exit_state: &'mir mut D,
bb: BasicBlock,
- propagate: &'a mut F,
+ propagate: &'mir mut F,
effects_applied: bool,
}
@@ -449,7 +449,7 @@ impl Direction for Forward {
{
results.reset_to_block_entry(state, block);
- vis.visit_block_start(results, state, block_data, block);
+ vis.visit_block_start(state);
for (statement_index, stmt) in block_data.statements.iter().enumerate() {
let loc = Location { block, statement_index };
@@ -466,7 +466,7 @@ impl Direction for Forward {
results.reconstruct_terminator_effect(state, term, loc);
vis.visit_terminator_after_primary_effect(results, state, term, loc);
- vis.visit_block_end(results, state, block_data, block);
+ vis.visit_block_end(state);
}
fn join_state_into_successors_of<'tcx, A>(
@@ -523,9 +523,9 @@ impl Direction for Forward {
}
}
-struct ForwardSwitchIntEdgeEffectsApplier<'a, D, F> {
- exit_state: &'a mut D,
- targets: &'a SwitchTargets,
+struct ForwardSwitchIntEdgeEffectsApplier<'mir, D, F> {
+ exit_state: &'mir mut D,
+ targets: &'mir SwitchTargets,
propagate: F,
effects_applied: bool,
diff --git a/compiler/rustc_mir_dataflow/src/framework/engine.rs b/compiler/rustc_mir_dataflow/src/framework/engine.rs
index a29962d77..784872c7e 100644
--- a/compiler/rustc_mir_dataflow/src/framework/engine.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/engine.rs
@@ -5,9 +5,7 @@ use crate::errors::{
};
use crate::framework::BitSetExt;
-use std::borrow::Borrow;
use std::ffi::OsString;
-use std::marker::PhantomData;
use std::path::PathBuf;
use rustc_ast as ast;
@@ -24,42 +22,37 @@ use rustc_span::symbol::{sym, Symbol};
use super::fmt::DebugWithContext;
use super::graphviz;
use super::{
- visit_results, Analysis, AnalysisDomain, CloneAnalysis, Direction, GenKill, GenKillAnalysis,
- GenKillSet, JoinSemiLattice, ResultsClonedCursor, ResultsCursor, ResultsRefCursor,
- ResultsVisitor,
+ visit_results, Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis, GenKillSet,
+ JoinSemiLattice, ResultsCursor, ResultsVisitor,
};
pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as AnalysisDomain<'tcx>>::Domain>;
/// A dataflow analysis that has converged to fixpoint.
-pub struct Results<'tcx, A, E = EntrySets<'tcx, A>>
+#[derive(Clone)]
+pub struct Results<'tcx, A>
where
A: Analysis<'tcx>,
{
pub analysis: A,
- pub(super) entry_sets: E,
- pub(super) _marker: PhantomData<&'tcx ()>,
+ pub(super) entry_sets: EntrySets<'tcx, A>,
}
-/// `Results` type with a cloned `Analysis` and borrowed entry sets.
-pub type ResultsCloned<'res, 'tcx, A> = Results<'tcx, A, &'res EntrySets<'tcx, A>>;
-
-impl<'tcx, A, E> Results<'tcx, A, E>
+impl<'tcx, A> Results<'tcx, A>
where
A: Analysis<'tcx>,
- E: Borrow<EntrySets<'tcx, A>>,
{
/// Creates a `ResultsCursor` that can inspect these `Results`.
pub fn into_results_cursor<'mir>(
self,
body: &'mir mir::Body<'tcx>,
- ) -> ResultsCursor<'mir, 'tcx, A, Self> {
+ ) -> ResultsCursor<'mir, 'tcx, A> {
ResultsCursor::new(body, self)
}
/// Gets the dataflow state for the given block.
pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
- &self.entry_sets.borrow()[block]
+ &self.entry_sets[block]
}
pub fn visit_with<'mir>(
@@ -80,60 +73,14 @@ where
visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
}
}
-impl<'tcx, A> Results<'tcx, A>
-where
- A: Analysis<'tcx>,
-{
- /// Creates a `ResultsCursor` that can inspect these `Results`.
- pub fn as_results_cursor<'a, 'mir>(
- &'a mut self,
- body: &'mir mir::Body<'tcx>,
- ) -> ResultsRefCursor<'a, 'mir, 'tcx, A> {
- ResultsCursor::new(body, self)
- }
-}
-impl<'tcx, A> Results<'tcx, A>
-where
- A: Analysis<'tcx> + CloneAnalysis,
-{
- /// Creates a new `Results` type with a cloned `Analysis` and borrowed entry sets.
- pub fn clone_analysis(&self) -> ResultsCloned<'_, 'tcx, A> {
- Results {
- analysis: self.analysis.clone_analysis(),
- entry_sets: &self.entry_sets,
- _marker: PhantomData,
- }
- }
-
- /// Creates a `ResultsCursor` that can inspect these `Results`.
- pub fn cloned_results_cursor<'mir>(
- &self,
- body: &'mir mir::Body<'tcx>,
- ) -> ResultsClonedCursor<'_, 'mir, 'tcx, A> {
- self.clone_analysis().into_results_cursor(body)
- }
-}
-impl<'res, 'tcx, A> Results<'tcx, A, &'res EntrySets<'tcx, A>>
-where
- A: Analysis<'tcx> + CloneAnalysis,
-{
- /// Creates a new `Results` type with a cloned `Analysis` and borrowed entry sets.
- pub fn reclone_analysis(&self) -> Self {
- Results {
- analysis: self.analysis.clone_analysis(),
- entry_sets: self.entry_sets,
- _marker: PhantomData,
- }
- }
-}
/// A solver for dataflow problems.
-pub struct Engine<'a, 'tcx, A>
+pub struct Engine<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
tcx: TyCtxt<'tcx>,
- body: &'a mir::Body<'tcx>,
+ body: &'mir mir::Body<'tcx>,
entry_sets: IndexVec<BasicBlock, A::Domain>,
pass_name: Option<&'static str>,
analysis: A,
@@ -147,14 +94,14 @@ where
apply_statement_trans_for_block: Option<Box<dyn Fn(BasicBlock, &mut A::Domain)>>,
}
-impl<'a, 'tcx, A, D, T> Engine<'a, 'tcx, A>
+impl<'mir, 'tcx, A, D, T> Engine<'mir, 'tcx, A>
where
A: GenKillAnalysis<'tcx, Idx = T, Domain = D>,
D: Clone + JoinSemiLattice + GenKill<T> + BitSetExt<T>,
T: Idx,
{
/// Creates a new `Engine` to solve a gen-kill dataflow problem.
- pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, mut analysis: A) -> Self {
+ pub fn new_gen_kill(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, mut analysis: A) -> Self {
// If there are no back-edges in the control-flow graph, we only ever need to apply the
// transfer function for each block exactly once (assuming that we process blocks in RPO).
//
@@ -186,7 +133,7 @@ where
}
}
-impl<'a, 'tcx, A, D> Engine<'a, 'tcx, A>
+impl<'mir, 'tcx, A, D> Engine<'mir, 'tcx, A>
where
A: Analysis<'tcx, Domain = D>,
D: Clone + JoinSemiLattice,
@@ -196,13 +143,13 @@ where
///
/// Gen-kill problems should use `new_gen_kill`, which will coalesce transfer functions for
/// better performance.
- pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'a mir::Body<'tcx>, analysis: A) -> Self {
+ pub fn new_generic(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>, analysis: A) -> Self {
Self::new(tcx, body, analysis, None)
}
fn new(
tcx: TyCtxt<'tcx>,
- body: &'a mir::Body<'tcx>,
+ body: &'mir mir::Body<'tcx>,
analysis: A,
apply_statement_trans_for_block: Option<Box<dyn Fn(BasicBlock, &mut A::Domain)>>,
) -> Self {
@@ -239,7 +186,6 @@ where
tcx,
apply_statement_trans_for_block,
pass_name,
- ..
} = self;
let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks.len());
@@ -292,29 +238,31 @@ where
);
}
- let mut results = Results { analysis, entry_sets, _marker: PhantomData };
+ let results = Results { analysis, entry_sets };
if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
- let res = write_graphviz_results(tcx, &body, &mut results, pass_name);
+ let (res, results) = write_graphviz_results(tcx, body, results, pass_name);
if let Err(e) = res {
error!("Failed to write graphviz dataflow results: {}", e);
}
+ results
+ } else {
+ results
}
-
- results
}
}
// Graphviz
/// Writes a DOT file containing the results of a dataflow analysis if the user requested it via
-/// `rustc_mir` attributes and `-Z dump-mir-dataflow`.
+/// `rustc_mir` attributes and `-Z dump-mir-dataflow`. The `Result` in and the `Results` out are
+/// the same.
fn write_graphviz_results<'tcx, A>(
tcx: TyCtxt<'tcx>,
body: &mir::Body<'tcx>,
- results: &mut Results<'tcx, A>,
+ results: Results<'tcx, A>,
pass_name: Option<&'static str>,
-) -> std::io::Result<()>
+) -> (std::io::Result<()>, Results<'tcx, A>)
where
A: Analysis<'tcx>,
A::Domain: DebugWithContext<A>,
@@ -325,23 +273,30 @@ where
let def_id = body.source.def_id();
let Ok(attrs) = RustcMirAttrs::parse(tcx, def_id) else {
// Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
- return Ok(());
+ return (Ok(()), results);
};
- let mut file = match attrs.output_path(A::NAME) {
- Some(path) => {
- debug!("printing dataflow results for {:?} to {}", def_id, path.display());
- if let Some(parent) = path.parent() {
- fs::create_dir_all(parent)?;
+ let file = try {
+ match attrs.output_path(A::NAME) {
+ Some(path) => {
+ debug!("printing dataflow results for {:?} to {}", def_id, path.display());
+ if let Some(parent) = path.parent() {
+ fs::create_dir_all(parent)?;
+ }
+ let f = fs::File::create(&path)?;
+ io::BufWriter::new(f)
}
- io::BufWriter::new(fs::File::create(&path)?)
- }
- None if dump_enabled(tcx, A::NAME, def_id) => {
- create_dump_file(tcx, ".dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
- }
+ None if dump_enabled(tcx, A::NAME, def_id) => {
+ create_dump_file(tcx, ".dot", false, A::NAME, &pass_name.unwrap_or("-----"), body)?
+ }
- _ => return Ok(()),
+ _ => return (Ok(()), results),
+ }
+ };
+ let mut file = match file {
+ Ok(f) => f,
+ Err(e) => return (Err(e), results),
};
let style = match attrs.formatter {
@@ -357,11 +312,14 @@ where
if tcx.sess.opts.unstable_opts.graphviz_dark_mode {
render_opts.push(dot::RenderOption::DarkTheme);
}
- with_no_trimmed_paths!(dot::render_opts(&graphviz, &mut buf, &render_opts)?);
+ let r = with_no_trimmed_paths!(dot::render_opts(&graphviz, &mut buf, &render_opts));
- file.write_all(&buf)?;
+ let lhs = try {
+ r?;
+ file.write_all(&buf)?;
+ };
- Ok(())
+ (lhs, graphviz.into_results())
}
#[derive(Default)]
diff --git a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
index c12ccba1e..0270e059a 100644
--- a/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/graphviz.rs
@@ -12,10 +12,10 @@ use rustc_middle::mir::graphviz_safe_def_name;
use rustc_middle::mir::{self, BasicBlock, Body, Location};
use super::fmt::{DebugDiffWithAdapter, DebugWithAdapter, DebugWithContext};
-use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsRefCursor, ResultsVisitor};
+use super::{Analysis, CallReturnPlaces, Direction, Results, ResultsCursor, ResultsVisitor};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
-pub enum OutputStyle {
+pub(crate) enum OutputStyle {
AfterOnly,
BeforeAndAfter,
}
@@ -29,33 +29,37 @@ impl OutputStyle {
}
}
-pub struct Formatter<'res, 'mir, 'tcx, A>
+pub(crate) struct Formatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
body: &'mir Body<'tcx>,
- results: RefCell<&'res mut Results<'tcx, A>>,
+ results: RefCell<Option<Results<'tcx, A>>>,
style: OutputStyle,
reachable: BitSet<BasicBlock>,
}
-impl<'res, 'mir, 'tcx, A> Formatter<'res, 'mir, 'tcx, A>
+impl<'mir, 'tcx, A> Formatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
- pub fn new(
+ pub(crate) fn new(
body: &'mir Body<'tcx>,
- results: &'res mut Results<'tcx, A>,
+ results: Results<'tcx, A>,
style: OutputStyle,
) -> Self {
let reachable = mir::traversal::reachable_as_bitset(body);
- Formatter { body, results: results.into(), style, reachable }
+ Formatter { body, results: Some(results).into(), style, reachable }
+ }
+
+ pub(crate) fn into_results(self) -> Results<'tcx, A> {
+ self.results.into_inner().unwrap()
}
}
/// A pair of a basic block and an index into that basic blocks `successors`.
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct CfgEdge {
+pub(crate) struct CfgEdge {
source: BasicBlock,
index: usize,
}
@@ -69,7 +73,7 @@ fn dataflow_successors(body: &Body<'_>, bb: BasicBlock) -> Vec<CfgEdge> {
.collect()
}
-impl<'tcx, A> dot::Labeller<'_> for Formatter<'_, '_, 'tcx, A>
+impl<'tcx, A> dot::Labeller<'_> for Formatter<'_, 'tcx, A>
where
A: Analysis<'tcx>,
A::Domain: DebugWithContext<A>,
@@ -88,14 +92,19 @@ where
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
let mut label = Vec::new();
- let mut results = self.results.borrow_mut();
- let mut fmt = BlockFormatter {
- results: results.as_results_cursor(self.body),
- style: self.style,
- bg: Background::Light,
- };
+ self.results.replace_with(|results| {
+ // `Formatter::result` is a `RefCell<Option<_>>` so we can replace
+ // the value with `None`, move it into the results cursor, move it
+ // back out, and return it to the refcell wrapped in `Some`.
+ let mut fmt = BlockFormatter {
+ results: results.take().unwrap().into_results_cursor(self.body),
+ style: self.style,
+ bg: Background::Light,
+ };
- fmt.write_node_label(&mut label, *block).unwrap();
+ fmt.write_node_label(&mut label, *block).unwrap();
+ Some(fmt.results.into_results())
+ });
dot::LabelText::html(String::from_utf8(label).unwrap())
}
@@ -109,7 +118,7 @@ where
}
}
-impl<'mir, 'tcx, A> dot::GraphWalk<'mir> for Formatter<'_, 'mir, 'tcx, A>
+impl<'mir, 'tcx, A> dot::GraphWalk<'mir> for Formatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
@@ -143,16 +152,16 @@ where
}
}
-struct BlockFormatter<'res, 'mir, 'tcx, A>
+struct BlockFormatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
{
- results: ResultsRefCursor<'res, 'mir, 'tcx, A>,
+ results: ResultsCursor<'mir, 'tcx, A>,
bg: Background,
style: OutputStyle,
}
-impl<'res, 'mir, 'tcx, A> BlockFormatter<'res, 'mir, 'tcx, A>
+impl<'mir, 'tcx, A> BlockFormatter<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
A::Domain: DebugWithContext<A>,
@@ -536,25 +545,13 @@ where
{
type FlowState = A::Domain;
- fn visit_block_start(
- &mut self,
- _results: &mut Results<'tcx, A>,
- state: &Self::FlowState,
- _block_data: &mir::BasicBlockData<'tcx>,
- _block: BasicBlock,
- ) {
+ fn visit_block_start(&mut self, state: &Self::FlowState) {
if A::Direction::IS_FORWARD {
self.prev_state.clone_from(state);
}
}
- fn visit_block_end(
- &mut self,
- _results: &mut Results<'tcx, A>,
- state: &Self::FlowState,
- _block_data: &mir::BasicBlockData<'tcx>,
- _block: BasicBlock,
- ) {
+ fn visit_block_end(&mut self, state: &Self::FlowState) {
if A::Direction::IS_BACKWARD {
self.prev_state.clone_from(state);
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
index 3b89598d2..1c2b475a4 100644
--- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs
@@ -342,7 +342,7 @@ impl<V: Clone> Clone for MaybeReachable<V> {
fn clone_from(&mut self, source: &Self) {
match (&mut *self, source) {
(MaybeReachable::Reachable(x), MaybeReachable::Reachable(y)) => {
- x.clone_from(&y);
+ x.clone_from(y);
}
_ => *self = source.clone(),
}
diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs
index 5020a1cf0..09cdb055a 100644
--- a/compiler/rustc_mir_dataflow/src/framework/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs
@@ -45,9 +45,9 @@ pub mod graphviz;
pub mod lattice;
mod visitor;
-pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
+pub use self::cursor::ResultsCursor;
pub use self::direction::{Backward, Direction, Forward};
-pub use self::engine::{Engine, EntrySets, Results, ResultsCloned};
+pub use self::engine::{Engine, Results};
pub use self::lattice::{JoinSemiLattice, MaybeReachable};
pub use self::visitor::{visit_results, ResultsVisitable, ResultsVisitor};
@@ -246,35 +246,21 @@ pub trait Analysis<'tcx>: AnalysisDomain<'tcx> {
}
}
-/// Defines an `Analysis` which can be cloned for use in multiple `ResultsCursor`s or
-/// `ResultsVisitor`s. Note this need not be a full clone, only enough of one to be used with a new
-/// `ResultsCursor` or `ResultsVisitor`
-pub trait CloneAnalysis {
- fn clone_analysis(&self) -> Self;
-}
-impl<'tcx, A> CloneAnalysis for A
-where
- A: Analysis<'tcx> + Copy,
-{
- fn clone_analysis(&self) -> Self {
- *self
- }
-}
-
/// A gen/kill dataflow problem.
///
-/// Each method in this trait has a corresponding one in `Analysis`. However, these methods only
-/// allow modification of the dataflow state via "gen" and "kill" operations. By defining transfer
-/// functions for each statement in this way, the transfer function for an entire basic block can
-/// be computed efficiently.
+/// Each method in this trait has a corresponding one in `Analysis`. However, the first two methods
+/// here only allow modification of the dataflow state via "gen" and "kill" operations. By defining
+/// transfer functions for each statement in this way, the transfer function for an entire basic
+/// block can be computed efficiently. The remaining methods match up with `Analysis` exactly.
///
-/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis`.
+/// `Analysis` is automatically implemented for all implementers of `GenKillAnalysis` via a blanket
+/// impl below.
pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
type Idx: Idx;
fn domain_size(&self, body: &mir::Body<'tcx>) -> usize;
- /// See `Analysis::apply_statement_effect`.
+ /// See `Analysis::apply_statement_effect`. Note how the second arg differs.
fn statement_effect(
&mut self,
trans: &mut impl GenKill<Self::Idx>,
@@ -282,7 +268,8 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
location: Location,
);
- /// See `Analysis::apply_before_statement_effect`.
+ /// See `Analysis::apply_before_statement_effect`. Note how the second arg
+ /// differs.
fn before_statement_effect(
&mut self,
_trans: &mut impl GenKill<Self::Idx>,
@@ -302,7 +289,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
/// See `Analysis::apply_before_terminator_effect`.
fn before_terminator_effect(
&mut self,
- _trans: &mut impl GenKill<Self::Idx>,
+ _trans: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) {
@@ -313,7 +300,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
/// See `Analysis::apply_call_return_effect`.
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
block: BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
);
@@ -328,6 +315,7 @@ pub trait GenKillAnalysis<'tcx>: Analysis<'tcx> {
}
}
+// Blanket impl: any impl of `GenKillAnalysis` automatically impls `Analysis`.
impl<'tcx, A> Analysis<'tcx> for A
where
A: GenKillAnalysis<'tcx>,
diff --git a/compiler/rustc_mir_dataflow/src/framework/tests.rs b/compiler/rustc_mir_dataflow/src/framework/tests.rs
index 9cce5b26c..6b338efd5 100644
--- a/compiler/rustc_mir_dataflow/src/framework/tests.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/tests.rs
@@ -2,9 +2,7 @@
use std::marker::PhantomData;
-use rustc_index::bit_set::BitSet;
use rustc_index::IndexVec;
-use rustc_middle::mir::{self, BasicBlock, Location};
use rustc_middle::ty;
use rustc_span::DUMMY_SP;
@@ -267,8 +265,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
let body = analysis.body;
let mut cursor =
- Results { entry_sets: analysis.mock_entry_sets(), analysis, _marker: PhantomData }
- .into_results_cursor(body);
+ Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_results_cursor(body);
cursor.allow_unreachable();
diff --git a/compiler/rustc_mir_dataflow/src/framework/visitor.rs b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
index 3cfa7cc1c..8b8a16bda 100644
--- a/compiler/rustc_mir_dataflow/src/framework/visitor.rs
+++ b/compiler/rustc_mir_dataflow/src/framework/visitor.rs
@@ -1,8 +1,6 @@
-use std::borrow::Borrow;
-
use rustc_middle::mir::{self, BasicBlock, Location};
-use super::{Analysis, Direction, EntrySets, Results};
+use super::{Analysis, Direction, Results};
/// Calls the corresponding method in `ResultsVisitor` for every location in a `mir::Body` with the
/// dataflow state at that location.
@@ -33,14 +31,7 @@ pub fn visit_results<'mir, 'tcx, F, R>(
pub trait ResultsVisitor<'mir, 'tcx, R> {
type FlowState;
- fn visit_block_start(
- &mut self,
- _results: &mut R,
- _state: &Self::FlowState,
- _block_data: &'mir mir::BasicBlockData<'tcx>,
- _block: BasicBlock,
- ) {
- }
+ fn visit_block_start(&mut self, _state: &Self::FlowState) {}
/// Called with the `before_statement_effect` of the given statement applied to `state` but not
/// its `statement_effect`.
@@ -88,20 +79,13 @@ pub trait ResultsVisitor<'mir, 'tcx, R> {
) {
}
- fn visit_block_end(
- &mut self,
- _results: &mut R,
- _state: &Self::FlowState,
- _block_data: &'mir mir::BasicBlockData<'tcx>,
- _block: BasicBlock,
- ) {
- }
+ fn visit_block_end(&mut self, _state: &Self::FlowState) {}
}
/// Things that can be visited by a `ResultsVisitor`.
///
-/// This trait exists so that we can visit the results of multiple dataflow analyses simultaneously.
-/// DO NOT IMPLEMENT MANUALLY. Instead, use the `impl_visitable` macro below.
+/// This trait exists so that we can visit the results of one or more dataflow analyses
+/// simultaneously.
pub trait ResultsVisitable<'tcx> {
type Direction: Direction;
type FlowState;
@@ -143,10 +127,9 @@ pub trait ResultsVisitable<'tcx> {
);
}
-impl<'tcx, A, E> ResultsVisitable<'tcx> for Results<'tcx, A, E>
+impl<'tcx, A> ResultsVisitable<'tcx> for Results<'tcx, A>
where
A: Analysis<'tcx>,
- E: Borrow<EntrySets<'tcx, A>>,
{
type FlowState = A::Domain;
diff --git a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
index 01acc380f..693994b5d 100644
--- a/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/borrowed_locals.rs
@@ -62,7 +62,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeBorrowedLocals {
fn call_return_effect(
&mut self,
- _trans: &mut impl GenKill<Self::Idx>,
+ _trans: &mut Self::Domain,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index c968e7aea..6653b99b3 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
) -> bool {
if let LookupResult::Exact(path) = self.move_data().rev_lookup.find(place.as_ref()) {
let mut maybe_live = false;
- on_all_children_bits(self.tcx, self.body, self.move_data(), path, |child| {
+ on_all_children_bits(self.move_data(), path, |child| {
maybe_live |= state.contains(child);
});
!maybe_live
@@ -203,14 +203,13 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
/// this data and `MaybeInitializedPlaces` yields the set of places
/// that would require a dynamic drop-flag at that statement.
pub struct DefinitelyInitializedPlaces<'a, 'tcx> {
- tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
}
impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
- pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
- DefinitelyInitializedPlaces { tcx, body, mdpe }
+ pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
+ DefinitelyInitializedPlaces { body, mdpe }
}
}
@@ -250,15 +249,13 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
/// }
/// ```
pub struct EverInitializedPlaces<'a, 'tcx> {
- #[allow(dead_code)]
- tcx: TyCtxt<'tcx>,
body: &'a Body<'tcx>,
mdpe: &'a MoveDataParamEnv<'tcx>,
}
impl<'a, 'tcx> EverInitializedPlaces<'a, 'tcx> {
- pub fn new(tcx: TyCtxt<'tcx>, body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
- EverInitializedPlaces { tcx, body, mdpe }
+ pub fn new(body: &'a Body<'tcx>, mdpe: &'a MoveDataParamEnv<'tcx>) -> Self {
+ EverInitializedPlaces { body, mdpe }
}
}
@@ -319,7 +316,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
*state =
MaybeReachable::Reachable(ChunkedBitSet::new_empty(self.move_data().move_paths.len()));
- drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
+ drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| {
assert!(s == DropFlagState::Present);
state.gen(path);
});
@@ -339,7 +336,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
statement: &mir::Statement<'tcx>,
location: Location,
) {
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(trans, path, s)
});
@@ -351,7 +348,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
| mir::Rvalue::AddressOf(_, place) = rvalue
&& let LookupResult::Exact(mpi) = self.move_data().rev_lookup.find(place.as_ref())
{
- on_all_children_bits(self.tcx, self.body, self.move_data(), mpi, |child| {
+ on_all_children_bits(self.move_data(), mpi, |child| {
trans.gen(child);
})
}
@@ -371,7 +368,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
{
edges = TerminatorEdges::Single(target);
}
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(state, path, s)
});
edges
@@ -379,7 +376,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -387,8 +384,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
// when a call returns successfully, that means we need to set
// the bits for that dest_place to 1 (initialized).
on_lookup_result_bits(
- self.tcx,
- self.body,
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
@@ -409,7 +404,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
}
let enum_ = discr.place().and_then(|discr| {
- switch_on_enum_discriminant(self.tcx, &self.body, &self.body[block], discr)
+ switch_on_enum_discriminant(self.tcx, self.body, &self.body[block], discr)
});
let Some((enum_place, enum_def)) = enum_ else {
@@ -432,8 +427,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
// Kill all move paths that correspond to variants we know to be inactive along this
// particular outgoing edge of a `SwitchInt`.
drop_flag_effects::on_all_inactive_variants(
- self.tcx,
- self.body,
self.move_data(),
enum_place,
variant,
@@ -458,7 +451,7 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
// set all bits to 1 (uninit) before gathering counter-evidence
state.insert_all();
- drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
+ drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| {
assert!(s == DropFlagState::Present);
state.remove(path);
});
@@ -478,7 +471,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
_statement: &mir::Statement<'tcx>,
location: Location,
) {
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(trans, path, s)
});
@@ -492,7 +485,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(trans, path, s)
});
if self.skip_unreachable_unwind.contains(location.block) {
@@ -506,7 +499,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -514,8 +507,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
// when a call returns successfully, that means we need to set
// the bits for that dest_place to 0 (initialized).
on_lookup_result_bits(
- self.tcx,
- self.body,
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
@@ -540,7 +531,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
}
let enum_ = discr.place().and_then(|discr| {
- switch_on_enum_discriminant(self.tcx, &self.body, &self.body[block], discr)
+ switch_on_enum_discriminant(self.tcx, self.body, &self.body[block], discr)
});
let Some((enum_place, enum_def)) = enum_ else {
@@ -563,8 +554,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
// Mark all move paths that correspond to variants other than this one as maybe
// uninitialized (in reality, they are *definitely* uninitialized).
drop_flag_effects::on_all_inactive_variants(
- self.tcx,
- self.body,
self.move_data(),
enum_place,
variant,
@@ -589,7 +578,7 @@ impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut Self::Domain) {
state.0.clear();
- drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
+ drop_flag_effects_for_function_entry(self.body, self.mdpe, |path, s| {
assert!(s == DropFlagState::Present);
state.0.insert(path);
});
@@ -609,7 +598,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
_statement: &mir::Statement<'tcx>,
location: Location,
) {
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(trans, path, s)
})
}
@@ -620,7 +609,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
terminator: &'mir mir::Terminator<'tcx>,
location: Location,
) -> TerminatorEdges<'mir, 'tcx> {
- drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
+ drop_flag_effects_for_location(self.body, self.mdpe, location, |path, s| {
Self::update_bits(trans, path, s)
});
terminator.edges()
@@ -628,7 +617,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -636,8 +625,6 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
// when a call returns successfully, that means we need to set
// the bits for that dest_place to 1 (initialized).
on_lookup_result_bits(
- self.tcx,
- self.body,
self.move_data(),
self.move_data().rev_lookup.find(place.as_ref()),
|mpi| {
@@ -725,7 +712,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
block: mir::BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index bdfb6a6ff..04bae6ae2 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -23,7 +23,6 @@ use crate::{Analysis, AnalysisDomain, Backward, GenKill, GenKillAnalysis};
/// [`MaybeBorrowedLocals`]: super::MaybeBorrowedLocals
/// [flow-test]: https://github.com/rust-lang/rust/blob/a08c47310c7d49cbdc5d7afb38408ba519967ecd/src/test/ui/mir-dataflow/liveness-ptr.rs
/// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis
-#[derive(Clone, Copy)]
pub struct MaybeLiveLocals;
impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
@@ -70,7 +69,7 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
diff --git a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
index 5a58e3af8..646c70eb8 100644
--- a/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/storage_liveness.rs
@@ -5,7 +5,7 @@ use rustc_middle::mir::*;
use std::borrow::Cow;
use super::MaybeBorrowedLocals;
-use crate::{GenKill, ResultsClonedCursor};
+use crate::{GenKill, ResultsCursor};
#[derive(Clone)]
pub struct MaybeStorageLive<'a> {
@@ -18,12 +18,6 @@ impl<'a> MaybeStorageLive<'a> {
}
}
-impl crate::CloneAnalysis for MaybeStorageLive<'_> {
- fn clone_analysis(&self) -> Self {
- self.clone()
- }
-}
-
impl<'tcx, 'a> crate::AnalysisDomain<'tcx> for MaybeStorageLive<'a> {
type Domain = BitSet<Local>;
@@ -78,7 +72,7 @@ impl<'tcx, 'a> crate::GenKillAnalysis<'tcx> for MaybeStorageLive<'a> {
fn call_return_effect(
&mut self,
- _trans: &mut impl GenKill<Self::Idx>,
+ _trans: &mut Self::Domain,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -150,7 +144,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead {
fn call_return_effect(
&mut self,
- _trans: &mut impl GenKill<Self::Idx>,
+ _trans: &mut Self::Domain,
_block: BasicBlock,
_return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -158,28 +152,21 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeStorageDead {
}
}
-type BorrowedLocalsResults<'res, 'mir, 'tcx> =
- ResultsClonedCursor<'res, 'mir, 'tcx, MaybeBorrowedLocals>;
+type BorrowedLocalsResults<'mir, 'tcx> = ResultsCursor<'mir, 'tcx, MaybeBorrowedLocals>;
/// Dataflow analysis that determines whether each local requires storage at a
/// given location; i.e. whether its storage can go away without being observed.
-pub struct MaybeRequiresStorage<'res, 'mir, 'tcx> {
- borrowed_locals: BorrowedLocalsResults<'res, 'mir, 'tcx>,
+pub struct MaybeRequiresStorage<'mir, 'tcx> {
+ borrowed_locals: BorrowedLocalsResults<'mir, 'tcx>,
}
-impl<'res, 'mir, 'tcx> MaybeRequiresStorage<'res, 'mir, 'tcx> {
- pub fn new(borrowed_locals: BorrowedLocalsResults<'res, 'mir, 'tcx>) -> Self {
+impl<'mir, 'tcx> MaybeRequiresStorage<'mir, 'tcx> {
+ pub fn new(borrowed_locals: BorrowedLocalsResults<'mir, 'tcx>) -> Self {
MaybeRequiresStorage { borrowed_locals }
}
}
-impl crate::CloneAnalysis for MaybeRequiresStorage<'_, '_, '_> {
- fn clone_analysis(&self) -> Self {
- Self { borrowed_locals: self.borrowed_locals.new_cursor() }
- }
-}
-
-impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
+impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
type Domain = BitSet<Local>;
const NAME: &'static str = "requires_storage";
@@ -198,7 +185,7 @@ impl<'tcx> crate::AnalysisDomain<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
}
}
-impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
+impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
type Idx = Local;
fn domain_size(&self, body: &Body<'tcx>) -> usize {
@@ -251,7 +238,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
fn before_terminator_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
terminator: &Terminator<'tcx>,
loc: Location,
) {
@@ -347,7 +334,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
fn call_return_effect(
&mut self,
- trans: &mut impl GenKill<Self::Idx>,
+ trans: &mut Self::Domain,
_block: BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
@@ -355,7 +342,7 @@ impl<'tcx> crate::GenKillAnalysis<'tcx> for MaybeRequiresStorage<'_, '_, 'tcx> {
}
}
-impl<'tcx> MaybeRequiresStorage<'_, '_, 'tcx> {
+impl<'tcx> MaybeRequiresStorage<'_, 'tcx> {
/// Kill locals that are fully moved and have not been borrowed.
fn check_for_move(&mut self, trans: &mut impl GenKill<Local>, loc: Location) {
let body = self.borrowed_locals.body();
@@ -364,12 +351,12 @@ impl<'tcx> MaybeRequiresStorage<'_, '_, 'tcx> {
}
}
-struct MoveVisitor<'a, 'res, 'mir, 'tcx, T> {
- borrowed_locals: &'a mut BorrowedLocalsResults<'res, 'mir, 'tcx>,
+struct MoveVisitor<'a, 'mir, 'tcx, T> {
+ borrowed_locals: &'a mut BorrowedLocalsResults<'mir, 'tcx>,
trans: &'a mut T,
}
-impl<'tcx, T> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx, T>
+impl<'tcx, T> Visitor<'tcx> for MoveVisitor<'_, '_, 'tcx, T>
where
T: GenKill<Local>,
{
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index eea0e030e..f0b21fd41 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -4,7 +4,7 @@
#![feature(let_chains)]
#![feature(min_specialization)]
#![feature(stmt_expr_attributes)]
-#![feature(trusted_step)]
+#![feature(try_blocks)]
#![recursion_limit = "256"]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
@@ -14,24 +14,17 @@ extern crate tracing;
#[macro_use]
extern crate rustc_middle;
-use rustc_ast::MetaItem;
-use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
-use rustc_fluent_macro::fluent_messages;
-use rustc_hir::def_id::DefId;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_span::symbol::{sym, Symbol};
+use rustc_middle::ty;
pub use self::drop_flag_effects::{
drop_flag_effects_for_function_entry, drop_flag_effects_for_location,
move_path_children_matching, on_all_children_bits, on_lookup_result_bits,
};
pub use self::framework::{
- fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward,
- CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis, JoinSemiLattice,
- MaybeReachable, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor,
- ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
+ fmt, lattice, visit_results, Analysis, AnalysisDomain, Direction, GenKill, GenKillAnalysis,
+ JoinSemiLattice, MaybeReachable, Results, ResultsCursor, ResultsVisitable, ResultsVisitor,
};
-
+use self::framework::{Backward, SwitchIntEdgeEffects};
use self::move_paths::MoveData;
pub mod debuginfo;
@@ -46,26 +39,9 @@ pub mod storage;
pub mod un_derefer;
pub mod value_analysis;
-fluent_messages! { "../messages.ftl" }
-
-pub(crate) mod indexes {
- pub(crate) use super::move_paths::MovePathIndex;
-}
+rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub struct MoveDataParamEnv<'tcx> {
pub move_data: MoveData<'tcx>,
pub param_env: ty::ParamEnv<'tcx>,
}
-
-pub fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> {
- for attr in tcx.get_attrs(def_id, sym::rustc_mir) {
- let items = attr.meta_item_list();
- for item in items.iter().flat_map(|l| l.iter()) {
- match item.meta_item() {
- Some(mi) if mi.has_name(name) => return Some(mi.clone()),
- _ => continue,
- }
- }
- }
- None
-}
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
index 7ab1a9ed0..22cf39992 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs
@@ -14,6 +14,7 @@ use self::abs_domain::{AbstractElem, Lift};
mod abs_domain;
rustc_index::newtype_index! {
+ #[orderable]
#[debug_format = "mp{}"]
pub struct MovePathIndex {}
}
@@ -25,6 +26,7 @@ impl polonius_engine::Atom for MovePathIndex {
}
rustc_index::newtype_index! {
+ #[orderable]
#[debug_format = "mo{}"]
pub struct MoveOutIndex {}
}
diff --git a/compiler/rustc_mir_dataflow/src/rustc_peek.rs b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
index d3dce641b..448128b69 100644
--- a/compiler/rustc_mir_dataflow/src/rustc_peek.rs
+++ b/compiler/rustc_mir_dataflow/src/rustc_peek.rs
@@ -1,11 +1,3 @@
-use rustc_span::symbol::sym;
-use rustc_span::Span;
-
-use rustc_index::bit_set::ChunkedBitSet;
-use rustc_middle::mir::MirPass;
-use rustc_middle::mir::{self, Body, Local, Location};
-use rustc_middle::ty::{self, Ty, TyCtxt};
-
use crate::errors::{
PeekArgumentNotALocal, PeekArgumentUntracked, PeekBitNotSet, PeekMustBeNotTemporary,
PeekMustBePlaceOrRefPlace, StopAfterDataFlowEndedCompilation,
@@ -18,13 +10,33 @@ use crate::move_paths::{HasMoveData, MoveData};
use crate::move_paths::{LookupResult, MovePathIndex};
use crate::MoveDataParamEnv;
use crate::{Analysis, JoinSemiLattice, ResultsCursor};
+use rustc_ast::MetaItem;
+use rustc_hir::def_id::DefId;
+use rustc_index::bit_set::ChunkedBitSet;
+use rustc_middle::mir::MirPass;
+use rustc_middle::mir::{self, Body, Local, Location};
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_span::symbol::{sym, Symbol};
+use rustc_span::Span;
pub struct SanityCheck;
+fn has_rustc_mir_with(tcx: TyCtxt<'_>, def_id: DefId, name: Symbol) -> Option<MetaItem> {
+ for attr in tcx.get_attrs(def_id, sym::rustc_mir) {
+ let items = attr.meta_item_list();
+ for item in items.iter().flat_map(|l| l.iter()) {
+ match item.meta_item() {
+ Some(mi) if mi.has_name(name) => return Some(mi.clone()),
+ _ => continue,
+ }
+ }
+ }
+ None
+}
+
// FIXME: This should be a `MirLint`, but it needs to be moved back to `rustc_mir_transform` first.
impl<'tcx> MirPass<'tcx> for SanityCheck {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
- use crate::has_rustc_mir_with;
let def_id = body.source.def_id();
if !tcx.has_attr(def_id, sym::rustc_mir) {
debug!("skipping rustc_peek::SanityCheck on {}", tcx.def_path_str(def_id));
@@ -34,7 +46,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
}
let param_env = tcx.param_env(def_id);
- let move_data = MoveData::gather_moves(&body, tcx, param_env, |_| true);
+ let move_data = MoveData::gather_moves(body, tcx, param_env, |_| true);
let mdpe = MoveDataParamEnv { move_data, param_env };
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_maybe_init).is_some() {
@@ -54,7 +66,7 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
}
if has_rustc_mir_with(tcx, def_id, sym::rustc_peek_definite_init).is_some() {
- let flow_def_inits = DefinitelyInitializedPlaces::new(tcx, body, &mdpe)
+ let flow_def_inits = DefinitelyInitializedPlaces::new(body, &mdpe)
.into_engine(tcx, body)
.iterate_to_fixpoint();
@@ -89,10 +101,8 @@ impl<'tcx> MirPass<'tcx> for SanityCheck {
/// (If there are any calls to `rustc_peek` that do not match the
/// expression form above, then that emits an error as well, but those
/// errors are not intended to be used for unit tests.)
-pub fn sanity_check_via_rustc_peek<'tcx, A>(
- tcx: TyCtxt<'tcx>,
- mut cursor: ResultsCursor<'_, 'tcx, A>,
-) where
+fn sanity_check_via_rustc_peek<'tcx, A>(tcx: TyCtxt<'tcx>, mut cursor: ResultsCursor<'_, 'tcx, A>)
+where
A: RustcPeekAt<'tcx>,
{
let def_id = cursor.body().source.def_id();
@@ -129,7 +139,8 @@ pub fn sanity_check_via_rustc_peek<'tcx, A>(
) => {
let loc = Location { block: bb, statement_index };
cursor.seek_before_primary_effect(loc);
- let (state, analysis) = cursor.get_with_analysis();
+ let state = cursor.get();
+ let analysis = cursor.analysis();
analysis.peek_at(tcx, *place, state, call);
}
@@ -173,7 +184,7 @@ impl PeekCallKind {
}
#[derive(Clone, Copy, Debug)]
-pub struct PeekCall {
+struct PeekCall {
arg: Local,
kind: PeekCallKind,
span: Span,
@@ -221,7 +232,7 @@ impl PeekCall {
}
}
-pub trait RustcPeekAt<'tcx>: Analysis<'tcx> {
+trait RustcPeekAt<'tcx>: Analysis<'tcx> {
fn peek_at(
&self,
tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_mir_dataflow/src/un_derefer.rs b/compiler/rustc_mir_dataflow/src/un_derefer.rs
index 874d50ffd..b803ecc57 100644
--- a/compiler/rustc_mir_dataflow/src/un_derefer.rs
+++ b/compiler/rustc_mir_dataflow/src/un_derefer.rs
@@ -3,13 +3,13 @@ use rustc_middle::mir::*;
/// Used for reverting changes made by `DerefSeparator`
#[derive(Default, Debug)]
-pub struct UnDerefer<'tcx> {
+pub(crate) struct UnDerefer<'tcx> {
deref_chains: FxHashMap<Local, Vec<PlaceRef<'tcx>>>,
}
impl<'tcx> UnDerefer<'tcx> {
#[inline]
- pub fn insert(&mut self, local: Local, reffed: PlaceRef<'tcx>) {
+ pub(crate) fn insert(&mut self, local: Local, reffed: PlaceRef<'tcx>) {
let mut chain = self.deref_chains.remove(&reffed.local).unwrap_or_default();
chain.push(reffed);
self.deref_chains.insert(local, chain);
@@ -17,7 +17,7 @@ impl<'tcx> UnDerefer<'tcx> {
/// Returns the chain of places behind `DerefTemp` locals
#[inline]
- pub fn deref_chain(&self, local: Local) -> &[PlaceRef<'tcx>] {
+ pub(crate) fn deref_chain(&self, local: Local) -> &[PlaceRef<'tcx>] {
self.deref_chains.get(&local).map(Vec::as_slice).unwrap_or_default()
}
@@ -25,7 +25,7 @@ impl<'tcx> UnDerefer<'tcx> {
///
/// See [`PlaceRef::iter_projections`]
#[inline]
- pub fn iter_projections(
+ pub(crate) fn iter_projections(
&self,
place: PlaceRef<'tcx>,
) -> impl Iterator<Item = (PlaceRef<'tcx>, PlaceElem<'tcx>)> + '_ {
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 025d2ddfd..2802f5491 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -332,8 +332,6 @@ pub struct ValueAnalysisWrapper<T>(pub T);
impl<'tcx, T: ValueAnalysis<'tcx>> AnalysisDomain<'tcx> for ValueAnalysisWrapper<T> {
type Domain = State<T::Value>;
- type Direction = crate::Forward;
-
const NAME: &'static str = T::NAME;
fn bottom_value(&self, _body: &Body<'tcx>) -> Self::Domain {
@@ -476,26 +474,10 @@ impl<V: Clone> State<V> {
}
}
- pub fn is_reachable(&self) -> bool {
+ fn is_reachable(&self) -> bool {
matches!(&self.0, StateData::Reachable(_))
}
- pub fn mark_unreachable(&mut self) {
- self.0 = StateData::Unreachable;
- }
-
- pub fn flood_all(&mut self)
- where
- V: HasTop,
- {
- self.flood_all_with(V::TOP)
- }
-
- pub fn flood_all_with(&mut self, value: V) {
- let StateData::Reachable(values) = &mut self.0 else { return };
- values.raw.fill(value);
- }
-
/// Assign `value` to all places that are contained in `place` or may alias one.
pub fn flood_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
self.flood_with_tail_elem(place, None, map, value)
@@ -510,7 +492,7 @@ impl<V: Clone> State<V> {
}
/// Assign `value` to the discriminant of `place` and all places that may alias it.
- pub fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
+ fn flood_discr_with(&mut self, place: PlaceRef<'_>, map: &Map, value: V) {
self.flood_with_tail_elem(place, Some(TrackElem::Discriminant), map, value)
}
@@ -546,7 +528,7 @@ impl<V: Clone> State<V> {
/// This does nothing if the place is not tracked.
///
/// The target place must have been flooded before calling this method.
- pub fn insert_idx(&mut self, target: PlaceIndex, result: ValueOrPlace<V>, map: &Map) {
+ fn insert_idx(&mut self, target: PlaceIndex, result: ValueOrPlace<V>, map: &Map) {
match result {
ValueOrPlace::Value(value) => self.insert_value_idx(target, value, map),
ValueOrPlace::Place(source) => self.insert_place_idx(target, source, map),
@@ -841,7 +823,7 @@ impl Map {
) {
// Allocate a value slot if it doesn't have one, and the user requested one.
assert!(self.places[place].value_index.is_none());
- if tcx.layout_of(param_env.and(ty)).map_or(false, |layout| layout.abi.is_scalar()) {
+ if tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| layout.abi.is_scalar()) {
self.places[place].value_index = Some(self.value_count.into());
self.value_count += 1;
}
@@ -910,18 +892,13 @@ impl Map {
self.inner_values[root] = start..end;
}
- /// Returns the number of tracked places, i.e., those for which a value can be stored.
- pub fn tracked_places(&self) -> usize {
- self.value_count
- }
-
/// Applies a single projection element, yielding the corresponding child.
pub fn apply(&self, place: PlaceIndex, elem: TrackElem) -> Option<PlaceIndex> {
self.projections.get(&(place, elem)).copied()
}
/// Locates the given place, if it exists in the tree.
- pub fn find_extra(
+ fn find_extra(
&self,
place: PlaceRef<'_>,
extra: impl IntoIterator<Item = TrackElem>,
@@ -954,7 +931,7 @@ impl Map {
}
/// Iterate over all direct children.
- pub fn children(&self, parent: PlaceIndex) -> impl Iterator<Item = PlaceIndex> + '_ {
+ fn children(&self, parent: PlaceIndex) -> impl Iterator<Item = PlaceIndex> + '_ {
Children::new(self, parent)
}
@@ -979,11 +956,7 @@ impl Map {
// The local is not tracked at all, so it does not alias anything.
return;
};
- let elems = place
- .projection
- .iter()
- .map(|&elem| elem.try_into())
- .chain(tail_elem.map(Ok).into_iter());
+ let elems = place.projection.iter().map(|&elem| elem.try_into()).chain(tail_elem.map(Ok));
for elem in elems {
// A field aliases the parent place.
if let Some(vi) = self.places[index].value_index {