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)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
enum BinderScopeType {
|
enum BinderScopeType {
|
||||||
/// Any non-concatenating binder scopes.
|
/// Any non-concatenating binder scopes.
|
||||||
|
@ -200,52 +244,6 @@ enum BinderScopeType {
|
||||||
Concatenating,
|
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>;
|
type ScopeRef<'a> = &'a Scope<'a>;
|
||||||
|
|
||||||
pub(crate) fn provide(providers: &mut Providers) {
|
pub(crate) fn provide(providers: &mut Providers) {
|
||||||
|
@ -1144,7 +1142,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
|
||||||
{
|
{
|
||||||
let BoundVarContext { tcx, map, .. } = self;
|
let BoundVarContext { tcx, map, .. } = self;
|
||||||
let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
|
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();
|
let _enter = span.enter();
|
||||||
f(&mut this);
|
f(&mut this);
|
||||||
|
|
|
@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
|
||||||
#![doc(rust_logo)]
|
#![doc(rust_logo)]
|
||||||
#![feature(assert_matches)]
|
#![feature(assert_matches)]
|
||||||
#![feature(coroutines)]
|
#![feature(coroutines)]
|
||||||
|
#![feature(debug_closure_helpers)]
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(iter_from_coroutine)]
|
#![feature(iter_from_coroutine)]
|
||||||
#![feature(iter_intersperse)]
|
#![feature(iter_intersperse)]
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#![feature(const_type_name)]
|
#![feature(const_type_name)]
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(coroutines)]
|
#![feature(coroutines)]
|
||||||
|
#![feature(debug_closure_helpers)]
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
#![feature(discriminant_kind)]
|
#![feature(discriminant_kind)]
|
||||||
#![feature(extern_types)]
|
#![feature(extern_types)]
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//! Values computed by queries that use MIR.
|
//! Values computed by queries that use MIR.
|
||||||
|
|
||||||
use std::cell::Cell;
|
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
|
|
||||||
use rustc_abi::{FieldIdx, VariantIdx};
|
use rustc_abi::{FieldIdx, VariantIdx};
|
||||||
|
@ -62,55 +61,26 @@ pub struct CoroutineLayout<'tcx> {
|
||||||
|
|
||||||
impl Debug for CoroutineLayout<'_> {
|
impl Debug for CoroutineLayout<'_> {
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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);
|
|
||||||
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("CoroutineLayout")
|
fmt.debug_struct("CoroutineLayout")
|
||||||
.field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
|
.field_with("field_tys", |fmt| {
|
||||||
.field(
|
fmt.debug_map().entries(self.field_tys.iter_enumerated()).finish()
|
||||||
"variant_fields",
|
})
|
||||||
&MapPrinter::new(
|
.field_with("variant_fields", |fmt| {
|
||||||
self.variant_fields
|
let mut map = fmt.debug_map();
|
||||||
.iter_enumerated()
|
for (idx, fields) in self.variant_fields.iter_enumerated() {
|
||||||
.map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
|
map.key_with(|fmt| {
|
||||||
),
|
let variant_name = ty::CoroutineArgs::variant_name(idx);
|
||||||
)
|
if fmt.alternate() {
|
||||||
|
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:?}"));
|
||||||
|
}
|
||||||
|
map.finish()
|
||||||
|
})
|
||||||
.field("storage_conflicts", &self.storage_conflicts)
|
.field("storage_conflicts", &self.storage_conflicts)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2325,51 +2325,41 @@ macro_rules! sty_debug_print {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> TyCtxt<'tcx> {
|
impl<'tcx> TyCtxt<'tcx> {
|
||||||
pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
|
pub fn debug_stats(self) -> impl fmt::Debug + 'tcx {
|
||||||
struct DebugStats<'tcx>(TyCtxt<'tcx>);
|
fmt::from_fn(move |fmt| {
|
||||||
|
sty_debug_print!(
|
||||||
|
fmt,
|
||||||
|
self,
|
||||||
|
Adt,
|
||||||
|
Array,
|
||||||
|
Slice,
|
||||||
|
RawPtr,
|
||||||
|
Ref,
|
||||||
|
FnDef,
|
||||||
|
FnPtr,
|
||||||
|
UnsafeBinder,
|
||||||
|
Placeholder,
|
||||||
|
Coroutine,
|
||||||
|
CoroutineWitness,
|
||||||
|
Dynamic,
|
||||||
|
Closure,
|
||||||
|
CoroutineClosure,
|
||||||
|
Tuple,
|
||||||
|
Bound,
|
||||||
|
Param,
|
||||||
|
Infer,
|
||||||
|
Alias,
|
||||||
|
Pat,
|
||||||
|
Foreign
|
||||||
|
)?;
|
||||||
|
|
||||||
impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
|
writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
|
||||||
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
|
||||||
sty_debug_print!(
|
writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
|
||||||
fmt,
|
writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
|
||||||
self.0,
|
|
||||||
Adt,
|
|
||||||
Array,
|
|
||||||
Slice,
|
|
||||||
RawPtr,
|
|
||||||
Ref,
|
|
||||||
FnDef,
|
|
||||||
FnPtr,
|
|
||||||
UnsafeBinder,
|
|
||||||
Placeholder,
|
|
||||||
Coroutine,
|
|
||||||
CoroutineWitness,
|
|
||||||
Dynamic,
|
|
||||||
Closure,
|
|
||||||
CoroutineClosure,
|
|
||||||
Tuple,
|
|
||||||
Bound,
|
|
||||||
Param,
|
|
||||||
Infer,
|
|
||||||
Alias,
|
|
||||||
Pat,
|
|
||||||
Foreign
|
|
||||||
)?;
|
|
||||||
|
|
||||||
writeln!(fmt, "GenericArgs interner: #{}", self.0.interners.args.len())?;
|
Ok(())
|
||||||
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())?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugStats(self)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1598,45 +1598,35 @@ impl<'a> Parser<'a> {
|
||||||
// Only used when debugging.
|
// Only used when debugging.
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
|
pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
|
||||||
struct DebugParser<'dbg> {
|
fmt::from_fn(move |f| {
|
||||||
parser: &'dbg Parser<'dbg>,
|
let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of
|
||||||
lookahead: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Debug for DebugParser<'_> {
|
// we don't need N spans, but we want at least one, so print all of prev_token
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
dbg_fmt.field("prev_token", &self.prev_token);
|
||||||
let Self { parser, lookahead } = self;
|
let mut tokens = vec![];
|
||||||
let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of
|
for i in 0..lookahead {
|
||||||
|
let tok = self.look_ahead(i, |tok| tok.kind.clone());
|
||||||
// we don't need N spans, but we want at least one, so print all of prev_token
|
let is_eof = tok == TokenKind::Eof;
|
||||||
dbg_fmt.field("prev_token", &parser.prev_token);
|
tokens.push(tok);
|
||||||
let mut tokens = vec![];
|
if is_eof {
|
||||||
for i in 0..*lookahead {
|
// Don't look ahead past EOF.
|
||||||
let tok = parser.look_ahead(i, |tok| tok.kind.clone());
|
break;
|
||||||
let is_eof = tok == TokenKind::Eof;
|
|
||||||
tokens.push(tok);
|
|
||||||
if is_eof {
|
|
||||||
// Don't look ahead past EOF.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
|
|
||||||
dbg_fmt.field("approx_token_stream_pos", &parser.num_bump_calls);
|
|
||||||
|
|
||||||
// some fields are interesting for certain values, as they relate to macro parsing
|
|
||||||
if let Some(subparser) = parser.subparser_name {
|
|
||||||
dbg_fmt.field("subparser_name", &subparser);
|
|
||||||
}
|
|
||||||
if let Recovery::Forbidden = parser.recovery {
|
|
||||||
dbg_fmt.field("recovery", &parser.recovery);
|
|
||||||
}
|
|
||||||
|
|
||||||
// imply there's "more to know" than this view
|
|
||||||
dbg_fmt.finish_non_exhaustive()
|
|
||||||
}
|
}
|
||||||
}
|
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
|
||||||
|
dbg_fmt.field("approx_token_stream_pos", &self.num_bump_calls);
|
||||||
|
|
||||||
DebugParser { parser: self, lookahead }
|
// some fields are interesting for certain values, as they relate to macro parsing
|
||||||
|
if let Some(subparser) = self.subparser_name {
|
||||||
|
dbg_fmt.field("subparser_name", &subparser);
|
||||||
|
}
|
||||||
|
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()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_expected_token_types(&mut self) {
|
pub fn clear_expected_token_types(&mut self) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue