Introduce MaybeUnreachable.
This commit is contained in:
parent
934a99eb65
commit
32711b2b4e
4 changed files with 136 additions and 3 deletions
|
@ -1,6 +1,7 @@
|
||||||
//! Custom formatting traits used when outputting Graphviz diagrams with the results of a dataflow
|
//! Custom formatting traits used when outputting Graphviz diagrams with the results of a dataflow
|
||||||
//! analysis.
|
//! analysis.
|
||||||
|
|
||||||
|
use super::lattice::MaybeUnreachable;
|
||||||
use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet};
|
use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet};
|
||||||
use rustc_index::Idx;
|
use rustc_index::Idx;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -124,6 +125,37 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S, C> DebugWithContext<C> for MaybeUnreachable<S>
|
||||||
|
where
|
||||||
|
S: DebugWithContext<C>,
|
||||||
|
{
|
||||||
|
fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => {
|
||||||
|
write!(f, "unreachable")
|
||||||
|
}
|
||||||
|
MaybeUnreachable::Reachable(set) => set.fmt_with(ctxt, f),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
match (self, old) {
|
||||||
|
(MaybeUnreachable::Unreachable, MaybeUnreachable::Unreachable) => Ok(()),
|
||||||
|
(MaybeUnreachable::Unreachable, MaybeUnreachable::Reachable(set)) => {
|
||||||
|
write!(f, "\u{001f}+")?;
|
||||||
|
set.fmt_with(ctxt, f)
|
||||||
|
}
|
||||||
|
(MaybeUnreachable::Reachable(set), MaybeUnreachable::Unreachable) => {
|
||||||
|
write!(f, "\u{001f}-")?;
|
||||||
|
set.fmt_with(ctxt, f)
|
||||||
|
}
|
||||||
|
(MaybeUnreachable::Reachable(this), MaybeUnreachable::Reachable(old)) => {
|
||||||
|
this.fmt_diff_with(old, ctxt, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn fmt_diff<T, C>(
|
fn fmt_diff<T, C>(
|
||||||
inserted: &HybridBitSet<T>,
|
inserted: &HybridBitSet<T>,
|
||||||
removed: &HybridBitSet<T>,
|
removed: &HybridBitSet<T>,
|
||||||
|
|
|
@ -272,3 +272,88 @@ impl<T> HasBottom for FlatSet<T> {
|
||||||
impl<T> HasTop for FlatSet<T> {
|
impl<T> HasTop for FlatSet<T> {
|
||||||
const TOP: Self = Self::Top;
|
const TOP: Self = Self::Top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
|
pub enum MaybeUnreachable<T> {
|
||||||
|
Unreachable,
|
||||||
|
Reachable(T),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MaybeUnreachable<T> {
|
||||||
|
pub fn is_reachable(&self) -> bool {
|
||||||
|
matches!(self, MaybeUnreachable::Reachable(_))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> HasBottom for MaybeUnreachable<T> {
|
||||||
|
const BOTTOM: Self = MaybeUnreachable::Unreachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: HasTop> HasTop for MaybeUnreachable<T> {
|
||||||
|
const TOP: Self = MaybeUnreachable::Reachable(T::TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<S> MaybeUnreachable<S> {
|
||||||
|
pub fn contains<T>(&self, elem: T) -> bool
|
||||||
|
where
|
||||||
|
S: BitSetExt<T>,
|
||||||
|
{
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => false,
|
||||||
|
MaybeUnreachable::Reachable(set) => set.contains(elem),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, S: BitSetExt<T>> BitSetExt<T> for MaybeUnreachable<S> {
|
||||||
|
fn contains(&self, elem: T) -> bool {
|
||||||
|
self.contains(elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn union(&mut self, other: &HybridBitSet<T>) {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => {}
|
||||||
|
MaybeUnreachable::Reachable(set) => set.union(other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subtract(&mut self, other: &HybridBitSet<T>) {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => {}
|
||||||
|
MaybeUnreachable::Reachable(set) => set.subtract(other),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: Clone> Clone for MaybeUnreachable<V> {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Reachable(x) => MaybeUnreachable::Reachable(x.clone()),
|
||||||
|
MaybeUnreachable::Unreachable => MaybeUnreachable::Unreachable,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clone_from(&mut self, source: &Self) {
|
||||||
|
match (&mut *self, source) {
|
||||||
|
(MaybeUnreachable::Reachable(x), MaybeUnreachable::Reachable(y)) => {
|
||||||
|
x.clone_from(&y);
|
||||||
|
}
|
||||||
|
_ => *self = source.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: JoinSemiLattice + Clone> JoinSemiLattice for MaybeUnreachable<T> {
|
||||||
|
fn join(&mut self, other: &Self) -> bool {
|
||||||
|
match (&mut *self, &other) {
|
||||||
|
(_, MaybeUnreachable::Unreachable) => false,
|
||||||
|
(MaybeUnreachable::Unreachable, _) => {
|
||||||
|
*self = other.clone();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
(MaybeUnreachable::Reachable(this), MaybeUnreachable::Reachable(other)) => {
|
||||||
|
this.join(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ mod visitor;
|
||||||
pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
|
pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
|
||||||
pub use self::direction::{Backward, Direction, Forward};
|
pub use self::direction::{Backward, Direction, Forward};
|
||||||
pub use self::engine::{Engine, EntrySets, Results, ResultsCloned};
|
pub use self::engine::{Engine, EntrySets, Results, ResultsCloned};
|
||||||
pub use self::lattice::{JoinSemiLattice, MeetSemiLattice};
|
pub use self::lattice::{JoinSemiLattice, MaybeUnreachable, MeetSemiLattice};
|
||||||
pub use self::visitor::{visit_results, ResultsVisitable, ResultsVisitor};
|
pub use self::visitor::{visit_results, ResultsVisitable, ResultsVisitor};
|
||||||
|
|
||||||
/// Analysis domains are all bitsets of various kinds. This trait holds
|
/// Analysis domains are all bitsets of various kinds. This trait holds
|
||||||
|
@ -524,6 +524,22 @@ impl<T: Idx> GenKill<T> for ChunkedBitSet<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, S: GenKill<T>> GenKill<T> for MaybeUnreachable<S> {
|
||||||
|
fn gen(&mut self, elem: T) {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => {}
|
||||||
|
MaybeUnreachable::Reachable(set) => set.gen(elem),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kill(&mut self, elem: T) {
|
||||||
|
match self {
|
||||||
|
MaybeUnreachable::Unreachable => {}
|
||||||
|
MaybeUnreachable::Reachable(set) => set.kill(elem),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
|
impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
|
||||||
fn gen(&mut self, elem: T) {
|
fn gen(&mut self, elem: T) {
|
||||||
self.0.insert(elem);
|
self.0.insert(elem);
|
||||||
|
|
|
@ -29,8 +29,8 @@ pub use self::drop_flag_effects::{
|
||||||
pub use self::framework::{
|
pub use self::framework::{
|
||||||
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward,
|
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward,
|
||||||
CallReturnPlaces, CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis,
|
CallReturnPlaces, CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis,
|
||||||
JoinSemiLattice, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor,
|
JoinSemiLattice, MaybeUnreachable, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor,
|
||||||
ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
|
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::move_paths::MoveData;
|
use self::move_paths::MoveData;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue