-
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
attempted to leave type (enum) uninitialized, which is invalid #73573
Comments
`mem::uninitialized` is deprecated and for reasons I don't understand causes crash at runtime rust-lang/rust#73573
This code is sadly not perfectly valid. To implement this without causing undefined behavior, you can use use std::mem::MaybeUninit;
use std::ptr;
#[derive(Copy, Clone, Debug)]
enum Fruit {
Apple,
_Banana,
}
fn foo() -> Fruit {
unsafe {
let mut r = MaybeUninit::uninit();
ptr::write(r.as_mut_ptr(), Fruit::Apple);
r.assume_init()
}
}
fn main() {
println!("{:?}", foo());
} |
Closing as expected behavior |
Maybe technically it is UB, but practically that code worked fine for many years, and suddenly broke.
And even if it is that bad, then why panic at runtime, instead of compilation error? The latter is much more damaging because it's harder to spot, harder to debug: if This is not how backwards compatibility should work. Anyway, I have already patched the library, if you think this is not an issue, let be it. Also, CC @RalfJung who has implemented this check in #66059. |
UB is a property of the execution, not always possible to statically determine (e.g., you may have gated the mem::uninitialized on a zero-sized check or so and that happened to be sufficient to avoid UB in all cases), so this must be a runtime panic rather than a compile time error. |
Unfortunately, the code is not valid. It violates one of the fundamental rules of Rust:
These rules are as fundamental to Rust works as its type system. Unlike the type system, we cannot reliably ensure that you follow these rules when writing unsafe code. It is the responsibility of unsafe code authors to ensure that their code follows these rules. Some more background on Undefined Behavior: |
You were lucky. But this code had a bug all along, and that bug could have surfaced any time you change any of your code, update a dependency, or update the compiler.
Agreed, a static check would be better. That's why we have a lint that can detect some cases of using Your case seems detectable though. Feel free to report a bug to improve that lint (and Cc me). |
https://crates.io/crates/maybe-uninit could help with this. |
I should also mention that this UB is not theoretical, it has already lead to SIGILL errors in the past. I'll stop now.^^ Sorry for the multipost. |
@RalfJung thank you for the explanations and your work on improving Rust safety! |
This code worked fine a couple of months ago:
Now (1.44.1), this code crashes with:
This code looks perfectly valid to me: we create a slot for a variable, write to that slot exactly once, and return the value.
Play
The text was updated successfully, but these errors were encountered: