Skip to content

Commit 8b57fd9

Browse files
committed
use fmt::from_fn in more places, instead of using structs that impl formatting traits
1 parent 815be93 commit 8b57fd9

File tree

6 files changed

+111
-161
lines changed

6 files changed

+111
-161
lines changed

Diff for: compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs

+30-32
Original file line numberDiff line numberDiff line change
@@ -184,68 +184,66 @@ enum Scope<'a> {
184184
},
185185
}
186186

187-
#[derive(Copy, Clone, Debug)]
188-
enum BinderScopeType {
189-
/// Any non-concatenating binder scopes.
190-
Normal,
191-
/// Within a syntactic trait ref, there may be multiple poly trait refs that
192-
/// are nested (under the `associated_type_bounds` feature). The binders of
193-
/// the inner poly trait refs are extended from the outer poly trait refs
194-
/// and don't increase the late bound depth. If you had
195-
/// `T: for<'a> Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
196-
/// would be `Concatenating`. This also used in trait refs in where clauses
197-
/// where we have two binders `for<> T: for<> Foo` (I've intentionally left
198-
/// out any lifetimes because they aren't needed to show the two scopes).
199-
/// The inner `for<>` has a scope of `Concatenating`.
200-
Concatenating,
201-
}
202-
203-
// A helper struct for debugging scopes without printing parent scopes
204-
struct TruncatedScopeDebug<'a>(&'a Scope<'a>);
205-
206-
impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
207-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208-
match self.0 {
209-
Scope::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f
187+
impl<'a> Scope<'a> {
188+
// A helper for debugging scopes without printing parent scopes
189+
fn debug_truncated(&'a self) -> impl fmt::Debug + 'a {
190+
fmt::from_fn(move |f| match self {
191+
Self::Binder { bound_vars, scope_type, hir_id, where_bound_origin, s: _ } => f
210192
.debug_struct("Binder")
211193
.field("bound_vars", bound_vars)
212194
.field("scope_type", scope_type)
213195
.field("hir_id", hir_id)
214196
.field("where_bound_origin", where_bound_origin)
215197
.field("s", &"..")
216198
.finish(),
217-
Scope::Opaque { captures, def_id, s: _ } => f
199+
Self::Opaque { captures, def_id, s: _ } => f
218200
.debug_struct("Opaque")
219201
.field("def_id", def_id)
220202
.field("captures", &captures.borrow())
221203
.field("s", &"..")
222204
.finish(),
223-
Scope::Body { id, s: _ } => {
205+
Self::Body { id, s: _ } => {
224206
f.debug_struct("Body").field("id", id).field("s", &"..").finish()
225207
}
226-
Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
208+
Self::ObjectLifetimeDefault { lifetime, s: _ } => f
227209
.debug_struct("ObjectLifetimeDefault")
228210
.field("lifetime", lifetime)
229211
.field("s", &"..")
230212
.finish(),
231-
Scope::Supertrait { bound_vars, s: _ } => f
213+
Self::Supertrait { bound_vars, s: _ } => f
232214
.debug_struct("Supertrait")
233215
.field("bound_vars", bound_vars)
234216
.field("s", &"..")
235217
.finish(),
236-
Scope::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
237-
Scope::LateBoundary { s: _, what, deny_late_regions } => f
218+
Self::TraitRefBoundary { s: _ } => f.debug_struct("TraitRefBoundary").finish(),
219+
Self::LateBoundary { s: _, what, deny_late_regions } => f
238220
.debug_struct("LateBoundary")
239221
.field("what", what)
240222
.field("deny_late_regions", deny_late_regions)
241223
.finish(),
242-
Scope::Root { opt_parent_item } => {
224+
Self::Root { opt_parent_item } => {
243225
f.debug_struct("Root").field("opt_parent_item", &opt_parent_item).finish()
244226
}
245-
}
227+
})
246228
}
247229
}
248230

231+
#[derive(Copy, Clone, Debug)]
232+
enum BinderScopeType {
233+
/// Any non-concatenating binder scopes.
234+
Normal,
235+
/// Within a syntactic trait ref, there may be multiple poly trait refs that
236+
/// are nested (under the `associated_type_bounds` feature). The binders of
237+
/// the inner poly trait refs are extended from the outer poly trait refs
238+
/// and don't increase the late bound depth. If you had
239+
/// `T: for<'a> Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
240+
/// would be `Concatenating`. This also used in trait refs in where clauses
241+
/// where we have two binders `for<> T: for<> Foo` (I've intentionally left
242+
/// out any lifetimes because they aren't needed to show the two scopes).
243+
/// The inner `for<>` has a scope of `Concatenating`.
244+
Concatenating,
245+
}
246+
249247
type ScopeRef<'a> = &'a Scope<'a>;
250248

251249
pub(crate) fn provide(providers: &mut Providers) {
@@ -1144,7 +1142,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
11441142
{
11451143
let BoundVarContext { tcx, map, .. } = self;
11461144
let mut this = BoundVarContext { tcx: *tcx, map, scope: &wrap_scope };
1147-
let span = debug_span!("scope", scope = ?TruncatedScopeDebug(this.scope));
1145+
let span = debug_span!("scope", scope = ?this.scope.debug_truncated());
11481146
{
11491147
let _enter = span.enter();
11501148
f(&mut this);

Diff for: compiler/rustc_hir_analysis/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ This API is completely unstable and subject to change.
6363
#![doc(rust_logo)]
6464
#![feature(assert_matches)]
6565
#![feature(coroutines)]
66+
#![feature(debug_closure_helpers)]
6667
#![feature(if_let_guard)]
6768
#![feature(iter_from_coroutine)]
6869
#![feature(iter_intersperse)]

Diff for: compiler/rustc_middle/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#![feature(const_type_name)]
4141
#![feature(core_intrinsics)]
4242
#![feature(coroutines)]
43+
#![feature(debug_closure_helpers)]
4344
#![feature(decl_macro)]
4445
#![feature(discriminant_kind)]
4546
#![feature(extern_types)]

Diff for: compiler/rustc_middle/src/mir/query.rs

+19-49
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Values computed by queries that use MIR.
22
3-
use std::cell::Cell;
43
use std::fmt::{self, Debug};
54

65
use rustc_abi::{FieldIdx, VariantIdx};
@@ -62,55 +61,26 @@ pub struct CoroutineLayout<'tcx> {
6261

6362
impl Debug for CoroutineLayout<'_> {
6463
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
65-
/// Prints an iterator of (key, value) tuples as a map.
66-
struct MapPrinter<'a, K, V>(Cell<Option<Box<dyn Iterator<Item = (K, V)> + 'a>>>);
67-
impl<'a, K, V> MapPrinter<'a, K, V> {
68-
fn new(iter: impl Iterator<Item = (K, V)> + 'a) -> Self {
69-
Self(Cell::new(Some(Box::new(iter))))
70-
}
71-
}
72-
impl<'a, K: Debug, V: Debug> Debug for MapPrinter<'a, K, V> {
73-
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
74-
fmt.debug_map().entries(self.0.take().unwrap()).finish()
75-
}
76-
}
77-
78-
/// Prints the coroutine variant name.
79-
struct GenVariantPrinter(VariantIdx);
80-
impl From<VariantIdx> for GenVariantPrinter {
81-
fn from(idx: VariantIdx) -> Self {
82-
GenVariantPrinter(idx)
83-
}
84-
}
85-
impl Debug for GenVariantPrinter {
86-
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
87-
let variant_name = ty::CoroutineArgs::variant_name(self.0);
88-
if fmt.alternate() {
89-
write!(fmt, "{:9}({:?})", variant_name, self.0)
90-
} else {
91-
write!(fmt, "{variant_name}")
92-
}
93-
}
94-
}
95-
96-
/// Forces its contents to print in regular mode instead of alternate mode.
97-
struct OneLinePrinter<T>(T);
98-
impl<T: Debug> Debug for OneLinePrinter<T> {
99-
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
100-
write!(fmt, "{:?}", self.0)
101-
}
102-
}
103-
10464
fmt.debug_struct("CoroutineLayout")
105-
.field("field_tys", &MapPrinter::new(self.field_tys.iter_enumerated()))
106-
.field(
107-
"variant_fields",
108-
&MapPrinter::new(
109-
self.variant_fields
110-
.iter_enumerated()
111-
.map(|(k, v)| (GenVariantPrinter(k), OneLinePrinter(v))),
112-
),
113-
)
65+
.field_with("field_tys", |fmt| {
66+
fmt.debug_map().entries(self.field_tys.iter_enumerated()).finish()
67+
})
68+
.field_with("variant_fields", |fmt| {
69+
let mut map = fmt.debug_map();
70+
for (idx, fields) in self.variant_fields.iter_enumerated() {
71+
map.key_with(|fmt| {
72+
let variant_name = ty::CoroutineArgs::variant_name(idx);
73+
if fmt.alternate() {
74+
write!(fmt, "{variant_name:9}({idx:?})")
75+
} else {
76+
write!(fmt, "{variant_name}")
77+
}
78+
});
79+
// Force variant fields to print in regular mode instead of alternate mode.
80+
map.value_with(|fmt| write!(fmt, "{fields:?}"));
81+
}
82+
map.finish()
83+
})
11484
.field("storage_conflicts", &self.storage_conflicts)
11585
.finish()
11686
}

Diff for: compiler/rustc_middle/src/ty/context.rs

+35-45
Original file line numberDiff line numberDiff line change
@@ -2325,51 +2325,41 @@ macro_rules! sty_debug_print {
23252325
}
23262326

23272327
impl<'tcx> TyCtxt<'tcx> {
2328-
pub fn debug_stats(self) -> impl std::fmt::Debug + 'tcx {
2329-
struct DebugStats<'tcx>(TyCtxt<'tcx>);
2330-
2331-
impl<'tcx> std::fmt::Debug for DebugStats<'tcx> {
2332-
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2333-
sty_debug_print!(
2334-
fmt,
2335-
self.0,
2336-
Adt,
2337-
Array,
2338-
Slice,
2339-
RawPtr,
2340-
Ref,
2341-
FnDef,
2342-
FnPtr,
2343-
UnsafeBinder,
2344-
Placeholder,
2345-
Coroutine,
2346-
CoroutineWitness,
2347-
Dynamic,
2348-
Closure,
2349-
CoroutineClosure,
2350-
Tuple,
2351-
Bound,
2352-
Param,
2353-
Infer,
2354-
Alias,
2355-
Pat,
2356-
Foreign
2357-
)?;
2358-
2359-
writeln!(fmt, "GenericArgs interner: #{}", self.0.interners.args.len())?;
2360-
writeln!(fmt, "Region interner: #{}", self.0.interners.region.len())?;
2361-
writeln!(
2362-
fmt,
2363-
"Const Allocation interner: #{}",
2364-
self.0.interners.const_allocation.len()
2365-
)?;
2366-
writeln!(fmt, "Layout interner: #{}", self.0.interners.layout.len())?;
2367-
2368-
Ok(())
2369-
}
2370-
}
2371-
2372-
DebugStats(self)
2328+
pub fn debug_stats(self) -> impl fmt::Debug + 'tcx {
2329+
fmt::from_fn(move |fmt| {
2330+
sty_debug_print!(
2331+
fmt,
2332+
self,
2333+
Adt,
2334+
Array,
2335+
Slice,
2336+
RawPtr,
2337+
Ref,
2338+
FnDef,
2339+
FnPtr,
2340+
UnsafeBinder,
2341+
Placeholder,
2342+
Coroutine,
2343+
CoroutineWitness,
2344+
Dynamic,
2345+
Closure,
2346+
CoroutineClosure,
2347+
Tuple,
2348+
Bound,
2349+
Param,
2350+
Infer,
2351+
Alias,
2352+
Pat,
2353+
Foreign
2354+
)?;
2355+
2356+
writeln!(fmt, "GenericArgs interner: #{}", self.interners.args.len())?;
2357+
writeln!(fmt, "Region interner: #{}", self.interners.region.len())?;
2358+
writeln!(fmt, "Const Allocation interner: #{}", self.interners.const_allocation.len())?;
2359+
writeln!(fmt, "Layout interner: #{}", self.interners.layout.len())?;
2360+
2361+
Ok(())
2362+
})
23732363
}
23742364
}
23752365

Diff for: compiler/rustc_parse/src/parser/mod.rs

+25-35
Original file line numberDiff line numberDiff line change
@@ -1598,45 +1598,35 @@ impl<'a> Parser<'a> {
15981598
// Only used when debugging.
15991599
#[allow(unused)]
16001600
pub(crate) fn debug_lookahead(&self, lookahead: usize) -> impl fmt::Debug + '_ {
1601-
struct DebugParser<'dbg> {
1602-
parser: &'dbg Parser<'dbg>,
1603-
lookahead: usize,
1604-
}
1605-
1606-
impl fmt::Debug for DebugParser<'_> {
1607-
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1608-
let Self { parser, lookahead } = self;
1609-
let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of
1610-
1611-
// we don't need N spans, but we want at least one, so print all of prev_token
1612-
dbg_fmt.field("prev_token", &parser.prev_token);
1613-
let mut tokens = vec![];
1614-
for i in 0..*lookahead {
1615-
let tok = parser.look_ahead(i, |tok| tok.kind.clone());
1616-
let is_eof = tok == TokenKind::Eof;
1617-
tokens.push(tok);
1618-
if is_eof {
1619-
// Don't look ahead past EOF.
1620-
break;
1621-
}
1622-
}
1623-
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
1624-
dbg_fmt.field("approx_token_stream_pos", &parser.num_bump_calls);
1625-
1626-
// some fields are interesting for certain values, as they relate to macro parsing
1627-
if let Some(subparser) = parser.subparser_name {
1628-
dbg_fmt.field("subparser_name", &subparser);
1629-
}
1630-
if let Recovery::Forbidden = parser.recovery {
1631-
dbg_fmt.field("recovery", &parser.recovery);
1601+
fmt::from_fn(move |f| {
1602+
let mut dbg_fmt = f.debug_struct("Parser"); // or at least, one view of
1603+
1604+
// we don't need N spans, but we want at least one, so print all of prev_token
1605+
dbg_fmt.field("prev_token", &self.prev_token);
1606+
let mut tokens = vec![];
1607+
for i in 0..lookahead {
1608+
let tok = self.look_ahead(i, |tok| tok.kind.clone());
1609+
let is_eof = tok == TokenKind::Eof;
1610+
tokens.push(tok);
1611+
if is_eof {
1612+
// Don't look ahead past EOF.
1613+
break;
16321614
}
1615+
}
1616+
dbg_fmt.field_with("tokens", |field| field.debug_list().entries(tokens).finish());
1617+
dbg_fmt.field("approx_token_stream_pos", &self.num_bump_calls);
16331618

1634-
// imply there's "more to know" than this view
1635-
dbg_fmt.finish_non_exhaustive()
1619+
// some fields are interesting for certain values, as they relate to macro parsing
1620+
if let Some(subparser) = self.subparser_name {
1621+
dbg_fmt.field("subparser_name", &subparser);
1622+
}
1623+
if let Recovery::Forbidden = self.recovery {
1624+
dbg_fmt.field("recovery", &self.recovery);
16361625
}
1637-
}
16381626

1639-
DebugParser { parser: self, lookahead }
1627+
// imply there's "more to know" than this view
1628+
dbg_fmt.finish_non_exhaustive()
1629+
})
16401630
}
16411631

16421632
pub fn clear_expected_token_types(&mut self) {

0 commit comments

Comments
 (0)