-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Consider aggregate types containing unconstructable types to also be unconstructable #58374
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
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: