Make Analysis immutable in many more places.
The `state: A::Domain` value is the primary things that's modified when performing an analysis. The `Analysis` impl is immutable in every case but one (`MaybeRequiredStorage`) and it now uses interior mutability. As well as changing many `&mut A` arguments to `&A`, this also: - lets `CowMut` be replaced with the simpler `SimpleCow` in `cursor.rs`; - removes the need for the `RefCell` in `Formatter`; - removes the need for `MaybeBorrowedLocals` to impl `Clone`, because it's a unit type and it's now clear that its constructor can be used directly instead of being put into a local variable and cloned.
This commit is contained in:
parent
8afbd9fe02
commit
a97cd3ba57
16 changed files with 111 additions and 140 deletions
|
|
@ -44,7 +44,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &mir::Statement<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -55,7 +55,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &mir::Statement<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -66,7 +66,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_terminator_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
term: &mir::Terminator<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -77,7 +77,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
term: &'mir mir::Terminator<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -92,7 +92,7 @@ impl<'a, 'tcx> Analysis<'tcx> for Borrowck<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_state: &mut Self::Domain,
|
||||
_block: BasicBlock,
|
||||
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
@ -533,7 +533,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -542,7 +542,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -590,7 +590,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_terminator_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_terminator: &mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -599,7 +599,7 @@ impl<'tcx> rustc_mir_dataflow::Analysis<'tcx> for Borrows<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
_location: Location,
|
||||
|
|
|
|||
|
|
@ -537,13 +537,13 @@ fn borrowck_check_region_constraints<'tcx>(
|
|||
mbcx.report_region_errors(nll_errors);
|
||||
}
|
||||
|
||||
let (mut flow_analysis, flow_entry_states) =
|
||||
let (flow_analysis, flow_results) =
|
||||
get_flow_results(tcx, body, &move_data, &borrow_set, ®ioncx);
|
||||
visit_results(
|
||||
body,
|
||||
traversal::reverse_postorder(body).map(|(bb, _)| bb),
|
||||
&mut flow_analysis,
|
||||
&flow_entry_states,
|
||||
&flow_analysis,
|
||||
&flow_results,
|
||||
&mut mbcx,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ where
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -341,7 +341,7 @@ where
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -351,7 +351,7 @@ where
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
block: BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
//! Random access inspection of the results of a dataflow analysis.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::ops::Deref;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
use rustc_index::bit_set::DenseBitSet;
|
||||
|
|
@ -10,30 +9,20 @@ use rustc_middle::mir::{self, BasicBlock, Location};
|
|||
|
||||
use super::{Analysis, Direction, Effect, EffectIndex, Results};
|
||||
|
||||
/// Some `ResultsCursor`s want to own an `Analysis`, and some want to borrow an `Analysis`, either
|
||||
/// mutable or immutably. This type allows all of the above. It's similar to `Cow`, but `Cow`
|
||||
/// doesn't allow mutable borrowing.
|
||||
enum CowMut<'a, T> {
|
||||
BorrowedMut(&'a mut T),
|
||||
/// This is like `Cow`, but it lacks the `T: ToOwned` bound and doesn't support
|
||||
/// `to_owned`/`into_owned`.
|
||||
enum SimpleCow<'a, T> {
|
||||
Borrowed(&'a T),
|
||||
Owned(T),
|
||||
}
|
||||
|
||||
impl<T> Deref for CowMut<'_, T> {
|
||||
impl<T> Deref for SimpleCow<'_, T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &T {
|
||||
match self {
|
||||
CowMut::BorrowedMut(borrowed) => borrowed,
|
||||
CowMut::Owned(owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> DerefMut for CowMut<'_, T> {
|
||||
fn deref_mut(&mut self) -> &mut T {
|
||||
match self {
|
||||
CowMut::BorrowedMut(borrowed) => borrowed,
|
||||
CowMut::Owned(owned) => owned,
|
||||
SimpleCow::Borrowed(borrowed) => borrowed,
|
||||
SimpleCow::Owned(owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -53,8 +42,8 @@ where
|
|||
A: Analysis<'tcx>,
|
||||
{
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
analysis: CowMut<'mir, A>,
|
||||
results: Cow<'mir, Results<A::Domain>>,
|
||||
analysis: SimpleCow<'mir, A>,
|
||||
results: SimpleCow<'mir, Results<A::Domain>>,
|
||||
state: A::Domain,
|
||||
|
||||
pos: CursorPosition,
|
||||
|
|
@ -84,8 +73,8 @@ where
|
|||
|
||||
fn new(
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
analysis: CowMut<'mir, A>,
|
||||
results: Cow<'mir, Results<A::Domain>>,
|
||||
analysis: SimpleCow<'mir, A>,
|
||||
results: SimpleCow<'mir, Results<A::Domain>>,
|
||||
) -> Self {
|
||||
let bottom_value = analysis.bottom_value(body);
|
||||
ResultsCursor {
|
||||
|
|
@ -111,16 +100,16 @@ where
|
|||
analysis: A,
|
||||
results: Results<A::Domain>,
|
||||
) -> Self {
|
||||
Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
|
||||
Self::new(body, SimpleCow::Owned(analysis), SimpleCow::Owned(results))
|
||||
}
|
||||
|
||||
/// Returns a new cursor that borrows and inspects analysis results.
|
||||
pub fn new_borrowing(
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
analysis: &'mir mut A,
|
||||
analysis: &'mir A,
|
||||
results: &'mir Results<A::Domain>,
|
||||
) -> Self {
|
||||
Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
|
||||
Self::new(body, SimpleCow::Borrowed(analysis), SimpleCow::Borrowed(results))
|
||||
}
|
||||
|
||||
/// Allows inspection of unreachable basic blocks even with `debug_assertions` enabled.
|
||||
|
|
@ -236,7 +225,7 @@ where
|
|||
let target_effect_index = effect.at_index(target.statement_index);
|
||||
|
||||
A::Direction::apply_effects_in_range(
|
||||
&mut *self.analysis,
|
||||
&*self.analysis,
|
||||
&mut self.state,
|
||||
target.block,
|
||||
block_data,
|
||||
|
|
@ -251,8 +240,8 @@ 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.analysis, &mut self.state);
|
||||
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
|
||||
f(&self.analysis, &mut self.state);
|
||||
self.state_needs_reset = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ pub trait Direction {
|
|||
|
||||
/// Called by `iterate_to_fixpoint` during initial analysis computation.
|
||||
fn apply_effects_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
body: &mir::Body<'tcx>,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
|
|
@ -28,7 +28,7 @@ pub trait Direction {
|
|||
///
|
||||
/// `effects.start()` must precede or equal `effects.end()` in this direction.
|
||||
fn apply_effects_in_range<'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &mir::BasicBlockData<'tcx>,
|
||||
|
|
@ -40,7 +40,7 @@ pub trait Direction {
|
|||
/// all locations in a basic block (starting from `entry_state` and to
|
||||
/// visit them with `vis`.
|
||||
fn visit_results_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &'mir mir::BasicBlockData<'tcx>,
|
||||
|
|
@ -56,7 +56,7 @@ impl Direction for Backward {
|
|||
const IS_FORWARD: bool = false;
|
||||
|
||||
fn apply_effects_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
body: &mir::Body<'tcx>,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
|
|
@ -129,7 +129,7 @@ impl Direction for Backward {
|
|||
}
|
||||
|
||||
fn apply_effects_in_range<'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &mir::BasicBlockData<'tcx>,
|
||||
|
|
@ -206,7 +206,7 @@ impl Direction for Backward {
|
|||
}
|
||||
|
||||
fn visit_results_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &'mir mir::BasicBlockData<'tcx>,
|
||||
|
|
@ -242,7 +242,7 @@ impl Direction for Forward {
|
|||
const IS_FORWARD: bool = true;
|
||||
|
||||
fn apply_effects_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
body: &mir::Body<'tcx>,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
|
|
@ -312,7 +312,7 @@ impl Direction for Forward {
|
|||
}
|
||||
|
||||
fn apply_effects_in_range<'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &mir::BasicBlockData<'tcx>,
|
||||
|
|
@ -386,7 +386,7 @@ impl Direction for Forward {
|
|||
}
|
||||
|
||||
fn visit_results_in_block<'mir, 'tcx, A>(
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
state: &mut A::Domain,
|
||||
block: BasicBlock,
|
||||
block_data: &'mir mir::BasicBlockData<'tcx>,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
//! A helpful diagram for debugging dataflow problems.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::OsString;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::OnceLock;
|
||||
|
|
@ -33,7 +32,7 @@ use crate::errors::{
|
|||
pub(super) fn write_graphviz_results<'tcx, A>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &Body<'tcx>,
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
results: &Results<A::Domain>,
|
||||
pass_name: Option<&'static str>,
|
||||
) -> std::io::Result<()>
|
||||
|
|
@ -206,11 +205,7 @@ where
|
|||
A: Analysis<'tcx>,
|
||||
{
|
||||
body: &'mir Body<'tcx>,
|
||||
// The `RefCell` is used because `<Formatter as Labeller>::node_label`
|
||||
// takes `&self`, but it needs to modify the analysis. This is also the
|
||||
// reason for the `Formatter`/`BlockFormatter` split; `BlockFormatter` has
|
||||
// the operations that involve the mutation, i.e. within the `borrow_mut`.
|
||||
analysis: RefCell<&'mir mut A>,
|
||||
analysis: &'mir A,
|
||||
results: &'mir Results<A::Domain>,
|
||||
style: OutputStyle,
|
||||
reachable: DenseBitSet<BasicBlock>,
|
||||
|
|
@ -222,12 +217,12 @@ where
|
|||
{
|
||||
fn new(
|
||||
body: &'mir Body<'tcx>,
|
||||
analysis: &'mir mut A,
|
||||
analysis: &'mir A,
|
||||
results: &'mir Results<A::Domain>,
|
||||
style: OutputStyle,
|
||||
) -> Self {
|
||||
let reachable = traversal::reachable_as_bitset(body);
|
||||
Formatter { body, analysis: analysis.into(), results, style, reachable }
|
||||
Formatter { body, analysis, results, style, reachable }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -265,12 +260,11 @@ where
|
|||
}
|
||||
|
||||
fn node_label(&self, block: &Self::Node) -> dot::LabelText<'_> {
|
||||
let analysis = &mut **self.analysis.borrow_mut();
|
||||
|
||||
let diffs = StateDiffCollector::run(self.body, *block, analysis, self.results, self.style);
|
||||
let diffs =
|
||||
StateDiffCollector::run(self.body, *block, self.analysis, self.results, self.style);
|
||||
|
||||
let mut fmt = BlockFormatter {
|
||||
cursor: ResultsCursor::new_borrowing(self.body, analysis, self.results),
|
||||
cursor: ResultsCursor::new_borrowing(self.body, self.analysis, self.results),
|
||||
style: self.style,
|
||||
bg: Background::Light,
|
||||
};
|
||||
|
|
@ -698,7 +692,7 @@ impl<D> StateDiffCollector<D> {
|
|||
fn run<'tcx, A>(
|
||||
body: &Body<'tcx>,
|
||||
block: BasicBlock,
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
results: &Results<A::Domain>,
|
||||
style: OutputStyle,
|
||||
) -> Self
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ pub trait Analysis<'tcx> {
|
|||
/// analyses should not implement this without also implementing
|
||||
/// `apply_primary_statement_effect`.
|
||||
fn apply_early_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_state: &mut Self::Domain,
|
||||
_statement: &mir::Statement<'tcx>,
|
||||
_location: Location,
|
||||
|
|
@ -145,7 +145,7 @@ pub trait Analysis<'tcx> {
|
|||
|
||||
/// Updates the current dataflow state with the effect of evaluating a statement.
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -159,7 +159,7 @@ pub trait Analysis<'tcx> {
|
|||
/// analyses should not implement this without also implementing
|
||||
/// `apply_primary_terminator_effect`.
|
||||
fn apply_early_terminator_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_state: &mut Self::Domain,
|
||||
_terminator: &mir::Terminator<'tcx>,
|
||||
_location: Location,
|
||||
|
|
@ -173,7 +173,7 @@ pub trait Analysis<'tcx> {
|
|||
/// `InitializedPlaces` analyses, the return place for a function call is not marked as
|
||||
/// initialized here.
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
_state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
_location: Location,
|
||||
|
|
@ -189,7 +189,7 @@ pub trait Analysis<'tcx> {
|
|||
/// This is separate from `apply_primary_terminator_effect` to properly track state across
|
||||
/// unwind edges.
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_state: &mut Self::Domain,
|
||||
_block: BasicBlock,
|
||||
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
@ -211,7 +211,7 @@ pub trait Analysis<'tcx> {
|
|||
/// engine doesn't need to clone the exit state for a block unless
|
||||
/// `get_switch_int_data` is actually called.
|
||||
fn get_switch_int_data(
|
||||
&mut self,
|
||||
&self,
|
||||
_block: mir::BasicBlock,
|
||||
_discr: &mir::Operand<'tcx>,
|
||||
) -> Option<Self::SwitchIntData> {
|
||||
|
|
@ -220,7 +220,7 @@ pub trait Analysis<'tcx> {
|
|||
|
||||
/// See comments on `get_switch_int_data`.
|
||||
fn apply_switch_int_edge_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_data: &mut Self::SwitchIntData,
|
||||
_state: &mut Self::Domain,
|
||||
_value: SwitchTargetValue,
|
||||
|
|
@ -245,7 +245,7 @@ pub trait Analysis<'tcx> {
|
|||
/// Without a `pass_name` to differentiates them, only the results for the latest run will be
|
||||
/// saved.
|
||||
fn iterate_to_fixpoint<'mir>(
|
||||
mut self,
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
pass_name: Option<&'static str>,
|
||||
|
|
@ -285,7 +285,7 @@ pub trait Analysis<'tcx> {
|
|||
state.clone_from(&results[bb]);
|
||||
|
||||
Self::Direction::apply_effects_in_block(
|
||||
&mut self,
|
||||
&self,
|
||||
body,
|
||||
&mut state,
|
||||
bb,
|
||||
|
|
@ -300,7 +300,7 @@ pub trait Analysis<'tcx> {
|
|||
}
|
||||
|
||||
if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
|
||||
let res = write_graphviz_results(tcx, body, &mut self, &results, pass_name);
|
||||
let res = write_graphviz_results(tcx, body, &self, &results, pass_name);
|
||||
if let Err(e) = res {
|
||||
error!("Failed to write graphviz dataflow results: {}", e);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
|
|||
}
|
||||
|
||||
fn apply_early_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -185,7 +185,7 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -195,7 +195,7 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
|
|||
}
|
||||
|
||||
fn apply_early_terminator_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_terminator: &mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -205,7 +205,7 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use super::{Analysis, Direction, Results};
|
|||
pub fn visit_results<'mir, 'tcx, A>(
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
blocks: impl IntoIterator<Item = BasicBlock>,
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
results: &Results<A::Domain>,
|
||||
vis: &mut impl ResultsVisitor<'tcx, A>,
|
||||
) where
|
||||
|
|
@ -31,7 +31,7 @@ pub fn visit_results<'mir, 'tcx, A>(
|
|||
/// Like `visit_results`, but only for reachable blocks.
|
||||
pub fn visit_reachable_results<'mir, 'tcx, A>(
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
analysis: &mut A,
|
||||
analysis: &A,
|
||||
results: &Results<A::Domain>,
|
||||
vis: &mut impl ResultsVisitor<'tcx, A>,
|
||||
) where
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ use crate::{Analysis, GenKill};
|
|||
/// At present, this is used as a very limited form of alias analysis. For example,
|
||||
/// `MaybeBorrowedLocals` is used to compute which locals are live during a yield expression for
|
||||
/// immovable coroutines.
|
||||
#[derive(Clone)]
|
||||
pub struct MaybeBorrowedLocals;
|
||||
|
||||
impl MaybeBorrowedLocals {
|
||||
|
|
@ -34,7 +33,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -43,7 +42,7 @@ impl<'tcx> Analysis<'tcx> for MaybeBorrowedLocals {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
|
|||
|
|
@ -376,7 +376,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -400,7 +400,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -429,7 +429,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: mir::BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
@ -448,7 +448,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_switch_int_data(
|
||||
&mut self,
|
||||
&self,
|
||||
block: mir::BasicBlock,
|
||||
discr: &mir::Operand<'tcx>,
|
||||
) -> Option<Self::SwitchIntData> {
|
||||
|
|
@ -460,7 +460,7 @@ impl<'tcx> Analysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_switch_int_edge_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
data: &mut Self::SwitchIntData,
|
||||
state: &mut Self::Domain,
|
||||
value: SwitchTargetValue,
|
||||
|
|
@ -513,7 +513,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -527,7 +527,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -545,7 +545,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: mir::BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
@ -564,7 +564,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn get_switch_int_data(
|
||||
&mut self,
|
||||
&self,
|
||||
block: mir::BasicBlock,
|
||||
discr: &mir::Operand<'tcx>,
|
||||
) -> Option<Self::SwitchIntData> {
|
||||
|
|
@ -580,7 +580,7 @@ impl<'tcx> Analysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_switch_int_edge_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
data: &mut Self::SwitchIntData,
|
||||
state: &mut Self::Domain,
|
||||
value: SwitchTargetValue,
|
||||
|
|
@ -627,7 +627,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
|||
|
||||
#[instrument(skip(self, state), level = "debug")]
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -652,7 +652,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
|||
|
||||
#[instrument(skip(self, state, terminator), level = "debug")]
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -674,7 +674,7 @@ impl<'tcx> Analysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
block: mir::BasicBlock,
|
||||
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -50,7 +50,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -60,7 +60,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLiveLocals {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: mir::BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
@ -278,7 +278,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &mir::Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -294,7 +294,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir mir::Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -304,7 +304,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: mir::BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageLive<'a> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &Statement<'tcx>,
|
||||
_: Location,
|
||||
|
|
@ -98,7 +98,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeStorageDead<'a> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &Statement<'tcx>,
|
||||
_: Location,
|
||||
|
|
@ -144,7 +144,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
stmt: &Statement<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -177,7 +177,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_: &Statement<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -188,7 +188,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_early_terminator_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &Terminator<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -243,7 +243,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'t>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'t Terminator<'tcx>,
|
||||
loc: Location,
|
||||
|
|
@ -284,7 +284,7 @@ impl<'tcx> Analysis<'tcx> for MaybeRequiresStorage<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -720,27 +720,16 @@ fn locals_live_across_suspend_points<'tcx>(
|
|||
|
||||
// Calculate the MIR locals that have been previously borrowed (even if they are still active).
|
||||
let borrowed_locals = MaybeBorrowedLocals.iterate_to_fixpoint(tcx, body, Some("coroutine"));
|
||||
let mut borrowed_locals_analysis1 = borrowed_locals.analysis;
|
||||
let mut borrowed_locals_analysis2 = borrowed_locals_analysis1.clone(); // trivial
|
||||
let borrowed_locals_cursor1 = ResultsCursor::new_borrowing(
|
||||
body,
|
||||
&mut borrowed_locals_analysis1,
|
||||
&borrowed_locals.results,
|
||||
);
|
||||
let mut borrowed_locals_cursor2 = ResultsCursor::new_borrowing(
|
||||
body,
|
||||
&mut borrowed_locals_analysis2,
|
||||
&borrowed_locals.results,
|
||||
);
|
||||
let borrowed_locals_cursor1 =
|
||||
ResultsCursor::new_borrowing(body, &MaybeBorrowedLocals, &borrowed_locals.results);
|
||||
let mut borrowed_locals_cursor2 =
|
||||
ResultsCursor::new_borrowing(body, &MaybeBorrowedLocals, &borrowed_locals.results);
|
||||
|
||||
// Calculate the MIR locals that we need to keep storage around for.
|
||||
let mut requires_storage =
|
||||
let requires_storage =
|
||||
MaybeRequiresStorage::new(borrowed_locals_cursor1).iterate_to_fixpoint(tcx, body, None);
|
||||
let mut requires_storage_cursor = ResultsCursor::new_borrowing(
|
||||
body,
|
||||
&mut requires_storage.analysis,
|
||||
&requires_storage.results,
|
||||
);
|
||||
let mut requires_storage_cursor =
|
||||
ResultsCursor::new_borrowing(body, &requires_storage.analysis, &requires_storage.results);
|
||||
|
||||
// Calculate the liveness of MIR locals ignoring borrows.
|
||||
let mut liveness =
|
||||
|
|
@ -812,7 +801,7 @@ fn locals_live_across_suspend_points<'tcx>(
|
|||
body,
|
||||
&saved_locals,
|
||||
always_live_locals.clone(),
|
||||
&mut requires_storage.analysis,
|
||||
&requires_storage.analysis,
|
||||
&requires_storage.results,
|
||||
);
|
||||
|
||||
|
|
@ -878,7 +867,7 @@ fn compute_storage_conflicts<'mir, 'tcx>(
|
|||
body: &'mir Body<'tcx>,
|
||||
saved_locals: &'mir CoroutineSavedLocals,
|
||||
always_live_locals: DenseBitSet<Local>,
|
||||
analysis: &mut MaybeRequiresStorage<'mir, 'tcx>,
|
||||
analysis: &MaybeRequiresStorage<'mir, 'tcx>,
|
||||
results: &Results<DenseBitSet<Local>>,
|
||||
) -> BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal> {
|
||||
assert_eq!(body.local_decls.len(), saved_locals.domain_size());
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
|
|||
let map = Map::new(tcx, body, place_limit);
|
||||
|
||||
// Perform the actual dataflow analysis.
|
||||
let mut const_ = debug_span!("analyze")
|
||||
let const_ = debug_span!("analyze")
|
||||
.in_scope(|| ConstAnalysis::new(tcx, body, map).iterate_to_fixpoint(tcx, body, None));
|
||||
|
||||
// Collect results and patch the body afterwards.
|
||||
let mut visitor = Collector::new(tcx, &body.local_decls);
|
||||
debug_span!("collect").in_scope(|| {
|
||||
visit_reachable_results(body, &mut const_.analysis, &const_.results, &mut visitor)
|
||||
visit_reachable_results(body, &const_.analysis, &const_.results, &mut visitor)
|
||||
});
|
||||
let mut patch = visitor.patch;
|
||||
debug_span!("patch").in_scope(|| patch.visit_body_preserves_cfg(body));
|
||||
|
|
@ -112,7 +112,7 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
statement: &Statement<'tcx>,
|
||||
_location: Location,
|
||||
|
|
@ -123,7 +123,7 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
terminator: &'mir Terminator<'tcx>,
|
||||
_location: Location,
|
||||
|
|
@ -136,7 +136,7 @@ impl<'tcx> Analysis<'tcx> for ConstAnalysis<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
state: &mut Self::Domain,
|
||||
_block: BasicBlock,
|
||||
return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
|
|
@ -1160,7 +1160,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLivePlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_statement_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
trans: &mut Self::Domain,
|
||||
statement: &Statement<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -1169,7 +1169,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLivePlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_primary_terminator_effect<'mir>(
|
||||
&mut self,
|
||||
&self,
|
||||
trans: &mut Self::Domain,
|
||||
terminator: &'mir Terminator<'tcx>,
|
||||
location: Location,
|
||||
|
|
@ -1179,7 +1179,7 @@ impl<'tcx> Analysis<'tcx> for MaybeLivePlaces<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn apply_call_return_effect(
|
||||
&mut self,
|
||||
&self,
|
||||
_trans: &mut Self::Domain,
|
||||
_block: BasicBlock,
|
||||
_return_places: CallReturnPlaces<'_, 'tcx>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue