@@ -124,12 +124,12 @@ impl<T: ?Sized> *mut T {
124
124
125
125
/// Gets the "address" portion of the pointer.
126
126
///
127
- /// This is similar to `self as usize`, which semantically discards * provenance* and
128
- /// *address-space* information. However, unlike `self as usize`, casting the returned address
129
- /// back to a pointer yields a [pointer without provenance][without_provenance_mut], which is undefined
130
- /// behavior to dereference. To properly restore the lost information and obtain a
131
- /// dereferenceable pointer, use [`with_addr`][pointer::with_addr] or
132
- /// [`map_addr`][pointer::map_addr].
127
+ /// This is similar to `self as usize`, except that the [ provenance][crate::ptr#provenance] of
128
+ /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
129
+ /// casting the returned address back to a pointer yields a [pointer without
130
+ /// provenance][without_provenance_mut], which is undefined behavior to dereference. To properly
131
+ /// restore the lost information and obtain a dereferenceable pointer, use
132
+ /// [`with_addr`][pointer::with_addr] or [` map_addr`][pointer::map_addr].
133
133
///
134
134
/// If using those APIs is not possible because there is no way to preserve a pointer with the
135
135
/// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
@@ -143,89 +143,80 @@ impl<T: ?Sized> *mut T {
143
143
/// perform a change of representation to produce a value containing only the address
144
144
/// portion of the pointer. What that means is up to the platform to define.
145
145
///
146
- /// This API and its claimed semantics are part of the Strict Provenance experiment, and as such
147
- /// might change in the future (including possibly weakening this so it becomes wholly
148
- /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details.
146
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
149
147
#[ must_use]
150
148
#[ inline( always) ]
151
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
149
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
152
150
pub fn addr ( self ) -> usize {
153
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
151
+ // A pointer-to-integer transmute currently has exactly the right semantics: it returns the
152
+ // address without exposing the provenance. Note that this is *not* a stable guarantee about
153
+ // transmute semantics, it relies on sysroot crates having special status.
154
154
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
155
155
// provenance).
156
156
unsafe { mem:: transmute ( self . cast :: < ( ) > ( ) ) }
157
157
}
158
158
159
- /// Exposes the "provenance" part of the pointer for future use in
160
- /// [`with_exposed_provenance`][ ] and returns the "address" portion.
159
+ /// Exposes the [ "provenance"][crate::ptr#provenance] part of the pointer for future use in
160
+ /// [`with_exposed_provenance_mut` ] and returns the "address" portion.
161
161
///
162
- /// This is equivalent to `self as usize`, which semantically discards *provenance* and
163
- /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
164
- /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
165
- /// later call [`with_exposed_provenance_mut`][] to reconstitute the original pointer including its
166
- /// provenance. (Reconstructing address space information, if required, is your responsibility.)
162
+ /// This is equivalent to `self as usize`, which semantically discards provenance information.
163
+ /// Furthermore, this (like the `as` cast) has the implicit side-effect of marking the
164
+ /// provenance as 'exposed', so on platforms that support it you can later call
165
+ /// [`with_exposed_provenance_mut`] to reconstitute the original pointer including its provenance.
167
166
///
168
- /// Using this method means that code is *not* following [Strict
169
- /// Provenance][super#strict-provenance] rules. Supporting
170
- /// [`with_exposed_provenance_mut`][] complicates specification and reasoning and may not be supported
171
- /// by tools that help you to stay conformant with the Rust memory model, so it is recommended
172
- /// to use [`addr`][pointer::addr] wherever possible.
167
+ /// Due to its inherent ambiguity, [`with_exposed_provenance_mut`] may not be supported by tools
168
+ /// that help you to stay conformant with the Rust memory model. It is recommended to use
169
+ /// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [`with_addr`][pointer::with_addr]
170
+ /// wherever possible, in which case [`addr`][pointer::addr] should be used instead of `expose_provenance`.
173
171
///
174
172
/// On most platforms this will produce a value with the same bytes as the original pointer,
175
173
/// because all the bytes are dedicated to describing the address. Platforms which need to store
176
174
/// additional information in the pointer may not support this operation, since the 'expose'
177
- /// side-effect which is required for [`with_exposed_provenance_mut`][] to work is typically not
175
+ /// side-effect which is required for [`with_exposed_provenance_mut`] to work is typically not
178
176
/// available.
179
177
///
180
- /// It is unclear whether this method can be given a satisfying unambiguous specification. This
181
- /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
178
+ /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
182
179
///
183
180
/// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
184
181
#[ inline( always) ]
185
- #[ unstable ( feature = "exposed_provenance" , issue = "95228 " ) ]
182
+ #[ stable ( feature = "exposed_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
186
183
pub fn expose_provenance ( self ) -> usize {
187
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
188
184
self . cast :: < ( ) > ( ) as usize
189
185
}
190
186
191
- /// Creates a new pointer with the given address.
187
+ /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
188
+ /// `self`.
192
189
///
193
- /// This performs the same operation as an `addr as ptr` cast, but copies
194
- /// the *address-space* and *provenance* of `self` to the new pointer.
195
- /// This allows us to dynamically preserve and propagate this important
196
- /// information in a way that is otherwise impossible with a unary cast.
190
+ /// This is similar to a `addr as *mut T` cast, but copies
191
+ /// the *provenance* of `self` to the new pointer.
192
+ /// This avoids the inherent ambiguity of the unary cast.
197
193
///
198
194
/// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
199
195
/// `self` to the given address, and therefore has all the same capabilities and restrictions.
200
196
///
201
- /// This API and its claimed semantics are an extension to the Strict Provenance experiment,
202
- /// see the [module documentation][crate::ptr] for details.
197
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
203
198
#[ must_use]
204
199
#[ inline]
205
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
200
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
206
201
pub fn with_addr ( self , addr : usize ) -> Self {
207
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
208
- //
209
- // In the mean-time, this operation is defined to be "as if" it was
210
- // a wrapping_offset, so we can emulate it as such. This should properly
211
- // restore pointer provenance even under today's compiler.
202
+ // This should probably be an intrinsic to avoid doing any sort of arithmetic, but
203
+ // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's
204
+ // provenance.
212
205
let self_addr = self . addr ( ) as isize ;
213
206
let dest_addr = addr as isize ;
214
207
let offset = dest_addr. wrapping_sub ( self_addr) ;
215
-
216
- // This is the canonical desugaring of this operation
217
208
self . wrapping_byte_offset ( offset)
218
209
}
219
210
220
- /// Creates a new pointer by mapping `self`'s address to a new one.
211
+ /// Creates a new pointer by mapping `self`'s address to a new one, preserving the original
212
+ /// pointer's [provenance][crate::ptr#provenance].
221
213
///
222
214
/// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
223
215
///
224
- /// This API and its claimed semantics are part of the Strict Provenance experiment,
225
- /// see the [module documentation][crate::ptr] for details.
216
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
226
217
#[ must_use]
227
218
#[ inline]
228
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
219
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
229
220
pub fn map_addr ( self , f : impl FnOnce ( usize ) -> usize ) -> Self {
230
221
self . with_addr ( f ( self . addr ( ) ) )
231
222
}
@@ -376,7 +367,7 @@ impl<T: ?Sized> *mut T {
376
367
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
377
368
/// "wrapping around"), must fit in an `isize`.
378
369
///
379
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
370
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
380
371
/// [allocated object], and the entire memory range between `self` and the result must be in
381
372
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
382
373
/// of the address space.
@@ -777,7 +768,7 @@ impl<T: ?Sized> *mut T {
777
768
/// * `self` and `origin` must either
778
769
///
779
770
/// * point to the same address, or
780
- /// * both be * derived from* a pointer to the same [allocated object], and the memory range between
771
+ /// * both be [ derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between
781
772
/// the two pointers must be in bounds of that object. (See below for an example.)
782
773
///
783
774
/// * The distance between the pointers, in bytes, must be an exact multiple
@@ -954,7 +945,7 @@ impl<T: ?Sized> *mut T {
954
945
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
955
946
/// "wrapping around"), must fit in an `isize`.
956
947
///
957
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
948
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
958
949
/// [allocated object], and the entire memory range between `self` and the result must be in
959
950
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
960
951
/// of the address space.
@@ -1061,7 +1052,7 @@ impl<T: ?Sized> *mut T {
1061
1052
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
1062
1053
/// "wrapping around"), must fit in an `isize`.
1063
1054
///
1064
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
1055
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
1065
1056
/// [allocated object], and the entire memory range between `self` and the result must be in
1066
1057
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
1067
1058
/// of the address space.
0 commit comments