authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-02-08 15:58:51+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-03-10 10:26:11+00:00
log12ddd5a698577e22a0bb5ed788ea4b9729a45b5d
treed76093ee057701f6aa7cb7825f138d56c6fbf6e1
parent1364cba90d41cb2f33380b23d534aaddbd6ceff2
signaturelock-open Commit is signed but in an unrecognized format.

behavior: update for changes to struct field default value resolution

This is separate from the previous commit so that these changes can be easily reverted in the event that we decide to allow more granularity in default value resolution in exchange for increased language complexity.

3 files changed, 3 insertions(+), 218 deletions(-)

test/behavior/eval.zig-114
...@@ -1081,120 +1081,6 @@ test "comptime break operand passing through runtime switch converted to runtime...@@ -1081,120 +1081,6 @@ test "comptime break operand passing through runtime switch converted to runtime
1081 try comptime S.doTheTest('b');1081 try comptime S.doTheTest('b');
1082}1082}
10831083
1084test "no dependency loop for alignment of self struct" {
1085 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1086 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1087 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1088
1089 const S = struct {
1090 fn doTheTest() !void {
1091 var a: namespace.A = undefined;
1092 a.d = .{ .g = &buf };
1093 a.d.g[3] = 42;
1094 a.d.g[3] += 1;
1095 try expect(a.d.g[3] == 43);
1096 }
1097
1098 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1099
1100 const namespace = struct {
1101 const B = struct { a: A };
1102 const A = C(B);
1103 };
1104
1105 pub fn C(comptime B: type) type {
1106 return struct {
1107 d: D(F) = .{},
1108
1109 const F = struct { b: B };
1110 };
1111 }
1112
1113 pub fn D(comptime F: type) type {
1114 return struct {
1115 g: [*]align(@alignOf(F)) u8 = undefined,
1116 };
1117 }
1118 };
1119 try S.doTheTest();
1120}
1121
1122test "no dependency loop for alignment of self bare union" {
1123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1124 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1125 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1126
1127 const S = struct {
1128 fn doTheTest() !void {
1129 var a: namespace.A = undefined;
1130 a.d = .{ .g = &buf };
1131 a.d.g[3] = 42;
1132 a.d.g[3] += 1;
1133 try expect(a.d.g[3] == 43);
1134 }
1135
1136 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1137
1138 const namespace = struct {
1139 const B = union { a: A, b: void };
1140 const A = C(B);
1141 };
1142
1143 pub fn C(comptime B: type) type {
1144 return struct {
1145 d: D(F) = .{},
1146
1147 const F = struct { b: B };
1148 };
1149 }
1150
1151 pub fn D(comptime F: type) type {
1152 return struct {
1153 g: [*]align(@alignOf(F)) u8 = undefined,
1154 };
1155 }
1156 };
1157 try S.doTheTest();
1158}
1159
1160test "no dependency loop for alignment of self tagged union" {
1161 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1162 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1163 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1164
1165 const S = struct {
1166 fn doTheTest() !void {
1167 var a: namespace.A = undefined;
1168 a.d = .{ .g = &buf };
1169 a.d.g[3] = 42;
1170 a.d.g[3] += 1;
1171 try expect(a.d.g[3] == 43);
1172 }
1173
1174 var buf: [10]u8 align(@alignOf([*]u8)) = undefined;
1175
1176 const namespace = struct {
1177 const B = union(enum) { a: A, b: void };
1178 const A = C(B);
1179 };
1180
1181 pub fn C(comptime B: type) type {
1182 return struct {
1183 d: D(F) = .{},
1184
1185 const F = struct { b: B };
1186 };
1187 }
1188
1189 pub fn D(comptime F: type) type {
1190 return struct {
1191 g: [*]align(@alignOf(F)) u8 = undefined,
1192 };
1193 }
1194 };
1195 try S.doTheTest();
1196}
1197
1198test "equality of pointers to comptime const" {1084test "equality of pointers to comptime const" {
1199 const a: i32 = undefined;1085 const a: i32 = undefined;
1200 comptime assert(&a == &a);1086 comptime assert(&a == &a);
test/behavior/struct.zig+3-55
...@@ -1249,20 +1249,6 @@ test "store to comptime field" {...@@ -1249,20 +1249,6 @@ test "store to comptime field" {
1249 }1249 }
1250}1250}
12511251
1252test "struct field init value is size of the struct" {
1253 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1254
1255 const namespace = struct {
1256 const S = extern struct {
1257 size: u8 = @sizeOf(S),
1258 blah: u16,
1259 };
1260 };
1261 var s: namespace.S = .{ .blah = 1234 };
1262 _ = &s;
1263 try expect(s.size == 4);
1264}
1265
1266test "under-aligned struct field" {1252test "under-aligned struct field" {
1267 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO1253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1268 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO1254 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
...@@ -1710,41 +1696,19 @@ test "comptimeness of optional and error union payload is analyzed properly" {...@@ -1710,41 +1696,19 @@ test "comptimeness of optional and error union payload is analyzed properly" {
1710 try std.testing.expectEqual(3, x);1696 try std.testing.expectEqual(3, x);
1711}1697}
17121698
1713test "initializer uses own alignment" {
1714 const S = struct {
1715 x: u32 = @alignOf(@This()) + 1,
1716 };
1717
1718 var s: S = .{};
1719 _ = &s;
1720 try expectEqual(4, @alignOf(S));
1721 try expectEqual(@as(usize, 5), s.x);
1722}
1723
1724test "initializer uses own size" {
1725 const S = struct {
1726 x: u32 = @sizeOf(@This()) + 1,
1727 };
1728
1729 var s: S = .{};
1730 _ = &s;
1731 try expectEqual(4, @sizeOf(S));
1732 try expectEqual(@as(usize, 5), s.x);
1733}
1734
1735test "initializer takes a pointer to a variable inside its struct" {1699test "initializer takes a pointer to a variable inside its struct" {
1736 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1700 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
17371701
1738 const namespace = struct {1702 const namespace = struct {
1739 const S = struct {1703 const S = struct {
1740 s: *S = &S.instance,1704 x: *u32 = &S.int,
1741 var instance: S = undefined;1705 var int: u32 = undefined;
1742 };1706 };
17431707
1744 fn doTheTest() !void {1708 fn doTheTest() !void {
1745 var foo: S = .{};1709 var foo: S = .{};
1746 _ = &foo;1710 _ = &foo;
1747 try expectEqual(&S.instance, foo.s);1711 try expectEqual(&S.int, foo.x);
1748 }1712 }
1749 };1713 };
17501714
...@@ -1775,22 +1739,6 @@ test "circular dependency through pointer field of a struct" {...@@ -1775,22 +1739,6 @@ test "circular dependency through pointer field of a struct" {
1775 try expect(outer.middle.inner == null);1739 try expect(outer.middle.inner == null);
1776}1740}
17771741
1778test "field calls do not force struct field init resolution" {
1779 const S = struct {
1780 x: u32 = blk: {
1781 _ = @TypeOf(make().dummyFn()); // runtime field call - S not fully resolved - dummyFn call should not force field init resolution
1782 break :blk 123;
1783 },
1784 dummyFn: *const fn () void = undefined,
1785 fn make() @This() {
1786 return .{};
1787 }
1788 };
1789 var s: S = .{};
1790 _ = &s;
1791 try expect(s.x == 123);
1792}
1793
1794test "tuple with comptime-only field" {1742test "tuple with comptime-only field" {
1795 const S = struct {1743 const S = struct {
1796 fn getTuple() struct { comptime_int } {1744 fn getTuple() struct { comptime_int } {
test/behavior/union.zig-49
...@@ -1796,55 +1796,6 @@ test "reinterpret packed union inside packed struct" {...@@ -1796,55 +1796,6 @@ test "reinterpret packed union inside packed struct" {
1796 try S.doTheTest();1796 try S.doTheTest();
1797}1797}
17981798
1799test "inner struct initializer uses union layout" {
1800 const namespace = struct {
1801 const U = union {
1802 a: struct {
1803 x: u32 = @alignOf(U) + 1,
1804 },
1805 b: struct {
1806 y: u16 = @sizeOf(U) + 2,
1807 },
1808 };
1809 };
1810
1811 {
1812 const u: namespace.U = .{ .a = .{} };
1813 try expectEqual(4, @alignOf(namespace.U));
1814 try expectEqual(@as(usize, 5), u.a.x);
1815 }
1816
1817 {
1818 const u: namespace.U = .{ .b = .{} };
1819 try expectEqual(@as(usize, @sizeOf(namespace.U) + 2), u.b.y);
1820 }
1821}
1822
1823test "inner struct initializer uses packed union layout" {
1824 const namespace = struct {
1825 const U = packed union {
1826 a: packed struct {
1827 x: u32 = @alignOf(U) + 1,
1828 },
1829 b: packed struct(u32) {
1830 y: u16 = @sizeOf(U) + 2,
1831 padding: u16 = 0,
1832 },
1833 };
1834 };
1835
1836 {
1837 const u: namespace.U = .{ .a = .{} };
1838 try expectEqual(4, @alignOf(namespace.U));
1839 try expectEqual(@as(usize, 5), u.a.x);
1840 }
1841
1842 {
1843 const u: namespace.U = .{ .b = .{} };
1844 try expectEqual(@as(usize, @sizeOf(namespace.U) + 2), u.b.y);
1845 }
1846}
1847
1848test "extern union initialized via reintepreted struct field initializer" {1799test "extern union initialized via reintepreted struct field initializer" {
1849 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;1800 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
18501801