Wrong compile error when using packed struct with fields not matching backing int type in extern function
Zig Version
0.11.0-dev.3+0bbb00035
Steps to Reproduce and Observed Behavior
const Foo = packed struct(u32) {
x: u1,
};
fn bar(_: Foo) callconv(.C) void {}
pub fn main() void {
bar(.{ .x = 0 });
}
This causes a compile error:
[mlugg@vega test]$ zig build-exe test.zig
test.zig:5:8: error: parameter of type 'test.Foo' not allowed in function with calling convention 'C'
fn bar(_: Foo) callconv(.C) void {}
^~~~~~
test.zig:5:8: note: only extern structs and ABI sized packed structs are extern compatible
test.zig:1:20: note: struct declared here
const Foo = packed struct(u32) {
~~~~~~~^~~~~~
referenced by:
main: test.zig:8:5
callMain: /home/mlugg/.opt/zig/lib/std/start.zig:596:17
remaining reference traces hidden; use '-freference-trace' to see all reference traces
Expected Behavior
The compilation should succeed, which happens if the struct fields fill the backing type (e.g. by adding a y: u31).
I'm not entirely confident that this is a bug, but if it's an intentional decision it seems like an odd one to me; while it has some undefined bits, the in-memory layout is still well-defined and the backing type is passable over C ABI.
This is a compile error regardless of whether one tries to use it on the C ABI, and this is 100% intentional:
const Foo = packed struct(u32) {
x: u1,
};
test {
_ = @sizeOf(Foo);
}
/tmp/foo.zig:1:27: error: backing integer type 'u32' has bit size 32 but the struct fields have a total bit size of 1
const Foo = packed struct(u32) {
^~~
The bug here is that your code example should trigger the same error message as mine.
Huh, I somehow totally missed that. But yeah, okay, makes sense, just a bad error message