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>
  • Loading branch information
Enselic and lukas-code committed Feb 15, 2025
1 parent d16da3b commit 892bb5f
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 892bb5f

Please sign in to comment.