@@ -137,10 +137,11 @@ impl<T: ?Sized> *const T {
137
137
138
138
/// Gets the "address" portion of the pointer.
139
139
///
140
- /// This is similar to `self as usize`, which semantically discards *provenance* and
141
- /// *address-space* information. However, unlike `self as usize`, casting the returned address
142
- /// back to a pointer yields a [pointer without provenance][without_provenance], which is undefined behavior to dereference. To
143
- /// properly restore the lost information and obtain a dereferenceable pointer, use
140
+ /// This is similar to `self as usize`, except that the [provenance][crate::ptr#provenance] of
141
+ /// the pointer is discarded and not [exposed][crate::ptr#exposed-provenance]. This means that
142
+ /// casting the returned address back to a pointer yields a [pointer without
143
+ /// provenance][without_provenance], which is undefined behavior to dereference. To properly
144
+ /// restore the lost information and obtain a dereferenceable pointer, use
144
145
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
145
146
///
146
147
/// If using those APIs is not possible because there is no way to preserve a pointer with the
@@ -155,90 +156,81 @@ impl<T: ?Sized> *const T {
155
156
/// perform a change of representation to produce a value containing only the address
156
157
/// portion of the pointer. What that means is up to the platform to define.
157
158
///
158
- /// This API and its claimed semantics are part of the Strict Provenance experiment, and as such
159
- /// might change in the future (including possibly weakening this so it becomes wholly
160
- /// equivalent to `self as usize`). See the [module documentation][crate::ptr] for details.
159
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
161
160
#[ must_use]
162
161
#[ inline( always) ]
163
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
162
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
164
163
pub fn addr ( self ) -> usize {
165
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
164
+ // A pointer-to-integer transmute currently has exactly the right semantics: it returns the
165
+ // address without exposing the provenance. Note that this is *not* a stable guarantee about
166
+ // transmute semantics, it relies on sysroot crates having special status.
166
167
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
167
168
// provenance).
168
169
unsafe { mem:: transmute ( self . cast :: < ( ) > ( ) ) }
169
170
}
170
171
171
- /// Exposes the "provenance" part of the pointer for future use in
172
- /// [`with_exposed_provenance`][] and returns the "address" portion.
172
+ /// Exposes the [ "provenance"][crate::ptr#provenance] part of the pointer for future use in
173
+ /// [`with_exposed_provenance`] and returns the "address" portion.
173
174
///
174
- /// This is equivalent to `self as usize`, which semantically discards *provenance* and
175
- /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
176
- /// side-effect of marking the provenance as 'exposed', so on platforms that support it you can
177
- /// later call [`with_exposed_provenance`][] to reconstitute the original pointer including its
178
- /// provenance. (Reconstructing address space information, if required, is your responsibility.)
175
+ /// This is equivalent to `self as usize`, which semantically discards provenance information.
176
+ /// Furthermore, this (like the `as` cast) has the implicit side-effect of marking the
177
+ /// provenance as 'exposed', so on platforms that support it you can later call
178
+ /// [`with_exposed_provenance`] to reconstitute the original pointer including its provenance.
179
179
///
180
- /// Using this method means that code is *not* following [Strict
181
- /// Provenance][super#strict-provenance] rules. Supporting
182
- /// [`with_exposed_provenance`][] complicates specification and reasoning and may not be supported by
183
- /// tools that help you to stay conformant with the Rust memory model, so it is recommended to
184
- /// use [`addr`][pointer::addr] wherever possible.
180
+ /// Due to its inherent ambiguity, [`with_exposed_provenance`] may not be supported by tools
181
+ /// that help you to stay conformant with the Rust memory model. It is recommended to use
182
+ /// [Strict Provenance][crate::ptr#strict-provenance] APIs such as [`with_addr`][pointer::with_addr]
183
+ /// wherever possible, in which case [`addr`][pointer::addr] should be used instead of `expose_provenance`.
185
184
///
186
185
/// On most platforms this will produce a value with the same bytes as the original pointer,
187
186
/// because all the bytes are dedicated to describing the address. Platforms which need to store
188
187
/// additional information in the pointer may not support this operation, since the 'expose'
189
- /// side-effect which is required for [`with_exposed_provenance`][] to work is typically not
188
+ /// side-effect which is required for [`with_exposed_provenance`] to work is typically not
190
189
/// available.
191
190
///
192
- /// It is unclear whether this method can be given a satisfying unambiguous specification. This
193
- /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
191
+ /// This is an [Exposed Provenance][crate::ptr#exposed-provenance] API.
194
192
///
195
193
/// [`with_exposed_provenance`]: with_exposed_provenance
196
194
#[ must_use]
197
195
#[ inline( always) ]
198
- #[ unstable ( feature = "exposed_provenance" , issue = "95228 " ) ]
196
+ #[ stable ( feature = "exposed_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
199
197
pub fn expose_provenance ( self ) -> usize {
200
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
201
198
self . cast :: < ( ) > ( ) as usize
202
199
}
203
200
204
- /// Creates a new pointer with the given address.
201
+ /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
202
+ /// `self`.
205
203
///
206
- /// This performs the same operation as an `addr as ptr` cast, but copies
207
- /// the *address-space* and *provenance* of `self` to the new pointer.
208
- /// This allows us to dynamically preserve and propagate this important
209
- /// information in a way that is otherwise impossible with a unary cast.
204
+ /// This is similar to a `addr as *const T` cast, but copies
205
+ /// the *provenance* of `self` to the new pointer.
206
+ /// This avoids the inherent ambiguity of the unary cast.
210
207
///
211
208
/// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
212
209
/// `self` to the given address, and therefore has all the same capabilities and restrictions.
213
210
///
214
- /// This API and its claimed semantics are part of the Strict Provenance experiment,
215
- /// see the [module documentation][crate::ptr] for details.
211
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
216
212
#[ must_use]
217
213
#[ inline]
218
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
214
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
219
215
pub fn with_addr ( self , addr : usize ) -> Self {
220
- // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
221
- //
222
- // In the mean-time, this operation is defined to be "as if" it was
223
- // a wrapping_offset, so we can emulate it as such. This should properly
224
- // restore pointer provenance even under today's compiler.
216
+ // This should probably be an intrinsic to avoid doing any sort of arithmetic, but
217
+ // meanwhile, we can implement it with `wrapping_offset`, which preserves the pointer's
218
+ // provenance.
225
219
let self_addr = self . addr ( ) as isize ;
226
220
let dest_addr = addr as isize ;
227
221
let offset = dest_addr. wrapping_sub ( self_addr) ;
228
-
229
- // This is the canonical desugaring of this operation
230
222
self . wrapping_byte_offset ( offset)
231
223
}
232
224
233
- /// Creates a new pointer by mapping `self`'s address to a new one.
225
+ /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
226
+ /// [provenance][crate::ptr#provenance] of `self`.
234
227
///
235
228
/// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
236
229
///
237
- /// This API and its claimed semantics are part of the Strict Provenance experiment,
238
- /// see the [module documentation][crate::ptr] for details.
230
+ /// This is a [Strict Provenance][crate::ptr#strict-provenance] API.
239
231
#[ must_use]
240
232
#[ inline]
241
- #[ unstable ( feature = "strict_provenance" , issue = "95228 " ) ]
233
+ #[ stable ( feature = "strict_provenance" , since = "CURRENT_RUSTC_VERSION " ) ]
242
234
pub fn map_addr ( self , f : impl FnOnce ( usize ) -> usize ) -> Self {
243
235
self . with_addr ( f ( self . addr ( ) ) )
244
236
}
@@ -379,7 +371,7 @@ impl<T: ?Sized> *const T {
379
371
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
380
372
/// "wrapping around"), must fit in an `isize`.
381
373
///
382
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
374
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
383
375
/// [allocated object], and the entire memory range between `self` and the result must be in
384
376
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
385
377
/// of the address space.
@@ -560,7 +552,7 @@ impl<T: ?Sized> *const T {
560
552
/// ## Examples
561
553
///
562
554
/// ```
563
- /// #![feature(ptr_mask, strict_provenance )]
555
+ /// #![feature(ptr_mask)]
564
556
/// let v = 17_u32;
565
557
/// let ptr: *const u32 = &v;
566
558
///
@@ -611,7 +603,7 @@ impl<T: ?Sized> *const T {
611
603
/// * `self` and `origin` must either
612
604
///
613
605
/// * point to the same address, or
614
- /// * both be * derived from* a pointer to the same [allocated object], and the memory range between
606
+ /// * both be [ derived from][crate::ptr#provenance] a pointer to the same [allocated object], and the memory range between
615
607
/// the two pointers must be in bounds of that object. (See below for an example.)
616
608
///
617
609
/// * The distance between the pointers, in bytes, must be an exact multiple
@@ -871,7 +863,7 @@ impl<T: ?Sized> *const T {
871
863
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
872
864
/// "wrapping around"), must fit in an `isize`.
873
865
///
874
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
866
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
875
867
/// [allocated object], and the entire memory range between `self` and the result must be in
876
868
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
877
869
/// of the address space.
@@ -978,7 +970,7 @@ impl<T: ?Sized> *const T {
978
970
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
979
971
/// "wrapping around"), must fit in an `isize`.
980
972
///
981
- /// * If the computed offset is non-zero, then `self` must be derived from a pointer to some
973
+ /// * If the computed offset is non-zero, then `self` must be [ derived from][crate::ptr#provenance] a pointer to some
982
974
/// [allocated object], and the entire memory range between `self` and the result must be in
983
975
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
984
976
/// of the address space.
0 commit comments