Skip to content

Commit

Permalink
Rollup merge of #130350 - RalfJung:strict-provenance, r=dtolnay
Browse files Browse the repository at this point in the history
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/rust#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/rust#95228.

[FCP comment](rust-lang/rust#130350 (comment))
  • Loading branch information
matthiaskrgr authored Oct 21, 2024
2 parents 1556144 + 9e0205d commit 1497744
Show file tree
Hide file tree
Showing 37 changed files with 4 additions and 38 deletions.
2 changes: 0 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
#![feature(let_chains)]
#![feature(trait_upcasting)]
#![feature(strict_overflow_ops)]
#![feature(strict_provenance)]
#![feature(exposed_provenance)]
#![feature(pointer_is_aligned_to)]
#![feature(unqualified_local_imports)]
// Configure clippy and other lints
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(strict_provenance)]
use std::ptr;

fn direct_raw(x: *const (i32, i32)) -> *const i32 {
Expand Down
1 change: 0 additions & 1 deletion tests/fail/dangling_pointers/deref_dangling_box.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Should be caught even without retagging
//@compile-flags: -Zmiri-disable-stacked-borrows
#![feature(strict_provenance)]
use std::ptr::{self, addr_of_mut};

// Deref'ing a dangling raw pointer is fine, but for a dangling box it is not.
Expand Down
1 change: 0 additions & 1 deletion tests/fail/dangling_pointers/deref_dangling_ref.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// Should be caught even without retagging
//@compile-flags: -Zmiri-disable-stacked-borrows
#![feature(strict_provenance)]
use std::ptr::{self, addr_of_mut};

// Deref'ing a dangling raw pointer is fine, but for a dangling reference it is not.
Expand Down
1 change: 0 additions & 1 deletion tests/fail/intrinsics/ptr_offset_from_different_ints.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(strict_provenance)]
use core::ptr;

fn main() {
Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/int_copy_looses_provenance3.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(strict_provenance)]
use std::mem;

#[repr(C, usize)]
Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/provenance_transmute.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-permissive-provenance
#![feature(strict_provenance)]

use std::mem;

Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/ptr_int_unexposed.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-permissive-provenance
#![feature(strict_provenance, exposed_provenance)]

fn main() {
let x: i32 = 3;
Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/ptr_invalid.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(strict_provenance, exposed_provenance)]

// Ensure that a `ptr::without_provenance` ptr is truly invalid.
fn main() {
Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/ptr_invalid_offset.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-strict-provenance
#![feature(strict_provenance)]

fn main() {
let x = 22;
Expand Down
1 change: 0 additions & 1 deletion tests/fail/provenance/strict_provenance_cast.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-strict-provenance
#![feature(exposed_provenance)]

fn main() {
let addr = &0 as *const i32 as usize;
Expand Down
1 change: 0 additions & 1 deletion tests/fail/stacked_borrows/exposed_only_ro.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-permissive-provenance
#![feature(exposed_provenance)]

// If we have only exposed read-only pointers, doing a write through a wildcard ptr should fail.

Expand Down
1 change: 0 additions & 1 deletion tests/fail/unaligned_pointers/promise_alignment.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@compile-flags: -Zmiri-symbolic-alignment-check
//@revisions: call_unaligned_ptr read_unaligned_ptr
#![feature(strict_provenance)]

#[path = "../../utils/mod.rs"]
mod utils;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//@compile-flags: -Zmiri-disable-validation
//@error-in-other-file: memory is uninitialized at [0x4..0x8]
//@normalize-stderr-test: "a[0-9]+" -> "ALLOC"
#![feature(strict_provenance)]
#![allow(dropping_copy_types)]

// Test printing allocations that contain single-byte provenance.
Expand Down
1 change: 0 additions & 1 deletion tests/pass-dep/libc/libc-affinity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//@compile-flags: -Zmiri-disable-isolation -Zmiri-num-cpus=4
#![feature(io_error_more)]
#![feature(pointer_is_aligned_to)]
#![feature(strict_provenance)]

use std::mem::{size_of, size_of_val};

Expand Down
1 change: 0 additions & 1 deletion tests/pass-dep/libc/libc-epoll-no-blocking.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@only-target: linux

#![feature(strict_provenance)]
use std::convert::TryInto;

fn main() {
Expand Down
2 changes: 1 addition & 1 deletion tests/pass-dep/libc/libc-mem.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(strict_provenance, pointer_is_aligned_to)]
#![feature(pointer_is_aligned_to)]
use std::{mem, ptr, slice};

fn test_memcpy() {
Expand Down
1 change: 0 additions & 1 deletion tests/pass-dep/libc/libc-misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//@compile-flags: -Zmiri-disable-isolation
#![feature(io_error_more)]
#![feature(pointer_is_aligned_to)]
#![feature(strict_provenance)]

use std::mem::transmute;

Expand Down
1 change: 0 additions & 1 deletion tests/pass-dep/libc/mmap.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@ignore-target: windows # No mmap on Windows
//@compile-flags: -Zmiri-disable-isolation -Zmiri-permissive-provenance
#![feature(strict_provenance)]

use std::io::Error;
use std::{ptr, slice};
Expand Down
1 change: 0 additions & 1 deletion tests/pass/align_offset_symbolic.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-symbolic-alignment-check
#![feature(strict_provenance)]

use std::mem;

Expand Down
2 changes: 1 addition & 1 deletion tests/pass/atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//@[tree]compile-flags: -Zmiri-tree-borrows
//@compile-flags: -Zmiri-strict-provenance

#![feature(strict_provenance, strict_provenance_atomic_ptr)]
#![feature(strict_provenance_atomic_ptr)]
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]

Expand Down
1 change: 0 additions & 1 deletion tests/pass/box-custom-alloc-aliasing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(allocator_api)]
#![feature(strict_provenance)]

use std::alloc::{AllocError, Allocator, Layout};
use std::cell::{Cell, UnsafeCell};
Expand Down
1 change: 0 additions & 1 deletion tests/pass/concurrency/address_reuse_happens_before.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Regression test for <https://github.com/rust-lang/miri/issues/3450>:
//! When the address gets reused, there should be a happens-before relation.
//@compile-flags: -Zmiri-address-reuse-cross-thread-rate=1.0
#![feature(strict_provenance)]
#![feature(sync_unsafe_cell)]

use std::cell::SyncUnsafeCell;
Expand Down
1 change: 0 additions & 1 deletion tests/pass/const-addrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
// MIR inlining will put every evaluation of the const we're repeatedly evaluating into the same
// stack frame, breaking this test.
//@compile-flags: -Zinline-mir=no
#![feature(strict_provenance)]

const EVALS: usize = 256;

Expand Down
2 changes: 1 addition & 1 deletion tests/pass/drop_type_without_drop_glue.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(custom_mir, core_intrinsics, strict_provenance)]
#![feature(custom_mir, core_intrinsics)]
use std::intrinsics::mir::*;

// The `Drop` terminator on a type with no drop glue should be a NOP.
Expand Down
2 changes: 1 addition & 1 deletion tests/pass/extern_types.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(extern_types, strict_provenance)]
#![feature(extern_types)]

