rust/compiler/rustc_mir_dataflow/src/framework/results.rs
Nicholas Nethercote 92799b6f89 Separate Analysis and Results.
`Results` contains and `Analysis` and an `EntryStates`. The unfortunate
thing about this is that the analysis needs to be mutable everywhere
(`&mut Analysis`) which forces the `Results` to be mutable everywhere,
even though `EntryStates` is immutable everywhere.

To fix this, this commit renames `Results` as `AnalysisAndResults`,
renames `EntryStates` as `Results`, and separates the analysis and
results as much as possible. (`AnalysisAndResults` doesn't get much use,
it's mostly there to facilitate method chaining of
`iterate_to_fixpoint`.)

`Results` is immutable everywhere, which:
- is a bit clearer on how the data is used,
- avoids an unnecessary clone of entry states in
  `locals_live_across_suspend_points`, and
- moves the results outside the `RefCell` in Formatter.

The commit also reformulates `ResultsHandle` as the generic `CowMut`,
which is simpler than `ResultsHandle` because it doesn't need the
`'tcx` lifetime and the trait bounds. It also which sits nicely
alongside the new use of `Cow` in `ResultsCursor`.
2025-04-24 11:36:07 +10:00

30 lines
1,014 B
Rust

//! Dataflow analysis results.
use rustc_index::IndexVec;
use rustc_middle::mir::{BasicBlock, Body};
use super::{Analysis, ResultsCursor};
/// The results of a dataflow analysis that has converged to fixpoint. It only holds the domain
/// values at the entry of each basic block. Domain values in other parts of the block are
/// recomputed on the fly by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
pub type Results<D> = IndexVec<BasicBlock, D>;
/// Utility type used in a few places where it's convenient to bundle an analysis with its results.
pub struct AnalysisAndResults<'tcx, A>
where
A: Analysis<'tcx>,
{
pub analysis: A,
pub results: Results<A::Domain>,
}
impl<'tcx, A> AnalysisAndResults<'tcx, A>
where
A: Analysis<'tcx>,
{
/// Creates a `ResultsCursor` that takes ownership of `self`.
pub fn into_results_cursor<'mir>(self, body: &'mir Body<'tcx>) -> ResultsCursor<'mir, 'tcx, A> {
ResultsCursor::new_owning(body, self.analysis, self.results)
}
}