Skip to content

Commit 2d7297e

Browse files
authored
Unrolled build for rust-lang#130350
Rollup merge of rust-lang#130350 - RalfJung:strict-provenance, r=dtolnay stabilize Strict Provenance and Exposed Provenance APIs Given that [RFC 3559](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html) has been accepted, t-lang has approved the concept of provenance to exist in the language. So I think it's time that we stabilize the strict provenance and exposed provenance APIs, and discuss provenance explicitly in the docs: ```rust // core::ptr pub const fn without_provenance<T>(addr: usize) -> *const T; pub const fn dangling<T>() -> *const T; pub const fn without_provenance_mut<T>(addr: usize) -> *mut T; pub const fn dangling_mut<T>() -> *mut T; pub fn with_exposed_provenance<T>(addr: usize) -> *const T; pub fn with_exposed_provenance_mut<T>(addr: usize) -> *mut T; impl<T: ?Sized> *const T { pub fn addr(self) -> usize; pub fn expose_provenance(self) -> usize; pub fn with_addr(self, addr: usize) -> Self; pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self; } impl<T: ?Sized> *mut T { pub fn addr(self) -> usize; pub fn expose_provenance(self) -> usize; pub fn with_addr(self, addr: usize) -> Self; pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self; } impl<T: ?Sized> NonNull<T> { pub fn addr(self) -> NonZero<usize>; pub fn with_addr(self, addr: NonZero<usize>) -> Self; pub fn map_addr(self, f: impl FnOnce(NonZero<usize>) -> NonZero<usize>) -> Self; } ``` I also did a pass over the docs to adjust them, because this is no longer an "experiment". The `ptr` docs now discuss the concept of provenance in general, and then they go into the two families of APIs for dealing with provenance: Strict Provenance and Exposed Provenance. I removed the discussion of how pointers also have an associated "address space" -- that is not actually tracked in the pointer value, it is tracked in the type, so IMO it just distracts from the core point of provenance. I also adjusted the docs for `with_exposed_provenance` to make it clear that we cannot guarantee much about this function, it's all best-effort. There are two unstable lints associated with the strict_provenance feature gate; I moved them to a new [strict_provenance_lints](rust-lang#130351) feature since I didn't want this PR to have an even bigger FCP. ;) `@rust-lang/opsem` Would be great to get some feedback on the docs here. :) Nominating for `@rust-lang/libs-api.` Part of rust-lang#95228. [FCP comment](rust-lang#130350 (comment))
2 parents edbd939 + 56ee492 commit 2d7297e

File tree

90 files changed

+352
-514
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+352
-514
lines changed

compiler/rustc_arena/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
#![feature(maybe_uninit_slice)]
2424
#![feature(rustc_attrs)]
2525
#![feature(rustdoc_internals)]
26-
#![feature(strict_provenance)]
2726
#![warn(unreachable_pub)]
2827
// tidy-alphabetical-end
2928

compiler/rustc_codegen_ssa/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#![feature(let_chains)]
1212
#![feature(negative_impls)]
1313
#![feature(rustdoc_internals)]
14-
#![feature(strict_provenance)]
1514
#![feature(trait_alias)]
1615
#![feature(try_blocks)]
1716
#![warn(unreachable_pub)]

compiler/rustc_codegen_ssa/src/mir/rvalue.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -361,12 +361,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
361361
(Int(..) | Float(_), Int(..) | Float(_)) => bx.bitcast(imm, to_backend_ty),
362362
(Pointer(..), Pointer(..)) => bx.pointercast(imm, to_backend_ty),
363363
(Int(..), Pointer(..)) => bx.ptradd(bx.const_null(bx.type_ptr()), imm),
364-
(Pointer(..), Int(..)) => bx.ptrtoint(imm, to_backend_ty),
364+
(Pointer(..), Int(..)) => {
365+
// FIXME: this exposes the provenance, which shouldn't be necessary.
366+
bx.ptrtoint(imm, to_backend_ty)
367+
}
365368
(Float(_), Pointer(..)) => {
366369
let int_imm = bx.bitcast(imm, bx.cx().type_isize());
367370
bx.ptradd(bx.const_null(bx.type_ptr()), int_imm)
368371
}
369372
(Pointer(..), Float(_)) => {
373+
// FIXME: this exposes the provenance, which shouldn't be necessary.
370374
let int_imm = bx.ptrtoint(imm, bx.cx().type_isize());
371375
bx.bitcast(int_imm, to_backend_ty)
372376
}

compiler/rustc_const_eval/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#![feature(never_type)]
1111
#![feature(rustdoc_internals)]
1212
#![feature(slice_ptr_get)]
13-
#![feature(strict_provenance)]
1413
#![feature(trait_alias)]
1514
#![feature(try_blocks)]
1615
#![feature(unqualified_local_imports)]

