about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYotam Ofek <yotam.ofek@gmail.com>2025-01-23 19:48:54 +0000
committerYotam Ofek <yotam.ofek@gmail.com>2025-01-24 14:45:56 +0000
commit8b57fd9e43baa9d8e1c72c54201d4820661f32c4 (patch)
treedfd51b9181e1bd84f564c4950ec0c941d6820123
parent815be937ab5a3baaa726090cfb57feb90f7c95f9 (diff)
downloadrust-8b57fd9e43baa9d8e1c72c54201d4820661f32c4.tar.gz
rust-8b57fd9e43baa9d8e1c72c54201d4820661f32c4.zip
use `fmt::from_fn` in more places, instead of using structs that impl formatting traits
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs62
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/mir/query.rs68
-rw-r--r--compiler/rustc_middle/src/ty/context.rs80
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs60
6 files changed, 111 insertions, 161 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,29 +184,11 @@ enum Scope<'a> {
     },
 }
 
-#[derive(Copy, Clone, Debug)]
-enum BinderScopeType {
-    /// Any non-concatenating binder scopes.
-    Normal,
-    /// Within a syntactic trait ref, there may be multiple poly trait refs that
-    /// are nested (under the `associated_type_bounds` feature). The binders of
-    /// the inner poly trait refs are extended from the outer poly trait refs
-    /// and don't increase the late bound depth. If you had
-    /// `T: for<'a>  Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
-    /// would be `Concatenating`. This also used in trait refs in where clauses
-    /// where we have two binders `for<> T: for<> Foo` (I've intentionally left
-    /// out any lifetimes because they aren't needed to show the two scopes).
-    /// The inner `for<>` has a scope of `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
+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)
@@ -214,38 +196,54 @@ impl<'a> fmt::Debug for TruncatedScopeDebug<'a> {
                 .field("where_bound_origin", where_bound_origin)
                 .field("s", &"..")
                 .finish(),
-            Scope::Opaque { captures, def_id, s: _ } => f
+            Self::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: _ } => {
+            Self::Body { id, s: _ } => {
                 f.debug_struct("Body").field("id", id).field("s", &"..").finish()
             }
-            Scope::ObjectLifetimeDefault { lifetime, s: _ } => f
+            Self::ObjectLifetimeDefault { lifetime, s: _ } => f
                 .debug_struct("ObjectLifetimeDefault")
                 .field("lifetime", lifetime)
                 .field("s", &"..")
                 .finish(),
-            Scope::Supertrait { bound_vars, s: _ } => f
+            Self::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
+            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(),
-            Scope::Root { opt_parent_item } => {
+            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.
+    Normal,
+    /// Within a syntactic trait ref, there may be multiple poly trait refs that
+    /// are nested (under the `associated_type_bounds` feature). The binders of
+    /// the inner poly trait refs are extended from the outer poly trait refs
+    /// and don't increase the late bound depth. If you had
+    /// `T: for<'a>  Foo<Bar: for<'b> Baz<'a, 'b>>`, then the `for<'b>` scope
+    /// would be `Concatenating`. This also used in trait refs in where clauses
+    /// where we have two binders `for<> T: for<> Foo` (I've intentionally left
+    /// out any lifetimes because they aren't needed to show the two scopes).
+    /// The inner `for<>` has a scope of `Concatenating`.
+    Concatenating,
+}
+
 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<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")
-            .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>);
-
-        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.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)
+    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
+            )?;
+
+            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(())
+        })
     }
 }
 
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,
-        }
-
-        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;
-                    }
-                }
-                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);
+        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", &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", &self.num_bump_calls);
 
-                // imply there's "more to know" than this view
-                dbg_fmt.finish_non_exhaustive()
+            // 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);
             }
-        }
 
-        DebugParser { parser: self, lookahead }
+            // imply there's "more to know" than this view
+            dbg_fmt.finish_non_exhaustive()
+        })
     }
 
     pub fn clear_expected_token_types(&mut self) {