-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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 for maybe_uninit_as_bytes #93092
Comments
Would it maybe make sense for these to be arrays of |
The only thing I can think of that can possibly be an issue is making a type with padding into a Like use std::mem::MaybeUninit;
#[repr(C)]
#[derive(Default)]
struct Foo {
a: u16,
b: u8
}
fn main() {
let mut f = Foo::default();
let fmur = &mut f as *mut Foo as *mut MaybeUninit<u8>;
unsafe {
dbg!(*std::slice::from_raw_parts_mut(fmur, 4)[3].write(42));
}
} This is presumably sound because padding bytes are only made uninit when you write a field of type But also I'd need to have a think about how that interacts with interior mutability. Presumably sound, in any case. |
In principle we could have such methods for any type |
If you allow casting to a type U, then you need to solve the problem of
These could be solved by panicking or returning an error, but none of these are problems when U is size 1 align 1. |
Should
I recognize the stdlib is not consistent on this. See |
The current implementation of #![feature(maybe_uninit_as_bytes)]
use std::mem::MaybeUninit;
use std::cell::Cell;
fn unsoundness_demo(a: &u8, b: &Cell<u8>) {
println!("{}", a);
b.set(2);
println!("{}", a);
}
fn main() {
unsafe {
let mut u = MaybeUninit::uninit();
u.write(Cell::new(1));
unsoundness_demo(u.as_bytes()[0].assume_init_ref(), u.assume_init_ref());
}
}
This problem could be fixed either via adding a new safety requirement on @RalfJung wrote:
There is actually an important use case for being able to do the equivalent of Although this works well if you know the return type already, there are cases where you'd want to do this sort of thing but don't know the type in advance. For example, I've been recently looking into "local allocators" in which allocations are made one at a time on-demand, but where deallocations are not allowed while the local allocator is alive (rather, dropping the local allocator drops all the allocations at once). This is a very efficient pattern which is commonly used in game development. In general the applications of this sort of allocator are fairly similar to the applications of If there were a safe |
IMO the fix is to say that for the duration that the reference returned by |
What about pointer provenance? Converting |
Although that conversion could be used to do a pointer-usize-pointer roundtrip, it doesn't actually violate any rules until you try to treat the resulting pointer as initialized. A much simpler example of the same sort of thing is to convert an In this case, the soundness requirement would be the usual "you musn't assume a |
Feature gate:
#![feature(maybe_uninit_as_bytes)
This is a tracking issue for APIs which allow access to individual bytes of a
MaybeUninit<T>
. This is always safe even for padding bytes since the bytes are themselves represented asMaybeUninit<u8>
.Public API
Steps / History
Unresolved Questions
The text was updated successfully, but these errors were encountered: