diff --git a/src/type.zig b/src/type.zig index 3e2e395d07..1fef525062 100644 --- a/src/type.zig +++ b/src/type.zig @@ -3458,12 +3458,21 @@ pub const Type = extern union { else => {}, } + const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) { + .scalar => |elem_size| elem_size, + .val => switch (strat) { + .sema_kit => unreachable, + .eager => unreachable, + .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) }, + }, + }; + // Optional types are represented as a struct with the child type as the first // field and a boolean as the second. Since the child type's abi alignment is // guaranteed to be >= that of bool's (1 byte) the added size is exactly equal // to the child type's ABI alignment. return AbiSizeAdvanced{ - .scalar = child_type.abiAlignment(target) + child_type.abiSize(target), + .scalar = child_type.abiAlignment(target) + payload_size, }; }, @@ -3478,7 +3487,14 @@ pub const Type = extern union { } const code_align = abiAlignment(Type.anyerror, target); const payload_align = abiAlignment(data.payload, target); - const payload_size = abiSize(data.payload, target); + const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) { + .scalar => |elem_size| elem_size, + .val => switch (strat) { + .sema_kit => unreachable, + .eager => unreachable, + .lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) }, + }, + }; var size: u64 = 0; if (code_align > payload_align) { diff --git a/test/behavior.zig b/test/behavior.zig index 019d9bbac7..ed7910cfbc 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -98,6 +98,7 @@ test { _ = @import("behavior/bugs/12911.zig"); _ = @import("behavior/bugs/12928.zig"); _ = @import("behavior/bugs/12945.zig"); + _ = @import("behavior/bugs/12984.zig"); _ = @import("behavior/byteswap.zig"); _ = @import("behavior/byval_arg_var.zig"); _ = @import("behavior/call.zig"); diff --git a/test/behavior/bugs/12984.zig b/test/behavior/bugs/12984.zig new file mode 100644 index 0000000000..a538b62e8d --- /dev/null +++ b/test/behavior/bugs/12984.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +pub fn DeleagateWithContext(comptime Function: type) type { + const ArgArgs = std.meta.ArgsTuple(Function); + return struct { + t: ArgArgs, + }; +} + +pub const OnConfirm = DeleagateWithContext(fn (bool) void); +pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void); + +test "simple test" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + var c: CustomDraw = undefined; + _ = c; +}