You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
These days, values of types like MaybeUninit are only ever represented in-memory in the interpreter; they cannot be stored in a Scalar. Only integers (that never have provenance) and pointers (that always have a single well-defined provenance) can exist as Scalar.
This does give us a chance to represent "partial pointers", so that we could support people writing their own memcpy in const that works by copying MaybeUninit<u8> in a loop. I don't know if there's any real usecase for this, but it seems neat. :D
The main challenge is that we have to ensure that when the bytes of a pointer get put back together, that they all appear in the right order. This is not a constraint that our current per-byte provenance system supports, and I doubt that we want to put such a constraint onto regular runtime semantics. We'd also have to report an error if such a pointer fragment byte makes it into the final value of a constant, since AFAIK we can't represent them in LLVM.
I realize this is probably too much to ask, but when building low-level code, it would be very useful to compose values that consist of real pointer bits and unrelated other bits.
For example, x86 page table entries are 64-bit values where the middle bits are part of a pointer to memory. The low bits are unused by the pointer because it's page-aligned. The high bits are unused by the pointer because the physical address space is architecturally defined to not cover the full 64 bits. The page table entry defined by the architecture therefore uses these bits for other things.
I was able to hack together the following using inline assembly:
pubconstfncheck_bits<T>(_:*constT,bits:u64){let low_bits = bits &((core::mem::align_of::<T>() - 1)asu64);let high_bits = bits &0xffff_ffff_0000_0000;assert!((bits ^ low_bits ^ high_bits) == 0,"ptr_with_bits: bits must only have bits set below alignment and above 32 bits");}#[allow(dead_code)]pubstructPtrWithBits(pub*const core::ffi::c_void);unsafeimplSyncforPtrWithBits{}/// Create values of type `PtrWithBits` which is composed of a pointer to/// a real item with extra bits set in the unused parts of the pointer. The/// unused parts are those low bits that are always zero due to the/// alignment of the type, and those high bits that are unused due to /// address space limitations.////// The current implementation assumes that the address space is 4GB.////// Example:////// ```rust,ignore/// unsafe_ptr_with_bits! {/// const PAGE_TABLE_ENTRY: PtrWithBits = &PAGE | 3;/// }/// ```////// Note: this macro contains global_asm! and must be used only in places/// where that is legal.////// # Safety////// The caller must ensure `$p` is in the first 4GB of memory#[macro_export]macro_rules! unsafe_ptr_with_bits {($(const $i:ident:PtrWithBits = &$p:path | $e:expr;)+) => {$(
core::arch::global_asm! {
concat!(".set ", stringify!($i),", {p} + {o}"),
p = sym $p,
o = const $e asu64}const _:() = {
$crate::x86_isa::check_bits(&MY_PAGE, $e);};const $i: $crate::x86_isa::PtrWithBits = $crate::x86_isa::PtrWithBits({unsafe extern "C"{static $i: core::ffi::c_void;}&raw const $i
});)+}}
I'm compiling the code with -C code-model=medium -C relocation=static to ensure the address space is small enough. It seems to work and the compiler generates ELF relocations with the needed bits in addend.
This is a closed issue, and the feature tracked here has been fully implemented. What you are asking for is something else, so please open a new issue. (Also, the example uses MY_PAGE without defining it so I am a bit confused about what you actually are trying to do.)
Activity
Rollup merge of rust-lang#137280 - RalfJung:const_swap_nonoverlapping…
Unrolled build for rust-lang#137280
Rollup merge of #137280 - RalfJung:const_swap_nonoverlapping, r=lcnr
Rollup merge of rust-lang#137280 - RalfJung:const_swap_nonoverlapping…
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=<try>
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of rust-lang#144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
theemathas commentedon Sep 10, 2025
This probably should be reopened due to rust-lang/rust#146324
2 remaining items
Auto merge of rust-lang#144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #148259 - RalfJung:const-ptr-fragment, r=oli-obk
Auto merge of #148259 - RalfJung:const-ptr-fragment, r=oli-obk
Auto merge of rust-lang#148259 - RalfJung:const-ptr-fragment, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of #144081 - RalfJung:const-ptr-fragments, r=oli-obk
jethrogb commentedon Mar 28, 2026
I realize this is probably too much to ask, but when building low-level code, it would be very useful to compose values that consist of real pointer bits and unrelated other bits.
For example, x86 page table entries are 64-bit values where the middle bits are part of a pointer to memory. The low bits are unused by the pointer because it's page-aligned. The high bits are unused by the pointer because the physical address space is architecturally defined to not cover the full 64 bits. The page table entry defined by the architecture therefore uses these bits for other things.
I was able to hack together the following using inline assembly:
I'm compiling the code with
-C code-model=medium -C relocation=staticto ensure the address space is small enough. It seems to work and the compiler generates ELF relocations with the needed bits in addend.RalfJung commentedon Mar 28, 2026
This is a closed issue, and the feature tracked here has been fully implemented. What you are asking for is something else, so please open a new issue. (Also, the example uses
MY_PAGEwithout defining it so I am a bit confused about what you actually are trying to do.)Auto merge of rust-lang#144081 - RalfJung:const-ptr-fragments, r=oli-obk
Auto merge of rust-lang#144081 - RalfJung:const-ptr-fragments, r=oli-obk