Skip to content

Commit 32711b2

Browse files
committed
Introduce MaybeUnreachable.
1 parent 934a99e commit 32711b2

File tree

4 files changed

+136
-3
lines changed

4 files changed

+136
-3
lines changed

compiler/rustc_mir_dataflow/src/framework/fmt.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Custom formatting traits used when outputting Graphviz diagrams with the results of a dataflow
22
//! analysis.
33
4+
use super::lattice::MaybeUnreachable;
45
use rustc_index::bit_set::{BitSet, ChunkedBitSet, HybridBitSet};
56
use rustc_index::Idx;
67
use std::fmt;
@@ -124,6 +125,37 @@ where
124125
}
125126
}
126127

128+
impl<S, C> DebugWithContext<C> for MaybeUnreachable<S>
129+
where
130+
S: DebugWithContext<C>,
131+
{
132+
fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133+
match self {
134+
MaybeUnreachable::Unreachable => {
135+
write!(f, "unreachable")
136+
}
137+
MaybeUnreachable::Reachable(set) => set.fmt_with(ctxt, f),
138+
}
139+
}
140+
141+
fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142+
match (self, old) {
143+
(MaybeUnreachable::Unreachable, MaybeUnreachable::Unreachable) => Ok(()),
144+
(MaybeUnreachable::Unreachable, MaybeUnreachable::Reachable(set)) => {
145+
write!(f, "\u{001f}+")?;
146+
set.fmt_with(ctxt, f)
147+
}
148+
(MaybeUnreachable::Reachable(set), MaybeUnreachable::Unreachable) => {
149+
write!(f, "\u{001f}-")?;
150+
set.fmt_with(ctxt, f)
151+
}
152+
(MaybeUnreachable::Reachable(this), MaybeUnreachable::Reachable(old)) => {
153+
this.fmt_diff_with(old, ctxt, f)
154+
}
155+
}
156+
}
157+
}
158+
127159
fn fmt_diff<T, C>(
128160
inserted: &HybridBitSet<T>,
129161
removed: &HybridBitSet<T>,

compiler/rustc_mir_dataflow/src/framework/lattice.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,88 @@ impl<T> HasBottom for FlatSet<T> {
272272
impl<T> HasTop for FlatSet<T> {
273273
const TOP: Self = Self::Top;
274274
}
275+
276+
#[derive(PartialEq, Eq, Debug)]
277+
pub enum MaybeUnreachable<T> {
278+
Unreachable,
279+
Reachable(T),
280+
}
281+
282+
impl<T> MaybeUnreachable<T> {
283+
pub fn is_reachable(&self) -> bool {
284+
matches!(self, MaybeUnreachable::Reachable(_))
285+
}
286+
}
287+
288+
impl<T> HasBottom for MaybeUnreachable<T> {
289+
const BOTTOM: Self = MaybeUnreachable::Unreachable;
290+
}
291+
292+
impl<T: HasTop> HasTop for MaybeUnreachable<T> {
293+
const TOP: Self = MaybeUnreachable::Reachable(T::TOP);
294+
}
295+
296+
impl<S> MaybeUnreachable<S> {
297+
pub fn contains<T>(&self, elem: T) -> bool
298+
where
299+
S: BitSetExt<T>,
300+
{
301+
match self {
302+
MaybeUnreachable::Unreachable => false,
303+
MaybeUnreachable::Reachable(set) => set.contains(elem),
304+
}
305+
}
306+
}
307+
308+
impl<T, S: BitSetExt<T>> BitSetExt<T> for MaybeUnreachable<S> {
309+
fn contains(&self, elem: T) -> bool {
310+
self.contains(elem)
311+
}
312+
313+
fn union(&mut self, other: &HybridBitSet<T>) {
314+
match self {
315+
MaybeUnreachable::Unreachable => {}
316+
MaybeUnreachable::Reachable(set) => set.union(other),
317+
}
318+
}
319+
320+
fn subtract(&mut self, other: &HybridBitSet<T>) {
321+
match self {
322+
MaybeUnreachable::Unreachable => {}
323+
MaybeUnreachable::Reachable(set) => set.subtract(other),
324+
}
325+
}
326+
}
327+
328+
impl<V: Clone> Clone for MaybeUnreachable<V> {
329+
fn clone(&self) -> Self {
330+
match self {
331+
MaybeUnreachable::Reachable(x) => MaybeUnreachable::Reachable(x.clone()),
332+
MaybeUnreachable::Unreachable => MaybeUnreachable::Unreachable,
333+
}
334+
}
335+
336+
fn clone_from(&mut self, source: &Self) {
337+
match (&mut *self, source) {
338+
(MaybeUnreachable::Reachable(x), MaybeUnreachable::Reachable(y)) => {
339+
x.clone_from(&y);
340+
}
341+
_ => *self = source.clone(),
342+
}
343+
}
344+
}
345+
346+
impl<T: JoinSemiLattice + Clone> JoinSemiLattice for MaybeUnreachable<T> {
347+
fn join(&mut self, other: &Self) -> bool {
348+
match (&mut *self, &other) {
349+
(_, MaybeUnreachable::Unreachable) => false,
350+
(MaybeUnreachable::Unreachable, _) => {
351+
*self = other.clone();
352+
true
353+
}
354+
(MaybeUnreachable::Reachable(this), MaybeUnreachable::Reachable(other)) => {
355+
this.join(other)
356+
}
357+
}
358+
}
359+
}

compiler/rustc_mir_dataflow/src/framework/mod.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ mod visitor;
4848
pub use self::cursor::{AnalysisResults, ResultsClonedCursor, ResultsCursor, ResultsRefCursor};
4949
pub use self::direction::{Backward, Direction, Forward};
5050
pub use self::engine::{Engine, EntrySets, Results, ResultsCloned};
51-
pub use self::lattice::{JoinSemiLattice, MeetSemiLattice};
51+
pub use self::lattice::{JoinSemiLattice, MaybeUnreachable, MeetSemiLattice};
5252
pub use self::visitor::{visit_results, ResultsVisitable, ResultsVisitor};
5353

5454
/// Analysis domains are all bitsets of various kinds. This trait holds
@@ -524,6 +524,22 @@ impl<T: Idx> GenKill<T> for ChunkedBitSet<T> {
524524
}
525525
}
526526

527+
impl<T, S: GenKill<T>> GenKill<T> for MaybeUnreachable<S> {
528+
fn gen(&mut self, elem: T) {
529+
match self {
530+
MaybeUnreachable::Unreachable => {}
531+
MaybeUnreachable::Reachable(set) => set.gen(elem),
532+
}
533+
}
534+
535+
fn kill(&mut self, elem: T) {
536+
match self {
537+
MaybeUnreachable::Unreachable => {}
538+
MaybeUnreachable::Reachable(set) => set.kill(elem),
539+
}
540+
}
541+
}
542+
527543
impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
528544
fn gen(&mut self, elem: T) {
529545
self.0.insert(elem);

compiler/rustc_mir_dataflow/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ pub use self::drop_flag_effects::{
2929
pub use self::framework::{
3030
fmt, graphviz, lattice, visit_results, Analysis, AnalysisDomain, AnalysisResults, Backward,
3131
CallReturnPlaces, CloneAnalysis, Direction, Engine, Forward, GenKill, GenKillAnalysis,
32-
JoinSemiLattice, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor, ResultsRefCursor,
33-
ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
32+
JoinSemiLattice, MaybeUnreachable, Results, ResultsCloned, ResultsClonedCursor, ResultsCursor,
33+
ResultsRefCursor, ResultsVisitable, ResultsVisitor, SwitchIntEdgeEffects,
3434
};
3535

3636
use self::move_paths::MoveData;

0 commit comments

Comments
 (0)