compiler/rustc_data_structures/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#![feature(ptr_alignment_type)]
3434
#![feature(rustc_attrs)]
3535
#![feature(rustdoc_internals)]
36-
#![feature(strict_provenance)]
3736
#![feature(test)]
3837
#![feature(thread_id_value)]
3938
#![feature(type_alias_impl_trait)]

compiler/rustc_feature/src/unstable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,7 @@ declare_features! (
595595
/// Allows attributes on expressions and non-item statements.
596596
(unstable, stmt_expr_attributes, "1.6.0", Some(15701)),
597597
/// Allows lints part of the strict provenance effort.
598-
(unstable, strict_provenance, "1.61.0", Some(95228)),
598+
(unstable, strict_provenance_lints, "1.61.0", Some(130351)),
599599
/// Allows string patterns to dereference values to match them.
600600
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
601601
/// Allows the use of `#[target_feature]` on safe functions.

compiler/rustc_lint_defs/src/builtin.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2667,7 +2667,6 @@ declare_lint! {
26672667
/// ### Example
26682668
///
26692669
/// ```rust
2670-
/// #![feature(strict_provenance)]
26712670
/// #![warn(fuzzy_provenance_casts)]
26722671
///
26732672
/// fn main() {
@@ -2701,7 +2700,7 @@ declare_lint! {
27012700
pub FUZZY_PROVENANCE_CASTS,
27022701
Allow,
27032702
"a fuzzy integer to pointer cast is used",
2704-
@feature_gate = strict_provenance;
2703+
@feature_gate = strict_provenance_lints;
27052704
}
27062705

27072706
declare_lint! {
@@ -2711,7 +2710,6 @@ declare_lint! {
27112710
/// ### Example
27122711
///
27132712
/// ```rust
2714-
/// #![feature(strict_provenance)]
27152713
/// #![warn(lossy_provenance_casts)]
27162714
///
27172715
/// fn main() {
@@ -2747,7 +2745,7 @@ declare_lint! {
27472745
pub LOSSY_PROVENANCE_CASTS,
27482746
Allow,
27492747
"a lossy pointer to integer cast is used",
2750-
@feature_gate = strict_provenance;
2748+
@feature_gate = strict_provenance_lints;
27512749
}
27522750

27532751
declare_lint! {

compiler/rustc_middle/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@
5656
#![feature(ptr_alignment_type)]
5757
#![feature(rustc_attrs)]
5858
#![feature(rustdoc_internals)]
59-
#![feature(strict_provenance)]
6059
#![feature(trait_upcasting)]
6160
#![feature(trusted_len)]
6261
#![feature(try_blocks)]

compiler/rustc_span/src/symbol.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1913,7 +1913,7 @@ symbols! {
19131913
str_trim,
19141914
str_trim_end,
19151915
str_trim_start,
1916-
strict_provenance,
1916+
strict_provenance_lints,
19171917
string_as_mut_str,
19181918
string_as_str,
19191919
string_deref_patterns,

library/alloc/benches/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
#![feature(iter_next_chunk)]
55
#![feature(repr_simd)]
66
#![feature(slice_partition_dedup)]
7-
#![feature(strict_provenance)]
7+
#![cfg_attr(bootstrap, feature(strict_provenance))]
8+
#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
89
#![feature(test)]
910
#![deny(fuzzy_provenance_casts)]
1011

library/alloc/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@
147147
#![feature(slice_range)]
148148
#![feature(std_internals)]
149149
#![feature(str_internals)]
150-
#![feature(strict_provenance)]
151150
#![feature(trusted_fused)]
152151
#![feature(trusted_len)]
153152
#![feature(trusted_random_access)]
@@ -162,6 +161,8 @@
162161
//
163162
// Language features:
164163
// tidy-alphabetical-start
164+
#![cfg_attr(bootstrap, feature(strict_provenance))]
165+
#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
165166
#![cfg_attr(not(test), feature(coroutine_trait))]
166167
#![cfg_attr(test, feature(panic_update_hook))]
167168
#![cfg_attr(test, feature(test))]

library/alloc/tests/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
#![feature(panic_update_hook)]
3333
#![feature(pointer_is_aligned_to)]
3434
#![feature(thin_box)]
35-
#![feature(strict_provenance)]
35+
#![cfg_attr(bootstrap, feature(strict_provenance))]
36+
#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
3637
#![feature(drain_keep_rest)]
3738
#![feature(local_waker)]
3839
#![feature(vec_pop_if)]

library/core/src/intrinsics.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2794,7 +2794,6 @@ where
27942794
/// #![feature(is_val_statically_known)]
27952795
/// #![feature(core_intrinsics)]
27962796
/// # #![allow(internal_features)]
2797-
/// #![feature(strict_provenance)]
27982797
/// use std::intrinsics::is_val_statically_known;
27992798
///
28002799
/// fn foo(x: &i32) -> bool {

library/core/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,6 @@
163163
#![feature(str_internals)]
164164
#![feature(str_split_inclusive_remainder)]
165165
#![feature(str_split_remainder)]
166-
#![feature(strict_provenance)]
167166
#![feature(ub_checks)]
168167
#![feature(unchecked_neg)]
169168
#![feature(unchecked_shifts)]
@@ -174,6 +173,8 @@
174173
//
175174
// Language features:
176175
// tidy-alphabetical-start
176+
#![cfg_attr(bootstrap, feature(strict_provenance))]
177+
#![cfg_attr(not(bootstrap), feature(strict_provenance_lints))]
177178
#![feature(abi_unadjusted)]
178179
#![feature(adt_const_params)]
179180
#![feature(allow_internal_unsafe)]

library/core/src/ptr/const_ptr.rs

+42-50
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,11 @@ impl<T: ?Sized> *const T {
137137

138138
/// Gets the "address" portion of the pointer.
139139
///
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
144145
/// [`with_addr`][pointer::with_addr] or [`map_addr`][pointer::map_addr].
145146
///
146147
/// 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 {
155156
/// perform a change of representation to produce a value containing only the address
156157
/// portion of the pointer. What that means is up to the platform to define.
157158
///
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.
161160
#[must_use]
162161
#[inline(always)]
163-
#[unstable(feature = "strict_provenance", issue = "95228")]
162+
#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
164163
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.
166167
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
167168
// provenance).
168169
unsafe { mem::transmute(self.cast::<()>()) }
169170
}
170171

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.
173174
///
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.
179179
///
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`.
185184
///
186185
/// On most platforms this will produce a value with the same bytes as the original pointer,
187186
/// because all the bytes are dedicated to describing the address. Platforms which need to store
188187
/// 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
190189
/// available.
191190
///
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.
194192
///
195193
/// [`with_exposed_provenance`]: with_exposed_provenance
196194
#[must_use]
197195
#[inline(always)]
198-
#[unstable(feature = "exposed_provenance", issue = "95228")]
196+
#[stable(feature = "exposed_provenance", since = "CURRENT_RUSTC_VERSION")]
199197
pub fn expose_provenance(self) -> usize {
200-
// FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
201198
self.cast::<()>() as usize
202199
}
203200

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`.
205203
///
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.
210207
///
211208
/// This is equivalent to using [`wrapping_offset`][pointer::wrapping_offset] to offset
212209
/// `self` to the given address, and therefore has all the same capabilities and restrictions.
213210
///
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.
216212
#[must_use]
217213
#[inline]
218-
#[unstable(feature = "strict_provenance", issue = "95228")]
214+
#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
219215
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.
225219
let self_addr = self.addr() as isize;
226220
let dest_addr = addr as isize;
227221
let offset = dest_addr.wrapping_sub(self_addr);
228-
229-
// This is the canonical desugaring of this operation
230222
self.wrapping_byte_offset(offset)
231223
}
232224

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`.
234227
///
235228
/// This is a convenience for [`with_addr`][pointer::with_addr], see that method for details.
236229
///
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.
239231
#[must_use]
240232
#[inline]
241-
#[unstable(feature = "strict_provenance", issue = "95228")]
233+
#[stable(feature = "strict_provenance", since = "CURRENT_RUSTC_VERSION")]
242234
pub fn map_addr(self, f: impl FnOnce(usize) -> usize) -> Self {
243235
self.with_addr(f(self.addr()))
244236
}
@@ -379,7 +371,7 @@ impl<T: ?Sized> *const T {
379371
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
380372
/// "wrapping around"), must fit in an `isize`.
381373
///
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
383375
/// [allocated object], and the entire memory range between `self` and the result must be in
384376
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
385377
/// of the address space.
@@ -560,7 +552,7 @@ impl<T: ?Sized> *const T {
560552
/// ## Examples
561553
///
562554
/// ```
563-
/// #![feature(ptr_mask, strict_provenance)]
555+
/// #![feature(ptr_mask)]
564556
/// let v = 17_u32;
565557
/// let ptr: *const u32 = &v;
566558
///
@@ -611,7 +603,7 @@ impl<T: ?Sized> *const T {
611603
/// * `self` and `origin` must either
612604
///
613605
/// * 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
615607
/// the two pointers must be in bounds of that object. (See below for an example.)
616608
///
617609
/// * The distance between the pointers, in bytes, must be an exact multiple
@@ -871,7 +863,7 @@ impl<T: ?Sized> *const T {
871863
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
872864
/// "wrapping around"), must fit in an `isize`.
873865
///
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
875867
/// [allocated object], and the entire memory range between `self` and the result must be in
876868
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
877869
/// of the address space.
@@ -978,7 +970,7 @@ impl<T: ?Sized> *const T {
978970
/// * The offset in bytes, `count * size_of::<T>()`, computed on mathematical integers (without
979971
/// "wrapping around"), must fit in an `isize`.
980972
///
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
982974
/// [allocated object], and the entire memory range between `self` and the result must be in
983975
/// bounds of that allocated object. In particular, this range must not "wrap around" the edge
984976
/// of the address space.

0 commit comments

Comments
 (0)