-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[tracking issue] dereferencing raw pointers inside constants (const_raw_ptr_deref) #51911
Comments
What does this feature actually do? To my mind the primary use case for this is going to be static references to memory-mapped I/O registers in embedded development; however, the obvious thing static REG_DEBUG_ENABLE: &'static u16 = unsafe { &*(0x4fff780 as *mut u16) }; gets me the error
which suggests that it's constructing |
Not quite. That happens transparently. The error comes from the sanity checks on the value of constants and statics. This feature is for when you converted a safe reference to a raw pointer, allowing you to turn it back into a safe reference. What you are trying to do is simply not allowed (yet?). Side-note: Additionally it seems dangerous to create references to registers without using volatile accessors. A |
Yes, |
I wasn't being very careful when throwing out an example. Pretend I used (Sidenote: I'm surprised |
And once you are at the VolatileCell level, you might as well make that a ZST with a phantomdata on your concrete type and everything will work out nicely. |
Okay, now I'm lost. It sounds like you just told me it's undefined behaviour to access system memory unless I allocate something on the stack first. |
If you had a way to create What I was suggesting was that you'd use #![feature(const_raw_ptr_deref)]
const FOO: &'static VolatileCell<u32> = unsafe { &*(0x4fff780 as *const VolatileCell<u32>) };
struct VolatileCell<T: Copy> {
marker: std::marker::PhantomData<T>,
}
impl<T: Copy> VolatileCell<T> {
fn read(&self) -> T {
unsafe {
std::ptr::read_volatile(self as *const _ as *const T)
}
}
} to manage the access to device addresses |
FWIW, the use case I have for this is to create #[repr(transparent)]
pub struct CStr(str);
impl CStr {
/// Creates a new CStr from a str without performing any additional checks. `data` _must_ end
/// with a NUL byte, and should only have only a single NUL byte, or the string will be
/// truncated.
pub const unsafe fn new_unchecked(data: &str) -> &CStr {
&*(data as *const str as *const CStr)
}
} |
Related: every function in |
Mirroring some discussion from #86722 (not sure why that happened on the other tracking issue...): My only concern with const raw pointer deref is how and where to document that type-punning loads (i.e., raw-ptr-based transmutes) of pointers to integers are considered UB during CTFE. But just from an implementation perspective I can't think of any reason how raw ptr deref could screw us now that we have stabilized transmutes and union field accesses. The reason we only stabilized unions and transmute first is that those were already allowed in |
This should only be Edit: Tentatively moving ahead with stabilizing Edit 2: PR is up. #89551 |
The
const_raw_ptr_deref
feature allows dereferencing raw pointers inside constants.This can already be emulated via union transmuting raw pointers to references and referencing the references. This feature gate helps us experiment with the semantics of actually dereferencing normally.
Blocked on rust-lang/const-eval#14.
The text was updated successfully, but these errors were encountered: