blob cd4300c8 (38539B) - Raw
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 const native_endian = builtin.target.cpu.arch.endian(); 4 const expect = std.testing.expect; 5 const expectEqual = std.testing.expectEqual; 6 const expectEqualSlices = std.testing.expectEqualSlices; 7 const maxInt = std.math.maxInt; 8 9 top_level_field: i32, 10 11 test "top level fields" { 12 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 13 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 14 15 var instance = @This(){ 16 .top_level_field = 1234, 17 }; 18 instance.top_level_field += 1; 19 try expect(@as(i32, 1235) == instance.top_level_field); 20 } 21 22 const StructWithFields = struct { 23 a: u8, 24 b: u32, 25 c: u64, 26 d: u32, 27 28 fn first(self: *const StructWithFields) u8 { 29 return self.a; 30 } 31 32 fn second(self: *const StructWithFields) u32 { 33 return self.b; 34 } 35 36 fn third(self: *const StructWithFields) u64 { 37 return self.c; 38 } 39 40 fn fourth(self: *const StructWithFields) u32 { 41 return self.d; 42 } 43 }; 44 45 test "non-packed struct has fields padded out to the required alignment" { 46 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 47 48 const foo = StructWithFields{ .a = 5, .b = 1, .c = 10, .d = 2 }; 49 try expect(foo.first() == 5); 50 try expect(foo.second() == 1); 51 try expect(foo.third() == 10); 52 try expect(foo.fourth() == 2); 53 } 54 55 const SmallStruct = struct { 56 a: u8, 57 b: u8, 58 59 fn first(self: *SmallStruct) u8 { 60 return self.a; 61 } 62 63 fn second(self: *SmallStruct) u8 { 64 return self.b; 65 } 66 }; 67 68 test "lower unnamed constants" { 69 var foo = SmallStruct{ .a = 1, .b = 255 }; 70 try expect(foo.first() == 1); 71 try expect(foo.second() == 255); 72 } 73 74 const StructWithNoFields = struct { 75 fn add(a: i32, b: i32) i32 { 76 return a + b; 77 } 78 }; 79 80 const StructFoo = struct { 81 a: i32, 82 b: bool, 83 c: u64, 84 }; 85 86 test "structs" { 87 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 88 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 89 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 90 91 var foo: StructFoo = undefined; 92 @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo)); 93 foo.a += 1; 94 foo.b = foo.a == 1; 95 try testFoo(foo); 96 testMutation(&foo); 97 try expect(foo.c == 100); 98 } 99 fn testFoo(foo: StructFoo) !void { 100 try expect(foo.b); 101 } 102 fn testMutation(foo: *StructFoo) void { 103 foo.c = 100; 104 } 105 106 test "struct byval assign" { 107 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 109 110 var foo1: StructFoo = undefined; 111 var foo2: StructFoo = undefined; 112 113 foo1.a = 1234; 114 foo2.a = 0; 115 try expect(foo2.a == 0); 116 foo2 = foo1; 117 try expect(foo2.a == 1234); 118 } 119 120 test "call struct static method" { 121 const result = StructWithNoFields.add(3, 4); 122 try expect(result == 7); 123 } 124 125 const should_be_11 = StructWithNoFields.add(5, 6); 126 127 test "invoke static method in global scope" { 128 try expect(should_be_11 == 11); 129 } 130 131 const empty_global_instance = StructWithNoFields{}; 132 133 test "return empty struct instance" { 134 _ = returnEmptyStructInstance(); 135 } 136 fn returnEmptyStructInstance() StructWithNoFields { 137 return empty_global_instance; 138 } 139 140 test "fn call of struct field" { 141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 142 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 143 144 const Foo = struct { 145 ptr: fn () i32, 146 }; 147 const S = struct { 148 fn aFunc() i32 { 149 return 13; 150 } 151 152 fn callStructField(comptime foo: Foo) i32 { 153 return foo.ptr(); 154 } 155 }; 156 157 try expect(S.callStructField(Foo{ .ptr = S.aFunc }) == 13); 158 } 159 160 test "struct initializer" { 161 const val = Val{ .x = 42 }; 162 try expect(val.x == 42); 163 } 164 165 const MemberFnTestFoo = struct { 166 x: i32, 167 fn member(foo: MemberFnTestFoo) i32 { 168 return foo.x; 169 } 170 }; 171 172 test "call member function directly" { 173 const instance = MemberFnTestFoo{ .x = 1234 }; 174 const result = MemberFnTestFoo.member(instance); 175 try expect(result == 1234); 176 } 177 178 test "store member function in variable" { 179 const instance = MemberFnTestFoo{ .x = 1234 }; 180 const memberFn = MemberFnTestFoo.member; 181 const result = memberFn(instance); 182 try expect(result == 1234); 183 } 184 185 test "member functions" { 186 const r = MemberFnRand{ .seed = 1234 }; 187 try expect(r.getSeed() == 1234); 188 } 189 const MemberFnRand = struct { 190 seed: u32, 191 pub fn getSeed(r: *const MemberFnRand) u32 { 192 return r.seed; 193 } 194 }; 195 196 test "return struct byval from function" { 197 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 198 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 199 200 const bar = makeBar2(1234, 5678); 201 try expect(bar.y == 5678); 202 } 203 const Bar = struct { 204 x: i32, 205 y: i32, 206 }; 207 fn makeBar2(x: i32, y: i32) Bar { 208 return Bar{ 209 .x = x, 210 .y = y, 211 }; 212 } 213 214 test "call method with mutable reference to struct with no fields" { 215 const S = struct { 216 fn doC(s: *const @This()) bool { 217 _ = s; 218 return true; 219 } 220 fn do(s: *@This()) bool { 221 _ = s; 222 return true; 223 } 224 }; 225 226 var s = S{}; 227 try expect(S.doC(&s)); 228 try expect(s.doC()); 229 try expect(S.do(&s)); 230 try expect(s.do()); 231 } 232 233 test "usingnamespace within struct scope" { 234 const S = struct { 235 usingnamespace struct { 236 pub fn inner() i32 { 237 return 42; 238 } 239 }; 240 }; 241 try expect(@as(i32, 42) == S.inner()); 242 } 243 244 test "struct field init with catch" { 245 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 246 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 247 248 const S = struct { 249 fn doTheTest() !void { 250 var x: anyerror!isize = 1; 251 var req = Foo{ 252 .field = x catch undefined, 253 }; 254 try expect(req.field == 1); 255 } 256 257 pub const Foo = extern struct { 258 field: isize, 259 }; 260 }; 261 try S.doTheTest(); 262 comptime try S.doTheTest(); 263 } 264 265 const blah: packed struct { 266 a: u3, 267 b: u3, 268 c: u2, 269 } = undefined; 270 271 test "bit field alignment" { 272 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 273 try expect(@TypeOf(&blah.b) == *align(1:3:1) const u3); 274 } 275 276 const Node = struct { 277 val: Val, 278 next: *Node, 279 }; 280 281 const Val = struct { 282 x: i32, 283 }; 284 285 test "struct point to self" { 286 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 287 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 288 289 var root: Node = undefined; 290 root.val.x = 1; 291 292 var node: Node = undefined; 293 node.next = &root; 294 node.val.x = 2; 295 296 root.next = &node; 297 298 try expect(node.next.next.next.val.x == 1); 299 } 300 301 test "void struct fields" { 302 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 303 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 304 305 const foo = VoidStructFieldsFoo{ 306 .a = void{}, 307 .b = 1, 308 .c = void{}, 309 }; 310 try expect(foo.b == 1); 311 try expect(@sizeOf(VoidStructFieldsFoo) == 4); 312 } 313 const VoidStructFieldsFoo = struct { 314 a: void, 315 b: i32, 316 c: void, 317 }; 318 319 test "return empty struct from fn" { 320 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 321 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 322 323 _ = testReturnEmptyStructFromFn(); 324 } 325 const EmptyStruct2 = struct {}; 326 fn testReturnEmptyStructFromFn() EmptyStruct2 { 327 return EmptyStruct2{}; 328 } 329 330 test "pass slice of empty struct to fn" { 331 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 332 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 333 334 try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1); 335 } 336 fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize { 337 return slice.len; 338 } 339 340 test "self-referencing struct via array member" { 341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 343 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 344 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 345 346 const T = struct { 347 children: [1]*@This(), 348 }; 349 var x: T = undefined; 350 x = T{ .children = .{&x} }; 351 try expect(x.children[0] == &x); 352 } 353 354 test "empty struct method call" { 355 const es = EmptyStruct{}; 356 try expect(es.method() == 1234); 357 } 358 const EmptyStruct = struct { 359 fn method(es: *const EmptyStruct) i32 { 360 _ = es; 361 return 1234; 362 } 363 }; 364 365 test "align 1 field before self referential align 8 field as slice return type" { 366 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 367 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 368 369 const result = alloc(Expr); 370 try expect(result.len == 0); 371 } 372 373 const Expr = union(enum) { 374 Literal: u8, 375 Question: *Expr, 376 }; 377 378 fn alloc(comptime T: type) []T { 379 return &[_]T{}; 380 } 381 382 const APackedStruct = packed struct { 383 x: u8, 384 y: u8, 385 }; 386 387 test "packed struct" { 388 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 389 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 390 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 391 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 392 393 var foo = APackedStruct{ 394 .x = 1, 395 .y = 2, 396 }; 397 foo.y += 1; 398 const four = foo.x + foo.y; 399 try expect(four == 4); 400 } 401 402 const Foo24Bits = packed struct { 403 field: u24, 404 }; 405 const Foo96Bits = packed struct { 406 a: u24, 407 b: u24, 408 c: u24, 409 d: u24, 410 }; 411 412 test "packed struct 24bits" { 413 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 414 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 415 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 416 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 417 if (builtin.cpu.arch == .wasm32) return error.SkipZigTest; // TODO 418 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO 419 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 420 421 comptime { 422 std.debug.assert(@sizeOf(Foo24Bits) == @sizeOf(u24)); 423 std.debug.assert(@sizeOf(Foo96Bits) == @sizeOf(u96)); 424 } 425 426 var value = Foo96Bits{ 427 .a = 0, 428 .b = 0, 429 .c = 0, 430 .d = 0, 431 }; 432 value.a += 1; 433 try expect(value.a == 1); 434 try expect(value.b == 0); 435 try expect(value.c == 0); 436 try expect(value.d == 0); 437 438 value.b += 1; 439 try expect(value.a == 1); 440 try expect(value.b == 1); 441 try expect(value.c == 0); 442 try expect(value.d == 0); 443 444 value.c += 1; 445 try expect(value.a == 1); 446 try expect(value.b == 1); 447 try expect(value.c == 1); 448 try expect(value.d == 0); 449 450 value.d += 1; 451 try expect(value.a == 1); 452 try expect(value.b == 1); 453 try expect(value.c == 1); 454 try expect(value.d == 1); 455 } 456 457 test "runtime struct initialization of bitfield" { 458 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 459 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 460 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 461 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 462 463 const s1 = Nibbles{ 464 .x = x1, 465 .y = x1, 466 }; 467 const s2 = Nibbles{ 468 .x = @intCast(u4, x2), 469 .y = @intCast(u4, x2), 470 }; 471 472 try expect(s1.x == x1); 473 try expect(s1.y == x1); 474 try expect(s2.x == @intCast(u4, x2)); 475 try expect(s2.y == @intCast(u4, x2)); 476 } 477 478 var x1 = @as(u4, 1); 479 var x2 = @as(u8, 2); 480 481 const Nibbles = packed struct { 482 x: u4, 483 y: u4, 484 }; 485 486 const Bitfields = packed struct { 487 f1: u16, 488 f2: u16, 489 f3: u8, 490 f4: u8, 491 f5: u4, 492 f6: u4, 493 f7: u8, 494 }; 495 496 test "packed struct fields are ordered from LSB to MSB" { 497 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 498 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 499 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 501 502 var all: u64 = 0x7765443322221111; 503 var bytes: [8]u8 align(@alignOf(Bitfields)) = undefined; 504 @memcpy(&bytes, @ptrCast([*]u8, &all), 8); 505 var bitfields = @ptrCast(*Bitfields, &bytes).*; 506 507 try expect(bitfields.f1 == 0x1111); 508 try expect(bitfields.f2 == 0x2222); 509 try expect(bitfields.f3 == 0x33); 510 try expect(bitfields.f4 == 0x44); 511 try expect(bitfields.f5 == 0x5); 512 try expect(bitfields.f6 == 0x6); 513 try expect(bitfields.f7 == 0x77); 514 } 515 516 test "implicit cast packed struct field to const ptr" { 517 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 518 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 519 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 520 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 521 522 const LevelUpMove = packed struct { 523 move_id: u9, 524 level: u7, 525 526 fn toInt(value: u7) u7 { 527 return value; 528 } 529 }; 530 531 var lup: LevelUpMove = undefined; 532 lup.level = 12; 533 const res = LevelUpMove.toInt(lup.level); 534 try expect(res == 12); 535 } 536 537 test "zero-bit field in packed struct" { 538 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 539 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 540 541 const S = packed struct { 542 x: u10, 543 y: void, 544 }; 545 var x: S = undefined; 546 _ = x; 547 } 548 549 test "packed struct with non-ABI-aligned field" { 550 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 551 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 552 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 553 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO 554 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 555 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 556 557 const S = packed struct { 558 x: u9, 559 y: u183, 560 }; 561 var s: S = undefined; 562 s.x = 1; 563 s.y = 42; 564 try expect(s.x == 1); 565 try expect(s.y == 42); 566 } 567 568 const BitField1 = packed struct { 569 a: u3, 570 b: u3, 571 c: u2, 572 }; 573 574 const bit_field_1 = BitField1{ 575 .a = 1, 576 .b = 2, 577 .c = 3, 578 }; 579 580 test "bit field access" { 581 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 582 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 583 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 584 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 585 586 var data = bit_field_1; 587 try expect(getA(&data) == 1); 588 try expect(getB(&data) == 2); 589 try expect(getC(&data) == 3); 590 comptime try expect(@sizeOf(BitField1) == 1); 591 592 data.b += 1; 593 try expect(data.b == 3); 594 595 data.a += 1; 596 try expect(data.a == 2); 597 try expect(data.b == 3); 598 } 599 600 fn getA(data: *const BitField1) u3 { 601 return data.a; 602 } 603 604 fn getB(data: *const BitField1) u3 { 605 return data.b; 606 } 607 608 fn getC(data: *const BitField1) u2 { 609 return data.c; 610 } 611 612 test "default struct initialization fields" { 613 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 614 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 615 616 const S = struct { 617 a: i32 = 1234, 618 b: i32, 619 }; 620 const x = S{ 621 .b = 5, 622 }; 623 var five: i32 = 5; 624 const y = S{ 625 .b = five, 626 }; 627 if (x.a + x.b != 1239) { 628 @compileError("it should be comptime-known"); 629 } 630 try expect(y.a == x.a); 631 try expect(y.b == x.b); 632 try expect(1239 == x.a + x.b); 633 } 634 635 test "packed array 24bits" { 636 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; 637 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 638 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 639 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 640 641 comptime { 642 try expect(@sizeOf([9]Foo32Bits) == 9 * 4); 643 try expect(@sizeOf(FooArray24Bits) == @sizeOf(u96)); 644 } 645 646 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1); 647 bytes[bytes.len - 1] = 0xbb; 648 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0]; 649 try expect(ptr.a == 0); 650 try expect(ptr.b0.field == 0); 651 try expect(ptr.b1.field == 0); 652 try expect(ptr.c == 0); 653 654 ptr.a = maxInt(u16); 655 try expect(ptr.a == maxInt(u16)); 656 try expect(ptr.b0.field == 0); 657 try expect(ptr.b1.field == 0); 658 try expect(ptr.c == 0); 659 660 ptr.b0.field = maxInt(u24); 661 try expect(ptr.a == maxInt(u16)); 662 try expect(ptr.b0.field == maxInt(u24)); 663 try expect(ptr.b1.field == 0); 664 try expect(ptr.c == 0); 665 666 ptr.b1.field = maxInt(u24); 667 try expect(ptr.a == maxInt(u16)); 668 try expect(ptr.b0.field == maxInt(u24)); 669 try expect(ptr.b1.field == maxInt(u24)); 670 try expect(ptr.c == 0); 671 672 ptr.c = maxInt(u16); 673 try expect(ptr.a == maxInt(u16)); 674 try expect(ptr.b0.field == maxInt(u24)); 675 try expect(ptr.b1.field == maxInt(u24)); 676 try expect(ptr.c == maxInt(u16)); 677 678 try expect(bytes[bytes.len - 1] == 0xbb); 679 } 680 681 const Foo32Bits = packed struct { 682 field: u24, 683 pad: u8, 684 }; 685 686 const FooArray24Bits = packed struct { 687 a: u16, 688 b0: Foo32Bits, 689 b1: Foo32Bits, 690 c: u16, 691 }; 692 693 const FooStructAligned = packed struct { 694 a: u8, 695 b: u8, 696 }; 697 698 const FooArrayOfAligned = packed struct { 699 a: [2]FooStructAligned, 700 }; 701 702 test "pointer to packed struct member in a stack variable" { 703 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 704 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 705 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 706 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 707 708 const S = packed struct { 709 a: u2, 710 b: u2, 711 }; 712 713 var s = S{ .a = 2, .b = 0 }; 714 var b_ptr = &s.b; 715 try expect(s.b == 0); 716 b_ptr.* = 2; 717 try expect(s.b == 2); 718 } 719 720 test "packed struct with u0 field access" { 721 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 722 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 723 724 const S = packed struct { 725 f0: u0, 726 }; 727 var s = S{ .f0 = 0 }; 728 comptime try expect(s.f0 == 0); 729 } 730 731 test "access to global struct fields" { 732 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 733 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 734 735 g_foo.bar.value = 42; 736 try expect(g_foo.bar.value == 42); 737 } 738 739 const S0 = struct { 740 bar: S1, 741 742 pub const S1 = struct { 743 value: u8, 744 }; 745 746 fn init() @This() { 747 return S0{ .bar = S1{ .value = 123 } }; 748 } 749 }; 750 751 var g_foo: S0 = S0.init(); 752 753 test "packed struct with fp fields" { 754 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 755 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 756 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 757 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 758 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 759 760 const S = packed struct { 761 data0: f32, 762 data1: f32, 763 data2: f32, 764 765 pub fn frob(self: *@This()) void { 766 self.data0 += self.data1 + self.data2; 767 self.data1 += self.data0 + self.data2; 768 self.data2 += self.data0 + self.data1; 769 } 770 }; 771 772 var s: S = undefined; 773 s.data0 = 1.0; 774 s.data1 = 2.0; 775 s.data2 = 3.0; 776 s.frob(); 777 try expect(@as(f32, 6.0) == s.data0); 778 try expect(@as(f32, 11.0) == s.data1); 779 try expect(@as(f32, 20.0) == s.data2); 780 } 781 782 test "fn with C calling convention returns struct by value" { 783 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 784 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 785 786 const S = struct { 787 fn entry() !void { 788 var x = makeBar(10); 789 try expect(@as(i32, 10) == x.handle); 790 } 791 792 const ExternBar = extern struct { 793 handle: i32, 794 }; 795 796 fn makeBar(t: i32) callconv(.C) ExternBar { 797 return ExternBar{ 798 .handle = t, 799 }; 800 } 801 }; 802 try S.entry(); 803 comptime try S.entry(); 804 } 805 806 test "non-packed struct with u128 entry in union" { 807 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 808 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 809 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 810 811 const U = union(enum) { 812 Num: u128, 813 Void, 814 }; 815 816 const S = struct { 817 f1: U, 818 f2: U, 819 }; 820 821 var sx: S = undefined; 822 var s = &sx; 823 try expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2")); 824 var v2 = U{ .Num = 123 }; 825 s.f2 = v2; 826 try expect(s.f2.Num == 123); 827 } 828 829 test "packed struct field passed to generic function" { 830 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 831 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 832 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 833 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 834 835 const S = struct { 836 const P = packed struct { 837 b: u5, 838 g: u5, 839 r: u5, 840 a: u1, 841 }; 842 843 fn genericReadPackedField(ptr: anytype) u5 { 844 return ptr.*; 845 } 846 }; 847 848 var p: S.P = undefined; 849 p.b = 29; 850 var loaded = S.genericReadPackedField(&p.b); 851 try expect(loaded == 29); 852 } 853 854 test "anonymous struct literal syntax" { 855 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 856 857 const S = struct { 858 const Point = struct { 859 x: i32, 860 y: i32, 861 }; 862 863 fn doTheTest() !void { 864 var p: Point = .{ 865 .x = 1, 866 .y = 2, 867 }; 868 try expect(p.x == 1); 869 try expect(p.y == 2); 870 } 871 }; 872 try S.doTheTest(); 873 comptime try S.doTheTest(); 874 } 875 876 test "fully anonymous struct" { 877 const S = struct { 878 fn doTheTest() !void { 879 try dump(.{ 880 .int = @as(u32, 1234), 881 .float = @as(f64, 12.34), 882 .b = true, 883 .s = "hi", 884 }); 885 } 886 fn dump(args: anytype) !void { 887 try expect(args.int == 1234); 888 try expect(args.float == 12.34); 889 try expect(args.b); 890 try expect(args.s[0] == 'h'); 891 try expect(args.s[1] == 'i'); 892 } 893 }; 894 try S.doTheTest(); 895 comptime try S.doTheTest(); 896 } 897 898 test "fully anonymous list literal" { 899 const S = struct { 900 fn doTheTest() !void { 901 try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" }); 902 } 903 fn dump(args: anytype) !void { 904 try expect(args.@"0" == 1234); 905 try expect(args.@"1" == 12.34); 906 try expect(args.@"2"); 907 try expect(args.@"3"[0] == 'h'); 908 try expect(args.@"3"[1] == 'i'); 909 } 910 }; 911 try S.doTheTest(); 912 comptime try S.doTheTest(); 913 } 914 915 test "tuple assigned to variable" { 916 var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) }; 917 try expect(vec.@"0" == 22); 918 try expect(vec.@"1" == 55); 919 try expect(vec.@"2" == 99); 920 try expect(vec[0] == 22); 921 try expect(vec[1] == 55); 922 try expect(vec[2] == 99); 923 } 924 925 test "comptime struct field" { 926 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 927 if (builtin.cpu.arch == .arm) return error.SkipZigTest; // TODO 928 929 const T = struct { 930 a: i32, 931 comptime b: i32 = 1234, 932 }; 933 934 comptime std.debug.assert(@sizeOf(T) == 4); 935 936 var foo: T = undefined; 937 comptime try expect(foo.b == 1234); 938 } 939 940 test "tuple element initialized with fn call" { 941 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 942 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 943 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 944 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 945 946 const S = struct { 947 fn doTheTest() !void { 948 var x = .{foo()}; 949 try expectEqualSlices(u8, x[0], "hi"); 950 } 951 fn foo() []const u8 { 952 return "hi"; 953 } 954 }; 955 try S.doTheTest(); 956 comptime try S.doTheTest(); 957 } 958 959 test "struct with union field" { 960 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 961 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 962 963 const Value = struct { 964 ref: u32 = 2, 965 kind: union(enum) { 966 None: usize, 967 Bool: bool, 968 }, 969 }; 970 971 var True = Value{ 972 .kind = .{ .Bool = true }, 973 }; 974 try expect(@as(u32, 2) == True.ref); 975 try expect(True.kind.Bool); 976 } 977 978 test "type coercion of anon struct literal to struct" { 979 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 980 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 981 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 982 983 const S = struct { 984 const S2 = struct { 985 A: u32, 986 B: []const u8, 987 C: void, 988 D: Foo = .{}, 989 }; 990 991 const Foo = struct { 992 field: i32 = 1234, 993 }; 994 995 fn doTheTest() !void { 996 var y: u32 = 42; 997 const t0 = .{ .A = 123, .B = "foo", .C = {} }; 998 const t1 = .{ .A = y, .B = "foo", .C = {} }; 999 const y0: S2 = t0; 1000 var y1: S2 = t1; 1001 try expect(y0.A == 123); 1002 try expect(std.mem.eql(u8, y0.B, "foo")); 1003 try expect(y0.C == {}); 1004 try expect(y0.D.field == 1234); 1005 try expect(y1.A == y); 1006 try expect(std.mem.eql(u8, y1.B, "foo")); 1007 try expect(y1.C == {}); 1008 try expect(y1.D.field == 1234); 1009 } 1010 }; 1011 try S.doTheTest(); 1012 comptime try S.doTheTest(); 1013 } 1014 1015 test "type coercion of pointer to anon struct literal to pointer to struct" { 1016 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1017 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1018 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1019 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1020 1021 const S = struct { 1022 const S2 = struct { 1023 A: u32, 1024 B: []const u8, 1025 C: void, 1026 D: Foo = .{}, 1027 }; 1028 1029 const Foo = struct { 1030 field: i32 = 1234, 1031 }; 1032 1033 fn doTheTest() !void { 1034 var y: u32 = 42; 1035 const t0 = &.{ .A = 123, .B = "foo", .C = {} }; 1036 const t1 = &.{ .A = y, .B = "foo", .C = {} }; 1037 const y0: *const S2 = t0; 1038 var y1: *const S2 = t1; 1039 try expect(y0.A == 123); 1040 try expect(std.mem.eql(u8, y0.B, "foo")); 1041 try expect(y0.C == {}); 1042 try expect(y0.D.field == 1234); 1043 try expect(y1.A == y); 1044 try expect(std.mem.eql(u8, y1.B, "foo")); 1045 try expect(y1.C == {}); 1046 try expect(y1.D.field == 1234); 1047 } 1048 }; 1049 try S.doTheTest(); 1050 comptime try S.doTheTest(); 1051 } 1052 1053 test "packed struct with undefined initializers" { 1054 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1055 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 1056 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1057 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1058 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1059 1060 const S = struct { 1061 const P = packed struct { 1062 a: u3, 1063 _a: u3 = undefined, 1064 b: u3, 1065 _b: u3 = undefined, 1066 c: u3, 1067 _c: u3 = undefined, 1068 }; 1069 1070 fn doTheTest() !void { 1071 var p: P = undefined; 1072 p = P{ .a = 2, .b = 4, .c = 6 }; 1073 // Make sure the compiler doesn't touch the unprefixed fields. 1074 // Use expect since x86-linux doesn't like expectEqual 1075 try expect(p.a == 2); 1076 try expect(p.b == 4); 1077 try expect(p.c == 6); 1078 } 1079 }; 1080 1081 try S.doTheTest(); 1082 comptime try S.doTheTest(); 1083 } 1084 1085 test "for loop over pointers to struct, getting field from struct pointer" { 1086 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1087 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1088 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1089 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1090 1091 const S = struct { 1092 const Foo = struct { 1093 name: []const u8, 1094 }; 1095 1096 var ok = true; 1097 1098 fn eql(a: []const u8) bool { 1099 _ = a; 1100 return true; 1101 } 1102 1103 const ArrayList = struct { 1104 fn toSlice(self: *ArrayList) []*Foo { 1105 _ = self; 1106 return @as([*]*Foo, undefined)[0..0]; 1107 } 1108 }; 1109 1110 fn doTheTest() !void { 1111 var objects: ArrayList = undefined; 1112 1113 for (objects.toSlice()) |obj| { 1114 if (eql(obj.name)) { 1115 ok = false; 1116 } 1117 } 1118 1119 try expect(ok); 1120 } 1121 }; 1122 try S.doTheTest(); 1123 } 1124 1125 test "anon init through error unions and optionals" { 1126 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1130 1131 const S = struct { 1132 a: u32, 1133 1134 fn foo() anyerror!?anyerror!@This() { 1135 return .{ .a = 1 }; 1136 } 1137 fn bar() ?anyerror![2]u8 { 1138 return .{ 1, 2 }; 1139 } 1140 1141 fn doTheTest() !void { 1142 var a = try (try foo()).?; 1143 var b = try bar().?; 1144 try expect(a.a + b[1] == 3); 1145 } 1146 }; 1147 1148 try S.doTheTest(); 1149 comptime try S.doTheTest(); 1150 } 1151 1152 test "anon init through optional" { 1153 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1154 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1155 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1157 1158 const S = struct { 1159 a: u32, 1160 1161 fn doTheTest() !void { 1162 var s: ?@This() = null; 1163 s = .{ .a = 1 }; 1164 try expect(s.?.a == 1); 1165 } 1166 }; 1167 1168 try S.doTheTest(); 1169 comptime try S.doTheTest(); 1170 } 1171 1172 test "anon init through error union" { 1173 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1174 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1175 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1177 1178 const S = struct { 1179 a: u32, 1180 1181 fn doTheTest() !void { 1182 var s: anyerror!@This() = error.Foo; 1183 s = .{ .a = 1 }; 1184 try expect((try s).a == 1); 1185 } 1186 }; 1187 1188 try S.doTheTest(); 1189 comptime try S.doTheTest(); 1190 } 1191 1192 test "typed init through error unions and optionals" { 1193 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1194 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1195 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1196 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1197 1198 const S = struct { 1199 a: u32, 1200 1201 fn foo() anyerror!?anyerror!@This() { 1202 return @This(){ .a = 1 }; 1203 } 1204 fn bar() ?anyerror![2]u8 { 1205 return [2]u8{ 1, 2 }; 1206 } 1207 1208 fn doTheTest() !void { 1209 var a = try (try foo()).?; 1210 var b = try bar().?; 1211 try expect(a.a + b[1] == 3); 1212 } 1213 }; 1214 1215 try S.doTheTest(); 1216 comptime try S.doTheTest(); 1217 } 1218 1219 test "initialize struct with empty literal" { 1220 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1222 1223 const S = struct { x: i32 = 1234 }; 1224 var s: S = .{}; 1225 try expect(s.x == 1234); 1226 } 1227 1228 test "loading a struct pointer perfoms a copy" { 1229 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1230 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1231 1232 const S = struct { 1233 a: i32, 1234 b: i32, 1235 c: i32, 1236 1237 fn swap(a: *@This(), b: *@This()) void { 1238 const tmp = a.*; 1239 a.* = b.*; 1240 b.* = tmp; 1241 } 1242 }; 1243 var s1: S = .{ .a = 1, .b = 2, .c = 3 }; 1244 var s2: S = .{ .a = 4, .b = 5, .c = 6 }; 1245 S.swap(&s1, &s2); 1246 try expect(s1.a == 4); 1247 try expect(s1.b == 5); 1248 try expect(s1.c == 6); 1249 try expect(s2.a == 1); 1250 try expect(s2.b == 2); 1251 try expect(s2.c == 3); 1252 } 1253 1254 test "packed struct aggregate init" { 1255 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1256 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1257 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1258 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1259 1260 const S = struct { 1261 fn foo(a: i2, b: i6) u8 { 1262 return @bitCast(u8, P{ .a = a, .b = b }); 1263 } 1264 1265 const P = packed struct { 1266 a: i2, 1267 b: i6, 1268 }; 1269 }; 1270 const result = @bitCast(u8, S.foo(1, 2)); 1271 try expect(result == 9); 1272 } 1273 1274 test "packed struct field access via pointer" { 1275 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1276 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1277 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1278 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1279 1280 const S = struct { 1281 fn doTheTest() !void { 1282 const S = packed struct { a: u30 }; 1283 var s1: S = .{ .a = 1 }; 1284 var s2 = &s1; 1285 try expect(s2.a == 1); 1286 var s3: S = undefined; 1287 var s4 = &s3; 1288 _ = s4; 1289 } 1290 }; 1291 try S.doTheTest(); 1292 comptime try S.doTheTest(); 1293 } 1294 1295 test "store to comptime field" { 1296 { 1297 const S = struct { 1298 comptime a: [2]u32 = [2]u32{ 1, 2 }, 1299 }; 1300 var s: S = .{}; 1301 s.a = [2]u32{ 1, 2 }; 1302 s.a[0] = 1; 1303 } 1304 { 1305 const T = struct { a: u32, b: u32 }; 1306 const S = struct { 1307 comptime a: T = T{ .a = 1, .b = 2 }, 1308 }; 1309 var s: S = .{}; 1310 s.a = T{ .a = 1, .b = 2 }; 1311 s.a.a = 1; 1312 } 1313 } 1314 1315 test "struct field init value is size of the struct" { 1316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1317 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1318 1319 const namespace = struct { 1320 const S = extern struct { 1321 size: u8 = @sizeOf(S), 1322 blah: u16, 1323 }; 1324 }; 1325 var s: namespace.S = .{ .blah = 1234 }; 1326 try expect(s.size == 4); 1327 } 1328 1329 test "under-aligned struct field" { 1330 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO 1331 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1332 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1333 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1334 1335 const U = extern union { 1336 fd: i32, 1337 u32: u32, 1338 u64: u64, 1339 }; 1340 const S = extern struct { 1341 events: u32, 1342 data: U align(4), 1343 }; 1344 var runtime: usize = 1234; 1345 const ptr = &S{ .events = 0, .data = .{ .u64 = runtime } }; 1346 const array = @ptrCast(*const [12]u8, ptr); 1347 const result = std.mem.readIntNative(u64, array[4..12]); 1348 try expect(result == 1234); 1349 } 1350 1351 test "address of zero-bit field is equal to address of only field" { 1352 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 1353 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1354 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1355 1356 { 1357 const A = struct { b: void = {}, u: u8 }; 1358 var a = A{ .u = 0 }; 1359 const a_ptr = @fieldParentPtr(A, "b", &a.b); 1360 try std.testing.expectEqual(&a, a_ptr); 1361 } 1362 { 1363 const A = struct { u: u8, b: void = {} }; 1364 var a = A{ .u = 0 }; 1365 const a_ptr = @fieldParentPtr(A, "b", &a.b); 1366 try std.testing.expectEqual(&a, a_ptr); 1367 } 1368 } 1369 1370 test "struct field has a pointer to an aligned version of itself" { 1371 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1372 1373 const E = struct { 1374 next: *align(1) @This(), 1375 }; 1376 var e: E = undefined; 1377 e = .{ .next = &e }; 1378 1379 try expect(&e == e.next); 1380 }