Skip to content

Commit 5fbb6ae

Browse files
committed
Improve GeneratorLayout debug output
1 parent 6c45801 commit 5fbb6ae

File tree

6 files changed

+105
-6
lines changed

6 files changed

+105
-6
lines changed

src/librustc_index/bit_set.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ impl<T: Idx> GrowableBitSet<T> {
700700
///
701701
/// All operations that involve a row and/or column index will panic if the
702702
/// index exceeds the relevant bound.
703-
#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)]
703+
#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
704704
pub struct BitMatrix<R: Idx, C: Idx> {
705705
num_rows: usize,
706706
num_columns: usize,
@@ -876,6 +876,22 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
876876
}
877877
}
878878

879+
impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
880+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
881+
/// Forces its contents to print in regular mode instead of alternate mode.
882+
struct OneLinePrinter<T>(T);
883+
impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
884+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
885+
write!(fmt, "{:?}", self.0)
886+
}
887+
}
888+
889+
write!(fmt, "BitMatrix({}x{}) ", self.num_rows, self.num_columns)?;
890+
let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
891+
fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
892+
}
893+
}
894+
879895
/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
880896
/// sparse representation.
881897
///

src/librustc_middle/mir/query.rs

+59-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use rustc_index::vec::IndexVec;
1010
use rustc_span::{Span, Symbol};
1111
use rustc_target::abi::VariantIdx;
1212
use smallvec::SmallVec;
13+
use std::cell::Cell;
14+
use std::fmt::{self, Debug};
1315

1416
use super::{Field, SourceInfo};
1517

@@ -58,7 +60,7 @@ rustc_index::newtype_index! {
5860
}
5961

6062
/// The layout of generator state.
61-
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
63+
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
6264
pub struct GeneratorLayout<'tcx> {
6365
/// The type of every local stored inside the generator.
6466
pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
@@ -77,6 +79,62 @@ pub struct GeneratorLayout<'tcx> {
7779
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
7880
}
7981

82+
impl Debug for GeneratorLayout<'_> {
83+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
84+
/// Prints an iterator of (key, value) tuples as a map.
85+
struct MapPrinter<'a, K, V>(Cell<Option<Box<dyn Iterator<Item = (K, V)> + 'a>>>);
86+
impl<'a, K, V> MapPrinter<'a, K, V> {
87+
fn new(iter: impl Iterator<Item = (K, V)> + 'a) -> Self {
88+
Self(Cell::new(Some(Box::new(iter))))
89+
}
90+
}
91+
impl<'a, K: Debug, V: Debug> Debug for MapPrinter<'a, K, V> {
92+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
93+
fmt.debug_map().entries(self.0.take().unwrap()).finish()
94+
}
95+
}
96+
97+
/// Prints the generator variant name.
98+
struct GenVariantPrinter(VariantIdx);
99+
impl From<VariantIdx> for GenVariantPrinter {
100+
fn from(idx: VariantIdx) -> Self {
101+
GenVariantPrinter(idx)
102+
}
103+
}
104+
impl Debug for GenVariantPrinter {
105+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
106+
let variant_name = ty::GeneratorSubsts::variant_name(self.0);
107+
if fmt.alternate() {
108+
write!(fmt, "{:9}({:?})", variant_name, self.0)
109+
} else {
110+
write!(fmt, "{}", variant_name)
111+
}
112+
}
113+
}
114+
115+
/// Forces its contents to print in regular mode instead of alternate mode.
116+
struct OneLinePrinter<T>(T);
117+
impl<T: Debug> Debug for OneLinePrinter<T> {
118+
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
119+
write!(fmt, "{:?}", self.0)
120+
}
121+
}
122+
123+
fmt.debug_struct("GeneratorLayout")
124+
.field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
125+
.field(
126+
"variant_fields",
127+
&MapPrinter::new(
128+
self.variant_fields
129+
.iter_enumerated()
130+
.map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
131+
),
132+
)
133+
.field("storage_conflicts", &self.storage_conflicts)
134+
.finish()
135+
}
136+
}
137+
80138
#[derive(Debug, RustcEncodable, RustcDecodable, HashStable)]
81139
pub struct BorrowCheckResult<'tcx> {
82140
/// All the opaque types that are restricted to concrete types

src/librustc_middle/ty/sty.rs

-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,6 @@ impl<'tcx> GeneratorSubsts<'tcx> {
516516

517517
/// Calls `f` with a reference to the name of the enumerator for the given
518518
/// variant `v`.
519-
#[inline]
520519
pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
521520
match v.as_usize() {
522521
Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),

src/librustc_mir/util/pretty.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ fn dump_matched_mir_node<'tcx, F>(
131131
}
132132
writeln!(file, " {} {}", disambiguator, pass_name)?;
133133
if let Some(ref layout) = body.generator_layout {
134-
writeln!(file, "// generator_layout = {:?}", layout)?;
134+
writeln!(file, "/* generator_layout = {:#?} */", layout)?;
135135
}
136136
writeln!(file)?;
137137
extra_data(PassWhere::BeforeCFG, &mut file)?;

src/test/mir-opt/generator-drop-cleanup/rustc.main-{{closure}}.generator_drop.0.mir

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
// MIR for `main::{{closure}}#0` 0 generator_drop
2-
// generator_layout = GeneratorLayout { field_tys: [std::string::String], variant_fields: [[], [], [], [_0]], variant_source_info: [SourceInfo { span: $DIR/generator-drop-cleanup.rs:10:15: 10:15 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-drop-cleanup.rs:13:6: 13:6 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-drop-cleanup.rs:13:6: 13:6 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-drop-cleanup.rs:12:9: 12:14 (#0), scope: scope[1] }], storage_conflicts: BitMatrix { num_rows: 1, num_columns: 1, words: [1], marker: PhantomData } }
2+
/* generator_layout = GeneratorLayout {
3+
field_tys: {
4+
_0: std::string::String,
5+
},
6+
variant_fields: {
7+
Unresumed(0): [],
8+
Returned (1): [],
9+
Panicked (2): [],
10+
Suspend0 (3): [_0],
11+
},
12+
storage_conflicts: BitMatrix(1x1) {
13+
(_0, _0),
14+
},
15+
} */
316

417
fn main::{{closure}}#0(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 13:6 {std::string::String, ()}]) -> () {
518
let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6

src/test/mir-opt/generator-tiny/rustc.main-{{closure}}.generator_resume.0.mir

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
// MIR for `main::{{closure}}#0` 0 generator_resume
2-
// generator_layout = GeneratorLayout { field_tys: [HasDrop], variant_fields: [[], [], [], [_0]], variant_source_info: [SourceInfo { span: $DIR/generator-tiny.rs:19:16: 19:16 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-tiny.rs:25:6: 25:6 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-tiny.rs:25:6: 25:6 (#0), scope: scope[0] }, SourceInfo { span: $DIR/generator-tiny.rs:22:13: 22:18 (#0), scope: scope[1] }], storage_conflicts: BitMatrix { num_rows: 1, num_columns: 1, words: [1], marker: PhantomData } }
2+
/* generator_layout = GeneratorLayout {
3+
field_tys: {
4+
_0: HasDrop,
5+
},
6+
variant_fields: {
7+
Unresumed(0): [],
8+
Returned (1): [],
9+
Panicked (2): [],
10+
Suspend0 (3): [_0],
11+
},
12+
storage_conflicts: BitMatrix(1x1) {
13+
(_0, _0),
14+
},
15+
} */
316

417
fn main::{{closure}}#0(_1: std::pin::Pin<&mut [generator@$DIR/generator-tiny.rs:19:16: 25:6 {u8, HasDrop, ()}]>, _2: u8) -> std::ops::GeneratorState<(), ()> {
518
debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:19:17: 19:19

0 commit comments

Comments
 (0)