behavior: re-introduce some previously-removed tests

Now that struct default value resolution is separate from struct layout
resolution, a handful of old behavior tests are now once again valid.

This partially reverts the commit titled "behavior: update for changes
to struct field default value resolution".
This commit is contained in:
Matthew Lugg 2026-02-27 11:23:05 +00:00
parent 5768b0542b
commit f366564bd5
No known key found for this signature in database
GPG key ID: 3F5B7DCCBF4AF02E
2 changed files with 104 additions and 3 deletions

View file

@ -1249,6 +1249,20 @@ test "store to comptime field" {
}
}
test "struct field init value is size of the struct" {
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
const namespace = struct {
const S = extern struct {
size: u8 = @sizeOf(S),
blah: u16,
};
};
var s: namespace.S = .{ .blah = 1234 };
_ = &s;
try expect(s.size == 4);
}
test "under-aligned struct field" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
@ -1696,19 +1710,41 @@ test "comptimeness of optional and error union payload is analyzed properly" {
try std.testing.expectEqual(3, x);
}
test "initializer uses own alignment" {
const S = struct {
x: u32 = @alignOf(@This()) + 1,
};
var s: S = .{};
_ = &s;
try expectEqual(4, @alignOf(S));
try expectEqual(@as(usize, 5), s.x);
}
test "initializer uses own size" {
const S = struct {
x: u32 = @sizeOf(@This()) + 1,
};
var s: S = .{};
_ = &s;
try expectEqual(4, @sizeOf(S));
try expectEqual(@as(usize, 5), s.x);
}
test "initializer takes a pointer to a variable inside its struct" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
const namespace = struct {
const S = struct {
x: *u32 = &S.int,
var int: u32 = undefined;
s: *S = &S.instance,
var instance: S = undefined;
};
fn doTheTest() !void {
var foo: S = .{};
_ = &foo;
try expectEqual(&S.int, foo.x);
try expectEqual(&S.instance, foo.s);
}
};
@ -1739,6 +1775,22 @@ test "circular dependency through pointer field of a struct" {
try expect(outer.middle.inner == null);
}
test "field calls do not force struct field init resolution" {
const S = struct {
x: u32 = blk: {
_ = @TypeOf(make().dummyFn()); // runtime field call - S not fully resolved - dummyFn call should not force field init resolution
break :blk 123;
},
dummyFn: *const fn () void = undefined,
fn make() @This() {
return .{};
}
};
var s: S = .{};
_ = &s;
try expect(s.x == 123);
}
test "tuple with comptime-only field" {
const S = struct {
fn getTuple() struct { comptime_int } {

View file

@ -1796,6 +1796,55 @@ test "reinterpret packed union inside packed struct" {
try S.doTheTest();
}
test "inner struct initializer uses union layout" {
const namespace = struct {
const U = union {
a: struct {
x: u32 = @alignOf(U) + 1,
},
b: struct {
y: u16 = @sizeOf(U) + 2,
},
};
};
{
const u: namespace.U = .{ .a = .{} };
try expectEqual(4, @alignOf(namespace.U));
try expectEqual(@as(usize, 5), u.a.x);
}
{
const u: namespace.U = .{ .b = .{} };
try expectEqual(@as(usize, @sizeOf(namespace.U) + 2), u.b.y);
}
}
test "inner struct initializer uses packed union layout" {
const namespace = struct {
const U = packed union {
a: packed struct {
x: u32 = @alignOf(U) + 1,
},
b: packed struct(u32) {
y: u16 = @sizeOf(U) + 2,
padding: u16 = 0,
},
};
};
{
const u: namespace.U = .{ .a = .{} };
try expectEqual(4, @alignOf(namespace.U));
try expectEqual(@as(usize, 5), u.a.x);
}
{
const u: namespace.U = .{ .b = .{} };
try expectEqual(@as(usize, @sizeOf(namespace.U) + 2), u.b.y);
}
}
test "extern union initialized via reintepreted struct field initializer" {
if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;