Rollup merge of #130350 - RalfJung:strict-provenance, r=dtolnay · qinheping/verify-rust-std@7f91dbe (original) (raw)
`@@ -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.
`