about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMartin Nordholts <martin.nordholts@codetale.se>2025-01-03 18:02:33 +0100
committerMartin Nordholts <martin.nordholts@codetale.se>2025-02-15 17:27:55 +0100
commit697737a8b18b685270f197ccdd1211e8a010b98b (patch)
tree898847f9c092427efb89281978a7b427f6c95666
parentd16da3b8b2be9f1da5a2e9d2b31c499a21d2d7a1 (diff)
downloadrust-697737a8b18b685270f197ccdd1211e8a010b98b.tar.gz
rust-697737a8b18b685270f197ccdd1211e8a010b98b.zip
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 <cuviper@gmail.com>
-rw-r--r--library/core/src/fmt/mod.rs9
-rw-r--r--library/core/src/unit.rs16
-rw-r--r--library/coretests/tests/fmt/mod.rs8
3 files changed, 28 insertions, 5 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index a1bf3a4d7a7..4cfcb412bfd 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<T: ?Sized> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        pointer_fmt_inner(self.expose_provenance(), f)
+        if <<T as core::ptr::Pointee>::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 d656005f3d4..d54816c444b 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<T: ?Sized> 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 13f7bca646f..cb185dae9de 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]