diff --git a/test/behavior.zig b/test/behavior.zig index 26333758086ae14904d9c275e4afcb55eb3176f7..25c39e172eb6d27c12defc046b5513bb32cff7ac 100644 --- a/test/behavior.zig +++ b/test/behavior.zig @@ -78,6 +78,7 @@ test { _ = @import("behavior/sizeof_and_typeof.zig"); _ = @import("behavior/slice.zig"); _ = @import("behavior/slice_sentinel_comptime.zig"); + _ = @import("behavior/splat.zig"); _ = @import("behavior/src.zig"); _ = @import("behavior/string_literals.zig"); _ = @import("behavior/struct.zig"); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index e4b7b6d75d1f891212d2e877779e41afa6f7d6db..4a68b51d33f11593b29f4783deec3b0267184a65 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -326,26 +326,6 @@ test "set global var array via slice embedded in struct" { try expect(s_array[2].b == 3); } -test "read/write through global variable array of struct fields initialized via splat" { - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_sparc64) 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 = @splat(.{ .term = 1 }); - }; - try S.doTheTest(); -} - test "implicit cast single-item pointer" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO @@ -988,74 +968,6 @@ test "runtime index of array of zero-bit values" { try std.testing.expect(result.value == {}); } -test "@splat array" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - - const S = struct { - fn doTheTest(comptime T: type, x: T) !void { - const arr: [10]T = @splat(x); - for (arr) |elem| { - try expectEqual(x, elem); - } - } - }; - - try S.doTheTest(u32, 123); - try comptime S.doTheTest(u32, 123); - - const Foo = struct { x: u8 }; - try S.doTheTest(Foo, .{ .x = 10 }); - try comptime S.doTheTest(Foo, .{ .x = 10 }); -} - -test "@splat array with sentinel" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - - const S = struct { - fn doTheTest(comptime T: type, x: T, comptime s: T) !void { - const arr: [10:s]T = @splat(x); - for (arr) |elem| { - try expectEqual(x, elem); - } - const ptr: [*]const T = &arr; - try expectEqual(s, ptr[10]); // sentinel correct - } - }; - - try S.doTheTest(u32, 100, 42); - try comptime S.doTheTest(u32, 100, 42); - - try S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null); - try comptime S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null); -} - -test "@splat zero-length array" { - if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - - const S = struct { - fn doTheTest(comptime T: type, comptime s: T) !void { - var runtime_undef: T = undefined; - runtime_undef = undefined; - // The array should be comptime-known despite the `@splat` operand being runtime-known. - const arr: [0:s]T = @splat(runtime_undef); - const ptr: [*]const T = &arr; - comptime assert(ptr[0] == s); - } - }; - - try S.doTheTest(u32, 42); - try comptime S.doTheTest(u32, 42); - - try S.doTheTest(?*anyopaque, null); - try comptime S.doTheTest(?*anyopaque, null); -} - test "initialize slice with reference to empty array initializer" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; @@ -1116,19 +1028,6 @@ test "sentinel of runtime-known array initialization is populated" { try expect(elems[1] == 123); } -test "splat with an error union or optional result type" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - - const S = struct { - fn doTest(T: type) !?T { - return @splat(1); - } - }; - - _ = try S.doTest(@Vector(4, u32)); - _ = try S.doTest([4]u32); -} - test "resist alias of explicit copy of array passed as arg" { const S = struct { const Thing = [1]u32; diff --git a/test/behavior/splat.zig b/test/behavior/splat.zig new file mode 100644 index 0000000000000000000000000000000000000000..60d4c23f19b0d3621ff49601fbd04e3c690b8b7a --- /dev/null +++ b/test/behavior/splat.zig @@ -0,0 +1,152 @@ +const builtin = @import("builtin"); + +const std = @import("std"); +const expect = std.testing.expect; +const assert = std.debug.assert; + +test "@splat array" { + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + const Foo = struct { x: u8 }; + const S = struct { + fn testInt(x: u32) !void { + const arr: [10]u32 = @splat(x); + for (arr) |elem| { + try expect(x == elem); + } + } + + fn testStruct(x: Foo) !void { + const arr: [10]Foo = @splat(x); + for (arr) |elem| { + try expect(x.x == elem.x); + } + } + }; + + try S.testInt(123); + try comptime S.testInt(123); + + try S.testStruct(.{ .x = 10 }); + try comptime S.testStruct(.{ .x = 10 }); +} + +test "@splat array with sentinel" { + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest(comptime T: type, x: T, comptime s: T) !void { + const arr: [10:s]T = @splat(x); + for (arr) |elem| { + try expect(x == elem); + } + const ptr: [*]const T = &arr; + try expect(s == ptr[10]); // sentinel correct + } + }; + + try S.doTheTest(u32, 100, 42); + try comptime S.doTheTest(u32, 100, 42); + + try S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null); + try comptime S.doTheTest(?*anyopaque, @ptrFromInt(0x1000), null); +} + +test "@splat zero-length array" { + if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + const S = struct { + fn doTheTest(comptime T: type, comptime s: T) !void { + var runtime_undef: T = undefined; + runtime_undef = undefined; + // The array should be comptime-known despite the `@splat` operand being runtime-known. + const arr: [0:s]T = @splat(runtime_undef); + const ptr: [*]const T = &arr; + comptime assert(ptr[0] == s); + } + }; + + try S.doTheTest(u32, 42); + try comptime S.doTheTest(u32, 42); + + try S.doTheTest(?*anyopaque, null); + try comptime S.doTheTest(?*anyopaque, null); +} + +test "splat with an error union or optional result type" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + const S = struct { + fn doTest(T: type) !?T { + return @splat(1); + } + }; + + _ = try S.doTest(@Vector(4, u32)); + _ = try S.doTest([4]u32); +} + +test "read/write through global variable array of struct fields initialized via splat" { + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) 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 = @splat(.{ .term = 1 }); + }; + try S.doTheTest(); +} + +test "vector @splat" { + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; + const S = struct { + fn testForT(comptime N: comptime_int, v: anytype) !void { + const T = @TypeOf(v); + var vec: @Vector(N, T) = @splat(v); + _ = &vec; + const as_array = @as([N]T, vec); + for (as_array) |elem| try expect(v == elem); + } + fn doTheTest() !void { + // Splats with multiple-of-8 bit types that fill a 128bit vector. + try testForT(16, @as(u8, 0xEE)); + try testForT(8, @as(u16, 0xBEEF)); + try testForT(4, @as(u32, 0xDEADBEEF)); + try testForT(2, @as(u64, 0xCAFEF00DDEADBEEF)); + + try testForT(8, @as(f16, 3.1415)); + try testForT(4, @as(f32, 3.1415)); + try testForT(2, @as(f64, 3.1415)); + + // Same but fill more than 128 bits. + try testForT(16 * 2, @as(u8, 0xEE)); + try testForT(8 * 2, @as(u16, 0xBEEF)); + try testForT(4 * 2, @as(u32, 0xDEADBEEF)); + try testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF)); + + try testForT(8 * 2, @as(f16, 3.1415)); + try testForT(4 * 2, @as(f32, 3.1415)); + try testForT(2 * 2, @as(f64, 3.1415)); + } + }; + try S.doTheTest(); + try comptime S.doTheTest(); +} diff --git a/test/behavior/vector.zig b/test/behavior/vector.zig index 79aaae3e3b5f003cf414b558e4aef048c383ebee..c19155c864124180b6baadcb2aaa9b7b6d7a4dfe 100644 --- a/test/behavior/vector.zig +++ b/test/behavior/vector.zig @@ -374,45 +374,6 @@ test "vector casts of sizes not divisible by 8" { try comptime S.doTheTest(); } -test "vector @splat" { - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; - const S = struct { - fn testForT(comptime N: comptime_int, v: anytype) !void { - const T = @TypeOf(v); - var vec: @Vector(N, T) = @splat(v); - _ = &vec; - const as_array = @as([N]T, vec); - for (as_array) |elem| try expect(v == elem); - } - fn doTheTest() !void { - // Splats with multiple-of-8 bit types that fill a 128bit vector. - try testForT(16, @as(u8, 0xEE)); - try testForT(8, @as(u16, 0xBEEF)); - try testForT(4, @as(u32, 0xDEADBEEF)); - try testForT(2, @as(u64, 0xCAFEF00DDEADBEEF)); - - try testForT(8, @as(f16, 3.1415)); - try testForT(4, @as(f32, 3.1415)); - try testForT(2, @as(f64, 3.1415)); - - // Same but fill more than 128 bits. - try testForT(16 * 2, @as(u8, 0xEE)); - try testForT(8 * 2, @as(u16, 0xBEEF)); - try testForT(4 * 2, @as(u32, 0xDEADBEEF)); - try testForT(2 * 2, @as(u64, 0xCAFEF00DDEADBEEF)); - - try testForT(8 * 2, @as(f16, 3.1415)); - try testForT(4 * 2, @as(f32, 3.1415)); - try testForT(2 * 2, @as(f64, 3.1415)); - } - }; - try S.doTheTest(); - try comptime S.doTheTest(); -} - test "load vector elements via comptime index" { if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO