master
   1const std = @import("std");
   2const builtin = @import("builtin");
   3const testing = std.testing;
   4const mem = std.mem;
   5const assert = std.debug.assert;
   6const expect = testing.expect;
   7const expectEqual = testing.expectEqual;
   8
   9test "array to slice" {
  10    const a: u32 align(4) = 3;
  11    const b: u32 align(8) = 4;
  12    const a_slice: []align(1) const u32 = @as(*const [1]u32, &a)[0..];
  13    const b_slice: []align(1) const u32 = @as(*const [1]u32, &b)[0..];
  14    try expect(a_slice[0] + b_slice[0] == 7);
  15
  16    const d: []const u32 = &[2]u32{ 1, 2 };
  17    const e: []const u32 = &[3]u32{ 3, 4, 5 };
  18    try expect(d[0] + e[0] + d[1] + e[1] == 10);
  19}
  20
  21test "arrays" {
  22    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
  23    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  24
  25    var array: [5]u32 = undefined;
  26
  27    var i: u32 = 0;
  28    while (i < 5) {
  29        array[i] = i + 1;
  30        i = array[i];
  31    }
  32
  33    i = 0;
  34    var accumulator = @as(u32, 0);
  35    while (i < 5) {
  36        accumulator += array[i];
  37
  38        i += 1;
  39    }
  40
  41    try expect(accumulator == 15);
  42    try expect(getArrayLen(&array) == 5);
  43}
  44fn getArrayLen(a: []const u32) usize {
  45    return a.len;
  46}
  47
  48test "array concat with undefined" {
  49    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  50    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  51
  52    const S = struct {
  53        fn doTheTest() !void {
  54            {
  55                var array = "hello".* ++ @as([5]u8, undefined);
  56                array[5..10].* = "world".*;
  57                try std.testing.expect(std.mem.eql(u8, &array, "helloworld"));
  58            }
  59            {
  60                var array = @as([5]u8, undefined) ++ "world".*;
  61                array[0..5].* = "hello".*;
  62                try std.testing.expect(std.mem.eql(u8, &array, "helloworld"));
  63            }
  64        }
  65    };
  66
  67    try S.doTheTest();
  68    try comptime S.doTheTest();
  69}
  70
  71test "array concat with tuple" {
  72    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  73    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
  74    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  75
  76    const array: [2]u8 = .{ 1, 2 };
  77    {
  78        const seq = array ++ .{ 3, 4 };
  79        try std.testing.expectEqualSlices(u8, &.{ 1, 2, 3, 4 }, &seq);
  80    }
  81    {
  82        const seq = .{ 3, 4 } ++ array;
  83        try std.testing.expectEqualSlices(u8, &.{ 3, 4, 1, 2 }, &seq);
  84    }
  85}
  86
  87test "array init with concat" {
  88    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  89
  90    const a = 'a';
  91    var i: [4]u8 = [2]u8{ a, 'b' } ++ [2]u8{ 'c', 'd' };
  92    try expect(std.mem.eql(u8, &i, "abcd"));
  93}
  94
  95test "array init with mult" {
  96    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  97    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  98
  99    const a = 'a';
 100    var i: [8]u8 = [2]u8{ a, 'b' } ** 4;
 101    try expect(std.mem.eql(u8, &i, "abababab"));
 102
 103    var j: [4]u8 = [1]u8{'a'} ** 4;
 104    try expect(std.mem.eql(u8, &j, "aaaa"));
 105}
 106
 107test "array literal with explicit type" {
 108    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 109
 110    const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 };
 111
 112    try expect(hex_mult.len == 4);
 113    try expect(hex_mult[1] == 256);
 114}
 115
 116test "array literal with inferred length" {
 117    const hex_mult = [_]u16{ 4096, 256, 16, 1 };
 118
 119    try expect(hex_mult.len == 4);
 120    try expect(hex_mult[1] == 256);
 121}
 122
 123test "array dot len const expr" {
 124    try expect(comptime x: {
 125        break :x some_array.len == 4;
 126    });
 127}
 128
 129const ArrayDotLenConstExpr = struct {
 130    y: [some_array.len]u8,
 131};
 132const some_array = [_]u8{ 0, 1, 2, 3 };
 133
 134test "array literal with specified size" {
 135    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 136    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 137
 138    var array = [2]u8{ 1, 2 };
 139    _ = &array;
 140    try expect(array[0] == 1);
 141    try expect(array[1] == 2);
 142}
 143
 144test "array len field" {
 145    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 146
 147    var arr = [4]u8{ 0, 0, 0, 0 };
 148    const ptr = &arr;
 149    try expect(arr.len == 4);
 150    comptime assert(arr.len == 4);
 151    try expect(ptr.len == 4);
 152    comptime assert(ptr.len == 4);
 153    try expect(@TypeOf(arr.len) == usize);
 154}
 155
 156test "array with sentinels" {
 157    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 158    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 159
 160    const S = struct {
 161        fn doTheTest(is_ct: bool) !void {
 162            {
 163                var zero_sized: [0:0xde]u8 = [_:0xde]u8{};
 164                try expect(zero_sized[0] == 0xde);
 165                var reinterpreted: *[1]u8 = @ptrCast(&zero_sized);
 166                _ = &reinterpreted;
 167                try expect(reinterpreted[0] == 0xde);
 168            }
 169            var arr: [3:0x55]u8 = undefined;
 170            // Make sure the sentinel pointer is pointing after the last element.
 171            if (!is_ct) {
 172                const sentinel_ptr = @intFromPtr(&arr[3]);
 173                const last_elem_ptr = @intFromPtr(&arr[2]);
 174                try expect((sentinel_ptr - last_elem_ptr) == 1);
 175            }
 176            // Make sure the sentinel is writeable.
 177            arr[3] = 0x55;
 178        }
 179    };
 180
 181    try S.doTheTest(false);
 182    try comptime S.doTheTest(true);
 183}
 184
 185test "void arrays" {
 186    var array: [4]void = undefined;
 187    array[0] = void{};
 188    array[1] = array[2];
 189    try expect(@sizeOf(@TypeOf(array)) == 0);
 190    try expect(array.len == 4);
 191}
 192
 193test "nested arrays of strings" {
 194    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 195    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 196    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 197
 198    const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" };
 199    for (array_of_strings, 0..) |s, i| {
 200        if (i == 0) try expect(mem.eql(u8, s, "hello"));
 201        if (i == 1) try expect(mem.eql(u8, s, "this"));
 202        if (i == 2) try expect(mem.eql(u8, s, "is"));
 203        if (i == 3) try expect(mem.eql(u8, s, "my"));
 204        if (i == 4) try expect(mem.eql(u8, s, "thing"));
 205    }
 206}
 207
 208test "nested arrays of integers" {
 209    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 210
 211    const array_of_numbers = [_][2]u8{
 212        [2]u8{ 1, 2 },
 213        [2]u8{ 3, 4 },
 214    };
 215
 216    try expect(array_of_numbers[0][0] == 1);
 217    try expect(array_of_numbers[0][1] == 2);
 218    try expect(array_of_numbers[1][0] == 3);
 219    try expect(array_of_numbers[1][1] == 4);
 220}
 221
 222test "implicit comptime in array type size" {
 223    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 224
 225    var arr: [plusOne(10)]bool = undefined;
 226    _ = &arr;
 227    try expect(arr.len == 11);
 228}
 229
 230fn plusOne(x: u32) u32 {
 231    return x + 1;
 232}
 233
 234test "single-item pointer to array indexing and slicing" {
 235    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 236    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 237
 238    try testSingleItemPtrArrayIndexSlice();
 239    try comptime testSingleItemPtrArrayIndexSlice();
 240}
 241
 242fn testSingleItemPtrArrayIndexSlice() !void {
 243    {
 244        var array: [4]u8 = "aaaa".*;
 245        doSomeMangling(&array);
 246        try expect(mem.eql(u8, "azya", &array));
 247    }
 248    {
 249        var array = "aaaa".*;
 250        doSomeMangling(&array);
 251        try expect(mem.eql(u8, "azya", &array));
 252    }
 253}
 254
 255fn doSomeMangling(array: *[4]u8) void {
 256    array[1] = 'z';
 257    array[2..3][0] = 'y';
 258}
 259
 260test "implicit cast zero sized array ptr to slice" {
 261    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 262
 263    {
 264        var b = "".*;
 265        const c: []const u8 = &b;
 266        try expect(c.len == 0);
 267    }
 268    {
 269        var b: [0]u8 = "".*;
 270        const c: []const u8 = &b;
 271        try expect(c.len == 0);
 272    }
 273}
 274
 275test "anonymous list literal syntax" {
 276    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 277    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 278
 279    const S = struct {
 280        fn doTheTest() !void {
 281            var array: [4]u8 = .{ 1, 2, 3, 4 };
 282            _ = &array;
 283            try expect(array[0] == 1);
 284            try expect(array[1] == 2);
 285            try expect(array[2] == 3);
 286            try expect(array[3] == 4);
 287        }
 288    };
 289    try S.doTheTest();
 290    try comptime S.doTheTest();
 291}
 292
 293var s_array: [8]Sub = undefined;
 294const Sub = struct { b: u8 };
 295const Str = struct { a: []Sub };
 296test "set global var array via slice embedded in struct" {
 297    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 298    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 299
 300    var s = Str{ .a = s_array[0..] };
 301
 302    s.a[0].b = 1;
 303    s.a[1].b = 2;
 304    s.a[2].b = 3;
 305
 306    try expect(s_array[0].b == 1);
 307    try expect(s_array[1].b == 2);
 308    try expect(s_array[2].b == 3);
 309}
 310
 311test "read/write through global variable array of struct fields initialized via array mult" {
 312    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 313    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 314
 315    const S = struct {
 316        fn doTheTest() !void {
 317            try expect(storage[0].term == 1);
 318            storage[0] = MyStruct{ .term = 123 };
 319            try expect(storage[0].term == 123);
 320        }
 321
 322        pub const MyStruct = struct {
 323            term: usize,
 324        };
 325
 326        var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1;
 327    };
 328    try S.doTheTest();
 329}
 330
 331test "implicit cast single-item pointer" {
 332    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 333    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 334
 335    try testImplicitCastSingleItemPtr();
 336    try comptime testImplicitCastSingleItemPtr();
 337}
 338
 339fn testImplicitCastSingleItemPtr() !void {
 340    var byte: u8 = 100;
 341    const slice = @as(*[1]u8, &byte)[0..];
 342    slice[0] += 1;
 343    try expect(byte == 101);
 344}
 345
 346fn testArrayByValAtComptime(b: [2]u8) u8 {
 347    return b[0];
 348}
 349
 350test "comptime evaluating function that takes array by value" {
 351    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 352
 353    const arr = [_]u8{ 1, 2 };
 354    const x = comptime testArrayByValAtComptime(arr);
 355    const y = comptime testArrayByValAtComptime(arr);
 356    try expect(x == 1);
 357    try expect(y == 1);
 358}
 359
 360test "runtime initialize array elem and then implicit cast to slice" {
 361    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 362    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 363
 364    var two: i32 = 2;
 365    _ = &two;
 366    const x: []const i32 = &[_]i32{two};
 367    try expect(x[0] == 2);
 368}
 369
 370test "array literal as argument to function" {
 371    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 372    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 373
 374    const S = struct {
 375        fn entry(two: i32) !void {
 376            try foo(&[_]i32{ 1, 2, 3 });
 377            try foo(&[_]i32{ 1, two, 3 });
 378            try foo2(true, &[_]i32{ 1, 2, 3 });
 379            try foo2(true, &[_]i32{ 1, two, 3 });
 380        }
 381        fn foo(x: []const i32) !void {
 382            try expect(x[0] == 1);
 383            try expect(x[1] == 2);
 384            try expect(x[2] == 3);
 385        }
 386        fn foo2(trash: bool, x: []const i32) !void {
 387            try expect(trash);
 388            try expect(x[0] == 1);
 389            try expect(x[1] == 2);
 390            try expect(x[2] == 3);
 391        }
 392    };
 393    try S.entry(2);
 394    try comptime S.entry(2);
 395}
 396
 397test "double nested array to const slice cast in array literal" {
 398    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 399    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 400    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 401
 402    const S = struct {
 403        fn entry(two: i32) !void {
 404            const cases = [_][]const []const i32{
 405                &[_][]const i32{&[_]i32{1}},
 406                &[_][]const i32{&[_]i32{ 2, 3 }},
 407                &[_][]const i32{
 408                    &[_]i32{4},
 409                    &[_]i32{ 5, 6, 7 },
 410                },
 411            };
 412            try check(&cases);
 413
 414            const cases2 = [_][]const i32{
 415                &[_]i32{1},
 416                &[_]i32{ two, 3 },
 417            };
 418            try expect(cases2.len == 2);
 419            try expect(cases2[0].len == 1);
 420            try expect(cases2[0][0] == 1);
 421            try expect(cases2[1].len == 2);
 422            try expect(cases2[1][0] == 2);
 423            try expect(cases2[1][1] == 3);
 424
 425            const cases3 = [_][]const []const i32{
 426                &[_][]const i32{&[_]i32{1}},
 427                &[_][]const i32{&[_]i32{ two, 3 }},
 428                &[_][]const i32{
 429                    &[_]i32{4},
 430                    &[_]i32{ 5, 6, 7 },
 431                },
 432            };
 433            try check(&cases3);
 434        }
 435
 436        fn check(cases: []const []const []const i32) !void {
 437            try expect(cases.len == 3);
 438            try expect(cases[0].len == 1);
 439            try expect(cases[0][0].len == 1);
 440            try expect(cases[0][0][0] == 1);
 441            try expect(cases[1].len == 1);
 442            try expect(cases[1][0].len == 2);
 443            try expect(cases[1][0][0] == 2);
 444            try expect(cases[1][0][1] == 3);
 445            try expect(cases[2].len == 2);
 446            try expect(cases[2][0].len == 1);
 447            try expect(cases[2][0][0] == 4);
 448            try expect(cases[2][1].len == 3);
 449            try expect(cases[2][1][0] == 5);
 450            try expect(cases[2][1][1] == 6);
 451            try expect(cases[2][1][2] == 7);
 452        }
 453    };
 454    try S.entry(2);
 455    try comptime S.entry(2);
 456}
 457
 458test "anonymous literal in array" {
 459    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 460    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 461
 462    const S = struct {
 463        const Foo = struct {
 464            a: usize = 2,
 465            b: usize = 4,
 466        };
 467        fn doTheTest() !void {
 468            var array: [2]Foo = .{
 469                .{ .a = 3 },
 470                .{ .b = 3 },
 471            };
 472            _ = &array;
 473            try expect(array[0].a == 3);
 474            try expect(array[0].b == 4);
 475            try expect(array[1].a == 2);
 476            try expect(array[1].b == 3);
 477        }
 478    };
 479    try S.doTheTest();
 480    try comptime S.doTheTest();
 481}
 482
 483test "access the null element of a null terminated array" {
 484    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 485
 486    const S = struct {
 487        fn doTheTest() !void {
 488            var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' };
 489            _ = &array;
 490            try expect(array[4] == 0);
 491            var len: usize = 4;
 492            _ = &len;
 493            try expect(array[len] == 0);
 494        }
 495    };
 496    try S.doTheTest();
 497    try comptime S.doTheTest();
 498}
 499
 500test "type deduction for array subscript expression" {
 501    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 502    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 503
 504    const S = struct {
 505        fn doTheTest() !void {
 506            var array = [_]u8{ 0x55, 0xAA };
 507            var v0 = true;
 508            try expect(@as(u8, 0xAA) == array[if (v0) 1 else 0]);
 509            var v1 = false;
 510            try expect(@as(u8, 0x55) == array[if (v1) 1 else 0]);
 511            _ = .{ &array, &v0, &v1 };
 512        }
 513    };
 514    try S.doTheTest();
 515    try comptime S.doTheTest();
 516}
 517
 518test "sentinel element count towards the ABI size calculation" {
 519    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 520    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 521    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 522
 523    const S = struct {
 524        fn doTheTest() !void {
 525            const T = extern struct {
 526                fill_pre: u8 = 0x55,
 527                data: [0:0]u8 = undefined,
 528                fill_post: u8 = 0xAA,
 529            };
 530            var x = T{};
 531            const as_slice = mem.asBytes(&x);
 532            try expect(@as(usize, 3) == as_slice.len);
 533            try expect(@as(u8, 0x55) == as_slice[0]);
 534            try expect(@as(u8, 0xAA) == as_slice[2]);
 535        }
 536    };
 537
 538    try S.doTheTest();
 539    try comptime S.doTheTest();
 540}
 541
 542test "zero-sized array with recursive type definition" {
 543    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 544    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 545
 546    const U = struct {
 547        fn foo(comptime T: type, comptime n: usize) type {
 548            return struct {
 549                s: [n]T,
 550                x: usize = n,
 551            };
 552        }
 553    };
 554
 555    const S = struct {
 556        list: U.foo(@This(), 0),
 557    };
 558
 559    var t: S = .{ .list = .{ .s = undefined } };
 560    _ = &t;
 561    try expect(@as(usize, 0) == t.list.x);
 562}
 563
 564test "type coercion of anon struct literal to array" {
 565    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 566    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 567    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 568    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 569
 570    const S = struct {
 571        const U = union {
 572            a: u32,
 573            b: bool,
 574            c: []const u8,
 575        };
 576
 577        fn doTheTest() !void {
 578            var x1: u8 = 42;
 579            _ = &x1;
 580            const t1 = .{ x1, 56, 54 };
 581            const arr1: [3]u8 = t1;
 582            try expect(arr1[0] == 42);
 583            try expect(arr1[1] == 56);
 584            try expect(arr1[2] == 54);
 585
 586            var x2: U = .{ .a = 42 };
 587            _ = &x2;
 588            const t2 = .{ x2, U{ .b = true }, U{ .c = "hello" } };
 589            const arr2: [3]U = t2;
 590            try expect(arr2[0].a == 42);
 591            try expect(arr2[1].b == true);
 592            try expect(mem.eql(u8, arr2[2].c, "hello"));
 593        }
 594    };
 595    try S.doTheTest();
 596    try comptime S.doTheTest();
 597}
 598
 599test "array with comptime-only element type" {
 600    const a = [_]type{ u32, i32 };
 601    try testing.expect(a[0] == u32);
 602    try testing.expect(a[1] == i32);
 603}
 604
 605test "tuple to array handles sentinel" {
 606    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 607    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 608
 609    const S = struct {
 610        const a = .{ 1, 2, 3 };
 611        var b: [3:0]u8 = a;
 612    };
 613    try expect(S.b[0] == 1);
 614}
 615
 616test "array init of container level array variable" {
 617    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 618    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 619    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 620
 621    const S = struct {
 622        var pair: [2]usize = .{ 1, 2 };
 623        noinline fn foo(x: usize, y: usize) void {
 624            pair = [2]usize{ x, y };
 625        }
 626        noinline fn bar(x: usize, y: usize) void {
 627            var tmp: [2]usize = .{ x, y };
 628            _ = &tmp;
 629            pair = tmp;
 630        }
 631    };
 632    try expectEqual([2]usize{ 1, 2 }, S.pair);
 633    S.foo(3, 4);
 634    try expectEqual([2]usize{ 3, 4 }, S.pair);
 635    S.bar(5, 6);
 636    try expectEqual([2]usize{ 5, 6 }, S.pair);
 637}
 638
 639test "runtime initialized sentinel-terminated array literal" {
 640    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 641
 642    var c: u16 = 300;
 643    _ = &c;
 644    const f = &[_:0x9999]u16{c};
 645    const g = @as(*const [4]u8, @ptrCast(f));
 646    try std.testing.expect(g[2] == 0x99);
 647    try std.testing.expect(g[3] == 0x99);
 648}
 649
 650test "array of array agregate init" {
 651    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 652    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 653
 654    var a = [1]u32{11} ** 10;
 655    var b = [1][10]u32{a} ** 2;
 656    _ = .{ &a, &b };
 657    try std.testing.expect(b[1][1] == 11);
 658}
 659
 660test "pointer to array has ptr field" {
 661    const arr: *const [5]u32 = &.{ 10, 20, 30, 40, 50 };
 662    try std.testing.expect(arr.ptr == @as([*]const u32, arr));
 663    try std.testing.expect(arr.ptr[0] == 10);
 664    try std.testing.expect(arr.ptr[1] == 20);
 665    try std.testing.expect(arr.ptr[2] == 30);
 666    try std.testing.expect(arr.ptr[3] == 40);
 667    try std.testing.expect((&arr.ptr).*[4] == 50);
 668}
 669
 670test "discarded array init preserves result location" {
 671    const S = struct {
 672        fn f(p: *u32) u16 {
 673            p.* += 1;
 674            return 0;
 675        }
 676    };
 677
 678    var x: u32 = 0;
 679    _ = [2]u8{
 680        @intCast(S.f(&x)),
 681        @intCast(S.f(&x)),
 682    };
 683
 684    // Ensure function was run
 685    try expect(x == 2);
 686}
 687
 688test "array init with no result location has result type" {
 689    const x = .{ .foo = [2]u16{
 690        @intCast(10),
 691        @intCast(20),
 692    } };
 693
 694    try expect(x.foo.len == 2);
 695    try expect(x.foo[0] == 10);
 696    try expect(x.foo[1] == 20);
 697}
 698
 699test "slicing array of zero-sized values" {
 700    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 701    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 702    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 703
 704    var arr: [32]u0 = undefined;
 705    for (arr[0..]) |*zero|
 706        zero.* = 0;
 707    for (arr[0..]) |zero|
 708        try expect(zero == 0);
 709}
 710
 711test "array init with no result pointer sets field result types" {
 712    const S = struct {
 713        // A function parameter has a result type, but no result pointer.
 714        fn f(arr: [1]u32) u32 {
 715            return arr[0];
 716        }
 717    };
 718
 719    const x: u64 = 123;
 720    const y = S.f(.{@intCast(x)});
 721
 722    try expect(y == x);
 723}
 724
 725test "runtime side-effects in comptime-known array init" {
 726    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 727
 728    var side_effects: u4 = 0;
 729    const init = [4]u4{
 730        blk: {
 731            side_effects += 1;
 732            break :blk 1;
 733        },
 734        blk: {
 735            side_effects += 2;
 736            break :blk 2;
 737        },
 738        blk: {
 739            side_effects += 4;
 740            break :blk 4;
 741        },
 742        blk: {
 743            side_effects += 8;
 744            break :blk 8;
 745        },
 746    };
 747    try expectEqual([4]u4{ 1, 2, 4, 8 }, init);
 748    try expectEqual(@as(u4, std.math.maxInt(u4)), side_effects);
 749}
 750
 751test "slice initialized through reference to anonymous array init provides result types" {
 752    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 753
 754    var my_u32: u32 = 123;
 755    var my_u64: u64 = 456;
 756    _ = .{ &my_u32, &my_u64 };
 757    const foo: []const u16 = &.{
 758        @intCast(my_u32),
 759        @intCast(my_u64),
 760        @truncate(my_u32),
 761        @truncate(my_u64),
 762    };
 763    try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
 764}
 765
 766test "sentinel-terminated slice initialized through reference to anonymous array init provides result types" {
 767    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 768
 769    var my_u32: u32 = 123;
 770    var my_u64: u64 = 456;
 771    _ = .{ &my_u32, &my_u64 };
 772    const foo: [:999]const u16 = &.{
 773        @intCast(my_u32),
 774        @intCast(my_u64),
 775        @truncate(my_u32),
 776        @truncate(my_u64),
 777    };
 778    try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
 779}
 780
 781test "many-item pointer initialized through reference to anonymous array init provides result types" {
 782    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 783    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 784
 785    var my_u32: u32 = 123;
 786    var my_u64: u64 = 456;
 787    _ = .{ &my_u32, &my_u64 };
 788    const foo: [*]const u16 = &.{
 789        @intCast(my_u32),
 790        @intCast(my_u64),
 791        @truncate(my_u32),
 792        @truncate(my_u64),
 793    };
 794    try expectEqual(123, foo[0]);
 795    try expectEqual(456, foo[1]);
 796    try expectEqual(123, foo[2]);
 797    try expectEqual(456, foo[3]);
 798}
 799
 800test "many-item sentinel-terminated pointer initialized through reference to anonymous array init provides result types" {
 801    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 802    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 803
 804    var my_u32: u32 = 123;
 805    var my_u64: u64 = 456;
 806    _ = .{ &my_u32, &my_u64 };
 807    const foo: [*:999]const u16 = &.{
 808        @intCast(my_u32),
 809        @intCast(my_u64),
 810        @truncate(my_u32),
 811        @truncate(my_u64),
 812    };
 813    try expectEqual(123, foo[0]);
 814    try expectEqual(456, foo[1]);
 815    try expectEqual(123, foo[2]);
 816    try expectEqual(456, foo[3]);
 817    try expectEqual(999, foo[4]);
 818}
 819
 820test "pointer to array initialized through reference to anonymous array init provides result types" {
 821    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 822
 823    var my_u32: u32 = 123;
 824    var my_u64: u64 = 456;
 825    _ = .{ &my_u32, &my_u64 };
 826    const foo: *const [4]u16 = &.{
 827        @intCast(my_u32),
 828        @intCast(my_u64),
 829        @truncate(my_u32),
 830        @truncate(my_u64),
 831    };
 832    try std.testing.expectEqualSlices(u16, &.{ 123, 456, 123, 456 }, foo);
 833}
 834
 835test "pointer to sentinel-terminated array initialized through reference to anonymous array init provides result types" {
 836    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 837
 838    var my_u32: u32 = 123;
 839    var my_u64: u64 = 456;
 840    _ = .{ &my_u32, &my_u64 };
 841    const foo: *const [4:999]u16 = &.{
 842        @intCast(my_u32),
 843        @intCast(my_u64),
 844        @truncate(my_u32),
 845        @truncate(my_u64),
 846    };
 847    try std.testing.expectEqualSentinel(u16, 999, &.{ 123, 456, 123, 456 }, foo);
 848}
 849
 850test "tuple initialized through reference to anonymous array init provides result types" {
 851    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 852
 853    const Tuple = struct { u64, *const u32 };
 854    const foo: *const Tuple = &.{
 855        @intCast(12345),
 856        @ptrFromInt(0x1000),
 857    };
 858    try expect(foo[0] == 12345);
 859    try expect(@intFromPtr(foo[1]) == 0x1000);
 860}
 861
 862test "copied array element doesn't alias source" {
 863    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 864    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 865
 866    var x: [10][10]u32 = undefined;
 867
 868    x[0][1] = 0;
 869    const a = x[0];
 870    x[0][1] = 15;
 871
 872    try expect(a[1] == 0);
 873}
 874
 875test "array initialized with string literal" {
 876    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 877    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 878
 879    const S = struct {
 880        a: u32,
 881        c: [5]u8,
 882    };
 883    const U = union {
 884        s: S,
 885    };
 886    const s_1 = S{
 887        .a = undefined,
 888        .c = "12345".*, // this caused problems
 889    };
 890
 891    var u_2 = U{ .s = s_1 };
 892    _ = &u_2;
 893    try std.testing.expectEqualStrings("12345", &u_2.s.c);
 894}
 895
 896test "array initialized with array with sentinel" {
 897    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 898    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 899
 900    const S = struct {
 901        a: u32,
 902        c: [5]u8,
 903    };
 904    const U = union {
 905        s: S,
 906    };
 907    const c = [5:0]u8{ 1, 2, 3, 4, 5 };
 908    const s_1 = S{
 909        .a = undefined,
 910        .c = c, // this caused problems
 911    };
 912    var u_2 = U{ .s = s_1 };
 913    _ = &u_2;
 914    try std.testing.expectEqualSlices(u8, &.{ 1, 2, 3, 4, 5 }, &u_2.s.c);
 915}
 916
 917test "store array of array of structs at comptime" {
 918    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 919    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 920
 921    const S = struct {
 922        fn storeArrayOfArrayOfStructs() u8 {
 923            const S = struct {
 924                x: u8,
 925            };
 926
 927            var cases = [_][1]S{
 928                [_]S{
 929                    S{ .x = 15 },
 930                },
 931            };
 932            _ = &cases;
 933            return cases[0][0].x;
 934        }
 935    };
 936
 937    try expect(S.storeArrayOfArrayOfStructs() == 15);
 938    comptime assert(S.storeArrayOfArrayOfStructs() == 15);
 939}
 940
 941test "accessing multidimensional global array at comptime" {
 942    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 943    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 944
 945    const S = struct {
 946        const array = [_][]const []const u8{
 947            &.{"hello"},
 948            &.{ "world", "hello" },
 949        };
 950    };
 951
 952    try std.testing.expect(S.array[0].len == 1);
 953    try std.testing.expectEqualStrings("hello", S.array[0][0]);
 954}
 955
 956test "union that needs padding bytes inside an array" {
 957    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 958    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 959    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 960    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 961
 962    const B = union(enum) {
 963        D: u8,
 964        E: u16,
 965    };
 966    const A = union(enum) {
 967        B: B,
 968        C: u8,
 969    };
 970    var as = [_]A{
 971        A{ .B = B{ .D = 1 } },
 972        A{ .B = B{ .D = 1 } },
 973    };
 974    _ = &as;
 975
 976    const a = as[0].B;
 977    try std.testing.expect(a.D == 1);
 978}
 979
 980test "runtime index of array of zero-bit values" {
 981    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 982
 983    var runtime: struct { array: [1]void, index: usize } = undefined;
 984    runtime = .{ .array = .{{}}, .index = 0 };
 985    const result = struct { index: usize, value: void }{
 986        .index = runtime.index,
 987        .value = runtime.array[runtime.index],
 988    };
 989    try std.testing.expect(result.index == 0);
 990    try std.testing.expect(result.value == {});
 991}
 992
 993test "@splat array" {
 994    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 995    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 996
 997    const S = struct {
 998        fn doTheTest(comptime T: type, x: T) !void {
 999            const arr: [10]T = @splat(x);
1000            for (arr) |elem| {
1001                try expectEqual(x, elem);
1002            }
1003        }
1004    };
1005
1006    try S.doTheTest(u32, 123);
1007    try comptime S.doTheTest(u32, 123);
1008
1009    const Foo = struct { x: u8 };
1010    try S.doTheTest(Foo, .{ .x = 10 });
1011    try comptime S.doTheTest(Foo, .{ .x = 10 });
1012}
1013
1014test "@splat array with sentinel" {
1015    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1016    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1017    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1018
1019    const S = struct {
1020        fn doTheTest(comptime T: type, x: T, comptime s: T) !void {
1021            const arr: [10:s]T = @splat(x);
1022            for (arr) |elem| {
1023                try expectEqual(x, elem);
1024            }
1025            const ptr: [*]const T = &arr;
1026            try expectEqual(s, ptr[10]); // sentinel correct
1027        }
1028    };
1029
1030    try S.doTheTest(u32, 100, 42);
1031    try comptime S.doTheTest(u32, 100, 42);
1032
1033    try S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null);
1034    try comptime S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null);
1035}
1036
1037test "@splat zero-length array" {
1038    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1039    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1040    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1041
1042    const S = struct {
1043        fn doTheTest(comptime T: type, comptime s: T) !void {
1044            var runtime_undef: T = undefined;
1045            runtime_undef = undefined;
1046            // The array should be comptime-known despite the `@splat` operand being runtime-known.
1047            const arr: [0:s]T = @splat(runtime_undef);
1048            const ptr: [*]const T = &arr;
1049            comptime assert(ptr[0] == s);
1050        }
1051    };
1052
1053    try S.doTheTest(u32, 42);
1054    try comptime S.doTheTest(u32, 42);
1055
1056    try S.doTheTest(?*anyopaque, null);
1057    try comptime S.doTheTest(?*anyopaque, null);
1058}
1059
1060test "initialize slice with reference to empty array initializer" {
1061    const a: []const u8 = &.{};
1062    comptime assert(a.len == 0);
1063}
1064
1065test "initialize many-pointer with reference to empty array initializer" {
1066    const a: [*]const u8 = &.{};
1067    _ = a; // nothing meaningful to test; points to zero bits
1068}
1069
1070test "initialize sentinel-terminated slice with reference to empty array initializer" {
1071    const a: [:0]const u8 = &.{};
1072    comptime assert(a.len == 0);
1073    comptime assert(a[0] == 0);
1074}
1075
1076test "initialize sentinel-terminated many-pointer with reference to empty array initializer" {
1077    const a: [*:0]const u8 = &.{};
1078    comptime assert(a[0] == 0);
1079}
1080
1081test "pass pointer to empty array initializer to anytype parameter" {
1082    const S = struct {
1083        fn TypeOf(x: anytype) type {
1084            return @TypeOf(x);
1085        }
1086    };
1087    comptime assert(S.TypeOf(&.{}) == @TypeOf(&.{}));
1088}
1089
1090test "initialize pointer to anyopaque with reference to empty array initializer" {
1091    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1092
1093    const ptr: *const anyopaque = &.{};
1094    // The above acts like an untyped initializer, since the `.{}` has no result type.
1095    // So, `ptr` points in memory to an empty tuple (`@TypeOf(.{})`).
1096    const casted: *const @TypeOf(.{}) = @ptrCast(@alignCast(ptr));
1097    const loaded = casted.*;
1098    // `val` should be a `@TypeOf(.{})`, as expected.
1099    // We can't check the value, but it's zero-bit, so the type matching is good enough.
1100    comptime assert(@TypeOf(loaded) == @TypeOf(.{}));
1101}
1102
1103test "sentinel of runtime-known array initialization is populated" {
1104    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1105
1106    var rt: u32 = undefined;
1107    rt = 42;
1108
1109    const arr: [1:123]u32 = .{rt};
1110    const elems: [*]const u32 = &arr;
1111
1112    try expect(elems[0] == 42);
1113    try expect(elems[1] == 123);
1114}
1115
1116test "splat with an error union or optional result type" {
1117    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1118
1119    const S = struct {
1120        fn doTest(T: type) !?T {
1121            return @splat(1);
1122        }
1123    };
1124
1125    _ = try S.doTest(@Vector(4, u32));
1126    _ = try S.doTest([4]u32);
1127}
1128
1129test "resist alias of explicit copy of array passed as arg" {
1130    const S = struct {
1131        const Thing = [1]u32;
1132
1133        fn destroy_and_replace(box_b: *Thing, a: Thing, box_a: *Thing) void {
1134            box_a.* = undefined;
1135            box_b.* = a;
1136        }
1137    };
1138
1139    var buf_a: S.Thing = .{1234};
1140    var buf_b: S.Thing = .{5678};
1141    const box_a = &buf_a;
1142    const box_b = &buf_b;
1143
1144    const a = box_a.*; // explicit copy
1145    S.destroy_and_replace(box_b, a, box_a);
1146
1147    try expect(buf_b[0] == 1234);
1148}