use std::ptr;

Expand Down
1 change: 0 additions & 1 deletion tests/pass/provenance.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(strict_provenance)]
use std::{mem, ptr};

const PTR_SIZE: usize = mem::size_of::<&i32>();
Expand Down
1 change: 0 additions & 1 deletion tests/pass/ptr_int_from_exposed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Tree Borrows doesn't support int2ptr casts, but let's make sure we don't immediately crash either.
//@[tree]compile-flags: -Zmiri-tree-borrows
//@[stack]compile-flags: -Zmiri-permissive-provenance
#![feature(strict_provenance, exposed_provenance)]

use std::ptr;

Expand Down
1 change: 0 additions & 1 deletion tests/pass/ptr_raw.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![feature(strict_provenance)]
use std::mem;
use std::ptr::{self, addr_of};

Expand Down
1 change: 0 additions & 1 deletion tests/pass/shims/ptr_mask.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#![feature(ptr_mask)]
#![feature(strict_provenance)]

fn main() {
let v: u32 = 0xABCDABCD;
Expand Down
1 change: 0 additions & 1 deletion tests/pass/slices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#![feature(slice_as_chunks)]
#![feature(slice_partition_dedup)]
#![feature(layout_for_ptr)]
#![feature(strict_provenance)]

use std::{ptr, slice};

Expand Down
1 change: 0 additions & 1 deletion tests/pass/stacked-borrows/int-to-ptr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-permissive-provenance
#![feature(exposed_provenance)]
use std::ptr;

// Just to make sure that casting a ref to raw, to int and back to raw
Expand Down
1 change: 0 additions & 1 deletion tests/pass/stacked-borrows/stack-printing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// printing, not how it interacts with the GC.
//@compile-flags: -Zmiri-permissive-provenance -Zmiri-provenance-gc=0

#![feature(strict_provenance)]
use std::alloc::{self, Layout};
use std::mem::ManuallyDrop;

Expand Down
1 change: 0 additions & 1 deletion tests/pass/stacked-borrows/unknown-bottom-gc.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@compile-flags: -Zmiri-permissive-provenance
#![feature(exposed_provenance)]

use std::ptr;

Expand Down
1 change: 0 additions & 1 deletion tests/pass/transmute_ptr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//@revisions: stack tree
//@[tree]compile-flags: -Zmiri-tree-borrows
#![feature(strict_provenance)]
use std::{mem, ptr};

fn t1() {
Expand Down
1 change: 0 additions & 1 deletion tests/pass/underscore_pattern.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Various tests ensuring that underscore patterns really just construct the place, but don't check its contents.
#![feature(strict_provenance)]
#![feature(never_type)]

use std::ptr;
Expand Down
1 change: 0 additions & 1 deletion tests/pass/zero-sized-accesses-and-offsets.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//! Tests specific for <https://github.com/rust-lang/rust/issues/117945>: zero-sized operations.
#![feature(strict_provenance)]
use std::ptr;

Expand Down

0 comments on commit 1497744

Please sign in to comment.