1 #![unstable(feature = "ptr_metadata", issue = /* FIXME */ "none")]
4 use crate::hash::{Hash, Hasher};
5 use crate::ptr::NonNull;
8 #[lang = "pointee_trait"]
10 /// The type for metadata in pointers and references to `Self`.
11 #[lang = "metadata_type"]
12 // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata`
13 // in `library/core/src/ptr/metadata.rs`
14 // in sync with those here:
15 type Metadata: Copy + Send + Sync + Ord + Hash + Unpin;
18 /// Pointers to types implementing this trait alias are “thin”
21 /// #![feature(ptr_metadata)]
23 /// fn this_never_panics<T: std::ptr::Thin>() {
24 /// assert_eq!(std::mem::size_of::<&T>(), std::mem::size_of::<usize>())
27 #[unstable(feature = "ptr_metadata", issue = /* FIXME */ "none")]
28 // NOTE: don’t stabilize this before trait aliases are stable in the language?
29 pub trait Thin = Pointee<Metadata = ()>;
31 /// Extract the metadata component of a pointer.
33 pub fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
34 // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
35 // and PtrComponents<T> have the same memory layouts. Only std can make this
37 unsafe { PtrRepr { const_ptr: ptr }.components.metadata }
41 union PtrRepr<T: ?Sized> {
43 components: PtrComponents<T>,
47 struct PtrComponents<T: ?Sized> {
49 metadata: <T as Pointee>::Metadata,
52 // Manual impl needed to avoid `T: Copy` bound.
53 impl<T: ?Sized> Copy for PtrComponents<T> {}
55 // Manual impl needed to avoid `T: Clone` bound.
56 impl<T: ?Sized> Clone for PtrComponents<T> {
57 fn clone(&self) -> Self {
62 /// The metadata for a `dyn SomeTrait` trait object type.
63 #[lang = "dyn_metadata"]
64 pub struct DynMetadata<Dyn: ?Sized> {
66 vtable_ptr: NonNull<()>,
67 phantom: crate::marker::PhantomData<Dyn>,
70 unsafe impl<Dyn: ?Sized> Send for DynMetadata<Dyn> {}
71 unsafe impl<Dyn: ?Sized> Sync for DynMetadata<Dyn> {}
73 impl<Dyn: ?Sized> fmt::Debug for DynMetadata<Dyn> {
74 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75 f.write_str("DynMetadata { … }")
79 // Manual impls needed to avoid `Dyn: $Trait` bounds.
81 impl<Dyn: ?Sized> Unpin for DynMetadata<Dyn> {}
83 impl<Dyn: ?Sized> Copy for DynMetadata<Dyn> {}
85 impl<Dyn: ?Sized> Clone for DynMetadata<Dyn> {
87 fn clone(&self) -> Self {
92 impl<Dyn: ?Sized> Eq for DynMetadata<Dyn> {}
94 impl<Dyn: ?Sized> PartialEq for DynMetadata<Dyn> {
96 fn eq(&self, other: &Self) -> bool {
97 self.vtable_ptr == other.vtable_ptr
101 impl<Dyn: ?Sized> Ord for DynMetadata<Dyn> {
103 fn cmp(&self, other: &Self) -> crate::cmp::Ordering {
104 self.vtable_ptr.cmp(&other.vtable_ptr)
108 impl<Dyn: ?Sized> PartialOrd for DynMetadata<Dyn> {
110 fn partial_cmp(&self, other: &Self) -> Option<crate::cmp::Ordering> {
111 Some(self.vtable_ptr.cmp(&other.vtable_ptr))
115 impl<Dyn: ?Sized> Hash for DynMetadata<Dyn> {
117 fn hash<H: Hasher>(&self, hasher: &mut H) {
118 self.vtable_ptr.hash(hasher)