test/behavior/basic.zig (32284B) - Raw
1 const std = @import("std"); 2 const builtin = @import("builtin"); 3 const assert = std.debug.assert; 4 const mem = std.mem; 5 const expect = std.testing.expect; 6 const expectEqualStrings = std.testing.expectEqualStrings; 7 8 // normal comment 9 10 /// this is a documentation comment 11 /// doc comment line 2 12 fn emptyFunctionWithComments() void {} 13 14 test "empty function with comments" { 15 emptyFunctionWithComments(); 16 } 17 18 test "truncate" { 19 try expect(testTruncate(0x10fd) == 0xfd); 20 comptime try expect(testTruncate(0x10fd) == 0xfd); 21 } 22 fn testTruncate(x: u32) u8 { 23 return @truncate(u8, x); 24 } 25 26 test "truncate to non-power-of-two integers" { 27 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 28 29 try testTrunc(u32, u1, 0b10101, 0b1); 30 try testTrunc(u32, u1, 0b10110, 0b0); 31 try testTrunc(u32, u2, 0b10101, 0b01); 32 try testTrunc(u32, u2, 0b10110, 0b10); 33 try testTrunc(i32, i5, -4, -4); 34 try testTrunc(i32, i5, 4, 4); 35 try testTrunc(i32, i5, -28, 4); 36 try testTrunc(i32, i5, 28, -4); 37 try testTrunc(i32, i5, std.math.maxInt(i32), -1); 38 } 39 40 test "truncate to non-power-of-two integers from 128-bit" { 41 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 42 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 43 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 44 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 45 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 46 47 try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010101, 0x01); 48 try testTrunc(u128, u1, 0xffffffff_ffffffff_ffffffff_01010110, 0x00); 49 try testTrunc(u128, u2, 0xffffffff_ffffffff_ffffffff_01010101, 0x01); 50 try testTrunc(u128, u2, 0xffffffff_ffffffff_ffffffff_01010102, 0x02); 51 try testTrunc(i128, i5, -4, -4); 52 try testTrunc(i128, i5, 4, 4); 53 try testTrunc(i128, i5, -28, 4); 54 try testTrunc(i128, i5, 28, -4); 55 try testTrunc(i128, i5, std.math.maxInt(i128), -1); 56 } 57 58 fn testTrunc(comptime Big: type, comptime Little: type, big: Big, little: Little) !void { 59 try expect(@truncate(Little, big) == little); 60 } 61 62 const g1: i32 = 1233 + 1; 63 var g2: i32 = 0; 64 65 test "global variables" { 66 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 67 68 try expect(g2 == 0); 69 g2 = g1; 70 try expect(g2 == 1234); 71 } 72 73 test "comptime keyword on expressions" { 74 const x: i32 = comptime x: { 75 break :x 1 + 2 + 3; 76 }; 77 try expect(x == comptime 6); 78 } 79 80 test "type equality" { 81 try expect(*const u8 != *u8); 82 } 83 84 test "pointer dereferencing" { 85 var x = @as(i32, 3); 86 const y = &x; 87 88 y.* += 1; 89 90 try expect(x == 4); 91 try expect(y.* == 4); 92 } 93 94 test "const expression eval handling of variables" { 95 var x = true; 96 while (x) { 97 x = false; 98 } 99 } 100 101 test "character literals" { 102 try expect('\'' == single_quote); 103 } 104 const single_quote = '\''; 105 106 test "non const ptr to aliased type" { 107 const int = i32; 108 try expect(?*int == ?*i32); 109 } 110 111 test "cold function" { 112 thisIsAColdFn(); 113 comptime thisIsAColdFn(); 114 } 115 116 fn thisIsAColdFn() void { 117 @setCold(true); 118 } 119 120 test "unicode escape in character literal" { 121 var a: u24 = '\u{01f4a9}'; 122 try expect(a == 128169); 123 } 124 125 test "unicode character in character literal" { 126 try expect('💩' == 128169); 127 } 128 129 fn first4KeysOfHomeRow() []const u8 { 130 return "aoeu"; 131 } 132 133 test "return string from function" { 134 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 135 136 try expect(mem.eql(u8, first4KeysOfHomeRow(), "aoeu")); 137 } 138 139 test "hex escape" { 140 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 141 142 try expect(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello")); 143 } 144 145 test "multiline string" { 146 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 147 148 const s1 = 149 \\one 150 \\two) 151 \\three 152 ; 153 const s2 = "one\ntwo)\nthree"; 154 try expect(mem.eql(u8, s1, s2)); 155 } 156 157 test "multiline string comments at start" { 158 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 159 160 const s1 = 161 //\\one 162 \\two) 163 \\three 164 ; 165 const s2 = "two)\nthree"; 166 try expect(mem.eql(u8, s1, s2)); 167 } 168 169 test "multiline string comments at end" { 170 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 171 172 const s1 = 173 \\one 174 \\two) 175 //\\three 176 ; 177 const s2 = "one\ntwo)"; 178 try expect(mem.eql(u8, s1, s2)); 179 } 180 181 test "multiline string comments in middle" { 182 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 183 184 const s1 = 185 \\one 186 //\\two) 187 \\three 188 ; 189 const s2 = "one\nthree"; 190 try expect(mem.eql(u8, s1, s2)); 191 } 192 193 test "multiline string comments at multiple places" { 194 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 195 196 const s1 = 197 \\one 198 //\\two 199 \\three 200 //\\four 201 \\five 202 ; 203 const s2 = "one\nthree\nfive"; 204 try expect(mem.eql(u8, s1, s2)); 205 } 206 207 test "string concatenation simple" { 208 try expect(mem.eql(u8, "OK" ++ " IT " ++ "WORKED", "OK IT WORKED")); 209 } 210 211 test "array mult operator" { 212 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 213 214 try expect(mem.eql(u8, "ab" ** 5, "ababababab")); 215 } 216 217 const OpaqueA = opaque {}; 218 const OpaqueB = opaque {}; 219 220 test "opaque types" { 221 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 222 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 223 224 try expect(*OpaqueA != *OpaqueB); 225 226 try expect(mem.eql(u8, @typeName(OpaqueA), "behavior.basic.OpaqueA")); 227 try expect(mem.eql(u8, @typeName(OpaqueB), "behavior.basic.OpaqueB")); 228 } 229 230 const global_a: i32 = 1234; 231 const global_b: *const i32 = &global_a; 232 const global_c: *const f32 = @ptrCast(*const f32, global_b); 233 test "compile time global reinterpret" { 234 const d = @ptrCast(*const i32, global_c); 235 try expect(d.* == 1234); 236 } 237 238 test "cast undefined" { 239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 240 241 const array: [100]u8 = undefined; 242 const slice = @as([]const u8, &array); 243 testCastUndefined(slice); 244 } 245 fn testCastUndefined(x: []const u8) void { 246 _ = x; 247 } 248 249 test "implicit cast after unreachable" { 250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 252 253 try expect(outer() == 1234); 254 } 255 fn inner() i32 { 256 return 1234; 257 } 258 fn outer() i64 { 259 return inner(); 260 } 261 262 test "comptime if inside runtime while which unconditionally breaks" { 263 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); 264 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true); 265 } 266 fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void { 267 while (cond) { 268 if (false) {} 269 break; 270 } 271 } 272 273 test "implicit comptime while" { 274 while (false) { 275 @compileError("bad"); 276 } 277 } 278 279 fn fnThatClosesOverLocalConst() type { 280 const c = 1; 281 return struct { 282 fn g() i32 { 283 return c; 284 } 285 }; 286 } 287 288 test "function closes over local const" { 289 const x = fnThatClosesOverLocalConst().g(); 290 try expect(x == 1); 291 } 292 293 test "volatile load and store" { 294 var number: i32 = 1234; 295 const ptr = @as(*volatile i32, &number); 296 ptr.* += 1; 297 try expect(ptr.* == 1235); 298 } 299 300 fn fA() []const u8 { 301 return "a"; 302 } 303 fn fB() []const u8 { 304 return "b"; 305 } 306 307 test "call function pointer in struct" { 308 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 309 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 310 311 try expect(mem.eql(u8, f3(true), "a")); 312 try expect(mem.eql(u8, f3(false), "b")); 313 } 314 315 fn f3(x: bool) []const u8 { 316 var wrapper: FnPtrWrapper = .{ 317 .fn_ptr = fB, 318 }; 319 320 if (x) { 321 wrapper.fn_ptr = fA; 322 } 323 324 return wrapper.fn_ptr(); 325 } 326 327 const FnPtrWrapper = struct { 328 fn_ptr: *const fn () []const u8, 329 }; 330 331 test "const ptr from var variable" { 332 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 333 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 334 335 var x: u64 = undefined; 336 var y: u64 = undefined; 337 338 x = 78; 339 copy(&x, &y); 340 341 try expect(x == y); 342 } 343 344 fn copy(src: *const u64, dst: *u64) void { 345 dst.* = src.*; 346 } 347 348 test "call result of if else expression" { 349 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 350 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 351 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 352 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 353 354 try expect(mem.eql(u8, f2(true), "a")); 355 try expect(mem.eql(u8, f2(false), "b")); 356 } 357 fn f2(x: bool) []const u8 { 358 return (if (x) &fA else &fB)(); 359 } 360 361 test "variable is allowed to be a pointer to an opaque type" { 362 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 363 364 var x: i32 = 1234; 365 _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x)); 366 } 367 fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA { 368 var a = ptr; 369 return a; 370 } 371 372 test "take address of parameter" { 373 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 374 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 375 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 376 377 try testTakeAddressOfParameter(12.34); 378 } 379 fn testTakeAddressOfParameter(f: f32) !void { 380 const f_ptr = &f; 381 try expect(f_ptr.* == 12.34); 382 } 383 384 test "pointer to void return type" { 385 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 386 387 try testPointerToVoidReturnType(); 388 } 389 fn testPointerToVoidReturnType() anyerror!void { 390 const a = testPointerToVoidReturnType2(); 391 return a.*; 392 } 393 const test_pointer_to_void_return_type_x = void{}; 394 fn testPointerToVoidReturnType2() *const void { 395 return &test_pointer_to_void_return_type_x; 396 } 397 398 test "array 2D const double ptr" { 399 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 400 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 401 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 402 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 403 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 404 405 const rect_2d_vertexes = [_][1]f32{ 406 [_]f32{1.0}, 407 [_]f32{2.0}, 408 }; 409 try testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]); 410 } 411 412 test "array 2D const double ptr with offset" { 413 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 414 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 415 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 416 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 417 418 const rect_2d_vertexes = [_][2]f32{ 419 [_]f32{ 3.0, 4.239 }, 420 [_]f32{ 1.0, 2.0 }, 421 }; 422 try testArray2DConstDoublePtr(&rect_2d_vertexes[1][0]); 423 } 424 425 test "array 3D const double ptr with offset" { 426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 427 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 428 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 429 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 430 431 const rect_3d_vertexes = [_][2][2]f32{ 432 [_][2]f32{ 433 [_]f32{ 3.0, 4.239 }, 434 [_]f32{ 3.5, 7.2 }, 435 }, 436 [_][2]f32{ 437 [_]f32{ 3.0, 4.239 }, 438 [_]f32{ 1.0, 2.0 }, 439 }, 440 }; 441 try testArray2DConstDoublePtr(&rect_3d_vertexes[1][1][0]); 442 } 443 444 fn testArray2DConstDoublePtr(ptr: *const f32) !void { 445 const ptr2 = @ptrCast([*]const f32, ptr); 446 try expect(ptr2[0] == 1.0); 447 try expect(ptr2[1] == 2.0); 448 } 449 450 test "double implicit cast in same expression" { 451 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 452 453 var x = @as(i32, @as(u16, nine())); 454 try expect(x == 9); 455 } 456 fn nine() u8 { 457 return 9; 458 } 459 460 test "struct inside function" { 461 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 462 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 463 464 try testStructInFn(); 465 comptime try testStructInFn(); 466 } 467 468 fn testStructInFn() !void { 469 const BlockKind = u32; 470 471 const Block = struct { 472 kind: BlockKind, 473 }; 474 475 var block = Block{ .kind = 1234 }; 476 477 block.kind += 1; 478 479 try expect(block.kind == 1235); 480 } 481 482 test "fn call returning scalar optional in equality expression" { 483 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 484 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 485 try expect(getNull() == null); 486 } 487 488 fn getNull() ?*i32 { 489 return null; 490 } 491 492 test "global variable assignment with optional unwrapping with var initialized to undefined" { 493 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 494 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 495 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 496 497 const S = struct { 498 var data: i32 = 1234; 499 fn foo() ?*i32 { 500 return &data; 501 } 502 }; 503 global_foo = S.foo() orelse { 504 @panic("bad"); 505 }; 506 try expect(global_foo.* == 1234); 507 } 508 509 var global_foo: *i32 = undefined; 510 511 test "peer result location with typed parent, runtime condition, comptime prongs" { 512 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 513 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 514 515 const S = struct { 516 fn doTheTest(arg: i32) i32 { 517 const st = Structy{ 518 .bleh = if (arg == 1) 1 else 1, 519 }; 520 521 if (st.bleh == 1) 522 return 1234; 523 return 0; 524 } 525 526 const Structy = struct { 527 bleh: i32, 528 }; 529 }; 530 try expect(S.doTheTest(0) == 1234); 531 try expect(S.doTheTest(1) == 1234); 532 } 533 534 test "non-ambiguous reference of shadowed decls" { 535 try expect(ZA().B().Self != ZA().Self); 536 } 537 538 fn ZA() type { 539 return struct { 540 b: B(), 541 542 const Self = @This(); 543 544 fn B() type { 545 return struct { 546 const Self = @This(); 547 }; 548 } 549 }; 550 } 551 552 test "use of declaration with same name as primitive" { 553 const S = struct { 554 const @"u8" = u16; 555 const alias = @"u8"; 556 }; 557 const a: S.u8 = 300; 558 try expect(a == 300); 559 560 const b: S.alias = 300; 561 try expect(b == 300); 562 563 const @"u8" = u16; 564 const c: @"u8" = 300; 565 try expect(c == 300); 566 } 567 568 test "constant equal function pointers" { 569 const alias = emptyFn; 570 try expect(comptime x: { 571 break :x emptyFn == alias; 572 }); 573 } 574 575 fn emptyFn() void {} 576 577 const addr1 = @ptrCast(*const u8, &emptyFn); 578 test "comptime cast fn to ptr" { 579 const addr2 = @ptrCast(*const u8, &emptyFn); 580 comptime try expect(addr1 == addr2); 581 } 582 583 test "equality compare fn ptrs" { 584 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // Test passes but should not 585 586 var a = &emptyFn; 587 try expect(a == a); 588 } 589 590 test "self reference through fn ptr field" { 591 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 592 593 const S = struct { 594 const A = struct { 595 f: *const fn (A) u8, 596 }; 597 598 fn foo(a: A) u8 { 599 _ = a; 600 return 12; 601 } 602 }; 603 var a: S.A = undefined; 604 a.f = S.foo; 605 try expect(a.f(a) == 12); 606 } 607 608 test "global variable initialized to global variable array element" { 609 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 610 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 611 612 try expect(global_ptr == &gdt[0]); 613 } 614 const GDTEntry = struct { 615 field: i32, 616 }; 617 var gdt = [_]GDTEntry{ 618 GDTEntry{ .field = 1 }, 619 GDTEntry{ .field = 2 }, 620 }; 621 var global_ptr = &gdt[0]; 622 623 test "global constant is loaded with a runtime-known index" { 624 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 625 626 const S = struct { 627 fn doTheTest() !void { 628 var index: usize = 1; 629 const ptr = &pieces[index].field; 630 try expect(ptr.* == 2); 631 } 632 const Piece = struct { 633 field: i32, 634 }; 635 const pieces = [_]Piece{ Piece{ .field = 1 }, Piece{ .field = 2 }, Piece{ .field = 3 } }; 636 }; 637 try S.doTheTest(); 638 } 639 640 test "multiline string literal is null terminated" { 641 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 642 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 643 644 const s1 = 645 \\one 646 \\two) 647 \\three 648 ; 649 const s2 = "one\ntwo)\nthree"; 650 try expect(std.cstr.cmp(s1, s2) == 0); 651 } 652 653 test "string escapes" { 654 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 655 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 656 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 657 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 658 659 try expectEqualStrings("\"", "\x22"); 660 try expectEqualStrings("\'", "\x27"); 661 try expectEqualStrings("\n", "\x0a"); 662 try expectEqualStrings("\r", "\x0d"); 663 try expectEqualStrings("\t", "\x09"); 664 try expectEqualStrings("\\", "\x5c"); 665 try expectEqualStrings("\u{1234}\u{069}\u{1}", "\xe1\x88\xb4\x69\x01"); 666 } 667 668 test "explicit cast optional pointers" { 669 const a: ?*i32 = undefined; 670 const b: ?*f32 = @ptrCast(?*f32, a); 671 _ = b; 672 } 673 674 test "pointer comparison" { 675 const a = @as([]const u8, "a"); 676 const b = &a; 677 try expect(ptrEql(b, b)); 678 } 679 fn ptrEql(a: *const []const u8, b: *const []const u8) bool { 680 return a == b; 681 } 682 683 test "string concatenation" { 684 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 685 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 686 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 687 688 const a = "OK" ++ " IT " ++ "WORKED"; 689 const b = "OK IT WORKED"; 690 691 comptime try expect(@TypeOf(a) == *const [12:0]u8); 692 comptime try expect(@TypeOf(b) == *const [12:0]u8); 693 694 const len = b.len; 695 const len_with_null = len + 1; 696 { 697 var i: u32 = 0; 698 while (i < len_with_null) : (i += 1) { 699 try expect(a[i] == b[i]); 700 } 701 } 702 try expect(a[len] == 0); 703 try expect(b[len] == 0); 704 } 705 706 fn manyptrConcat(comptime s: [*:0]const u8) [*:0]const u8 { 707 return "very " ++ s; 708 } 709 710 test "comptime manyptr concatenation" { 711 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 712 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 713 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 714 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 715 716 const s = "epic"; 717 const actual = manyptrConcat(s); 718 const expected = "very epic"; 719 720 const len = mem.len(actual); 721 const len_with_null = len + 1; 722 { 723 var i: u32 = 0; 724 while (i < len_with_null) : (i += 1) { 725 try expect(actual[i] == expected[i]); 726 } 727 } 728 try expect(actual[len] == 0); 729 try expect(expected[len] == 0); 730 } 731 732 test "result location is optional inside error union" { 733 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 734 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 735 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 736 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 737 738 const x = maybe(true) catch unreachable; 739 try expect(x.? == 42); 740 } 741 742 fn maybe(x: bool) anyerror!?u32 { 743 return switch (x) { 744 true => @as(u32, 42), 745 else => null, 746 }; 747 } 748 749 test "auto created variables have correct alignment" { 750 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 751 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 752 753 const S = struct { 754 fn foo(str: [*]const u8) u32 { 755 for (@ptrCast([*]align(1) const u32, str)[0..1]) |v| { 756 return v; 757 } 758 return 0; 759 } 760 }; 761 try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); 762 comptime try expect(S.foo("\x7a\x7a\x7a\x7a") == 0x7a7a7a7a); 763 } 764 765 test "extern variable with non-pointer opaque type" { 766 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 767 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 768 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 769 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 770 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 771 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO 772 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 773 774 @export(var_to_export, .{ .name = "opaque_extern_var" }); 775 try expect(@ptrCast(*align(1) u32, &opaque_extern_var).* == 42); 776 } 777 extern var opaque_extern_var: opaque {}; 778 var var_to_export: u32 = 42; 779 780 test "lazy typeInfo value as generic parameter" { 781 const S = struct { 782 fn foo(args: anytype) void { 783 _ = args; 784 } 785 }; 786 S.foo(@typeInfo(@TypeOf(.{}))); 787 } 788 789 test "variable name containing underscores does not shadow int primitive" { 790 const _u0 = 0; 791 const i_8 = 0; 792 const u16_ = 0; 793 const i3_2 = 0; 794 const u6__4 = 0; 795 const i2_04_8 = 0; 796 797 _ = _u0; 798 _ = i_8; 799 _ = u16_; 800 _ = i3_2; 801 _ = u6__4; 802 _ = i2_04_8; 803 } 804 805 test "if expression type coercion" { 806 var cond: bool = true; 807 const x: u16 = if (cond) 1 else 0; 808 try expect(@as(u16, x) == 1); 809 } 810 811 test "discarding the result of various expressions" { 812 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 813 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 814 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 815 816 const S = struct { 817 fn foo() !u32 { 818 return 1; 819 } 820 fn bar() ?u32 { 821 return 1; 822 } 823 }; 824 _ = S.bar() orelse { 825 // do nothing 826 }; 827 _ = S.foo() catch { 828 // do nothing 829 }; 830 _ = switch (1) { 831 1 => 1, 832 2 => {}, 833 else => return, 834 }; 835 _ = try S.foo(); 836 _ = if (S.bar()) |some| some else {}; 837 _ = blk: { 838 if (S.bar()) |some| break :blk some; 839 break :blk; 840 }; 841 _ = while (S.bar()) |some| break some else {}; 842 _ = for ("foo") |char| break char else {}; 843 } 844 845 test "labeled block implicitly ends in a break" { 846 var a = false; 847 blk: { 848 if (a) break :blk; 849 } 850 } 851 852 test "catch in block has correct result location" { 853 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 854 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 855 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 856 857 const S = struct { 858 fn open() error{A}!@This() { 859 return @This(){}; 860 } 861 fn foo(_: @This()) u32 { 862 return 1; 863 } 864 }; 865 const config_h_text: u32 = blk: { 866 var dir = S.open() catch unreachable; 867 break :blk dir.foo(); 868 }; 869 try expect(config_h_text == 1); 870 } 871 872 test "labeled block with runtime branch forwards its result location type to break statements" { 873 const E = enum { a, b }; 874 var a = false; 875 const e: E = blk: { 876 if (a) { 877 break :blk .a; 878 } 879 break :blk .b; 880 }; 881 try expect(e == .b); 882 } 883 884 test "try in labeled block doesn't cast to wrong type" { 885 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 886 887 const S = struct { 888 a: u32, 889 fn foo() anyerror!u32 { 890 return 1; 891 } 892 }; 893 const s: ?*S = blk: { 894 var a = try S.foo(); 895 896 _ = a; 897 break :blk null; 898 }; 899 _ = s; 900 } 901 902 test "vector initialized with array init syntax has proper type" { 903 comptime { 904 const actual = -@Vector(4, i32){ 1, 2, 3, 4 }; 905 try std.testing.expectEqual(@Vector(4, i32){ -1, -2, -3, -4 }, actual); 906 } 907 } 908 909 test "weird array and tuple initializations" { 910 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 911 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 912 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 913 914 const E = enum { a, b }; 915 const S = struct { e: E }; 916 var a = false; 917 const b = S{ .e = .a }; 918 919 _ = &[_]S{ 920 if (a) .{ .e = .a } else .{ .e = .b }, 921 }; 922 923 if (true) return error.SkipZigTest; 924 925 const S2 = @TypeOf(.{ false, b }); 926 _ = &S2{ 927 true, 928 if (a) .{ .e = .a } else .{ .e = .b }, 929 }; 930 const S3 = @TypeOf(.{ .a = false, .b = b }); 931 _ = &S3{ 932 .a = true, 933 .b = if (a) .{ .e = .a } else .{ .e = .b }, 934 }; 935 } 936 937 test "array type comes from generic function" { 938 const S = struct { 939 fn A() type { 940 return struct { a: u8 = 0 }; 941 } 942 }; 943 const args = [_]S.A(){.{}}; 944 _ = args; 945 } 946 947 test "generic function uses return type of other generic function" { 948 if (true) { 949 // This test has been failing sporadically on the CI. 950 // It's not enough to verify that it works locally; we need to diagnose why 951 // it fails on the CI sometimes before turning it back on. 952 // https://github.com/ziglang/zig/issues/12208 953 return error.SkipZigTest; 954 } 955 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 956 957 const S = struct { 958 fn call( 959 f: anytype, 960 args: anytype, 961 ) @TypeOf(@call(.auto, f, @as(@TypeOf(args), undefined))) { 962 return @call(.auto, f, args); 963 } 964 965 fn func(arg: anytype) @TypeOf(arg) { 966 return arg; 967 } 968 }; 969 try std.testing.expect(S.call(S.func, .{@as(u8, 1)}) == 1); 970 } 971 972 test "const alloc with comptime-known initializer is made comptime-known" { 973 const S = struct { 974 a: bool, 975 b: [2]u8, 976 }; 977 { 978 const s: S = .{ 979 .a = false, 980 .b = .{ 1, 2 }, 981 }; 982 if (s.a) @compileError("bad"); 983 } 984 { 985 const s: S = .{ 986 .a = false, 987 .b = [2]u8{ 1, 2 }, 988 }; 989 if (s.a) @compileError("bad"); 990 } 991 { 992 const s: S = comptime .{ 993 .a = false, 994 .b = .{ 1, 2 }, 995 }; 996 if (s.a) @compileError("bad"); 997 } 998 { 999 const Const = struct { 1000 limbs: []const usize, 1001 positive: bool, 1002 }; 1003 const biggest: Const = .{ 1004 .limbs = &([1]usize{comptime std.math.maxInt(usize)} ** 128), 1005 .positive = false, 1006 }; 1007 if (biggest.positive) @compileError("bad"); 1008 } 1009 { 1010 const U = union(enum) { 1011 a: usize, 1012 }; 1013 const u: U = .{ 1014 .a = comptime std.math.maxInt(usize), 1015 }; 1016 if (u.a == 0) @compileError("bad"); 1017 } 1018 } 1019 1020 comptime { 1021 // coerce result ptr outside a function 1022 const S = struct { a: comptime_int }; 1023 var s: S = undefined; 1024 s = S{ .a = 1 }; 1025 assert(s.a == 1); 1026 } 1027 1028 test "switch inside @as gets correct type" { 1029 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1030 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1031 1032 var a: u32 = 0; 1033 var b: [2]u32 = undefined; 1034 b[0] = @as(u32, switch (a) { 1035 1 => 1, 1036 else => 0, 1037 }); 1038 } 1039 1040 test "inline call of function with a switch inside the return statement" { 1041 const S = struct { 1042 inline fn foo(x: anytype) @TypeOf(x) { 1043 return switch (x) { 1044 1 => 1, 1045 else => unreachable, 1046 }; 1047 } 1048 }; 1049 try expect(S.foo(1) == 1); 1050 } 1051 1052 test "namespace lookup ignores decl causing the lookup" { 1053 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1054 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1055 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1056 1057 if (builtin.zig_backend == .stage2_llvm) { 1058 // regressed with LLVM 15 1059 // https://github.com/ziglang/zig/issues/12681 1060 return error.SkipZigTest; 1061 } 1062 1063 const S = struct { 1064 fn Mixin(comptime T: type) type { 1065 return struct { 1066 fn foo() void { 1067 const set = std.EnumSet(T.E).init(undefined); 1068 _ = set; 1069 } 1070 }; 1071 } 1072 1073 const E = enum { a, b }; 1074 usingnamespace Mixin(@This()); 1075 }; 1076 _ = S.foo(); 1077 } 1078 1079 test "ambiguous reference error ignores current declaration" { 1080 const S = struct { 1081 const foo = 666; 1082 1083 const a = @This(); 1084 const b = struct { 1085 const foo = a.foo; 1086 const bar = struct { 1087 bar: u32 = b.foo, 1088 }; 1089 1090 comptime { 1091 _ = b.foo; 1092 } 1093 }; 1094 1095 usingnamespace b; 1096 }; 1097 try expect(S.b.foo == 666); 1098 } 1099 1100 test "pointer to zero sized global is mutable" { 1101 const S = struct { 1102 const Thing = struct {}; 1103 1104 var thing: Thing = undefined; 1105 }; 1106 try expect(@TypeOf(&S.thing) == *S.Thing); 1107 } 1108 1109 test "returning an opaque type from a function" { 1110 const S = struct { 1111 fn foo(comptime a: u32) type { 1112 return opaque { 1113 const b = a; 1114 }; 1115 } 1116 }; 1117 try expect(S.foo(123).b == 123); 1118 } 1119 1120 test "orelse coercion as function argument" { 1121 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1122 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1123 1124 const Loc = struct { start: i32 = -1 }; 1125 const Container = struct { 1126 a: ?Loc = null, 1127 fn init(a: Loc) @This() { 1128 return .{ 1129 .a = a, 1130 }; 1131 } 1132 }; 1133 var optional: ?Loc = .{}; 1134 var foo = Container.init(optional orelse .{}); 1135 try expect(foo.a.?.start == -1); 1136 } 1137 1138 test "runtime-known globals initialized with undefined" { 1139 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1140 1141 const S = struct { 1142 var array: [10]u32 = [_]u32{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 1143 var vp: [*]u32 = undefined; 1144 var s: []u32 = undefined; 1145 }; 1146 1147 S.vp = &S.array; 1148 S.s = S.vp[0..5]; 1149 1150 try expect(S.s[0] == 1); 1151 try expect(S.s[4] == 5); 1152 } 1153 1154 test "arrays and vectors with big integers" { 1155 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1156 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; 1157 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 1158 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; 1159 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; 1160 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1161 1162 // TODO: only aarch64-windows didn't pass in the PR that added this code. 1163 // figure out why if you can run this target. 1164 if (builtin.os.tag == .windows and builtin.cpu.arch == .aarch64) return error.SkipZigTest; 1165 1166 inline for (.{ u65528, u65529, u65535 }) |Int| { 1167 var a: [1]Int = undefined; 1168 a[0] = std.math.maxInt(Int); 1169 try expect(a[0] == comptime std.math.maxInt(Int)); 1170 var b: @Vector(1, Int) = undefined; 1171 b[0] = std.math.maxInt(Int); 1172 try expect(b[0] == comptime std.math.maxInt(Int)); 1173 } 1174 } 1175 1176 test "pointer to struct literal with runtime field is constant" { 1177 const S = struct { data: usize }; 1178 var runtime_zero: usize = 0; 1179 const ptr = &S{ .data = runtime_zero }; 1180 try expect(@typeInfo(@TypeOf(ptr)).Pointer.is_const); 1181 }