diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-07-01 15:52:54 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-07-01 15:52:54 -0700 |
| commit | c89dd15e1be4959800dc7092d7dd4375253db7bc (patch) | |
| tree | ca184ae53592efa21e67128a5f891d642d7f1118 /test/behavior/array.zig | |
| parent | 5466e87fce581f2ef90ac23bb80b1dbc05836fc6 (diff) | |
| parent | 2360f8c490f3ec684ed64ff28e8c1fade249070b (diff) | |
| download | zig-c89dd15e1be4959800dc7092d7dd4375253db7bc.tar.gz zig-c89dd15e1be4959800dc7092d7dd4375253db7bc.zip | |
Merge remote-tracking branch 'origin/master' into llvm14
Diffstat (limited to 'test/behavior/array.zig')
| -rw-r--r-- | test/behavior/array.zig | 406 |
1 files changed, 386 insertions, 20 deletions
diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 0450d0781b..aea4dd357b 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -6,7 +6,7 @@ const expect = testing.expect; const expectEqual = testing.expectEqual; test "array to slice" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; const a: u32 align(4) = 3; const b: u32 align(8) = 4; @@ -20,6 +20,7 @@ test "array to slice" { } test "arrays" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array: [5]u32 = undefined; @@ -46,7 +47,7 @@ fn getArrayLen(a: []const u32) usize { } test "array init with mult" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const a = 'a'; var i: [8]u8 = [2]u8{ a, 'b' } ** 4; @@ -57,7 +58,7 @@ test "array init with mult" { } test "array literal with explicit type" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const hex_mult: [4]u16 = .{ 4096, 256, 16, 1 }; @@ -66,8 +67,6 @@ test "array literal with explicit type" { } test "array literal with inferred length" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - const hex_mult = [_]u16{ 4096, 256, 16, 1 }; try expect(hex_mult.len == 4); @@ -86,7 +85,8 @@ const ArrayDotLenConstExpr = struct { const some_array = [_]u8{ 0, 1, 2, 3 }; test "array literal with specified size" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var array = [2]u8{ 1, 2 }; try expect(array[0] == 1); @@ -94,25 +94,28 @@ test "array literal with specified size" { } test "array len field" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - var arr = [4]u8{ 0, 0, 0, 0 }; var ptr = &arr; try expect(arr.len == 4); comptime try expect(arr.len == 4); try expect(ptr.len == 4); comptime try expect(ptr.len == 4); + try expect(@TypeOf(arr.len) == usize); } test "array with sentinels" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage1) { + // Stage1 test coverage disabled at runtime because of + // https://github.com/ziglang/zig/issues/4372 + return error.SkipZigTest; + } + + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; const S = struct { fn doTheTest(is_ct: bool) !void { - if (is_ct or builtin.zig_backend != .stage1) { + { var zero_sized: [0:0xde]u8 = [_:0xde]u8{}; - // Stage1 test coverage disabled at runtime because of - // https://github.com/ziglang/zig/issues/4372 try expect(zero_sized[0] == 0xde); var reinterpreted = @ptrCast(*[1]u8, &zero_sized); try expect(reinterpreted[0] == 0xde); @@ -134,8 +137,6 @@ test "array with sentinels" { } test "void arrays" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - var array: [4]void = undefined; array[0] = void{}; array[1] = array[2]; @@ -143,8 +144,9 @@ test "void arrays" { try expect(array.len == 4); } -test "nested arrays" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; +test "nested arrays of strings" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const array_of_strings = [_][]const u8{ "hello", "this", "is", "my", "thing" }; for (array_of_strings) |s, i| { @@ -156,7 +158,23 @@ test "nested arrays" { } } +test "nested arrays of integers" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + + const array_of_numbers = [_][2]u8{ + [2]u8{ 1, 2 }, + [2]u8{ 3, 4 }, + }; + + try expect(array_of_numbers[0][0] == 1); + try expect(array_of_numbers[0][1] == 2); + try expect(array_of_numbers[1][0] == 3); + try expect(array_of_numbers[1][1] == 4); +} + test "implicit comptime in array type size" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; var arr: [plusOne(10)]bool = undefined; @@ -168,7 +186,7 @@ fn plusOne(x: u32) u32 { } test "single-item pointer to array indexing and slicing" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; try testSingleItemPtrArrayIndexSlice(); comptime try testSingleItemPtrArrayIndexSlice(); @@ -193,8 +211,6 @@ fn doSomeMangling(array: *[4]u8) void { } test "implicit cast zero sized array ptr to slice" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - { var b = "".*; const c: []const u8 = &b; @@ -208,7 +224,8 @@ test "implicit cast zero sized array ptr to slice" { } test "anonymous list literal syntax" { - if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; const S = struct { fn doTheTest() !void { @@ -222,3 +239,352 @@ test "anonymous list literal syntax" { try S.doTheTest(); comptime try S.doTheTest(); } + +var s_array: [8]Sub = undefined; +const Sub = struct { b: u8 }; +const Str = struct { a: []Sub }; +test "set global var array via slice embedded in struct" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + var s = Str{ .a = s_array[0..] }; + + s.a[0].b = 1; + s.a[1].b = 2; + s.a[2].b = 3; + + try expect(s_array[0].b == 1); + try expect(s_array[1].b == 2); + try expect(s_array[2].b == 3); +} + +test "read/write through global variable array of struct fields initialized via array mult" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + try expect(storage[0].term == 1); + storage[0] = MyStruct{ .term = 123 }; + try expect(storage[0].term == 123); + } + + pub const MyStruct = struct { + term: usize, + }; + + var storage: [1]MyStruct = [_]MyStruct{MyStruct{ .term = 1 }} ** 1; + }; + try S.doTheTest(); +} + +test "implicit cast single-item pointer" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + try testImplicitCastSingleItemPtr(); + comptime try testImplicitCastSingleItemPtr(); +} + +fn testImplicitCastSingleItemPtr() !void { + var byte: u8 = 100; + const slice = @as(*[1]u8, &byte)[0..]; + slice[0] += 1; + try expect(byte == 101); +} + +fn testArrayByValAtComptime(b: [2]u8) u8 { + return b[0]; +} + +test "comptime evaluating function that takes array by value" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const arr = [_]u8{ 1, 2 }; + const x = comptime testArrayByValAtComptime(arr); + const y = comptime testArrayByValAtComptime(arr); + try expect(x == 1); + try expect(y == 1); +} + +test "runtime initialize array elem and then implicit cast to slice" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + var two: i32 = 2; + const x: []const i32 = &[_]i32{two}; + try expect(x[0] == 2); +} + +test "array literal as argument to function" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + const S = struct { + fn entry(two: i32) !void { + try foo(&[_]i32{ 1, 2, 3 }); + try foo(&[_]i32{ 1, two, 3 }); + try foo2(true, &[_]i32{ 1, 2, 3 }); + try foo2(true, &[_]i32{ 1, two, 3 }); + } + fn foo(x: []const i32) !void { + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + fn foo2(trash: bool, x: []const i32) !void { + try expect(trash); + try expect(x[0] == 1); + try expect(x[1] == 2); + try expect(x[2] == 3); + } + }; + try S.entry(2); + comptime try S.entry(2); +} + +test "double nested array to const slice cast in array literal" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn entry(two: i32) !void { + const cases = [_][]const []const i32{ + &[_][]const i32{&[_]i32{1}}, + &[_][]const i32{&[_]i32{ 2, 3 }}, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, + }, + }; + try check(&cases); + + const cases2 = [_][]const i32{ + &[_]i32{1}, + &[_]i32{ two, 3 }, + }; + try expect(cases2.len == 2); + try expect(cases2[0].len == 1); + try expect(cases2[0][0] == 1); + try expect(cases2[1].len == 2); + try expect(cases2[1][0] == 2); + try expect(cases2[1][1] == 3); + + const cases3 = [_][]const []const i32{ + &[_][]const i32{&[_]i32{1}}, + &[_][]const i32{&[_]i32{ two, 3 }}, + &[_][]const i32{ + &[_]i32{4}, + &[_]i32{ 5, 6, 7 }, + }, + }; + try check(&cases3); + } + + fn check(cases: []const []const []const i32) !void { + try expect(cases.len == 3); + try expect(cases[0].len == 1); + try expect(cases[0][0].len == 1); + try expect(cases[0][0][0] == 1); + try expect(cases[1].len == 1); + try expect(cases[1][0].len == 2); + try expect(cases[1][0][0] == 2); + try expect(cases[1][0][1] == 3); + try expect(cases[2].len == 2); + try expect(cases[2][0].len == 1); + try expect(cases[2][0][0] == 4); + try expect(cases[2][1].len == 3); + try expect(cases[2][1][0] == 5); + try expect(cases[2][1][1] == 6); + try expect(cases[2][1][2] == 7); + } + }; + try S.entry(2); + comptime try S.entry(2); +} + +test "anonymous literal in array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const Foo = struct { + a: usize = 2, + b: usize = 4, + }; + fn doTheTest() !void { + var array: [2]Foo = .{ + .{ .a = 3 }, + .{ .b = 3 }, + }; + try expect(array[0].a == 3); + try expect(array[0].b == 4); + try expect(array[1].a == 2); + try expect(array[1].b == 3); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "access the null element of a null terminated array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + var array: [4:0]u8 = .{ 'a', 'o', 'e', 'u' }; + try expect(array[4] == 0); + var len: usize = 4; + try expect(array[len] == 0); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "type deduction for array subscript expression" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + var array = [_]u8{ 0x55, 0xAA }; + var v0 = true; + try expect(@as(u8, 0xAA) == array[if (v0) 1 else 0]); + var v1 = false; + try expect(@as(u8, 0x55) == array[if (v1) 1 else 0]); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "sentinel element count towards the ABI size calculation" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest() !void { + const T = extern struct { + fill_pre: u8 = 0x55, + data: [0:0]u8 = undefined, + fill_post: u8 = 0xAA, + }; + var x = T{}; + var as_slice = mem.asBytes(&x); + try expect(@as(usize, 3) == as_slice.len); + try expect(@as(u8, 0x55) == as_slice[0]); + try expect(@as(u8, 0xAA) == as_slice[2]); + } + }; + + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "zero-sized array with recursive type definition" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const U = struct { + fn foo(comptime T: type, comptime n: usize) type { + return struct { + s: [n]T, + x: usize = n, + }; + } + }; + + const S = struct { + list: U.foo(@This(), 0), + }; + + var t: S = .{ .list = .{ .s = undefined } }; + try expect(@as(usize, 0) == t.list.x); +} + +test "type coercion of anon struct literal to array" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const U = union { + a: u32, + b: bool, + c: []const u8, + }; + + fn doTheTest() !void { + var x1: u8 = 42; + const t1 = .{ x1, 56, 54 }; + var arr1: [3]u8 = t1; + try expect(arr1[0] == 42); + try expect(arr1[1] == 56); + try expect(arr1[2] == 54); + + var x2: U = .{ .a = 42 }; + const t2 = .{ x2, .{ .b = true }, .{ .c = "hello" } }; + var arr2: [3]U = t2; + try expect(arr2[0].a == 42); + try expect(arr2[1].b == true); + try expect(mem.eql(u8, arr2[2].c, "hello")); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "type coercion of pointer to anon struct literal to pointer to array" { + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + + const S = struct { + const U = union { + a: u32, + b: bool, + c: []const u8, + }; + + fn doTheTest() !void { + var x1: u8 = 42; + const t1 = &.{ x1, 56, 54 }; + var arr1: *const [3]u8 = t1; + try expect(arr1[0] == 42); + try expect(arr1[1] == 56); + try expect(arr1[2] == 54); + + var x2: U = .{ .a = 42 }; + const t2 = &.{ x2, .{ .b = true }, .{ .c = "hello" } }; + var arr2: *const [3]U = t2; + try expect(arr2[0].a == 42); + try expect(arr2[1].b == true); + try expect(mem.eql(u8, arr2[2].c, "hello")); + } + }; + try S.doTheTest(); + comptime try S.doTheTest(); +} + +test "array with comptime only element type" { + const a = [_]type{ + u32, + i32, + }; + try testing.expect(a[0] == u32); + try testing.expect(a[1] == i32); +} + +test "tuple to array handles sentinel" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + + const S = struct { + const a = .{ 1, 2, 3 }; + var b: [3:0]u8 = a; + }; + try expect(S.b[0] == 1); +} |
