-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Consider aggregate types containing unconstructable types to also be unconstructable #58374
Comments
This has been discussed before. The complicated case is this one: let x: (u32, !);
x.0 = 100; That compiles today by actually writing the |
Thankfully, it does not really (playground): #![feature(never_type)]
fn main() {
let mut x: (u32, !);
x.0 = 100;
} |
@Centril That's absolutely what we tell LLVM to do, and what it does in debug mode (godbolt): pub fn foo() {
let x: (u32, !);
x.0 = 100;
} define void @_ZN7example3foo17hd23b272186309284E() unnamed_addr #0 !dbg !5 {
%x = alloca { [0 x i32], i32, [0 x i8], { [0 x i8] }, [0 x i8] }, align 4
%0 = bitcast { [0 x i32], i32, [0 x i8], { [0 x i8] }, [0 x i8] }* %x to i32*, !dbg !8
store i32 100, i32* %0, align 4, !dbg !8
ret void, !dbg !10
} example::foo:
push rax
mov dword ptr [rsp], 100
pop rax
ret LLVM may optimize it sometimes (like it does |
@scottmcm Sure, but this will eventually stop compiling so what we emit to LLVM is irrelevant because it won't reach LLVM and will fail during type checking instead. |
We actually deliberately went from considering this a ZST to not considering it a ZST to fix bugs, see #49298 That issue also contains an example (I've seen more but I think most discussion is effectively lost in old chat protocols) that highlights that |
Maybe attempts to write to a sibling of an uninhabited field should be just no-ops? With partial initialization layout adaptaions,
If |
cc rust-lang/unsafe-code-guidelines#79 and rust-lang/unsafe-code-guidelines#216 which also contain relevant discussion. |
Maybe it can be opt-in for structs? struct A {
a: u32,
b: !,
}
#[no_partial_initialisation]
struct B {
a: u32,
b: !,
}
fn main() {
println!("{}", std::mem::size_of::<A>()); // 4
loop { let _ = A { a: 23, b: break }; }
println!("{}", std::mem::size_of::<A>()); // 0
loop { let _ = B { a: 23, b: break }; } // compile error
} |
Currently
Option<!>
is 0-sized, butOption<(T, !)>
isn't, despite the fact that theSome
variant of the latter is unconstructable. If this were fixed then you could implementPhantomData
in userland as:instead of it being special-cased in the compiler.
The text was updated successfully, but these errors were encountered: