Improve GeneratorLayout debug output
This commit is contained in:
parent
242a5cd4c6
commit
547d86307c
6 changed files with 105 additions and 6 deletions
|
@ -700,7 +700,7 @@ impl<T: Idx> GrowableBitSet<T> {
|
|||
///
|
||||
/// All operations that involve a row and/or column index will panic if the
|
||||
/// index exceeds the relevant bound.
|
||||
#[derive(Clone, Debug, Eq, PartialEq, RustcDecodable, RustcEncodable)]
|
||||
#[derive(Clone, Eq, PartialEq, RustcDecodable, RustcEncodable)]
|
||||
pub struct BitMatrix<R: Idx, C: Idx> {
|
||||
num_rows: usize,
|
||||
num_columns: usize,
|
||||
|
@ -876,6 +876,22 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: Idx, C: Idx> fmt::Debug for BitMatrix<R, C> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// Forces its contents to print in regular mode instead of alternate mode.
|
||||
struct OneLinePrinter<T>(T);
|
||||
impl<T: fmt::Debug> fmt::Debug for OneLinePrinter<T> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(fmt, "{:?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
write!(fmt, "BitMatrix({}x{}) ", self.num_rows, self.num_columns)?;
|
||||
let items = self.rows().flat_map(|r| self.iter(r).map(move |c| (r, c)));
|
||||
fmt.debug_set().entries(items.map(OneLinePrinter)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// A fixed-column-size, variable-row-size 2D bit matrix with a moderately
|
||||
/// sparse representation.
|
||||
///
|
||||
|
|
|
@ -10,6 +10,8 @@ use rustc_index::vec::IndexVec;
|
|||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use smallvec::SmallVec;
|
||||
use std::cell::Cell;
|
||||
use std::fmt::{self, Debug};
|
||||
|
||||
use super::{Field, SourceInfo};
|
||||
|
||||
|
@ -58,7 +60,7 @@ rustc_index::newtype_index! {
|
|||
}
|
||||
|
||||
/// The layout of generator state.
|
||||
#[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||
#[derive(Clone, RustcEncodable, RustcDecodable, HashStable, TypeFoldable)]
|
||||
pub struct GeneratorLayout<'tcx> {
|
||||
/// The type of every local stored inside the generator.
|
||||
pub field_tys: IndexVec<GeneratorSavedLocal, Ty<'tcx>>,
|
||||
|
@ -77,6 +79,62 @@ pub struct GeneratorLayout<'tcx> {
|
|||
pub storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>,
|
||||
}
|
||||
|
||||
impl Debug for GeneratorLayout<'_> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
/// Prints an iterator of (key, value) tuples as a map.
|
||||
struct MapPrinter<'a, K, V>(Cell<Option<Box<dyn Iterator<Item = (K, V)> + 'a>>>);
|
||||
impl<'a, K, V> MapPrinter<'a, K, V> {
|
||||
fn new(iter: impl Iterator<Item = (K, V)> + 'a) -> Self {
|
||||
Self(Cell::new(Some(Box::new(iter))))
|
||||
}
|
||||
}
|
||||
impl<'a, K: Debug, V: Debug> Debug for MapPrinter<'a, K, V> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
fmt.debug_map().entries(self.0.take().unwrap()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the generator variant name.
|
||||
struct GenVariantPrinter(VariantIdx);
|
||||
impl From<VariantIdx> for GenVariantPrinter {
|
||||
fn from(idx: VariantIdx) -> Self {
|
||||
GenVariantPrinter(idx)
|
||||
}
|
||||
}
|
||||
impl Debug for GenVariantPrinter {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let variant_name = ty::GeneratorSubsts::variant_name(self.0);
|
||||
if fmt.alternate() {
|
||||
write!(fmt, "{:9}({:?})", variant_name, self.0)
|
||||
} else {
|
||||
write!(fmt, "{}", variant_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Forces its contents to print in regular mode instead of alternate mode.
|
||||
struct OneLinePrinter<T>(T);
|
||||
impl<T: Debug> Debug for OneLinePrinter<T> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(fmt, "{:?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.debug_struct("GeneratorLayout")
|
||||
.field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
|
||||
.field(
|
||||
"variant_fields",
|
||||
&MapPrinter::new(
|
||||
self.variant_fields
|
||||
.iter_enumerated()
|
||||
.map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
|
||||
),
|
||||
)
|
||||
.field("storage_conflicts", &self.storage_conflicts)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub struct BorrowCheckResult<'tcx> {
|
||||
/// All the opaque types that are restricted to concrete types
|
||||
|
|
|
@ -522,7 +522,6 @@ impl<'tcx> GeneratorSubsts<'tcx> {
|
|||
|
||||
/// Calls `f` with a reference to the name of the enumerator for the given
|
||||
/// variant `v`.
|
||||
#[inline]
|
||||
pub fn variant_name(v: VariantIdx) -> Cow<'static, str> {
|
||||
match v.as_usize() {
|
||||
Self::UNRESUMED => Cow::from(Self::UNRESUMED_NAME),
|
||||
|
|
|
@ -131,7 +131,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
|||
}
|
||||
writeln!(file, " {} {}", disambiguator, pass_name)?;
|
||||
if let Some(ref layout) = body.generator_layout {
|
||||
writeln!(file, "// generator_layout = {:?}", layout)?;
|
||||
writeln!(file, "/* generator_layout = {:#?} */", layout)?;
|
||||
}
|
||||
writeln!(file)?;
|
||||
extra_data(PassWhere::BeforeCFG, &mut file)?;
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// MIR for `main::{{closure}}#0` 0 generator_drop
|
||||
// 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 } }
|
||||
/* generator_layout = GeneratorLayout {
|
||||
field_tys: {
|
||||
_0: std::string::String,
|
||||
},
|
||||
variant_fields: {
|
||||
Unresumed(0): [],
|
||||
Returned (1): [],
|
||||
Panicked (2): [],
|
||||
Suspend0 (3): [_0],
|
||||
},
|
||||
storage_conflicts: BitMatrix(1x1) {
|
||||
(_0, _0),
|
||||
},
|
||||
} */
|
||||
|
||||
fn main::{{closure}}#0(_1: *mut [generator@$DIR/generator-drop-cleanup.rs:10:15: 13:6 {std::string::String, ()}]) -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/generator-drop-cleanup.rs:10:15: 13:6
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
// MIR for `main::{{closure}}#0` 0 generator_resume
|
||||
// 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 } }
|
||||
/* generator_layout = GeneratorLayout {
|
||||
field_tys: {
|
||||
_0: HasDrop,
|
||||
},
|
||||
variant_fields: {
|
||||
Unresumed(0): [],
|
||||
Returned (1): [],
|
||||
Panicked (2): [],
|
||||
Suspend0 (3): [_0],
|
||||
},
|
||||
storage_conflicts: BitMatrix(1x1) {
|
||||
(_0, _0),
|
||||
},
|
||||
} */
|
||||
|
||||
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<(), ()> {
|
||||
debug _x => _10; // in scope 0 at $DIR/generator-tiny.rs:19:17: 19:19
|
||||
|
|
Loading…
Reference in a new issue