@@ -63,21 +63,22 @@ impl<T: ?Sized> *const T {
63
63
self as _
64
64
}
65
65
66
- /// Uses the pointer value in a new pointer of another type.
66
+ /// Uses the address value in a new pointer of another type.
67
67
///
68
- /// In case `meta` is a (fat) pointer to an unsized type, this operation
69
- /// will ignore the pointer part, whereas for (thin) pointers to sized
70
- /// types, this has the same effect as a simple cast.
68
+ /// This operation will ignore the address part of its `meta` operand and discard existing
69
+ /// metadata of `self`. For pointers to a sized types (thin pointers), this has the same effect
70
+ /// as a simple cast. For pointers to an unsized type (fat pointers) this recombines the address
71
+ /// with new metadata such as slice lengths or `dyn`-vtable.
71
72
///
72
- /// The resulting pointer will have provenance of `self`, i.e., for a fat
73
- /// pointer, this operation is semantically the same as creating a new
74
- /// fat pointer with the data pointer value of `self` but the metadata of
75
- /// `meta`.
73
+ /// The resulting pointer will have provenance of `self`. This operation is semantically the
74
+ /// same as creating a new pointer with the data pointer value of `self` but the metadata of
75
+ /// `meta`, being fat or thing depending on the `meta` operand.
76
76
///
77
77
/// # Examples
78
78
///
79
- /// This function is primarily useful for allowing byte-wise pointer
80
- /// arithmetic on potentially fat pointers:
79
+ /// This function is primarily useful for enabling pointer arithmetic on potentially fat
80
+ /// pointers. The pointer is cast to a sized pointee to utilize offset operations and then
81
+ /// recombined with its own original metadata.
81
82
///
82
83
/// ```
83
84
/// #![feature(set_ptr_value)]
@@ -91,6 +92,26 @@ impl<T: ?Sized> *const T {
91
92
/// println!("{:?}", &*ptr); // will print "3"
92
93
/// }
93
94
/// ```
95
+ ///
96
+ /// # *Incorrect* usage
97
+ ///
98
+ /// The provenance from pointers is *not* combined. The result must only be used to refer to the
99
+ /// address allowed by `self`.
100
+ ///
101
+ /// ```rust,no_run
102
+ /// #![feature(set_ptr_value)]
103
+ /// let x = 0u32;
104
+ /// let y = 1u32;
105
+ ///
106
+ /// let x = (&x) as *const u32;
107
+ /// let y = (&y) as *const u32;
108
+ ///
109
+ /// let offset = (x as usize - y as usize) / 4;
110
+ /// let bad = x.wrapping_add(offset).with_metadata_of(y);
111
+ ///
112
+ /// // This dereference is UB. The pointer only has provenance for `x` but points to `y`.
113
+ /// println!("{:?}", unsafe { &*bad });
114
+ /// ```
94
115
#[ unstable( feature = "set_ptr_value" , issue = "75091" ) ]
95
116
#[ rustc_const_stable( feature = "ptr_metadata_const" , since = "CURRENT_RUSTC_VERSION" ) ]
96
117
#[ must_use = "returns a new pointer rather than modifying its argument" ]
0 commit comments