3
3
use crate :: fmt;
4
4
use crate :: hash:: { Hash , Hasher } ;
5
5
6
- /// FIXME docs
6
+ /// Provides the pointer metadata type of any pointed-to type.
7
+ ///
8
+ /// # Pointer metadata
9
+ ///
10
+ /// Raw pointer types and reference types in Rust can be thought of as made of two parts:
11
+ /// a data pointer that contains the memory address of the value, and some metadata.
12
+ ///
13
+ /// For statically-sized types (that implement the `Sized` traits)
14
+ /// as well as for `extern` types,
15
+ /// pointers are said to be “thin”: metadata is zero-sized and its type is `()`.
16
+ ///
17
+ /// Pointers to [dynamically-sized types][dst] are said to be “wide” or “fat”,
18
+ /// they have non-zero-sized metadata:
19
+ ///
20
+ /// * For structs whose last field is a DST, metadata is the metadata for the last field
21
+ /// * For the `str` type, metadata is the length in bytes as `usize`
22
+ /// * For slice types like `[T]`, metadata is the length in items as `usize`
23
+ /// * For trait objects like `dyn SomeTrait`, metadata is [`DynMetadata<Self>`][DynMetadata]
24
+ /// (e.g. `DynMetadata<dyn SomeTrait>`)
25
+ ///
26
+ /// In the future, the Rust language may gain new kinds of types
27
+ /// that have different pointer metadata.
28
+ ///
29
+ /// [dst]: https://doc.rust-lang.org/nomicon/exotic-sizes.html#dynamically-sized-types-dsts
30
+ ///
31
+ ///
32
+ /// # The `Pointee` trait
33
+ ///
34
+ /// The point of this trait is its `Metadata` associated type,
35
+ /// which is `()` or `usize` or `DynMetadata<_>` as described above.
36
+ /// It is automatically implemented for every type.
37
+ /// It can be assumed to be implemented in a generic context, even without a corresponding bound.
38
+ ///
39
+ ///
40
+ /// # Usage
41
+ ///
42
+ /// Raw pointers can be decomposed into the data address and metadata components
43
+ /// with their [`to_raw_parts`] method.
44
+ ///
45
+ /// Alternatively, metadata alone can be extracted with the [`metadata`] function.
46
+ /// A reference can be passed to [`metadata`] and implicitly coerced.
47
+ ///
48
+ /// A (possibly-wide) pointer can be put back together from its address and metadata
49
+ /// with [`from_raw_parts`] or [`from_raw_parts_mut`].
50
+ ///
51
+ /// [`to_raw_parts`]: <*const _>::to_raw_parts
7
52
#[ lang = "pointee_trait" ]
8
53
pub trait Pointee {
9
54
/// The type for metadata in pointers and references to `Self`.
@@ -14,7 +59,11 @@ pub trait Pointee {
14
59
type Metadata : Copy + Send + Sync + Ord + Hash + Unpin ;
15
60
}
16
61
17
- /// Pointers to types implementing this trait alias are “thin”
62
+ /// Pointers to types implementing this trait alias are “thin”.
63
+ ///
64
+ /// This includes statically-`Sized` types and `extern` types.
65
+ ///
66
+ /// # Example
18
67
///
19
68
/// ```rust
20
69
/// #![feature(ptr_metadata)]
@@ -28,6 +77,17 @@ pub trait Pointee {
28
77
pub trait Thin = Pointee < Metadata = ( ) > ;
29
78
30
79
/// Extract the metadata component of a pointer.
80
+ ///
81
+ /// Values of type `*mut T`, `&T`, or `&mut T` can be passed directly to this function
82
+ /// as they implicitly coerce to `* const T `.
83
+ ///
84
+ /// # Example
85
+ ///
86
+ /// ```
87
+ /// #![feature(ptr_metadata)]
88
+ ///
89
+ /// assert_eq!(std::ptr::metadata("foo"), 3_usize);
90
+ /// ```
31
91
#[ rustc_const_unstable( feature = "ptr_metadata", issue = /* FIXME */ "none") ]
32
92
#[ inline]
33
93
pub const fn metadata < T : ?Sized > ( ptr: * const T ) -> <T as Pointee >:: Metadata {
@@ -37,7 +97,13 @@ pub const fn metadata<T: ?Sized>(ptr: *const T) -> <T as Pointee>::Metadata {
37
97
unsafe { PtrRepr { const_ptr: ptr } . components. metadata }
38
98
}
39
99
40
- /// Forms a raw pointer from a data address and metadata.
100
+ /// Forms a (possibly-wide) raw pointer from a data address and metadata.
101
+ ///
102
+ /// This function is safe but the returned pointer is not necessarily safe to dereference.
103
+ /// For slices, see the documentation of [`slice::from_raw_parts`] for safety requirements.
104
+ /// For trait objects, the metadata must come from a pointer to the same underlying ereased type.
105
+ ///
106
+ /// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
41
107
#[ unstable( feature = "ptr_metadata" , issue = /* FIXME */ "none" ) ]
42
108
#[ rustc_const_unstable( feature = "ptr_metadata" , issue = /* FIXME */ "none" ) ]
43
109
#[ inline]
@@ -91,7 +157,23 @@ impl<T: ?Sized> Clone for PtrComponents<T> {
91
157
}
92
158
}
93
159
94
- /// The metadata for a `dyn SomeTrait` trait object type.
160
+ /// The metadata for a `Dyn = dyn SomeTrait` trait object type.
161
+ ///
162
+ /// It is a pointer to a vtable (virtual call table)
163
+ /// that represents all the necessary information
164
+ /// to manipulate the concrete type stored inside a trait object.
165
+ /// The vtable notably it contains:
166
+ ///
167
+ /// * type size
168
+ /// * type alignment
169
+ /// * a pointer to the type’s `drop_in_place` impl (may be a no-op for plain-old-data)
170
+ /// * pointers to all the methods for the type’s implementation of the trait
171
+ ///
172
+ /// Note that the first three are special because they’re necessary to allocate, drop,
173
+ /// and deallocate any trait object.
174
+ ///
175
+ /// It is possible to name this struct with a type parameter that is not a `dyn` trait object
176
+ /// (for example `DynMetadata<u64>`) but not to obtain a meaningful value of that struct.
95
177
#[ lang = "dyn_metadata" ]
96
178
pub struct DynMetadata < Dyn : ?Sized > {
97
179
vtable_ptr : & ' static VTable ,
0 commit comments