Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
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>
  • Loading branch information
3 people committed Feb 15, 2025
commit 697737a8b18b685270f197ccdd1211e8a010b98b
9 changes: 8 additions & 1 deletion library/core/src/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
}
}

Expand Down
16 changes: 16 additions & 0 deletions library/core/src/unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
8 changes: 4 additions & 4 deletions library/coretests/tests/fmt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down