Make it possible for ResultsCursor
to borrow a Results
.
`ResultsCursor` currently owns its `Results`. But sometimes the `Results` is needed again afterwards. So there is `ResultsCursor::into_results` for extracting the `Results`, which leads to some awkwardness. This commit adds `ResultsHandle`, a `Cow`-like type that can either borrow or own a a `Results`. `ResultsCursor` now uses it. This is good because some `ResultsCursor`s really want to own their `Results`, while others just want to borrow it. We end with with a few more lines of code, but get some nice cleanups. - `ResultsCursor::into_results` and `Formatter::into_results` are removed. - `write_graphviz_results` now just borrows a `Results`, instead of the awkward "take ownership of a `Results` and then return it unchanged" pattern. This reinstates the cursor flexibility that was lost in #118230 -- which removed the old `ResultsRefCursor` and `ResultsCloneCursor` types -- but in a much simpler way. Hooray!
This commit is contained in:
parent
1914dbe694
commit
be7c6a3b43
5 changed files with 81 additions and 31 deletions
|
@ -1,6 +1,7 @@
|
|||
//! Random access inspection of the results of a dataflow analysis.
|
||||
|
||||
use std::cmp::Ordering;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
use rustc_index::bit_set::BitSet;
|
||||
|
@ -8,6 +9,47 @@ use rustc_middle::mir::{self, BasicBlock, Location};
|
|||
|
||||
use super::{Analysis, Direction, Effect, EffectIndex, Results};
|
||||
|
||||
/// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`, either
|
||||
/// mutable or immutably. This type allows all of the above. It's similar to `Cow`.
|
||||
pub enum ResultsHandle<'a, 'tcx, A>
|
||||
where
|
||||
A: Analysis<'tcx>,
|
||||
{
|
||||
Borrowed(&'a Results<'tcx, A>),
|
||||
BorrowedMut(&'a mut Results<'tcx, A>),
|
||||
Owned(Results<'tcx, A>),
|
||||
}
|
||||
|
||||
impl<'tcx, A> Deref for ResultsHandle<'_, 'tcx, A>
|
||||
where
|
||||
A: Analysis<'tcx>,
|
||||
{
|
||||
type Target = Results<'tcx, A>;
|
||||
|
||||
fn deref(&self) -> &Results<'tcx, A> {
|
||||
match self {
|
||||
ResultsHandle::Borrowed(borrowed) => borrowed,
|
||||
ResultsHandle::BorrowedMut(borrowed) => borrowed,
|
||||
ResultsHandle::Owned(owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, A> DerefMut for ResultsHandle<'_, 'tcx, A>
|
||||
where
|
||||
A: Analysis<'tcx>,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut Results<'tcx, A> {
|
||||
match self {
|
||||
ResultsHandle::Borrowed(_borrowed) => {
|
||||
panic!("tried to deref_mut a `ResultsHandle::Borrowed")
|
||||
}
|
||||
ResultsHandle::BorrowedMut(borrowed) => borrowed,
|
||||
ResultsHandle::Owned(owned) => owned,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows random access inspection of the results of a dataflow analysis. Use this when you want
|
||||
/// to inspect domain values only in certain locations; use `ResultsVisitor` if you want to inspect
|
||||
/// domain values in many or all locations.
|
||||
|
@ -23,7 +65,7 @@ where
|
|||
A: Analysis<'tcx>,
|
||||
{
|
||||
body: &'mir mir::Body<'tcx>,
|
||||
results: Results<'tcx, A>,
|
||||
results: ResultsHandle<'mir, 'tcx, A>,
|
||||
state: A::Domain,
|
||||
|
||||
pos: CursorPosition,
|
||||
|
@ -51,13 +93,8 @@ where
|
|||
self.body
|
||||
}
|
||||
|
||||
/// Unwraps this cursor, returning the underlying `Results`.
|
||||
pub fn into_results(self) -> Results<'tcx, A> {
|
||||
self.results
|
||||
}
|
||||
|
||||
/// Returns a new cursor that can inspect `results`.
|
||||
pub fn new(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
|
||||
pub fn new(body: &'mir mir::Body<'tcx>, results: ResultsHandle<'mir, 'tcx, A>) -> Self {
|
||||
let bottom_value = results.analysis.bottom_value(body);
|
||||
ResultsCursor {
|
||||
body,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue