From c043f239a15c6e891ef65e4258e38f3a79268d04 Mon Sep 17 00:00:00 2001 From: Hanna Kruppe Date: Tue, 9 Jun 2026 23:54:51 +0200 Subject: [PATCH] improve polymorphization of raw pointer formatting This reduces the amount of LLVM IR rustc generates for basically every use of `fmt::Pointer` by several hundred lines per pointee type. Most of the gain is from side-stepping a code size issue with the current implementation of `Formatter::with_field`. But even if those were fixed, it would still be an improvement: * The "is it a thin pointer?" check can't be eliminated during codegen, so rustc codegens *both* branches for every pointer type and LLVM has to clean it up later. * For wide pointers, the use of `DebugStruct` isn't a *lot* of code, but it's still a bit of extra code per wide pointer type that can easily be shared across all wide pointer types. --- library/core/src/fmt/mod.rs | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 9e5f693246f33..8c9f4fd8091a7 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2996,20 +2996,19 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { + // Since the formatting will be identical for all pointer types, erase the pointee type and + // metadata type to reduce the amount of codegen work needed for each distinct type. + let ptr: *const T = *self; + let ptr_addr = ptr.expose_provenance(); if <::Metadata as core::unit::IsUnit>::is_unit() { - pointer_fmt_inner(self.expose_provenance(), f) + pointer_fmt_inner(ptr_addr, f) } else { - f.debug_struct("Pointer") - .field_with("addr", |f| pointer_fmt_inner(self.expose_provenance(), f)) - .field("metadata", &core::ptr::metadata(*self)) - .finish() + wide_pointer_fmt_inner(ptr_addr, &core::ptr::metadata(ptr), f) } } } -/// Since the formatting will be identical for all pointer types, uses a -/// non-monomorphized implementation for the actual formatting to reduce the -/// amount of codegen work needed. +/// Formats an address in `fmt::Pointer` style. /// /// This uses `ptr_addr: usize` and not `ptr: *const ()` to be able to use this for /// `fn(...) -> ...` without using [problematic] "Oxford Casts". @@ -3038,6 +3037,14 @@ pub(crate) fn pointer_fmt_inner(ptr_addr: usize, f: &mut Formatter<'_>) -> Resul ret } +/// Formats a wide pointer (address and type-erased metadata) in `fmt::Pointer` style. +fn wide_pointer_fmt_inner(ptr_addr: usize, metadata: &dyn Debug, f: &mut Formatter<'_>) -> Result { + f.debug_struct("Pointer") + .field_with("addr", move |f| pointer_fmt_inner(ptr_addr, f)) + .field("metadata", metadata) + .finish() +} + #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *mut T { fn fmt(&self, f: &mut Formatter<'_>) -> Result {