Skip to content

Commit

Permalink
core: Make Debug impl of raw pointers print metadata if present
Browse files Browse the repository at this point in the history
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
1 parent d16da3b commit 697737a
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
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

0 comments on commit 697737a

Please sign in to comment.