1const std = @import("std");
2const builtin = @import("builtin");
3const assert = std.debug.assert;
4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;
6
7test "flags in packed structs" {
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9
10 const Flags1 = packed struct {
11 // first 8 bits
12 b0_0: u1,
13 b0_1: u1,
14 b0_2: u1,
15 b0_3: u1,
16 b0_4: u1,
17 b0_5: u1,
18 b0_6: u1,
19 b0_7: u1,
20
21 // 7 more bits
22 b1_0: u1,
23 b1_1: u1,
24 b1_2: u1,
25 b1_3: u1,
26 b1_4: u1,
27 b1_5: u1,
28 b1_6: u1,
29
30 // some padding to fill to 24 bits
31 _: u9,
32 };
33
34 try expectEqual(@sizeOf(u24), @sizeOf(Flags1));
35 try expectEqual(24, @bitSizeOf(Flags1));
36
37 const Flags2 = packed struct {
38 // byte 0
39 b0_0: u1,
40 b0_1: u1,
41 b0_2: u1,
42 b0_3: u1,
43 b0_4: u1,
44 b0_5: u1,
45 b0_6: u1,
46 b0_7: u1,
47
48 // partial byte 1 (but not 8 bits)
49 b1_0: u1,
50 b1_1: u1,
51 b1_2: u1,
52 b1_3: u1,
53 b1_4: u1,
54 b1_5: u1,
55 b1_6: u1,
56
57 // some padding that should yield @sizeOf(Flags2) == 4
58 _: u10,
59 };
60
61 try expectEqual(@sizeOf(u25), @sizeOf(Flags2));
62 try expectEqual(25, @bitSizeOf(Flags2));
63
64 const Flags3 = packed struct {
65 // byte 0
66 b0_0: u1,
67 b0_1: u1,
68 b0_2: u1,
69 b0_3: u1,
70 b0_4: u1,
71 b0_5: u1,
72 b0_6: u1,
73 b0_7: u1,
74
75 // byte 1
76 b1_0: u1,
77 b1_1: u1,
78 b1_2: u1,
79 b1_3: u1,
80 b1_4: u1,
81 b1_5: u1,
82 b1_6: u1,
83 b1_7: u1,
84
85 // some padding that should yield @sizeOf(Flags2) == 4
86 _: u16, // it works, if the padding is 8-based
87 };
88
89 try expectEqual(@sizeOf(u32), @sizeOf(Flags3));
90 try expectEqual(32, @bitSizeOf(Flags3));
91}
92
93test "consistent size of packed structs" {
94 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
95
96 const TxData1 = packed struct { data: u8, _23: u23, full: bool = false };
97 const TxData2 = packed struct { data: u9, _22: u22, full: bool = false };
98
99 const register_size_bits = 32;
100 const register_size_bytes = @sizeOf(u32);
101
102 try expectEqual(register_size_bits, @bitSizeOf(TxData1));
103 try expectEqual(register_size_bytes, @sizeOf(TxData1));
104
105 try expectEqual(register_size_bits, @bitSizeOf(TxData2));
106 try expectEqual(register_size_bytes, @sizeOf(TxData2));
107
108 const TxData4 = packed struct { a: u32, b: u24 };
109 const TxData6 = packed struct { a: u24, b: u32 };
110
111 const expectedBitSize = 56;
112 const expectedByteSize = @sizeOf(u56);
113
114 try expectEqual(expectedBitSize, @bitSizeOf(TxData4));
115 try expectEqual(expectedByteSize, @sizeOf(TxData4));
116
117 try expectEqual(expectedBitSize, @bitSizeOf(TxData6));
118 try expectEqual(expectedByteSize, @sizeOf(TxData6));
119}
120
121test "correct sizeOf and offsets in packed structs" {
122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
123 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
124
125 const PStruct = packed struct(u32) {
126 bool_a: bool,
127 bool_b: bool,
128 bool_c: bool,
129 bool_d: bool,
130 bool_e: bool,
131 bool_f: bool,
132 u1_a: u1,
133 bool_g: bool,
134 u1_b: u1,
135 u3_a: u3,
136 u10_a: u10,
137 u10_b: u10,
138 };
139 try expectEqual(0, @offsetOf(PStruct, "bool_a"));
140 try expectEqual(0, @bitOffsetOf(PStruct, "bool_a"));
141 try expectEqual(0, @offsetOf(PStruct, "bool_b"));
142 try expectEqual(1, @bitOffsetOf(PStruct, "bool_b"));
143 try expectEqual(0, @offsetOf(PStruct, "bool_c"));
144 try expectEqual(2, @bitOffsetOf(PStruct, "bool_c"));
145 try expectEqual(0, @offsetOf(PStruct, "bool_d"));
146 try expectEqual(3, @bitOffsetOf(PStruct, "bool_d"));
147 try expectEqual(0, @offsetOf(PStruct, "bool_e"));
148 try expectEqual(4, @bitOffsetOf(PStruct, "bool_e"));
149 try expectEqual(0, @offsetOf(PStruct, "bool_f"));
150 try expectEqual(5, @bitOffsetOf(PStruct, "bool_f"));
151 try expectEqual(0, @offsetOf(PStruct, "u1_a"));
152 try expectEqual(6, @bitOffsetOf(PStruct, "u1_a"));
153 try expectEqual(0, @offsetOf(PStruct, "bool_g"));
154 try expectEqual(7, @bitOffsetOf(PStruct, "bool_g"));
155 try expectEqual(1, @offsetOf(PStruct, "u1_b"));
156 try expectEqual(8, @bitOffsetOf(PStruct, "u1_b"));
157 try expectEqual(1, @offsetOf(PStruct, "u3_a"));
158 try expectEqual(9, @bitOffsetOf(PStruct, "u3_a"));
159 try expectEqual(1, @offsetOf(PStruct, "u10_a"));
160 try expectEqual(12, @bitOffsetOf(PStruct, "u10_a"));
161 try expectEqual(2, @offsetOf(PStruct, "u10_b"));
162 try expectEqual(22, @bitOffsetOf(PStruct, "u10_b"));
163 try expectEqual(4, @sizeOf(PStruct));
164
165 const s1: PStruct = @fromBackingInt(0x12345678);
166 try expectEqual(false, s1.bool_a);
167 try expectEqual(false, s1.bool_b);
168 try expectEqual(false, s1.bool_c);
169 try expectEqual(true, s1.bool_d);
170 try expectEqual(true, s1.bool_e);
171 try expectEqual(true, s1.bool_f);
172 try expectEqual(1, s1.u1_a);
173 try expectEqual(false, s1.bool_g);
174 try expectEqual(0, s1.u1_b);
175 try expectEqual(3, s1.u3_a);
176 try expectEqual(0b1101000101, s1.u10_a);
177 try expectEqual(0b0001001000, s1.u10_b);
178
179 const s2: packed struct(u32) { x: u1, y: u7, z: u24 } = @fromBackingInt(0xd5c71ff4);
180 try expectEqual(0, s2.x);
181 try expectEqual(0b1111010, s2.y);
182 try expectEqual(0xd5c71f, s2.z);
183}
184
185test "nested packed structs" {
186 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
187 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
188
189 const S1 = packed struct { a: u8, b: u8, c: u8 };
190
191 const S2 = packed struct { d: u8, e: u8, f: u8 };
192
193 const S3 = packed struct { x: S1, y: S2 };
194 const S3Padded = packed struct(u64) { s3: S3, pad: u16 };
195
196 try expectEqual(48, @bitSizeOf(S3));
197 try expectEqual(@sizeOf(u48), @sizeOf(S3));
198
199 try expectEqual(3, @offsetOf(S3, "y"));
200 try expectEqual(24, @bitOffsetOf(S3, "y"));
201
202 const s3 = @as(S3Padded, @fromBackingInt(0xe952d5c71ff4)).s3;
203 try expectEqual(0xf4, s3.x.a);
204 try expectEqual(0x1f, s3.x.b);
205 try expectEqual(0xc7, s3.x.c);
206 try expectEqual(0xd5, s3.y.d);
207 try expectEqual(0x52, s3.y.e);
208 try expectEqual(0xe9, s3.y.f);
209
210 const S4 = packed struct { a: i32, b: i8 };
211 const S5 = packed struct { a: i32, b: i8, c: S4 };
212 const S6 = packed struct { a: i32, b: S4, c: i8 };
213
214 const expectedBitSize = 80;
215 const expectedByteSize = @sizeOf(u80);
216 try expectEqual(expectedBitSize, @bitSizeOf(S5));
217 try expectEqual(expectedByteSize, @sizeOf(S5));
218 try expectEqual(expectedBitSize, @bitSizeOf(S6));
219 try expectEqual(expectedByteSize, @sizeOf(S6));
220
221 try expectEqual(5, @offsetOf(S5, "c"));
222 try expectEqual(40, @bitOffsetOf(S5, "c"));
223 try expectEqual(9, @offsetOf(S6, "c"));
224 try expectEqual(72, @bitOffsetOf(S6, "c"));
225}
226
227test "regular in irregular packed struct" {
228 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
229 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
230 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
231
232 const Irregular = packed struct {
233 bar: Regular = Regular{},
234 _: u24 = 0,
235 pub const Regular = packed struct { a: u16 = 0, b: u8 = 0 };
236 };
237
238 var foo = Irregular{};
239 foo.bar.a = 235;
240 foo.bar.b = 42;
241
242 try expectEqual(235, foo.bar.a);
243 try expectEqual(42, foo.bar.b);
244}
245
246test "nested packed struct unaligned" {
247 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
248 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
249 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
250 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
251 const S1 = packed struct {
252 a: u4,
253 b: u4,
254 c: u8,
255 };
256 const S2 = packed struct {
257 base: u8,
258 p0: S1,
259 bit0: u1,
260 p1: packed struct {
261 a: u8,
262 },
263 p2: packed struct {
264 a: u7,
265 b: u8,
266 },
267 p3: S1,
268
269 var s: @This() = .{
270 .base = 1,
271 .p0 = .{ .a = 2, .b = 3, .c = 4 },
272 .bit0 = 0,
273 .p1 = .{ .a = 5 },
274 .p2 = .{ .a = 6, .b = 7 },
275 .p3 = .{ .a = 8, .b = 9, .c = 10 },
276 };
277 };
278
279 try expect(S2.s.base == 1);
280 try expect(S2.s.p0.a == 2);
281 try expect(S2.s.p0.b == 3);
282 try expect(S2.s.p0.c == 4);
283 try expect(S2.s.bit0 == 0);
284 try expect(S2.s.p1.a == 5);
285 try expect(S2.s.p2.a == 6);
286 try expect(S2.s.p2.b == 7);
287 try expect(S2.s.p3.a == 8);
288 try expect(S2.s.p3.b == 9);
289 try expect(S2.s.p3.c == 10);
290
291 const S3 = packed struct {
292 pad: u8,
293 v: u2,
294 s: packed struct {
295 v: u3,
296 s: packed struct {
297 v: u2,
298 s: packed struct {
299 bit0: u1,
300 byte: u8,
301 bit1: u1,
302 },
303 },
304 },
305 var v0: @This() = .{ .pad = 0, .v = 1, .s = .{ .v = 2, .s = .{ .v = 3, .s = .{ .bit0 = 0, .byte = 4, .bit1 = 1 } } } };
306 };
307
308 try expect(S3.v0.v == 1);
309 try expect(S3.v0.s.v == 2);
310 try expect(S3.v0.s.s.v == 3);
311 try expect(S3.v0.s.s.s.bit0 == 0);
312 try expect(S3.v0.s.s.s.byte == 4);
313 try expect(S3.v0.s.s.s.bit1 == 1);
314}
315
316test "byte-aligned field pointer offsets" {
317 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
318 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
319 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
321
322 const S = struct {
323 const A = packed struct {
324 a: u8,
325 b: u8,
326 c: u8,
327 d: u8,
328 };
329
330 const B = packed struct {
331 a: u16,
332 b: u16,
333 };
334
335 fn doTheTest() !void {
336 var a: A = .{
337 .a = 1,
338 .b = 2,
339 .c = 3,
340 .d = 4,
341 };
342
343 comptime assert(@TypeOf(&a.a) == *align(4:0:4) u8);
344 comptime assert(@TypeOf(&a.b) == *align(4:8:4) u8);
345 comptime assert(@TypeOf(&a.c) == *align(4:16:4) u8);
346 comptime assert(@TypeOf(&a.d) == *align(4:24:4) u8);
347
348 try expect(a.a == 1);
349 try expect(a.b == 2);
350 try expect(a.c == 3);
351 try expect(a.d == 4);
352
353 a.a += 1;
354 try expect(a.a == 2);
355 try expect(a.b == 2);
356 try expect(a.c == 3);
357 try expect(a.d == 4);
358
359 a.b += 1;
360 try expect(a.a == 2);
361 try expect(a.b == 3);
362 try expect(a.c == 3);
363 try expect(a.d == 4);
364
365 a.c += 1;
366 try expect(a.a == 2);
367 try expect(a.b == 3);
368 try expect(a.c == 4);
369 try expect(a.d == 4);
370
371 a.d += 1;
372 try expect(a.a == 2);
373 try expect(a.b == 3);
374 try expect(a.c == 4);
375 try expect(a.d == 5);
376
377 var b: B = .{
378 .a = 1,
379 .b = 2,
380 };
381
382 comptime assert(@TypeOf(&b.a) == *align(4:0:4) u16);
383 comptime assert(@TypeOf(&b.b) == *align(4:16:4) u16);
384
385 try expect(b.a == 1);
386 try expect(b.b == 2);
387
388 b.a += 1;
389 try expect(b.a == 2);
390 try expect(b.b == 2);
391
392 b.b += 1;
393 try expect(b.a == 2);
394 try expect(b.b == 3);
395 }
396 };
397
398 try S.doTheTest();
399 try comptime S.doTheTest();
400}
401
402test "nested packed struct field pointers" {
403 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
404 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
405 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
406 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
407 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
408 const S2 = packed struct {
409 base: u8,
410 p0: packed struct {
411 a: u4,
412 b: u4,
413 c: u8,
414 },
415 bit: u1,
416 p1: packed struct {
417 a: u7,
418 b: u8,
419 },
420
421 var s: @This() = .{ .base = 1, .p0 = .{ .a = 2, .b = 3, .c = 4 }, .bit = 0, .p1 = .{ .a = 5, .b = 6 } };
422 };
423
424 const ptr_base = &S2.s.base;
425 const ptr_p0_a = &S2.s.p0.a;
426 const ptr_p0_b = &S2.s.p0.b;
427 const ptr_p0_c = &S2.s.p0.c;
428 const ptr_p1_a = &S2.s.p1.a;
429 const ptr_p1_b = &S2.s.p1.b;
430 try expectEqual(1, ptr_base.*);
431 try expectEqual(2, ptr_p0_a.*);
432 try expectEqual(3, ptr_p0_b.*);
433 try expectEqual(4, ptr_p0_c.*);
434 try expectEqual(5, ptr_p1_a.*);
435 try expectEqual(6, ptr_p1_b.*);
436}
437
438test "@intFromPtr on a packed struct field" {
439 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
440 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
441 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
442
443 const S = struct {
444 const P = packed struct {
445 x: u8,
446 y: u8,
447 z: u32,
448 };
449
450 var p0: P = P{
451 .x = 1,
452 .y = 2,
453 .z = 0,
454 };
455 };
456 try expect(@intFromPtr(&S.p0.z) - @intFromPtr(&S.p0.x) == 0);
457}
458
459test "@intFromPtr on a packed struct field unaligned and nested" {
460 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
461 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
462 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
463
464 const S1 = packed struct {
465 a: u4,
466 b: u4,
467 c: u8,
468 };
469 const S2 = packed struct {
470 base: u8,
471 p0: S1,
472 bit0: u1,
473 p1: packed struct {
474 a: u8,
475 },
476 p2: packed struct {
477 a: u7,
478 b: u8,
479 },
480 p3: S1,
481
482 var s: @This() = .{
483 .base = 1,
484 .p0 = .{ .a = 2, .b = 3, .c = 4 },
485 .bit0 = 0,
486 .p1 = .{ .a = 5 },
487 .p2 = .{ .a = 6, .b = 7 },
488 .p3 = .{ .a = 8, .b = 9, .c = 10 },
489 };
490 };
491
492 {
493 const a = @alignOf(S2);
494 comptime assert(@TypeOf(&S2.s.base) == *align(a:0:8) u8);
495 comptime assert(@TypeOf(&S2.s.p0.a) == *align(a:8:8) u4);
496 comptime assert(@TypeOf(&S2.s.p0.b) == *align(a:12:8) u4);
497 comptime assert(@TypeOf(&S2.s.p0.c) == *align(a:16:8) u8);
498 comptime assert(@TypeOf(&S2.s.bit0) == *align(a:24:8) u1);
499 comptime assert(@TypeOf(&S2.s.p1.a) == *align(a:25:8) u8);
500 comptime assert(@TypeOf(&S2.s.p2.a) == *align(a:33:8) u7);
501 comptime assert(@TypeOf(&S2.s.p2.b) == *align(a:40:8) u8);
502 comptime assert(@TypeOf(&S2.s.p3.a) == *align(a:48:8) u4);
503 comptime assert(@TypeOf(&S2.s.p3.b) == *align(a:52:8) u4);
504 comptime assert(@TypeOf(&S2.s.p3.c) == *align(a:56:8) u8);
505 }
506
507 try expect(@intFromPtr(&S2.s.base) - @intFromPtr(&S2.s) == 0);
508 try expect(@intFromPtr(&S2.s.p0.a) - @intFromPtr(&S2.s) == 0);
509 try expect(@intFromPtr(&S2.s.p0.b) - @intFromPtr(&S2.s) == 0);
510 try expect(@intFromPtr(&S2.s.p0.c) - @intFromPtr(&S2.s) == 0);
511 try expect(@intFromPtr(&S2.s.bit0) - @intFromPtr(&S2.s) == 0);
512 try expect(@intFromPtr(&S2.s.p1.a) - @intFromPtr(&S2.s) == 0);
513 try expect(@intFromPtr(&S2.s.p2.a) - @intFromPtr(&S2.s) == 0);
514 try expect(@intFromPtr(&S2.s.p2.b) - @intFromPtr(&S2.s) == 0);
515 try expect(@intFromPtr(&S2.s.p3.a) - @intFromPtr(&S2.s) == 0);
516 try expect(@intFromPtr(&S2.s.p3.b) - @intFromPtr(&S2.s) == 0);
517 try expect(@intFromPtr(&S2.s.p3.c) - @intFromPtr(&S2.s) == 0);
518
519 const S3 = packed struct {
520 pad: u8,
521 v: u2,
522 s: packed struct {
523 v: u3,
524 s: packed struct {
525 v: u2,
526 s: packed struct {
527 bit0: u1,
528 byte: u8,
529 bit1: u1,
530 },
531 },
532 },
533 var v0: @This() = .{ .pad = 0, .v = 1, .s = .{ .v = 2, .s = .{ .v = 3, .s = .{ .bit0 = 0, .byte = 4, .bit1 = 1 } } } };
534 };
535
536 comptime assert(@TypeOf(&S3.v0.v) == *align(4:8:4) u2);
537 comptime assert(@TypeOf(&S3.v0.s.v) == *align(4:10:4) u3);
538 comptime assert(@TypeOf(&S3.v0.s.s.v) == *align(4:13:4) u2);
539 comptime assert(@TypeOf(&S3.v0.s.s.s.bit0) == *align(4:15:4) u1);
540 comptime assert(@TypeOf(&S3.v0.s.s.s.byte) == *align(4:16:4) u8);
541 comptime assert(@TypeOf(&S3.v0.s.s.s.bit1) == *align(4:24:4) u1);
542 try expect(@intFromPtr(&S3.v0.v) - @intFromPtr(&S3.v0) == 0);
543 try expect(@intFromPtr(&S3.v0.s) - @intFromPtr(&S3.v0) == 0);
544 try expect(@intFromPtr(&S3.v0.s.v) - @intFromPtr(&S3.v0) == 0);
545 try expect(@intFromPtr(&S3.v0.s.s) - @intFromPtr(&S3.v0) == 0);
546 try expect(@intFromPtr(&S3.v0.s.s.v) - @intFromPtr(&S3.v0) == 0);
547 try expect(@intFromPtr(&S3.v0.s.s.s) - @intFromPtr(&S3.v0) == 0);
548 try expect(@intFromPtr(&S3.v0.s.s.s.bit0) - @intFromPtr(&S3.v0) == 0);
549 try expect(@intFromPtr(&S3.v0.s.s.s.byte) - @intFromPtr(&S3.v0) == 0);
550 try expect(@intFromPtr(&S3.v0.s.s.s.bit1) - @intFromPtr(&S3.v0) == 0);
551}
552
553test "packed struct fields modification" {
554 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
555 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
556
557 // Originally reported at https://github.com/ziglang/zig/issues/16615
558 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
559
560 const Small = packed struct(u16) {
561 val: u8 = 0,
562 lo: u4 = 0,
563 hi: u4 = 0,
564
565 var p: @This() = undefined;
566 };
567 Small.p = .{
568 .val = 0x12,
569 .lo = 3,
570 .hi = 4,
571 };
572 try expect(@backingInt(Small.p) == 0x4312);
573
574 Small.p.val -= Small.p.lo;
575 Small.p.val += Small.p.hi;
576 Small.p.hi -= Small.p.lo;
577 try expect(@backingInt(Small.p) == 0x1313);
578}
579
580test "nested packed struct field access test" {
581 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
582 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
583 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
584 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
585 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
586
587 const Vec2 = packed struct {
588 x: f32,
589 y: f32,
590 };
591
592 const Vec3 = packed struct {
593 x: f32,
594 y: f32,
595 z: f32,
596 };
597
598 const NestedVec2 = packed struct {
599 nested: Vec2,
600 };
601
602 const NestedVec3 = packed struct {
603 nested: Vec3,
604 };
605
606 const vec2 = Vec2{
607 .x = 1.0,
608 .y = 2.0,
609 };
610
611 try std.testing.expectEqual(vec2.x, 1.0);
612 try std.testing.expectEqual(vec2.y, 2.0);
613
614 var vec2_o: Vec2 = undefined;
615 const vec2_o_ptr: *Vec2 = &vec2_o;
616 vec2_o_ptr.* = vec2;
617
618 try std.testing.expectEqual(vec2_o.x, 1.0);
619 try std.testing.expectEqual(vec2_o.y, 2.0);
620
621 const nested_vec2 = NestedVec2{
622 .nested = Vec2{
623 .x = 1.0,
624 .y = 2.0,
625 },
626 };
627
628 try std.testing.expectEqual(nested_vec2.nested.x, 1.0);
629 try std.testing.expectEqual(nested_vec2.nested.y, 2.0);
630
631 var nested_o: NestedVec2 = undefined;
632 const nested_o_ptr: *NestedVec2 = &nested_o;
633 nested_o_ptr.* = nested_vec2;
634
635 try std.testing.expectEqual(nested_o.nested.x, 1.0);
636 try std.testing.expectEqual(nested_o.nested.y, 2.0);
637
638 const vec3 = Vec3{
639 .x = 1.0,
640 .y = 2.0,
641 .z = 3.0,
642 };
643
644 try std.testing.expectEqual(vec3.x, 1.0);
645 try std.testing.expectEqual(vec3.y, 2.0);
646 try std.testing.expectEqual(vec3.z, 3.0);
647
648 var vec3_o: Vec3 = undefined;
649 const vec3_o_ptr: *Vec3 = &vec3_o;
650 vec3_o_ptr.* = vec3;
651
652 try std.testing.expectEqual(vec3_o.x, 1.0);
653 try std.testing.expectEqual(vec3_o.y, 2.0);
654 try std.testing.expectEqual(vec3_o.z, 3.0);
655
656 const nested_vec3 = NestedVec3{
657 .nested = Vec3{
658 .x = 1.0,
659 .y = 2.0,
660 .z = 3.0,
661 },
662 };
663
664 try std.testing.expectEqual(nested_vec3.nested.x, 1.0);
665 try std.testing.expectEqual(nested_vec3.nested.y, 2.0);
666 try std.testing.expectEqual(nested_vec3.nested.z, 3.0);
667
668 var nested_vec3_o: NestedVec3 = undefined;
669 const nested_vec3_o_ptr: *NestedVec3 = &nested_vec3_o;
670 nested_vec3_o_ptr.* = nested_vec3;
671
672 try std.testing.expectEqual(nested_vec3_o.nested.x, 1.0);
673 try std.testing.expectEqual(nested_vec3_o.nested.y, 2.0);
674 try std.testing.expectEqual(nested_vec3_o.nested.z, 3.0);
675
676 const hld = packed struct {
677 c: u64,
678 d: u32,
679 };
680
681 const mld = packed struct {
682 h: u64,
683 i: u64,
684 };
685
686 const a = packed struct {
687 b: hld,
688 g: mld,
689 };
690
691 var arg = a{ .b = hld{ .c = 1, .d = 2 }, .g = mld{ .h = 6, .i = 8 } };
692 _ = &arg;
693 try std.testing.expect(arg.b.c == 1);
694 try std.testing.expect(arg.b.d == 2);
695 try std.testing.expect(arg.g.h == 6);
696 try std.testing.expect(arg.g.i == 8);
697}
698
699test "nested packed struct at non-zero offset" {
700 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
701 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
702 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
703
704 const Pair = packed struct(u24) {
705 a: u16 = 0,
706 b: u8 = 0,
707 };
708 const A = packed struct {
709 p1: Pair,
710 p2: Pair,
711 };
712
713 var k: u8 = 123;
714 _ = &k;
715 var v: A = .{
716 .p1 = .{ .a = k + 1, .b = k },
717 .p2 = .{ .a = k + 1, .b = k },
718 };
719
720 try expect(v.p1.a == k + 1 and v.p1.b == k);
721 try expect(v.p2.a == k + 1 and v.p2.b == k);
722
723 v.p2.a -= v.p1.a;
724 v.p2.b -= v.p1.b;
725 try expect(v.p2.a == 0 and v.p2.b == 0);
726 try expect(v.p1.a == k + 1 and v.p1.b == k);
727}
728
729test "nested packed struct at non-zero offset 2" {
730 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
731 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
732 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
733 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
734 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
735
736 const S = struct {
737 const Pair = packed struct(u40) {
738 a: u32 = 0,
739 b: u8 = 0,
740 };
741 const A = packed struct {
742 p1: Pair,
743 p2: Pair,
744 c: C,
745 };
746 const C = packed struct {
747 p1: Pair,
748 pad1: u5,
749 p2: Pair,
750 pad2: u3,
751 last: i16,
752 };
753
754 fn doTheTest() !void {
755 var k: u8 = 123;
756 _ = &k;
757 var v: A = .{
758 .p1 = .{ .a = k + 1, .b = k },
759 .p2 = .{ .a = k + 1, .b = k },
760 .c = .{
761 .pad1 = 11,
762 .pad2 = 2,
763 .p1 = .{ .a = k + 1, .b = k },
764 .p2 = .{ .a = k + 1, .b = k },
765 .last = -12345,
766 },
767 };
768
769 try expect(v.p1.a == k + 1 and v.p1.b == k);
770 try expect(v.p2.a == k + 1 and v.p2.b == k);
771 try expect(v.c.p2.a == k + 1 and v.c.p2.b == k);
772 try expect(v.c.p2.a == k + 1 and v.c.p2.b == k);
773 try expect(v.c.last == -12345);
774 try expect(v.c.pad1 == 11 and v.c.pad2 == 2);
775
776 v.p2.a -= v.p1.a;
777 v.p2.b -= v.p1.b;
778 v.c.p2.a -= v.c.p1.a;
779 v.c.p2.b -= v.c.p1.b;
780 v.c.last -|= 32000;
781 try expect(v.p2.a == 0 and v.p2.b == 0);
782 try expect(v.p1.a == k + 1 and v.p1.b == k);
783 try expect(v.c.p2.a == 0 and v.c.p2.b == 0);
784 try expect(v.c.p1.a == k + 1 and v.c.p1.b == k);
785 try expect(v.c.last == -32768);
786 try expect(v.c.pad1 == 11 and v.c.pad2 == 2);
787 }
788 };
789
790 try S.doTheTest();
791 try comptime S.doTheTest();
792}
793
794test "runtime init of unnamed packed struct type" {
795 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
796 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
797 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
798
799 var z: u8 = 123;
800 _ = &z;
801 try (packed struct {
802 x: u8,
803 pub fn m(s: @This()) !void {
804 try expect(s.x == 123);
805 }
806 }{ .x = z }).m();
807}
808
809test "packed struct passed to callconv(.c) function" {
810 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
811 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
812 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
813 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
814 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
815
816 const S = struct {
817 const Packed = packed struct(u64) {
818 a: u16,
819 b: bool = true,
820 c: bool = true,
821 d: u46 = 0,
822 };
823
824 fn foo(p: Packed, a1: u64, a2: u64, a3: u64, a4: u64, a5: u64) callconv(.c) bool {
825 return p.a == 12345 and p.b == true and p.c == true and p.d == 0 and a1 == 5 and a2 == 4 and a3 == 3 and a4 == 2 and a5 == 1;
826 }
827 };
828 const result = S.foo(S.Packed{
829 .a = 12345,
830 .b = true,
831 .c = true,
832 }, 5, 4, 3, 2, 1);
833 try expect(result);
834}
835
836test "overaligned pointer to packed struct" {
837 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
838 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
839 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
840 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
841
842 const S = packed struct { a: u32, b: u32 };
843 var foo: S align(4) = .{ .a = 123, .b = 456 };
844 const ptr: *align(4) S = &foo;
845 const ptr_to_a: *align(4:0:8) u32 = &ptr.a;
846 try expect(ptr_to_a.* == 123);
847}
848
849test "packed struct initialized in bitcast" {
850 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
851 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
852 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
853 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
854
855 const T = packed struct { val: u8 };
856 var val: u8 = 123;
857 _ = &val;
858 const t = @as(u8, @bitCast(T{ .val = val }));
859 try expect(t == val);
860}
861
862test "pointer to container level packed struct field" {
863 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
864 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
865 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
866 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
867 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
868
869 const S = packed struct(u32) {
870 test_bit: bool,
871 someother_data: u12,
872 other_test_bit: bool,
873 someother_more_different_data: u12,
874 other_bits: packed struct(u6) {
875 enable_1: bool,
876 enable_2: bool,
877 enable_3: bool,
878 enable_4: bool,
879 enable_5: bool,
880 enable_6: bool,
881 },
882 var arr: [2]u32 = @splat(0);
883 };
884 @as(*S, @ptrCast(&S.arr[0])).other_bits.enable_3 = true;
885 try expect(S.arr[0] == 0x10000000);
886}
887
888test "store undefined to packed result location" {
889 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
890 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
891 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
892 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
893
894 var x: u4 = 0;
895 _ = &x;
896 const s = packed struct { x: u4, y: u4 }{ .x = x, .y = if (x > 0) x else undefined };
897 try expectEqual(x, s.x);
898}
899
900// Originally reported at https://github.com/ziglang/zig/issues/9914
901test "bitcast back and forth" {
902 const S = packed struct { one: u6, two: u1 };
903 const s = S{ .one = 0b110101, .two = 0b1 };
904 const u: u7 = @bitCast(s);
905 const s2: S = @bitCast(u);
906 try expect(s.one == s2.one);
907 try expect(s.two == s2.two);
908}
909
910// Originally reported at https://github.com/ziglang/zig/issues/14200
911test "field access of packed struct smaller than its abi size inside struct initialized with rls" {
912 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
913 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
914 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
915
916 const S = struct {
917 ps: packed struct { x: i2, y: i2 },
918
919 fn init(cond: bool) @This() {
920 return .{ .ps = .{ .x = 0, .y = if (cond) 1 else 0 } };
921 }
922 };
923
924 const s = S.init(true);
925 // note: this bug is triggered by the == operator, expectEqual will hide it
926 try expect(@as(i2, 0) == s.ps.x);
927 try expect(@as(i2, 1) == s.ps.y);
928}
929
930// Originally reported at https://github.com/ziglang/zig/issues/14632
931test "modify nested packed struct aligned field" {
932 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
933 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
934 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
935 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
936
937 const Options = packed struct {
938 foo: bool = false,
939 bar: bool = false,
940 pretty_print: packed struct {
941 enabled: bool = false,
942 num_spaces: u4 = 4,
943 space_char: enum(u1) { space, tab } = .space,
944 indent: u8 = 0,
945 } = .{},
946 baz: bool = false,
947 };
948
949 var opts = Options{};
950 opts.pretty_print.indent += 1;
951 try std.testing.expectEqual(0b00000000100100000, @as(u17, @bitCast(opts)));
952 try std.testing.expect(!opts.foo);
953 try std.testing.expect(!opts.bar);
954 try std.testing.expect(!opts.pretty_print.enabled);
955 try std.testing.expectEqual(4, opts.pretty_print.num_spaces);
956 try std.testing.expectEqual(1, opts.pretty_print.indent);
957 try std.testing.expect(!opts.baz);
958}
959
960// Originally reported at https://github.com/ziglang/zig/issues/9674
961test "assigning packed struct inside another packed struct" {
962 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
963 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
964 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
965
966 const S = struct {
967 const Inner = packed struct {
968 bits: u3,
969 more_bits: u6,
970 };
971
972 const Outer = packed struct {
973 padding: u5,
974 inner: Inner,
975 };
976 fn t(inner: Inner) void {
977 r.inner = inner;
978 }
979
980 var mem: Outer = undefined;
981 var r: *volatile Outer = &mem;
982 };
983
984 const val = S.Inner{ .bits = 1, .more_bits = 11 };
985 S.mem.padding = 0;
986 S.t(val);
987
988 try expectEqual(val, S.mem.inner);
989 try expect(S.mem.padding == 0);
990}
991
992test "packed struct acts as a namespace" {
993 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
994
995 const Bar = packed struct {
996 const Baz = enum {
997 fizz,
998 buzz,
999 };
1000 };
1001 var foo = Bar.Baz.fizz;
1002 _ = &foo;
1003 try expect(foo == .fizz);
1004}
1005
1006test "assignment to non-byte-aligned field in packed struct" {
1007 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1008 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1009 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1010 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1011
1012 const Frame = packed struct {
1013 num: u20,
1014 };
1015
1016 const Entry = packed struct {
1017 other: u12,
1018 frame: Frame,
1019 };
1020
1021 const frame = Frame{ .num = 0x7FDE };
1022 var entry = Entry{ .other = 0, .frame = .{ .num = 0xFFFFF } };
1023 entry.frame = frame;
1024 try expect(entry.frame.num == 0x7FDE);
1025}
1026
1027test "packed struct field pointer aligned properly" {
1028 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1029 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1030 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1031
1032 const Foo = packed struct {
1033 a: i32,
1034 b: u8,
1035
1036 var buffer: [256]u8 = undefined;
1037 };
1038
1039 var f1: *align(16) Foo = @alignCast(@as(*align(1) Foo, @ptrCast(&Foo.buffer[0])));
1040 try expect(@typeInfo(@TypeOf(f1)).pointer.attrs.@"align" == 16);
1041 try expect(@intFromPtr(f1) == @intFromPtr(&f1.a));
1042 try expect(@typeInfo(@TypeOf(&f1.a)).pointer.attrs.@"align" == 16);
1043}
1044
1045test "load flag from packed struct in union" {
1046 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1047 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1048 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1049 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1050 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1051
1052 const A = packed struct {
1053 a: bool,
1054 b: bool,
1055 c: bool,
1056 d: bool,
1057
1058 e: bool,
1059 f: bool,
1060 g: bool,
1061 h: bool,
1062 };
1063
1064 const X = union {
1065 x: A,
1066 y: u64,
1067
1068 pub fn a(_: i32, _: i32, _: i32, _: i32, _: i32, _: bool, flag_b: bool) !void {
1069 const flag_b_byte: u8 = @intFromBool(flag_b);
1070 try std.testing.expect(flag_b_byte == 1);
1071 }
1072 pub fn b(x: *@This()) !void {
1073 try a(0, 1, 2, 3, 4, x.x.a, x.x.b);
1074 }
1075 };
1076 var flags = A{
1077 .a = false,
1078 .b = true,
1079 .c = false,
1080 .d = false,
1081
1082 .e = false,
1083 .f = true,
1084 .g = false,
1085 .h = false,
1086 };
1087 _ = &flags;
1088 var x = X{
1089 .x = flags,
1090 };
1091 try X.b(&x);
1092 comptime if (@sizeOf(A) != 1) unreachable;
1093}
1094
1095test "bitcasting a packed struct at comptime and using the result" {
1096 comptime {
1097 const Struct = packed struct {
1098 x: packed union {
1099 a: u63,
1100 b: packed struct(u63) {
1101 a: i32,
1102 b: u31 = 0,
1103 },
1104 },
1105 y: u1,
1106
1107 pub fn bitcast(fd: u64) @This() {
1108 return @bitCast(fd);
1109 }
1110
1111 pub fn cannotReach(_: @This()) i32 {
1112 return 0;
1113 }
1114 };
1115
1116 _ = Struct.bitcast(@as(u64, 0)).cannotReach();
1117 }
1118}
1119
1120test "2-byte packed struct argument in C calling convention" {
1121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1122 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1123 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1124 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1125
1126 const S = packed struct(u16) {
1127 x: u15 = 0,
1128 y: u1 = 0,
1129
1130 fn foo(s: @This()) callconv(.c) i32 {
1131 return s.x;
1132 }
1133 fn bar(s: @This()) !void {
1134 try expect(foo(s) == 1);
1135 }
1136 };
1137 {
1138 var s: S = .{};
1139 s.x += 1;
1140 try S.bar(s);
1141 }
1142 comptime {
1143 var s: S = .{};
1144 s.x += 1;
1145 try S.bar(s);
1146 }
1147}
1148
1149test "packed struct equality" {
1150 const Foo = packed struct {
1151 a: u4,
1152 b: u4,
1153 };
1154
1155 const S = struct {
1156 fn doTest(x: Foo, y: Foo) !void {
1157 try expect(x == y);
1158 try expect(!(x != y));
1159 }
1160 };
1161
1162 const x: Foo = .{ .a = 1, .b = 2 };
1163 const y: Foo = .{ .b = 2, .a = 1 };
1164
1165 try S.doTest(x, y);
1166 comptime try S.doTest(x, y);
1167}
1168
1169test "packed struct equality ignores padding bits" {
1170 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1171 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1172
1173 const S = packed struct { b: bool };
1174 var s: S = undefined;
1175 s.b = true;
1176 try std.testing.expect(s != S{ .b = false });
1177 try std.testing.expect(s == S{ .b = true });
1178}
1179
1180test "packed struct with signed field" {
1181 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1182 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1183
1184 var s: packed struct {
1185 a: i2,
1186 b: u6,
1187 } = .{ .a = -1, .b = 42 };
1188 s = s;
1189 try expect(s.a == -1);
1190 try expect(s.b == 42);
1191}
1192
1193test "assign packed struct initialized with RLS to packed struct literal field" {
1194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1195 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1196 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1197
1198 const Inner = packed struct { x: u17 };
1199 const Outer = packed struct { inner: Inner, x: u15 };
1200
1201 var x: u15 = undefined;
1202 x = 23385;
1203 var inner: Inner = undefined;
1204 inner = .{ .x = x };
1205 const outer = Outer{ .x = x, .inner = inner };
1206 try expect(outer.inner.x == x);
1207 try expect(outer.x == x);
1208}
1209
1210test "packed struct store of comparison result" {
1211 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1212 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1213 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1214
1215 const S1 = packed struct {
1216 val1: u3,
1217 val2: u3,
1218 };
1219 const S2 = packed struct {
1220 a: bool,
1221 b: bool,
1222 };
1223
1224 var A: S1 = .{ .val1 = 1, .val2 = 1 };
1225 A.val2 += 1;
1226 try expectEqual(1, A.val1);
1227 try expectEqual(2, A.val2);
1228 try expect((A.val2 & 1) != 1);
1229 const result1: S2 = .{ .a = (A.val2 & 1) != 1, .b = (A.val1 & 1) != 1 };
1230 try expect(result1.a);
1231 try expect(!result1.b);
1232
1233 try expect((A.val2 == 3) == false);
1234 try expect((A.val2 == 2) == true);
1235 const result2: S2 = .{ .a = !(A.val2 == 3), .b = (A.val1 == 2) };
1236 try expect(result2.a);
1237 try expect(!result2.b);
1238}
1239
1240test "initialize packed struct field to undefined at comptime" {
1241 const S = packed struct(u8) { x: u8 };
1242 const val: S = .{ .x = undefined };
1243 _ = val;
1244}
1245
1246test "convert from/to backing int" {
1247 const S = packed struct(u33) {
1248 a: u7,
1249 b: enum(u10) { x, y, z },
1250 c: f16,
1251 fn doTheTest(s: @This()) !void {
1252 const backing_int = @backingInt(s);
1253 const reconstructed: @This() = @fromBackingInt(backing_int);
1254 try expect(reconstructed == s);
1255 }
1256 };
1257 try S.doTheTest(.{ .a = 123, .b = .y, .c = 0.23 });
1258 try comptime S.doTheTest(.{ .a = 123, .b = .y, .c = 0.23 });
1259}
1260
1261test "equality with wide backing integer" {
1262 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // https://codeberg.org/ziglang/zig/issues/35982
1263
1264 const S = packed struct(i200) {
1265 x: u200,
1266 fn doTheTest(s: @This(), int: i200) !void {
1267 try expect(s == @as(@This(), @bitCast(int)));
1268 }
1269 };
1270 try S.doTheTest(.{ .x = (1 << 200) - 1 }, -1);
1271 try comptime S.doTheTest(.{ .x = (1 << 200) - 1 }, -1);
1272}