From 8b57fd9e43baa9d8e1c72c54201d4820661f32c4 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Thu, 23 Jan 2025 19:48:54 +0000 Subject: [PATCH] use `fmt::from_fn` in more places, instead of using structs that impl formatting traits --- .../src/collect/resolve_bound_vars.rs | 92 +++++++++---------- compiler/rustc_hir_analysis/src/lib.rs | 1 + compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/mir/query.rs | 68 ++++---------- compiler/rustc_middle/src/ty/context.rs | 76 +++++++-------- compiler/rustc_parse/src/parser/mod.rs | 60 +++++------- 6 files changed, 124 insertions(+), 174 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs index 582a2c7a0fc..72baf5c4b58 100644 --- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs +++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs @@ -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); diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs index a42a168234f..bc7d4365eee 100644 --- a/compiler/rustc_hir_analysis/src/lib.rs +++ b/compiler/rustc_hir_analysis/src/lib.rs @@ -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)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 04a06ba7464..bbe23d8abe8 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -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)] diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs index db5da941f1e..50494355e3e 100644 --- a/compiler/rustc_middle/src/mir/query.rs +++ b/compiler/rustc_middle/src/mir/query.rs @@ -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 + 'a>>>); - impl<'a, K, V> MapPrinter<'a, K, V> { - fn new(iter: impl Iterator + '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 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); - impl Debug for OneLinePrinter { - 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))), - ), - ) + .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, "{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) .finish() } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index aeb734ba3f6..d1079743004 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2325,51 +2325,41 @@ macro_rules! sty_debug_print { } impl<'tcx> TyCtxt<'tcx> { - pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx { - struct DebugStats<'tcx>(TyCtxt<'tcx>); + pub fn debug_stats(self) -> impl fmt::Debug + '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> { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - sty_debug_print!( - fmt, - 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.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())?; - 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())?; - - Ok(()) - } - } - - DebugStats(self) + Ok(()) + }) } } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 25d8eb9b453..714a60cb179 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1598,45 +1598,35 @@ 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, - } + fmt::from_fn(move |f| { + let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of - impl fmt::Debug for DebugParser<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let Self { parser, lookahead } = self; - 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); - let mut tokens = vec![]; - for i in 0..*lookahead { - let tok = parser.look_ahead(i, |tok| tok.kind.clone()); - let is_eof = tok == TokenKind::Eof; - tokens.push(tok); - if is_eof { - // Don't look ahead past EOF. - break; - } + // we don't need N spans, but we want at least one, so print all of prev_token + dbg_fmt.field("prev_token", &self.prev_token); + let mut tokens = vec![]; + 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 { + // 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) {