From 697737a8b18b685270f197ccdd1211e8a010b98b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 3 Jan 2025 18:02:33 +0100 Subject: [PATCH] core: Make `Debug` impl of raw pointers print metadata if present Make Rust pointers less magic by including metadata information in their `Debug` output. This does not break Rust stability guarantees because `Debug` output is explicitly exempted from stability: https://doc.rust-lang.org/std/fmt/trait.Debug.html#stability Co-authored-by: Lukas <26522220+lukas-code@users.noreply.github.com> Co-authored-by: Josh Stone --- library/core/src/fmt/mod.rs | 9 ++++++++- library/core/src/unit.rs | 16 ++++++++++++++++ library/coretests/tests/fmt/mod.rs | 8 ++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index a1bf3a4d7a706..4cfcb412bfd29 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2776,7 +2776,14 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - pointer_fmt_inner(self.expose_provenance(), f) + if <::Metadata as core::unit::IsUnit>::is_unit() { + pointer_fmt_inner(self.expose_provenance(), f) + } else { + f.debug_struct("Pointer") + .field_with("addr", |f| pointer_fmt_inner(self.expose_provenance(), f)) + .field("metadata", &core::ptr::metadata(*self)) + .finish() + } } } diff --git a/library/core/src/unit.rs b/library/core/src/unit.rs index d656005f3d42d..d54816c444bc4 100644 --- a/library/core/src/unit.rs +++ b/library/core/src/unit.rs @@ -17,3 +17,19 @@ impl FromIterator<()> for () { iter.into_iter().for_each(|()| {}) } } + +pub(crate) trait IsUnit { + fn is_unit() -> bool; +} + +impl IsUnit for T { + default fn is_unit() -> bool { + false + } +} + +impl IsUnit for () { + fn is_unit() -> bool { + true + } +} diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 13f7bca646fa8..cb185dae9de35 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -42,12 +42,12 @@ fn test_fmt_debug_of_raw_pointers() { check_fmt(plain as *const i32, "$HEX"); let slice = &mut [200, 300, 400][..]; - check_fmt(slice as *mut [i32], "$HEX"); - check_fmt(slice as *const [i32], "$HEX"); + check_fmt(slice as *mut [i32], "Pointer { addr: $HEX, metadata: 3 }"); + check_fmt(slice as *const [i32], "Pointer { addr: $HEX, metadata: 3 }"); let vtable = &mut 500 as &mut dyn Debug; - check_fmt(vtable as *mut dyn Debug, "$HEX"); - check_fmt(vtable as *const dyn Debug, "$HEX"); + check_fmt(vtable as *mut dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); + check_fmt(vtable as *const dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); } #[test]