From be589ef6d1c459959a9a90257bdbfc3cf94c0d6d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 16 Nov 2025 10:28:31 +0100 Subject: [PATCH 1/2] UB: update the extra clause for provenance UB during const evaluation --- src/behavior-considered-undefined.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index b1315a46fd..35c3ebb0e5 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -76,13 +76,6 @@ r[undefined.asm] * Incorrect use of inline assembly. For more details, refer to the [rules] to follow when writing code that uses inline assembly. -r[undefined.const-transmute-ptr2int] -* **In [const context](const_eval.md#const-context)**: transmuting or otherwise - reinterpreting a pointer (reference, raw pointer, or function pointer) into - some allocation as a non-pointer type (such as integers). - 'Reinterpreting' refers to loading the pointer value at integer type without a - cast, e.g. by doing raw pointer casts or using a union. - r[undefined.runtime] * Violating assumptions of the Rust runtime. Most assumptions of the Rust runtime are currently not explicitly documented. * For assumptions specifically related to unwinding, see the [panic documentation][unwinding-ffi]. @@ -119,7 +112,7 @@ the pointer that was dereferenced, *not* the type of the field that is being accessed. r[undefined.misaligned.load-store] -Note that a place based on a misaligned pointer only leads to Undefined Behavior +Note that a place based on a misaligned pointer only leads to undefined behavior when it is loaded from or stored to. r[undefined.misaligned.raw] @@ -221,6 +214,15 @@ r[undefined.validity.valid-range] > [!NOTE] > `rustc` achieves this with the unstable `rustc_layout_scalar_valid_range_*` attributes. +r[undefined.validity.const-provenance] +* **In [const context](const_eval.md#const-context)**: In addition to what is described above, + further provenance-related requirements apply during const evaluation. + Any value that holds pure integer data (the `i*`/`u*`/`f*` types as well as `bool` and `char`, enum discriminants, and slice metadata) must not carry any provenance. + Any value that holds pointer data (references, raw pointers, function pointers, and `dyn Trait` metadata) must either carry no provenance, + or all bytes must be fragments of the same original pointer value in the correct order. + + This implies that transmuting or otherwise reinterpreting a pointer (reference, raw pointer, or function pointer) into a non-pointer type (such as integers) is undefined behavior if the pointer had provenance. + r[undefined.validity.undef] **Note:** Uninitialized memory is also implicitly invalid for any type that has a restricted set of valid values. In other words, the only cases in which From 0cea1caf4a3577f2a1e7e8cd8fe19ec2c7797bec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 19 Nov 2025 08:59:09 +0100 Subject: [PATCH 2/2] add examples --- src/behavior-considered-undefined.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 35c3ebb0e5..fb4d59cae2 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -223,6 +223,22 @@ r[undefined.validity.const-provenance] This implies that transmuting or otherwise reinterpreting a pointer (reference, raw pointer, or function pointer) into a non-pointer type (such as integers) is undefined behavior if the pointer had provenance. + > [!EXAMPLE] + > All of the following are UB: + > ```rust,compile_fail + > const REINTERPRET_PTR_AS_INT: usize = { + > let ptr = &0; + > unsafe { (&raw const ptr as *const usize).read() } + > }; + > + > const PTR_BYTES_IN_WRONG_ORDER: &i32 = { + > let mut ptr = &0; + > let ptr_bytes = &raw mut ptr as *mut std::mem::MaybeUninit::; + > unsafe { std::ptr::swap(ptr_bytes.add(1), ptr_bytes.add(2)) }; + > ptr + > }; + > ``` + r[undefined.validity.undef] **Note:** Uninitialized memory is also implicitly invalid for any type that has a restricted set of valid values. In other words, the only cases in which