diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 02ac4fb800655..1872848778404 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -4,11 +4,13 @@ use crate::cell::{Cell, Ref, RefCell, RefMut, UnsafeCell}; use crate::char::EscapeDebugExtArgs; +use crate::intrinsics::size_of; use crate::iter; use crate::marker::PhantomData; use crate::mem; use crate::num::flt2dec; use crate::ops::Deref; +use crate::ptr; use crate::result; use crate::str; @@ -2130,6 +2132,15 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { + if size_of::<*const T>() > size_of::<*const ()>() { + // Fat pointer, format as (address, metadata) + let meta = ptr::metadata(*self); + return f.debug_tuple("") + .field(&(*self as *const ())) + .field(&meta) + .finish(); + } + let old_width = f.width; let old_flags = f.flags; diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 7c7dce0ce74e2..679da15ce130e 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -1,6 +1,6 @@ #![unstable(feature = "ptr_metadata", issue = "81513")] -use crate::fmt; +use crate::fmt::{self, Debug}; use crate::hash::{Hash, Hasher}; /// Provides the pointer metadata type of any pointed-to type. @@ -56,7 +56,7 @@ 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: - type Metadata: Copy + Send + Sync + Ord + Hash + Unpin; + type Metadata: Copy + Send + Sync + Ord + Hash + Unpin + Debug; } /// Pointers to types implementing this trait alias are “thin”. diff --git a/library/core/tests/fmt/mod.rs b/library/core/tests/fmt/mod.rs index 7b281ce48e6aa..366ffdaae500e 100644 --- a/library/core/tests/fmt/mod.rs +++ b/library/core/tests/fmt/mod.rs @@ -2,6 +2,10 @@ mod builders; mod float; mod num; +use core::any; +use core::fmt; +use core::ptr; + #[test] fn test_format_flags() { // No residual flags left by pointer formatting @@ -13,10 +17,20 @@ fn test_format_flags() { #[test] fn test_pointer_formats_data_pointer() { - let b: &[u8] = b""; - let s: &str = ""; - assert_eq!(format!("{:p}", s), format!("{:p}", s.as_ptr())); - assert_eq!(format!("{:p}", b), format!("{:p}", b.as_ptr())); + // Thin ptr + let thinptr = &42 as *const i32; + assert_eq!(format!("{:p}", thinptr), format!("{:?}", thinptr as *const ())); + + // Ptr with length + let b: &[u8] = b"hello"; + let s: &str = "hello"; + assert_eq!(format!("{:p}", b), format!("({:?}, 5)", b.as_ptr())); + assert_eq!(format!("{:p}", s), format!("({:?}, 5)", s.as_ptr())); + + // Ptr with v-table + let mut any: Box = Box::new(42); + let dyn_ptr = &mut *any as *mut dyn any::Any; + assert_eq!(format!("{:p}", dyn_ptr), format!("({:?}, {:?})", dyn_ptr as *const (), ptr::metadata(dyn_ptr))); } #[test] @@ -33,8 +47,8 @@ fn test_estimated_capacity() { fn pad_integral_resets() { struct Bar; - impl core::fmt::Display for Bar { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + impl fmt::Display for Bar { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { "1".fmt(f)?; f.pad_integral(true, "", "5")?; "1".fmt(f) diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs index 11af8090c3a4f..e9701356e37c5 100644 --- a/library/core/tests/ptr.rs +++ b/library/core/tests/ptr.rs @@ -500,7 +500,7 @@ fn ptr_metadata_bounds() { fn static_assert_expected_bounds_for_metadata() where // Keep this in sync with the associated type in `library/core/src/ptr/metadata.rs` - Meta: Copy + Send + Sync + Ord + std::hash::Hash + Unpin, + Meta: Copy + Send + Sync + Ord + std::hash::Hash + Unpin + Debug, { } }