use fmt::from_fn
in more places, instead of using structs that impl formatting traits
This commit is contained in:
parent
815be937ab
commit
8b57fd9e43
6 changed files with 124 additions and 174 deletions
|
@ -184,6 +184,50 @@ enum Scope<'a> {
|
|||
},
|
||||
}
|
||||
|
||||
impl<'a> Scope<'a> {
|
||||
// A helper for debugging scopes without printing parent scopes
|
||||
fn debug_truncated(&'a self) -> impl fmt::Debug + 'a {
|
||||
fmt::from_fn(move |f| match self {
|
||||
Self::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f
|
||||
.debug_struct("Binder")
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("scope_type", scope_type)
|
||||
.field("hir_id", hir_id)
|
||||
.field("where_bound_origin", where_bound_origin)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Self::Opaque { captures, def_id, s: _ } => f
|
||||
.debug_struct("Opaque")
|
||||
.field("def_id", def_id)
|
||||
.field("captures", &captures.borrow())
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Self::Body { id, s: _ } => {
|
||||
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
|
||||
}
|
||||
Self::ObjectLifetimeDefault { lifetime, s: _ } => f
|
||||
.debug_struct("ObjectLifetimeDefault")
|
||||
.field("lifetime", lifetime)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Self::Supertrait { bound_vars, s: _ } => f
|
||||
.debug_struct("Supertrait")
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Self::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
|
||||
Self::LateBoundary { s: _, what, deny_late_regions } => f
|
||||
.debug_struct("LateBoundary")
|
||||
.field("what", what)
|
||||
.field("deny_late_regions", deny_late_regions)
|
||||
.finish(),
|
||||
Self::Root { opt_parent_item } => {
|
||||
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
enum BinderScopeType {
|
||||
/// Any non-concatenating binder scopes.
|
||||
|
@ -200,52 +244,6 @@ enum BinderScopeType {
|
|||
Concatenating,
|
||||
}
|
||||
|
||||
// A helper struct for debugging scopes without printing parent scopes
|
||||
struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
|
||||
|
||||
impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self.0 {
|
||||
Scope::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f
|
||||
.debug_struct("Binder")
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("scope_type", scope_type)
|
||||
.field("hir_id", hir_id)
|
||||
.field("where_bound_origin", where_bound_origin)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Opaque { captures, def_id, s: _ } => f
|
||||
.debug_struct("Opaque")
|
||||
.field("def_id", def_id)
|
||||
.field("captures", &captures.borrow())
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Body { id, s: _ } => {
|
||||
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
|
||||
}
|
||||
Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
|
||||
.debug_struct("ObjectLifetimeDefault")
|
||||
.field("lifetime", lifetime)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::Supertrait { bound_vars, s: _ } => f
|
||||
.debug_struct("Supertrait")
|
||||
.field("bound_vars", bound_vars)
|
||||
.field("s", &"..")
|
||||
.finish(),
|
||||
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
|
||||
Scope::LateBoundary { s: _, what, deny_late_regions } => f
|
||||
.debug_struct("LateBoundary")
|
||||
.field("what", what)
|
||||
.field("deny_late_regions", deny_late_regions)
|
||||
.finish(),
|
||||
Scope::Root { opt_parent_item } => {
|
||||
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ScopeRef<'a> = &'a Scope<'a>;
|
||||
|
||||
pub(crate) fn provide(providers: &mut Providers) {
|
||||
|
@ -1144,7 +1142,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
|||
{
|
||||
let BoundVarContext { tcx, map, .. } = self;
|
||||
let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
|
||||
let span = debug_span!("scope", scope = ?TruncatedScopeDebug(this.scope));
|
||||
let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
|
||||
{
|
||||
let _enter = span.enter();
|
||||
f(&mut this);
|
||||
|
|
|
@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
|
|||
#![doc(rust_logo)]
|
||||
#![feature(assert_matches)]
|
||||
#![feature(coroutines)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(if_let_guard)]
|
||||
#![feature(iter_from_coroutine)]
|
||||
#![feature(iter_intersperse)]
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#![feature(const_type_name)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(coroutines)]
|
||||
#![feature(debug_closure_helpers)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(discriminant_kind)]
|
||||
#![feature(extern_types)]
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! Values computed by queries that use MIR.
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::fmt::{self, Debug};
|
||||
|
||||
use rustc_abi::{FieldIdx, VariantIdx};
|
||||
|
@ -62,55 +61,26 @@ pub struct CoroutineLayout<'tcx> {
|
|||
|
||||
impl Debug for CoroutineLayout<'_> {
|
||||
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 coroutine 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::CoroutineArgs::variant_name(self.0);
|
||||
fmt.debug_struct("CoroutineLayout")
|
||||
.field_with("field_tys", |fmt| {
|
||||
fmt.debug_map().entries(self.field_tys.iter_enumerated()).finish()
|
||||
})
|
||||
.field_with("variant_fields", |fmt| {
|
||||
let mut map = fmt.debug_map();
|
||||
for (idx, fields) in self.variant_fields.iter_enumerated() {
|
||||
map.key_with(|fmt| {
|
||||
let variant_name = ty::CoroutineArgs::variant_name(idx);
|
||||
if fmt.alternate() {
|
||||
write!(fmt, "{:9}({:?})", variant_name, self.0)
|
||||
write!(fmt, "{variant_name:9}({idx:?})")
|
||||
} else {
|
||||
write!(fmt, "{variant_name}")
|
||||
}
|
||||
});
|
||||
// Force variant fields to print in regular mode instead of alternate mode.
|
||||
map.value_with(|fmt| write!(fmt, "{fields:?}"));
|
||||
}
|
||||
}
|
||||
|
||||
/// 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("CoroutineLayout")
|
||||
.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))),
|
||||
),
|
||||
)
|
||||
map.finish()
|
||||
})
|
||||
.field("storage_conflicts", &self.storage_conflicts)
|
||||
.finish()
|
||||
}
|
||||
|
|
|
@ -2325,14 +2325,11 @@ macro_rules! sty_debug_print {
|
|||
}
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
|
||||
struct DebugStats<'tcx>(TyCtxt<'tcx>);
|
||||
|
||||
impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
|
||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
pub fn debug_stats(self) -> impl fmt::Debug + 'tcx {
|
||||
fmt::from_fn(move |fmt| {
|
||||
sty_debug_print!(
|
||||
fmt,
|
||||
self.0,
|
||||
self,
|
||||
Adt,
|
||||
Array,
|
||||
Slice,
|
||||
|
@ -2356,20 +2353,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
Foreign
|
||||
)?;
|
||||
|
||||
writeln!(fmt, "GenericArgs interner: #{}", self.0.interners.args.len())?;
|
||||
writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
|
||||
writeln!(
|
||||
fmt,
|
||||
"Const Allocation interner: #{}",
|
||||
self.0.interners.const_allocation.len()
|
||||
)?;
|
||||
writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
|
||||
writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
|
||||
writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
|
||||
writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
|
||||
writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
DebugStats(self)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1598,21 +1598,14 @@ impl<'a> Parser<'a> {
|
|||
// Only used when debugging.
|
||||
#[allow(unused)]
|
||||
pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
|
||||
struct DebugParser<'dbg> {
|
||||
parser: &'dbg Parser<'dbg>,
|
||||
lookahead: usize,
|
||||
}
|
||||
|
||||
impl fmt::Debug for DebugParser<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Self { parser, lookahead } = self;
|
||||
fmt::from_fn(move |f| {
|
||||
let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of
|
||||
|
||||
// we don't need N spans, but we want at least one, so print all of prev_token
|
||||
dbg_fmt.field("prev_token", &parser.prev_token);
|
||||
dbg_fmt.field("prev_token", &self.prev_token);
|
||||
let mut tokens = vec![];
|
||||
for i in 0..*lookahead {
|
||||
let tok = parser.look_ahead(i, |tok| tok.kind.clone());
|
||||
for i in 0..lookahead {
|
||||
let tok = self.look_ahead(i, |tok| tok.kind.clone());
|
||||
let is_eof = tok == TokenKind::Eof;
|
||||
tokens.push(tok);
|
||||
if is_eof {
|
||||
|
@ -1621,22 +1614,19 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
|
||||
dbg_fmt.field("approx_token_stream_pos", &parser.num_bump_calls);
|
||||
dbg_fmt.field("approx_token_stream_pos", &self.num_bump_calls);
|
||||
|
||||
// some fields are interesting for certain values, as they relate to macro parsing
|
||||
if let Some(subparser) = parser.subparser_name {
|
||||
if let Some(subparser) = self.subparser_name {
|
||||
dbg_fmt.field("subparser_name", &subparser);
|
||||
}
|
||||
if let Recovery::Forbidden = parser.recovery {
|
||||
dbg_fmt.field("recovery", &parser.recovery);
|
||||
if let Recovery::Forbidden = self.recovery {
|
||||
dbg_fmt.field("recovery", &self.recovery);
|
||||
}
|
||||
|
||||
// imply there's "more to know" than this view
|
||||
dbg_fmt.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
DebugParser { parser: self, lookahead }
|
||||
})
|
||||
}
|
||||
|
||||
pub fn clear_expected_token_types(&mut self) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue