diff options
| author | 许杰友 Jieyou Xu (Joe) <39484203+jieyouxu@users.noreply.github.com> | 2025-03-16 13:19:51 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-16 13:19:51 +0800 |
| commit | a23a93cb4e848c75d6cf2ddb9ca418a0e501af90 (patch) | |
| tree | f03275adb8cf505e3e2710b3c205fa7260382723 /library/core/src | |
| parent | 66678e68227913a42438afc7320a2849dffd4d51 (diff) | |
| parent | 697737a8b18b685270f197ccdd1211e8a010b98b (diff) | |
Rollup merge of #135080 - Enselic:debug-ptr-metadata, r=thomcc
core: Make `Debug` impl of raw pointers print metadata if present
Make Rust pointers appear less magic by including metadata information in their `Debug` output.
This does not break Rust stability guarantees because `Debug` impl are explicitly exempted from stability:
https://doc.rust-lang.org/std/fmt/trait.Debug.html#stability
> ## Stability
>
> Derived `Debug` formats are not stable, and so may change with future Rust versions. Additionally, `Debug` implementations of types provided by the standard library (`std`, `core`, `alloc`, etc.) are not stable, and may also change with future Rust versions.
Note that a regression test is added as a separate commit to make it clear what impact the last commit has on the output.
Closes #128684 because the output of that code now becomes:
```
thread 'main' panicked at src/main.rs:5:5:
assertion `left == right` failed
left: Pointer { addr: 0x7ffd45c6fc6b, metadata: 5 }
right: Pointer { addr: 0x7ffd45c6fc6b, metadata: 3 }
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```
Diffstat (limited to 'library/core/src')
| -rw-r--r-- | library/core/src/fmt/mod.rs | 9 | ||||
| -rw-r--r-- | library/core/src/ptr/metadata.rs | 2 | ||||
| -rw-r--r-- | library/core/src/unit.rs | 16 |
3 files changed, 26 insertions, 1 deletions
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index a0f5b00cd2d..b13c7ee5aa2 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2771,7 +2771,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/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 48707506389..9c5da306e27 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -61,6 +61,8 @@ pub trait Pointee { // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` // in `library/core/src/ptr/metadata.rs` // in sync with those here: + // NOTE: The metadata of `dyn Trait + 'a` is `DynMetadata<dyn Trait + 'a>` + // so a `'static` bound must not be added. type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin + Freeze; } 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 + } +} |
