Commit c349191b75
Changed files (15)
test/behavior/array.zig
@@ -222,3 +222,353 @@ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ 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_llvm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ const T = packed 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_llvm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) 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_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) 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);
+
+ if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
+ if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ 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_llvm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) 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: *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/behavior/array_llvm.zig
@@ -1,315 +0,0 @@
-const std = @import("std");
-const testing = std.testing;
-const expect = testing.expect;
-const mem = std.mem;
-
-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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var two: i32 = 2;
- const x: []const i32 = &[_]i32{two};
- try expect(x[0] == 2);
-}
-
-test "array literal as argument to function" {
- if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn doTheTest() !void {
- const T = packed 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 (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_c) 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 (@import("builtin").zig_backend == .stage2_c) 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);
-
- if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-
- 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 (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
- if (@import("builtin").zig_backend == .stage2_c) 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/behavior/cast.zig
@@ -1,8 +1,9 @@
+const builtin = @import("builtin");
const std = @import("std");
const expect = std.testing.expect;
const mem = std.mem;
const maxInt = std.math.maxInt;
-const builtin = @import("builtin");
+const native_endian = builtin.target.cpu.arch.endian();
test "int to ptr cast" {
const x = @as(usize, 13);
@@ -93,7 +94,8 @@ test "comptime_int @intToFloat" {
}
test "@floatToInt" {
- if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
try testFloatToInts();
comptime try testFloatToInts();
@@ -802,3 +804,337 @@ test "comptime float casts" {
try expectFloatToInt(comptime_int, 1234, i16, 1234);
try expectFloatToInt(comptime_float, 12.3, comptime_int, 12);
}
+
+test "pointer reinterpret const float to int" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ // The hex representation is 0x3fe3333333333303.
+ const float: f64 = 5.99999999999994648725e-01;
+ const float_ptr = &float;
+ const int_ptr = @ptrCast(*const i32, float_ptr);
+ const int_val = int_ptr.*;
+ if (native_endian == .Little)
+ try expect(int_val == 0x33333303)
+ else
+ try expect(int_val == 0x3fe33333);
+}
+
+test "implicit cast from [*]T to ?*anyopaque" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var a = [_]u8{ 3, 2, 1 };
+ var runtime_zero: usize = 0;
+ incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
+ try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
+}
+
+fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
+ var n: usize = 0;
+ while (n < len) : (n += 1) {
+ @ptrCast([*]u8, array.?)[n] += 1;
+ }
+}
+
+test "compile time int to ptr of function" {
+ if (builtin.zig_backend == .stage1) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .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
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ try foobar(FUNCTION_CONSTANT);
+}
+
+pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
+pub const PFN_void = *const fn (*anyopaque) callconv(.C) void;
+
+fn foobar(func: PFN_void) !void {
+ try std.testing.expect(@ptrToInt(func) == maxInt(usize));
+}
+
+test "implicit ptr to *anyopaque" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var a: u32 = 1;
+ var ptr: *align(@alignOf(u32)) anyopaque = &a;
+ var b: *u32 = @ptrCast(*u32, ptr);
+ try expect(b.* == 1);
+ var ptr2: ?*align(@alignOf(u32)) anyopaque = &a;
+ var c: *u32 = @ptrCast(*u32, ptr2.?);
+ try expect(c.* == 1);
+}
+
+test "return null from fn() anyerror!?&T" {
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ const a = returnNullFromOptionalTypeErrorRef();
+ const b = returnNullLitFromOptionalTypeErrorRef();
+ try expect((try a) == null and (try b) == null);
+}
+fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
+ const a: ?*A = null;
+ return a;
+}
+fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
+ return null;
+}
+
+test "peer type resolution: [0]u8 and []const u8" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+ try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+ comptime {
+ try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+ try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+ }
+}
+fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
+ if (a) {
+ return &[_]u8{};
+ }
+
+ return slice[0..1];
+}
+
+test "implicitly cast from [N]T to ?[]const T" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
+ comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
+}
+
+fn castToOptionalSlice() ?[]const u8 {
+ return "hi";
+}
+
+test "cast u128 to f128 and back" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ comptime try testCast128();
+ try testCast128();
+}
+
+fn testCast128() !void {
+ try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
+}
+
+fn cast128Int(x: f128) u128 {
+ return @bitCast(u128, x);
+}
+
+fn cast128Float(x: u128) f128 {
+ return @bitCast(f128, x);
+}
+
+test "implicit cast from *[N]T to ?[*]T" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var x: ?[*]u16 = null;
+ var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
+
+ x = &y;
+ try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
+ x.?[0] = 8;
+ y[3] = 6;
+ try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
+}
+
+test "implicit cast from *T to ?*anyopaque" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var a: u8 = 1;
+ incrementVoidPtrValue(&a);
+ try std.testing.expect(a == 2);
+}
+
+fn incrementVoidPtrValue(value: ?*anyopaque) void {
+ @ptrCast(*u8, value.?).* += 1;
+}
+
+test "implicit cast *[0]T to E![]const u8" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var x = @as(anyerror![]const u8, &[0]u8{});
+ try expect((x catch unreachable).len == 0);
+}
+
+var global_array: [4]u8 = undefined;
+test "cast from array reference to fn: comptime fn ptr" {
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ const f = @ptrCast(*const fn () callconv(.C) void, &global_array);
+ try expect(@ptrToInt(f) == @ptrToInt(&global_array));
+}
+test "cast from array reference to fn: runtime fn ptr" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var f = @ptrCast(*const fn () callconv(.C) void, &global_array);
+ try expect(@ptrToInt(f) == @ptrToInt(&global_array));
+}
+
+test "*const [N]null u8 to ?[]const u8" {
+ if (builtin.zig_backend == .stage2_c) 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 {
+ fn doTheTest() !void {
+ var a = "Hello";
+ var b: ?[]const u8 = a;
+ try expect(mem.eql(u8, b.?, "Hello"));
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "cast between [*c]T and ?[*:0]T on fn parameter" {
+ 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 Handler = ?fn ([*c]const u8) callconv(.C) void;
+ fn addCallback(handler: Handler) void {
+ _ = handler;
+ }
+
+ fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {
+ _ = cstr;
+ }
+
+ fn doTheTest() void {
+ addCallback(myCallback);
+ }
+ };
+ S.doTheTest();
+}
+
+var global_struct: struct { f0: usize } = undefined;
+test "assignment to optional pointer result loc" {
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
+ try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct));
+}
+
+test "cast between *[N]void and []void" {
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ var a: [4]void = undefined;
+ var b: []void = &a;
+ try expect(b.len == 4);
+}
+
+test "peer resolve arrays of different size to const slice" {
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ try expect(mem.eql(u8, boolToStr(true), "true"));
+ try expect(mem.eql(u8, boolToStr(false), "false"));
+ comptime try expect(mem.eql(u8, boolToStr(true), "true"));
+ comptime try expect(mem.eql(u8, boolToStr(false), "false"));
+}
+fn boolToStr(b: bool) []const u8 {
+ return if (b) "true" else "false";
+}
+
+test "cast f16 to wider types" {
+ if (builtin.zig_backend == .stage2_c) 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
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var x: f16 = 1234.0;
+ try expect(@as(f32, 1234.0) == x);
+ try expect(@as(f64, 1234.0) == x);
+ try expect(@as(f128, 1234.0) == x);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "cast f128 to narrower types" {
+ if (builtin.zig_backend == .stage2_c) 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
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var x: f128 = 1234.0;
+ try expect(@as(f16, 1234.0) == @floatCast(f16, x));
+ try expect(@as(f32, 1234.0) == @floatCast(f32, x));
+ try expect(@as(f64, 1234.0) == @floatCast(f64, x));
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "peer type resolution: unreachable, null, slice" {
+ if (builtin.zig_backend == .stage2_c) 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 {
+ fn doTheTest(num: usize, word: []const u8) !void {
+ const result = switch (num) {
+ 0 => null,
+ 1 => word,
+ else => unreachable,
+ };
+ try expect(mem.eql(u8, result.?, "hi"));
+ }
+ };
+ try S.doTheTest(1, "hi");
+}
+
+test "cast i8 fn call peers to i32 result" {
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var cond = true;
+ const value: i32 = if (cond) smallBoi() else bigBoi();
+ try expect(value == 123);
+ }
+ fn smallBoi() i8 {
+ return 123;
+ }
+ fn bigBoi() i16 {
+ return 1234;
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
test/behavior/cast_llvm.zig
@@ -1,299 +0,0 @@
-const builtin = @import("builtin");
-const std = @import("std");
-const expect = std.testing.expect;
-const mem = std.mem;
-const maxInt = std.math.maxInt;
-const native_endian = builtin.target.cpu.arch.endian();
-
-test "pointer reinterpret const float to int" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- // The hex representation is 0x3fe3333333333303.
- const float: f64 = 5.99999999999994648725e-01;
- const float_ptr = &float;
- const int_ptr = @ptrCast(*const i32, float_ptr);
- const int_val = int_ptr.*;
- if (native_endian == .Little)
- try expect(int_val == 0x33333303)
- else
- try expect(int_val == 0x3fe33333);
-}
-
-test "@floatToInt" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- try testFloatToInts();
- comptime try testFloatToInts();
-}
-
-fn testFloatToInts() !void {
- try expectFloatToInt(f16, 255.1, u8, 255);
- try expectFloatToInt(f16, 127.2, i8, 127);
- try expectFloatToInt(f16, -128.2, i8, -128);
-}
-
-fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
- try expect(@floatToInt(I, f) == i);
-}
-
-test "implicit cast from [*]T to ?*anyopaque" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- var a = [_]u8{ 3, 2, 1 };
- var runtime_zero: usize = 0;
- incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
- try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
-}
-
-fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
- var n: usize = 0;
- while (n < len) : (n += 1) {
- @ptrCast([*]u8, array.?)[n] += 1;
- }
-}
-
-test "compile time int to ptr of function" {
- if (builtin.zig_backend == .stage1) return error.SkipZigTest;
- if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- try foobar(FUNCTION_CONSTANT);
-}
-
-pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
-pub const PFN_void = *const fn (*anyopaque) callconv(.C) void;
-
-fn foobar(func: PFN_void) !void {
- try std.testing.expect(@ptrToInt(func) == maxInt(usize));
-}
-
-test "implicit ptr to *anyopaque" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
-
- var a: u32 = 1;
- var ptr: *align(@alignOf(u32)) anyopaque = &a;
- var b: *u32 = @ptrCast(*u32, ptr);
- try expect(b.* == 1);
- var ptr2: ?*align(@alignOf(u32)) anyopaque = &a;
- var c: *u32 = @ptrCast(*u32, ptr2.?);
- try expect(c.* == 1);
-}
-
-const A = struct {
- a: i32,
-};
-test "return null from fn() anyerror!?&T" {
- const a = returnNullFromOptionalTypeErrorRef();
- const b = returnNullLitFromOptionalTypeErrorRef();
- try expect((try a) == null and (try b) == null);
-}
-fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
- const a: ?*A = null;
- return a;
-}
-fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
- return null;
-}
-
-test "peer type resolution: [0]u8 and []const u8" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
- try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
- comptime {
- try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
- try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
- }
-}
-fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
- if (a) {
- return &[_]u8{};
- }
-
- return slice[0..1];
-}
-
-test "implicitly cast from [N]T to ?[]const T" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
- comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
-}
-
-fn castToOptionalSlice() ?[]const u8 {
- return "hi";
-}
-
-test "cast u128 to f128 and back" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- comptime try testCast128();
- try testCast128();
-}
-
-fn testCast128() !void {
- try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
-}
-
-fn cast128Int(x: f128) u128 {
- return @bitCast(u128, x);
-}
-
-fn cast128Float(x: u128) f128 {
- return @bitCast(f128, x);
-}
-
-test "implicit cast from *[N]T to ?[*]T" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var x: ?[*]u16 = null;
- var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
-
- x = &y;
- try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
- x.?[0] = 8;
- y[3] = 6;
- try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
-}
-
-test "implicit cast from *T to ?*anyopaque" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var a: u8 = 1;
- incrementVoidPtrValue(&a);
- try std.testing.expect(a == 2);
-}
-
-fn incrementVoidPtrValue(value: ?*anyopaque) void {
- @ptrCast(*u8, value.?).* += 1;
-}
-
-test "implicit cast *[0]T to E![]const u8" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var x = @as(anyerror![]const u8, &[0]u8{});
- try expect((x catch unreachable).len == 0);
-}
-
-var global_array: [4]u8 = undefined;
-test "cast from array reference to fn: comptime fn ptr" {
- const f = @ptrCast(*const fn () callconv(.C) void, &global_array);
- try expect(@ptrToInt(f) == @ptrToInt(&global_array));
-}
-test "cast from array reference to fn: runtime fn ptr" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var f = @ptrCast(*const fn () callconv(.C) void, &global_array);
- try expect(@ptrToInt(f) == @ptrToInt(&global_array));
-}
-
-test "*const [N]null u8 to ?[]const u8" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- const S = struct {
- fn doTheTest() !void {
- var a = "Hello";
- var b: ?[]const u8 = a;
- try expect(mem.eql(u8, b.?, "Hello"));
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "cast between [*c]T and ?[*:0]T on fn parameter" {
- const S = struct {
- const Handler = ?fn ([*c]const u8) callconv(.C) void;
- fn addCallback(handler: Handler) void {
- _ = handler;
- }
-
- fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {
- _ = cstr;
- }
-
- fn doTheTest() void {
- addCallback(myCallback);
- }
- };
- S.doTheTest();
-}
-
-var global_struct: struct { f0: usize } = undefined;
-test "assignment to optional pointer result loc" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct };
- try expect(foo.ptr.? == @ptrCast(*anyopaque, &global_struct));
-}
-
-test "cast between *[N]void and []void" {
- var a: [4]void = undefined;
- var b: []void = &a;
- try expect(b.len == 4);
-}
-
-test "peer resolve arrays of different size to const slice" {
- try expect(mem.eql(u8, boolToStr(true), "true"));
- try expect(mem.eql(u8, boolToStr(false), "false"));
- comptime try expect(mem.eql(u8, boolToStr(true), "true"));
- comptime try expect(mem.eql(u8, boolToStr(false), "false"));
-}
-fn boolToStr(b: bool) []const u8 {
- return if (b) "true" else "false";
-}
-
-test "cast f16 to wider types" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
- const S = struct {
- fn doTheTest() !void {
- var x: f16 = 1234.0;
- try expect(@as(f32, 1234.0) == x);
- try expect(@as(f64, 1234.0) == x);
- try expect(@as(f128, 1234.0) == x);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "cast f128 to narrower types" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn doTheTest() !void {
- var x: f128 = 1234.0;
- try expect(@as(f16, 1234.0) == @floatCast(f16, x));
- try expect(@as(f32, 1234.0) == @floatCast(f32, x));
- try expect(@as(f64, 1234.0) == @floatCast(f64, x));
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "peer type resolution: unreachable, null, slice" {
- if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
- const S = struct {
- fn doTheTest(num: usize, word: []const u8) !void {
- const result = switch (num) {
- 0 => null,
- 1 => word,
- else => unreachable,
- };
- try expect(mem.eql(u8, result.?, "hi"));
- }
- };
- try S.doTheTest(1, "hi");
-}
-
-test "cast i8 fn call peers to i32 result" {
- const S = struct {
- fn doTheTest() !void {
- var cond = true;
- const value: i32 = if (cond) smallBoi() else bigBoi();
- try expect(value == 123);
- }
- fn smallBoi() i8 {
- return 123;
- }
- fn bigBoi() i16 {
- return 1234;
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
test/behavior/error.zig
@@ -478,3 +478,29 @@ test "error union comptime caching" {
S.quux(@as(anyerror!void, {}));
S.quux(@as(anyerror!void, {}));
}
+
+test "@errorName" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ try expect(mem.eql(u8, @errorName(error.AnError), "AnError"));
+ try expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
+ try expect(mem.eql(u8, @errorName(gimmeItBroke()), "ItBroke"));
+}
+fn gimmeItBroke() anyerror {
+ return error.ItBroke;
+}
+
+test "@errorName sentinel length matches slice length" {
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+
+ const name = testBuiltinErrorName(error.FooBar);
+ const length: usize = 6;
+ try expect(length == std.mem.indexOfSentinel(u8, 0, name.ptr));
+ try expect(length == name.len);
+}
+
+pub fn testBuiltinErrorName(err: anyerror) [:0]const u8 {
+ return @errorName(err);
+}
test/behavior/error_llvm.zig
@@ -1,24 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const mem = std.mem;
-
-fn gimmeItBroke() anyerror {
- return error.ItBroke;
-}
-
-test "@errorName" {
- try expect(mem.eql(u8, @errorName(error.AnError), "AnError"));
- try expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
- try expect(mem.eql(u8, @errorName(gimmeItBroke()), "ItBroke"));
-}
-
-test "@errorName sentinel length matches slice length" {
- const name = testBuiltinErrorName(error.FooBar);
- const length: usize = 6;
- try expect(length == std.mem.indexOfSentinel(u8, 0, name.ptr));
- try expect(length == name.len);
-}
-
-pub fn testBuiltinErrorName(err: anyerror) [:0]const u8 {
- return @errorName(err);
-}
test/behavior/sizeof_and_typeof.zig
@@ -1,3 +1,4 @@
+const builtin = @import("builtin");
const std = @import("std");
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
@@ -160,3 +161,115 @@ test "@bitOffsetOf" {
try expect(@offsetOf(A, "f") * 8 == @bitOffsetOf(A, "f"));
try expect(@offsetOf(A, "g") * 8 == @bitOffsetOf(A, "g"));
}
+
+test "@sizeOf(T) == 0 doesn't force resolving struct size" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Foo = struct {
+ y: if (@sizeOf(Foo) == 0) u64 else u32,
+ };
+ const Bar = struct {
+ x: i32,
+ y: if (0 == @sizeOf(Bar)) u64 else u32,
+ };
+ };
+
+ try expect(@sizeOf(S.Foo) == 4);
+ try expect(@sizeOf(S.Bar) == 8);
+}
+
+test "@TypeOf() has no runtime side effects" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn foo(comptime T: type, ptr: *T) T {
+ ptr.* += 1;
+ return ptr.*;
+ }
+ };
+ var data: i32 = 0;
+ const T = @TypeOf(S.foo(i32, &data));
+ comptime try expect(T == i32);
+ try expect(data == 0);
+}
+
+test "branching logic inside @TypeOf" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ var data: i32 = 0;
+ fn foo() anyerror!i32 {
+ data += 1;
+ return undefined;
+ }
+ };
+ const T = @TypeOf(S.foo() catch undefined);
+ comptime try expect(T == i32);
+ try expect(S.data == 0);
+}
+
+test "@bitSizeOf" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try expect(@bitSizeOf(u2) == 2);
+ try expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
+ try expect(@bitSizeOf(struct {
+ a: u2,
+ }) == 8);
+ try expect(@bitSizeOf(packed struct {
+ a: u2,
+ }) == 2);
+}
+
+test "@sizeOf comparison against zero" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S0 = struct {
+ f: *@This(),
+ };
+ const U0 = union {
+ f: *@This(),
+ };
+ const S1 = struct {
+ fn H(comptime T: type) type {
+ return struct {
+ x: T,
+ };
+ }
+ f0: H(*@This()),
+ f1: H(**@This()),
+ f2: H(***@This()),
+ };
+ const U1 = union {
+ fn H(comptime T: type) type {
+ return struct {
+ x: T,
+ };
+ }
+ f0: H(*@This()),
+ f1: H(**@This()),
+ f2: H(***@This()),
+ };
+ const S = struct {
+ fn doTheTest(comptime T: type, comptime result: bool) !void {
+ try expectEqual(result, @sizeOf(T) > 0);
+ }
+ };
+ // Zero-sized type
+ try S.doTheTest(u0, false);
+ try S.doTheTest(*u0, false);
+ // Non byte-sized type
+ try S.doTheTest(u1, true);
+ try S.doTheTest(*u1, true);
+ // Regular type
+ try S.doTheTest(u8, true);
+ try S.doTheTest(*u8, true);
+ try S.doTheTest(f32, true);
+ try S.doTheTest(*f32, true);
+ // Container with ptr pointing to themselves
+ try S.doTheTest(S0, true);
+ try S.doTheTest(U0, true);
+ try S.doTheTest(S1, true);
+ try S.doTheTest(U1, true);
+}
test/behavior/sizeof_and_typeof_stage1.zig
@@ -1,105 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const expectEqual = std.testing.expectEqual;
-
-test "@sizeOf(T) == 0 doesn't force resolving struct size" {
- const S = struct {
- const Foo = struct {
- y: if (@sizeOf(Foo) == 0) u64 else u32,
- };
- const Bar = struct {
- x: i32,
- y: if (0 == @sizeOf(Bar)) u64 else u32,
- };
- };
-
- try expect(@sizeOf(S.Foo) == 4);
- try expect(@sizeOf(S.Bar) == 8);
-}
-
-test "@TypeOf() has no runtime side effects" {
- const S = struct {
- fn foo(comptime T: type, ptr: *T) T {
- ptr.* += 1;
- return ptr.*;
- }
- };
- var data: i32 = 0;
- const T = @TypeOf(S.foo(i32, &data));
- comptime try expect(T == i32);
- try expect(data == 0);
-}
-
-test "branching logic inside @TypeOf" {
- const S = struct {
- var data: i32 = 0;
- fn foo() anyerror!i32 {
- data += 1;
- return undefined;
- }
- };
- const T = @TypeOf(S.foo() catch undefined);
- comptime try expect(T == i32);
- try expect(S.data == 0);
-}
-
-test "@bitSizeOf" {
- try expect(@bitSizeOf(u2) == 2);
- try expect(@bitSizeOf(u8) == @sizeOf(u8) * 8);
- try expect(@bitSizeOf(struct {
- a: u2,
- }) == 8);
- try expect(@bitSizeOf(packed struct {
- a: u2,
- }) == 2);
-}
-
-test "@sizeOf comparison against zero" {
- const S0 = struct {
- f: *@This(),
- };
- const U0 = union {
- f: *@This(),
- };
- const S1 = struct {
- fn H(comptime T: type) type {
- return struct {
- x: T,
- };
- }
- f0: H(*@This()),
- f1: H(**@This()),
- f2: H(***@This()),
- };
- const U1 = union {
- fn H(comptime T: type) type {
- return struct {
- x: T,
- };
- }
- f0: H(*@This()),
- f1: H(**@This()),
- f2: H(***@This()),
- };
- const S = struct {
- fn doTheTest(comptime T: type, comptime result: bool) !void {
- try expectEqual(result, @sizeOf(T) > 0);
- }
- };
- // Zero-sized type
- try S.doTheTest(u0, false);
- try S.doTheTest(*u0, false);
- // Non byte-sized type
- try S.doTheTest(u1, true);
- try S.doTheTest(*u1, true);
- // Regular type
- try S.doTheTest(u8, true);
- try S.doTheTest(*u8, true);
- try S.doTheTest(f32, true);
- try S.doTheTest(*f32, true);
- // Container with ptr pointing to themselves
- try S.doTheTest(S0, true);
- try S.doTheTest(U0, true);
- try S.doTheTest(S1, true);
- try S.doTheTest(U1, true);
-}
test/behavior/struct.zig
@@ -133,15 +133,6 @@ fn returnEmptyStructInstance() StructWithNoFields {
return empty_global_instance;
}
-const Node = struct {
- val: Val,
- next: *Node,
-};
-
-const Val = struct {
- x: i32,
-};
-
test "fn call of struct field" {
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
@@ -294,3 +285,888 @@ const blah: packed struct {
test "bit field alignment" {
try expect(@TypeOf(&blah.b) == *align(1:3:1) const u3);
}
+
+const Node = struct {
+ val: Val,
+ next: *Node,
+};
+
+const Val = struct {
+ x: i32,
+};
+
+test "struct point to self" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var root: Node = undefined;
+ root.val.x = 1;
+
+ var node: Node = undefined;
+ node.next = &root;
+ node.val.x = 2;
+
+ root.next = &node;
+
+ try expect(node.next.next.next.val.x == 1);
+}
+
+test "void struct fields" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 foo = VoidStructFieldsFoo{
+ .a = void{},
+ .b = 1,
+ .c = void{},
+ };
+ try expect(foo.b == 1);
+ try expect(@sizeOf(VoidStructFieldsFoo) == 4);
+}
+const VoidStructFieldsFoo = struct {
+ a: void,
+ b: i32,
+ c: void,
+};
+
+test "return empty struct from fn" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ _ = testReturnEmptyStructFromFn();
+}
+const EmptyStruct2 = struct {};
+fn testReturnEmptyStructFromFn() EmptyStruct2 {
+ return EmptyStruct2{};
+}
+
+test "pass slice of empty struct to fn" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
+}
+fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
+ return slice.len;
+}
+
+test "self-referencing struct via array member" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 T = struct {
+ children: [1]*@This(),
+ };
+ var x: T = undefined;
+ x = T{ .children = .{&x} };
+ try expect(x.children[0] == &x);
+}
+
+test "empty struct method call" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 es = EmptyStruct{};
+ try expect(es.method() == 1234);
+}
+const EmptyStruct = struct {
+ fn method(es: *const EmptyStruct) i32 {
+ _ = es;
+ return 1234;
+ }
+};
+
+test "align 1 field before self referential align 8 field as slice return type" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 result = alloc(Expr);
+ try expect(result.len == 0);
+}
+
+const Expr = union(enum) {
+ Literal: u8,
+ Question: *Expr,
+};
+
+fn alloc(comptime T: type) []T {
+ return &[_]T{};
+}
+
+const APackedStruct = packed struct {
+ x: u8,
+ y: u8,
+};
+
+test "packed struct" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var foo = APackedStruct{
+ .x = 1,
+ .y = 2,
+ };
+ foo.y += 1;
+ const four = foo.x + foo.y;
+ try expect(four == 4);
+}
+
+const Foo24Bits = packed struct {
+ field: u24,
+};
+const Foo96Bits = packed struct {
+ a: u24,
+ b: u24,
+ c: u24,
+ d: u24,
+};
+
+test "packed struct 24bits" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ comptime {
+ try expect(@sizeOf(Foo24Bits) == 4);
+ if (@sizeOf(usize) == 4) {
+ try expect(@sizeOf(Foo96Bits) == 12);
+ } else {
+ try expect(@sizeOf(Foo96Bits) == 16);
+ }
+ }
+
+ var value = Foo96Bits{
+ .a = 0,
+ .b = 0,
+ .c = 0,
+ .d = 0,
+ };
+ value.a += 1;
+ try expect(value.a == 1);
+ try expect(value.b == 0);
+ try expect(value.c == 0);
+ try expect(value.d == 0);
+
+ value.b += 1;
+ try expect(value.a == 1);
+ try expect(value.b == 1);
+ try expect(value.c == 0);
+ try expect(value.d == 0);
+
+ value.c += 1;
+ try expect(value.a == 1);
+ try expect(value.b == 1);
+ try expect(value.c == 1);
+ try expect(value.d == 0);
+
+ value.d += 1;
+ try expect(value.a == 1);
+ try expect(value.b == 1);
+ try expect(value.c == 1);
+ try expect(value.d == 1);
+}
+
+test "runtime struct initialization of bitfield" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 s1 = Nibbles{
+ .x = x1,
+ .y = x1,
+ };
+ const s2 = Nibbles{
+ .x = @intCast(u4, x2),
+ .y = @intCast(u4, x2),
+ };
+
+ try expect(s1.x == x1);
+ try expect(s1.y == x1);
+ try expect(s2.x == @intCast(u4, x2));
+ try expect(s2.y == @intCast(u4, x2));
+}
+
+var x1 = @as(u4, 1);
+var x2 = @as(u8, 2);
+
+const Nibbles = packed struct {
+ x: u4,
+ y: u4,
+};
+
+const Bitfields = packed struct {
+ f1: u16,
+ f2: u16,
+ f3: u8,
+ f4: u8,
+ f5: u4,
+ f6: u4,
+ f7: u8,
+};
+
+test "native bit field understands endianness" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var all: u64 = if (native_endian != .Little)
+ 0x1111222233445677
+ else
+ 0x7765443322221111;
+ var bytes: [8]u8 = undefined;
+ @memcpy(&bytes, @ptrCast([*]u8, &all), 8);
+ var bitfields = @ptrCast(*Bitfields, &bytes).*;
+
+ try expect(bitfields.f1 == 0x1111);
+ try expect(bitfields.f2 == 0x2222);
+ try expect(bitfields.f3 == 0x33);
+ try expect(bitfields.f4 == 0x44);
+ try expect(bitfields.f5 == 0x5);
+ try expect(bitfields.f6 == 0x6);
+ try expect(bitfields.f7 == 0x77);
+}
+
+test "implicit cast packed struct field to const ptr" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 LevelUpMove = packed struct {
+ move_id: u9,
+ level: u7,
+
+ fn toInt(value: u7) u7 {
+ return value;
+ }
+ };
+
+ var lup: LevelUpMove = undefined;
+ lup.level = 12;
+ const res = LevelUpMove.toInt(lup.level);
+ try expect(res == 12);
+}
+
+test "zero-bit field in packed struct" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 = packed struct {
+ x: u10,
+ y: void,
+ };
+ var x: S = undefined;
+ _ = x;
+}
+
+test "packed struct with non-ABI-aligned field" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 = packed struct {
+ x: u9,
+ y: u183,
+ };
+ var s: S = undefined;
+ s.x = 1;
+ s.y = 42;
+ try expect(s.x == 1);
+ try expect(s.y == 42);
+}
+
+const BitField1 = packed struct {
+ a: u3,
+ b: u3,
+ c: u2,
+};
+
+const bit_field_1 = BitField1{
+ .a = 1,
+ .b = 2,
+ .c = 3,
+};
+
+test "bit field access" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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
+
+ var data = bit_field_1;
+ try expect(getA(&data) == 1);
+ try expect(getB(&data) == 2);
+ try expect(getC(&data) == 3);
+ comptime try expect(@sizeOf(BitField1) == 1);
+
+ data.b += 1;
+ try expect(data.b == 3);
+
+ data.a += 1;
+ try expect(data.a == 2);
+ try expect(data.b == 3);
+}
+
+fn getA(data: *const BitField1) u3 {
+ return data.a;
+}
+
+fn getB(data: *const BitField1) u3 {
+ return data.b;
+}
+
+fn getC(data: *const BitField1) u2 {
+ return data.c;
+}
+
+test "default struct initialization fields" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 {
+ a: i32 = 1234,
+ b: i32,
+ };
+ const x = S{
+ .b = 5,
+ };
+ var five: i32 = 5;
+ const y = S{
+ .b = five,
+ };
+ if (x.a + x.b != 1239) {
+ @compileError("it should be comptime known");
+ }
+ try expect(y.a == x.a);
+ try expect(y.b == x.b);
+ try expect(1239 == x.a + x.b);
+}
+
+// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
+test "packed array 24bits" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ comptime {
+ try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
+ try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
+ }
+
+ var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
+ bytes[bytes.len - 1] = 0xaa;
+ const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
+ try expect(ptr.a == 0);
+ try expect(ptr.b[0].field == 0);
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.a = maxInt(u16);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == 0);
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.b[0].field = maxInt(u24);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == 0);
+ try expect(ptr.c == 0);
+
+ ptr.b[1].field = maxInt(u24);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == maxInt(u24));
+ try expect(ptr.c == 0);
+
+ ptr.c = maxInt(u16);
+ try expect(ptr.a == maxInt(u16));
+ try expect(ptr.b[0].field == maxInt(u24));
+ try expect(ptr.b[1].field == maxInt(u24));
+ try expect(ptr.c == maxInt(u16));
+
+ try expect(bytes[bytes.len - 1] == 0xaa);
+}
+
+const Foo32Bits = packed struct {
+ field: u24,
+ pad: u8,
+};
+
+const FooArray24Bits = packed struct {
+ a: u16,
+ b: [2]Foo32Bits,
+ c: u16,
+};
+
+test "aligned array of packed struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ comptime {
+ try expect(@sizeOf(FooStructAligned) == 2);
+ try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
+ }
+
+ var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
+ const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
+
+ try expect(ptr.a[0].a == 0xbb);
+ try expect(ptr.a[0].b == 0xbb);
+ try expect(ptr.a[1].a == 0xbb);
+ try expect(ptr.a[1].b == 0xbb);
+}
+
+const FooStructAligned = packed struct {
+ a: u8,
+ b: u8,
+};
+
+const FooArrayOfAligned = packed struct {
+ a: [2]FooStructAligned,
+};
+
+test "pointer to packed struct member in a stack variable" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ a: u2,
+ b: u2,
+ };
+
+ var s = S{ .a = 2, .b = 0 };
+ var b_ptr = &s.b;
+ try expect(s.b == 0);
+ b_ptr.* = 2;
+ try expect(s.b == 2);
+}
+
+test "non-byte-aligned array inside packed struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Foo = packed struct {
+ a: bool,
+ b: [0x16]u8,
+ };
+ const S = struct {
+ fn bar(slice: []const u8) !void {
+ try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
+ }
+ fn doTheTest() !void {
+ var foo = Foo{
+ .a = true,
+ .b = "abcdefghijklmnopqurstu".*,
+ };
+ const value = foo.b;
+ try bar(&value);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "packed struct with u0 field access" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ f0: u0,
+ };
+ var s = S{ .f0 = 0 };
+ comptime try expect(s.f0 == 0);
+}
+
+test "access to global struct fields" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ g_foo.bar.value = 42;
+ try expect(g_foo.bar.value == 42);
+}
+
+const S0 = struct {
+ bar: S1,
+
+ pub const S1 = struct {
+ value: u8,
+ };
+
+ fn init() @This() {
+ return S0{ .bar = S1{ .value = 123 } };
+ }
+};
+
+var g_foo: S0 = S0.init();
+
+test "packed struct with fp fields" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = packed struct {
+ data: [3]f32,
+
+ pub fn frob(self: *@This()) void {
+ self.data[0] += self.data[1] + self.data[2];
+ self.data[1] += self.data[0] + self.data[2];
+ self.data[2] += self.data[0] + self.data[1];
+ }
+ };
+
+ var s: S = undefined;
+ s.data[0] = 1.0;
+ s.data[1] = 2.0;
+ s.data[2] = 3.0;
+ s.frob();
+ try expectEqual(@as(f32, 6.0), s.data[0]);
+ try expectEqual(@as(f32, 11.0), s.data[1]);
+ try expectEqual(@as(f32, 20.0), s.data[2]);
+}
+
+test "fn with C calling convention returns struct by value" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn entry() !void {
+ var x = makeBar(10);
+ try expectEqual(@as(i32, 10), x.handle);
+ }
+
+ const ExternBar = extern struct {
+ handle: i32,
+ };
+
+ fn makeBar(t: i32) callconv(.C) ExternBar {
+ return ExternBar{
+ .handle = t,
+ };
+ }
+ };
+ try S.entry();
+ comptime try S.entry();
+}
+
+test "non-packed struct with u128 entry in union" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const U = union(enum) {
+ Num: u128,
+ Void,
+ };
+
+ const S = struct {
+ f1: U,
+ f2: U,
+ };
+
+ var sx: S = undefined;
+ var s = &sx;
+ try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
+ var v2 = U{ .Num = 123 };
+ s.f2 = v2;
+ try std.testing.expect(s.f2.Num == 123);
+}
+
+test "packed struct field passed to generic function" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const P = packed struct {
+ b: u5,
+ g: u5,
+ r: u5,
+ a: u1,
+ };
+
+ fn genericReadPackedField(ptr: anytype) u5 {
+ return ptr.*;
+ }
+ };
+
+ var p: S.P = undefined;
+ p.b = 29;
+ var loaded = S.genericReadPackedField(&p.b);
+ try expect(loaded == 29);
+}
+
+test "anonymous struct literal syntax" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 Point = struct {
+ x: i32,
+ y: i32,
+ };
+
+ fn doTheTest() !void {
+ var p: Point = .{
+ .x = 1,
+ .y = 2,
+ };
+ try expect(p.x == 1);
+ try expect(p.y == 2);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "fully anonymous struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try dump(.{
+ .int = @as(u32, 1234),
+ .float = @as(f64, 12.34),
+ .b = true,
+ .s = "hi",
+ });
+ }
+ fn dump(args: anytype) !void {
+ try expect(args.int == 1234);
+ try expect(args.float == 12.34);
+ try expect(args.b);
+ try expect(args.s[0] == 'h');
+ try expect(args.s[1] == 'i');
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "fully anonymous list literal" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
+ }
+ fn dump(args: anytype) !void {
+ try expect(args.@"0" == 1234);
+ try expect(args.@"1" == 12.34);
+ try expect(args.@"2");
+ try expect(args.@"3"[0] == 'h');
+ try expect(args.@"3"[1] == 'i');
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "anonymous struct literal assigned to variable" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
+ try expect(vec.@"0" == 22);
+ try expect(vec.@"1" == 55);
+ try expect(vec.@"2" == 99);
+}
+
+test "comptime struct field" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const T = struct {
+ a: i32,
+ comptime b: i32 = 1234,
+ };
+
+ var foo: T = undefined;
+ comptime try expect(foo.b == 1234);
+}
+
+test "anon struct literal field value initialized with fn call" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ fn doTheTest() !void {
+ var x = .{foo()};
+ try expectEqualSlices(u8, x[0], "hi");
+ }
+ fn foo() []const u8 {
+ return "hi";
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "struct with union field" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Value = struct {
+ ref: u32 = 2,
+ kind: union(enum) {
+ None: usize,
+ Bool: bool,
+ },
+ };
+
+ var True = Value{
+ .kind = .{ .Bool = true },
+ };
+ try expectEqual(@as(u32, 2), True.ref);
+ try expectEqual(true, True.kind.Bool);
+}
+
+test "type coercion of anon struct literal to struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const S2 = struct {
+ A: u32,
+ B: []const u8,
+ C: void,
+ D: Foo = .{},
+ };
+
+ const Foo = struct {
+ field: i32 = 1234,
+ };
+
+ fn doTheTest() !void {
+ var y: u32 = 42;
+ const t0 = .{ .A = 123, .B = "foo", .C = {} };
+ const t1 = .{ .A = y, .B = "foo", .C = {} };
+ const y0: S2 = t0;
+ var y1: S2 = t1;
+ try expect(y0.A == 123);
+ try expect(std.mem.eql(u8, y0.B, "foo"));
+ try expect(y0.C == {});
+ try expect(y0.D.field == 1234);
+ try expect(y1.A == y);
+ try expect(std.mem.eql(u8, y1.B, "foo"));
+ try expect(y1.C == {});
+ try expect(y1.D.field == 1234);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "type coercion of pointer to anon struct literal to pointer to struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const S2 = struct {
+ A: u32,
+ B: []const u8,
+ C: void,
+ D: Foo = .{},
+ };
+
+ const Foo = struct {
+ field: i32 = 1234,
+ };
+
+ fn doTheTest() !void {
+ var y: u32 = 42;
+ const t0 = &.{ .A = 123, .B = "foo", .C = {} };
+ const t1 = &.{ .A = y, .B = "foo", .C = {} };
+ const y0: *const S2 = t0;
+ var y1: *const S2 = t1;
+ try expect(y0.A == 123);
+ try expect(std.mem.eql(u8, y0.B, "foo"));
+ try expect(y0.C == {});
+ try expect(y0.D.field == 1234);
+ try expect(y1.A == y);
+ try expect(std.mem.eql(u8, y1.B, "foo"));
+ try expect(y1.C == {});
+ try expect(y1.D.field == 1234);
+ }
+ };
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "packed struct with undefined initializers" {
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) 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 P = packed struct {
+ a: u3,
+ _a: u3 = undefined,
+ b: u3,
+ _b: u3 = undefined,
+ c: u3,
+ _c: u3 = undefined,
+ };
+
+ fn doTheTest() !void {
+ var p: P = undefined;
+ p = P{ .a = 2, .b = 4, .c = 6 };
+ // Make sure the compiler doesn't touch the unprefixed fields.
+ // Use expect since i386-linux doesn't like expectEqual
+ try expect(p.a == 2);
+ try expect(p.b == 4);
+ try expect(p.c == 6);
+ }
+ };
+
+ try S.doTheTest();
+ comptime try S.doTheTest();
+}
+
+test "for loop over pointers to struct, getting field from struct pointer" {
+ // When enabling this test, be careful. I have observed it to pass when compiling
+ // stage2 alone, but when using stage1 with -fno-stage1 -fLLVM it fails.
+ // Maybe eyeball the LLVM that it generates and run in valgrind, both the compiler
+ // and the generated test at runtime.
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const S = struct {
+ const Foo = struct {
+ name: []const u8,
+ };
+
+ var ok = true;
+
+ fn eql(a: []const u8) bool {
+ _ = a;
+ return true;
+ }
+
+ const ArrayList = struct {
+ fn toSlice(self: *ArrayList) []*Foo {
+ _ = self;
+ return @as([*]*Foo, undefined)[0..0];
+ }
+ };
+
+ fn doTheTest() !void {
+ var objects: ArrayList = undefined;
+
+ for (objects.toSlice()) |obj| {
+ if (eql(obj.name)) {
+ ok = false;
+ }
+ }
+
+ try expect(ok);
+ }
+ };
+ try S.doTheTest();
+}
test/behavior/struct_llvm.zig
@@ -1,802 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const native_endian = builtin.target.cpu.arch.endian();
-const expect = std.testing.expect;
-const expectEqual = std.testing.expectEqual;
-const expectEqualSlices = std.testing.expectEqualSlices;
-const maxInt = std.math.maxInt;
-
-const Node = struct {
- val: Val,
- next: *Node,
-};
-
-const Val = struct {
- x: i32,
-};
-
-test "struct point to self" {
- var root: Node = undefined;
- root.val.x = 1;
-
- var node: Node = undefined;
- node.next = &root;
- node.val.x = 2;
-
- root.next = &node;
-
- try expect(node.next.next.next.val.x == 1);
-}
-
-test "void struct fields" {
- const foo = VoidStructFieldsFoo{
- .a = void{},
- .b = 1,
- .c = void{},
- };
- try expect(foo.b == 1);
- try expect(@sizeOf(VoidStructFieldsFoo) == 4);
-}
-const VoidStructFieldsFoo = struct {
- a: void,
- b: i32,
- c: void,
-};
-
-test "return empty struct from fn" {
- _ = testReturnEmptyStructFromFn();
-}
-const EmptyStruct2 = struct {};
-fn testReturnEmptyStructFromFn() EmptyStruct2 {
- return EmptyStruct2{};
-}
-
-test "pass slice of empty struct to fn" {
- try expect(testPassSliceOfEmptyStructToFn(&[_]EmptyStruct2{EmptyStruct2{}}) == 1);
-}
-fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
- return slice.len;
-}
-
-test "self-referencing struct via array member" {
- const T = struct {
- children: [1]*@This(),
- };
- var x: T = undefined;
- x = T{ .children = .{&x} };
- try expect(x.children[0] == &x);
-}
-
-test "empty struct method call" {
- const es = EmptyStruct{};
- try expect(es.method() == 1234);
-}
-const EmptyStruct = struct {
- fn method(es: *const EmptyStruct) i32 {
- _ = es;
- return 1234;
- }
-};
-
-test "align 1 field before self referential align 8 field as slice return type" {
- const result = alloc(Expr);
- try expect(result.len == 0);
-}
-
-const Expr = union(enum) {
- Literal: u8,
- Question: *Expr,
-};
-
-fn alloc(comptime T: type) []T {
- return &[_]T{};
-}
-
-const APackedStruct = packed struct {
- x: u8,
- y: u8,
-};
-
-test "packed struct" {
- var foo = APackedStruct{
- .x = 1,
- .y = 2,
- };
- foo.y += 1;
- const four = foo.x + foo.y;
- try expect(four == 4);
-}
-
-const Foo24Bits = packed struct {
- field: u24,
-};
-const Foo96Bits = packed struct {
- a: u24,
- b: u24,
- c: u24,
- d: u24,
-};
-
-test "packed struct 24bits" {
- comptime {
- try expect(@sizeOf(Foo24Bits) == 4);
- if (@sizeOf(usize) == 4) {
- try expect(@sizeOf(Foo96Bits) == 12);
- } else {
- try expect(@sizeOf(Foo96Bits) == 16);
- }
- }
-
- var value = Foo96Bits{
- .a = 0,
- .b = 0,
- .c = 0,
- .d = 0,
- };
- value.a += 1;
- try expect(value.a == 1);
- try expect(value.b == 0);
- try expect(value.c == 0);
- try expect(value.d == 0);
-
- value.b += 1;
- try expect(value.a == 1);
- try expect(value.b == 1);
- try expect(value.c == 0);
- try expect(value.d == 0);
-
- value.c += 1;
- try expect(value.a == 1);
- try expect(value.b == 1);
- try expect(value.c == 1);
- try expect(value.d == 0);
-
- value.d += 1;
- try expect(value.a == 1);
- try expect(value.b == 1);
- try expect(value.c == 1);
- try expect(value.d == 1);
-}
-
-test "runtime struct initialization of bitfield" {
- const s1 = Nibbles{
- .x = x1,
- .y = x1,
- };
- const s2 = Nibbles{
- .x = @intCast(u4, x2),
- .y = @intCast(u4, x2),
- };
-
- try expect(s1.x == x1);
- try expect(s1.y == x1);
- try expect(s2.x == @intCast(u4, x2));
- try expect(s2.y == @intCast(u4, x2));
-}
-
-var x1 = @as(u4, 1);
-var x2 = @as(u8, 2);
-
-const Nibbles = packed struct {
- x: u4,
- y: u4,
-};
-
-const Bitfields = packed struct {
- f1: u16,
- f2: u16,
- f3: u8,
- f4: u8,
- f5: u4,
- f6: u4,
- f7: u8,
-};
-
-test "native bit field understands endianness" {
- var all: u64 = if (native_endian != .Little)
- 0x1111222233445677
- else
- 0x7765443322221111;
- var bytes: [8]u8 = undefined;
- @memcpy(&bytes, @ptrCast([*]u8, &all), 8);
- var bitfields = @ptrCast(*Bitfields, &bytes).*;
-
- try expect(bitfields.f1 == 0x1111);
- try expect(bitfields.f2 == 0x2222);
- try expect(bitfields.f3 == 0x33);
- try expect(bitfields.f4 == 0x44);
- try expect(bitfields.f5 == 0x5);
- try expect(bitfields.f6 == 0x6);
- try expect(bitfields.f7 == 0x77);
-}
-
-test "implicit cast packed struct field to const ptr" {
- const LevelUpMove = packed struct {
- move_id: u9,
- level: u7,
-
- fn toInt(value: u7) u7 {
- return value;
- }
- };
-
- var lup: LevelUpMove = undefined;
- lup.level = 12;
- const res = LevelUpMove.toInt(lup.level);
- try expect(res == 12);
-}
-
-test "zero-bit field in packed struct" {
- const S = packed struct {
- x: u10,
- y: void,
- };
- var x: S = undefined;
- _ = x;
-}
-
-test "packed struct with non-ABI-aligned field" {
- const S = packed struct {
- x: u9,
- y: u183,
- };
- var s: S = undefined;
- s.x = 1;
- s.y = 42;
- try expect(s.x == 1);
- try expect(s.y == 42);
-}
-
-const BitField1 = packed struct {
- a: u3,
- b: u3,
- c: u2,
-};
-
-const bit_field_1 = BitField1{
- .a = 1,
- .b = 2,
- .c = 3,
-};
-
-test "bit field access" {
- var data = bit_field_1;
- try expect(getA(&data) == 1);
- try expect(getB(&data) == 2);
- try expect(getC(&data) == 3);
- comptime try expect(@sizeOf(BitField1) == 1);
-
- data.b += 1;
- try expect(data.b == 3);
-
- data.a += 1;
- try expect(data.a == 2);
- try expect(data.b == 3);
-}
-
-fn getA(data: *const BitField1) u3 {
- return data.a;
-}
-
-fn getB(data: *const BitField1) u3 {
- return data.b;
-}
-
-fn getC(data: *const BitField1) u2 {
- return data.c;
-}
-
-test "default struct initialization fields" {
- const S = struct {
- a: i32 = 1234,
- b: i32,
- };
- const x = S{
- .b = 5,
- };
- var five: i32 = 5;
- const y = S{
- .b = five,
- };
- if (x.a + x.b != 1239) {
- @compileError("it should be comptime known");
- }
- try expect(y.a == x.a);
- try expect(y.b == x.b);
- try expect(1239 == x.a + x.b);
-}
-
-// TODO revisit this test when doing https://github.com/ziglang/zig/issues/1512
-test "packed array 24bits" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- comptime {
- try expect(@sizeOf([9]Foo32Bits) == 9 * 4);
- try expect(@sizeOf(FooArray24Bits) == 2 + 2 * 4 + 2);
- }
-
- var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
- bytes[bytes.len - 1] = 0xaa;
- const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
- try expect(ptr.a == 0);
- try expect(ptr.b[0].field == 0);
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.a = maxInt(u16);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == 0);
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.b[0].field = maxInt(u24);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == 0);
- try expect(ptr.c == 0);
-
- ptr.b[1].field = maxInt(u24);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == maxInt(u24));
- try expect(ptr.c == 0);
-
- ptr.c = maxInt(u16);
- try expect(ptr.a == maxInt(u16));
- try expect(ptr.b[0].field == maxInt(u24));
- try expect(ptr.b[1].field == maxInt(u24));
- try expect(ptr.c == maxInt(u16));
-
- try expect(bytes[bytes.len - 1] == 0xaa);
-}
-
-const Foo32Bits = packed struct {
- field: u24,
- pad: u8,
-};
-
-const FooArray24Bits = packed struct {
- a: u16,
- b: [2]Foo32Bits,
- c: u16,
-};
-
-test "aligned array of packed struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- comptime {
- try expect(@sizeOf(FooStructAligned) == 2);
- try expect(@sizeOf(FooArrayOfAligned) == 2 * 2);
- }
-
- var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
- const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
-
- try expect(ptr.a[0].a == 0xbb);
- try expect(ptr.a[0].b == 0xbb);
- try expect(ptr.a[1].a == 0xbb);
- try expect(ptr.a[1].b == 0xbb);
-}
-
-const FooStructAligned = packed struct {
- a: u8,
- b: u8,
-};
-
-const FooArrayOfAligned = packed struct {
- a: [2]FooStructAligned,
-};
-
-test "pointer to packed struct member in a stack variable" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = packed struct {
- a: u2,
- b: u2,
- };
-
- var s = S{ .a = 2, .b = 0 };
- var b_ptr = &s.b;
- try expect(s.b == 0);
- b_ptr.* = 2;
- try expect(s.b == 2);
-}
-
-test "non-byte-aligned array inside packed struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const Foo = packed struct {
- a: bool,
- b: [0x16]u8,
- };
- const S = struct {
- fn bar(slice: []const u8) !void {
- try expectEqualSlices(u8, slice, "abcdefghijklmnopqurstu");
- }
- fn doTheTest() !void {
- var foo = Foo{
- .a = true,
- .b = "abcdefghijklmnopqurstu".*,
- };
- const value = foo.b;
- try bar(&value);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "packed struct with u0 field access" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = packed struct {
- f0: u0,
- };
- var s = S{ .f0 = 0 };
- comptime try expect(s.f0 == 0);
-}
-
-test "access to global struct fields" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- g_foo.bar.value = 42;
- try expect(g_foo.bar.value == 42);
-}
-
-const S0 = struct {
- bar: S1,
-
- pub const S1 = struct {
- value: u8,
- };
-
- fn init() @This() {
- return S0{ .bar = S1{ .value = 123 } };
- }
-};
-
-var g_foo: S0 = S0.init();
-
-test "packed struct with fp fields" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = packed struct {
- data: [3]f32,
-
- pub fn frob(self: *@This()) void {
- self.data[0] += self.data[1] + self.data[2];
- self.data[1] += self.data[0] + self.data[2];
- self.data[2] += self.data[0] + self.data[1];
- }
- };
-
- var s: S = undefined;
- s.data[0] = 1.0;
- s.data[1] = 2.0;
- s.data[2] = 3.0;
- s.frob();
- try expectEqual(@as(f32, 6.0), s.data[0]);
- try expectEqual(@as(f32, 11.0), s.data[1]);
- try expectEqual(@as(f32, 20.0), s.data[2]);
-}
-
-test "fn with C calling convention returns struct by value" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn entry() !void {
- var x = makeBar(10);
- try expectEqual(@as(i32, 10), x.handle);
- }
-
- const ExternBar = extern struct {
- handle: i32,
- };
-
- fn makeBar(t: i32) callconv(.C) ExternBar {
- return ExternBar{
- .handle = t,
- };
- }
- };
- try S.entry();
- comptime try S.entry();
-}
-
-test "non-packed struct with u128 entry in union" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const U = union(enum) {
- Num: u128,
- Void,
- };
-
- const S = struct {
- f1: U,
- f2: U,
- };
-
- var sx: S = undefined;
- var s = &sx;
- try std.testing.expect(@ptrToInt(&s.f2) - @ptrToInt(&s.f1) == @offsetOf(S, "f2"));
- var v2 = U{ .Num = 123 };
- s.f2 = v2;
- try std.testing.expect(s.f2.Num == 123);
-}
-
-test "packed struct field passed to generic function" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- const P = packed struct {
- b: u5,
- g: u5,
- r: u5,
- a: u1,
- };
-
- fn genericReadPackedField(ptr: anytype) u5 {
- return ptr.*;
- }
- };
-
- var p: S.P = undefined;
- p.b = 29;
- var loaded = S.genericReadPackedField(&p.b);
- try expect(loaded == 29);
-}
-
-test "anonymous struct literal syntax" {
- const S = struct {
- const Point = struct {
- x: i32,
- y: i32,
- };
-
- fn doTheTest() !void {
- var p: Point = .{
- .x = 1,
- .y = 2,
- };
- try expect(p.x == 1);
- try expect(p.y == 2);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "fully anonymous struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn doTheTest() !void {
- try dump(.{
- .int = @as(u32, 1234),
- .float = @as(f64, 12.34),
- .b = true,
- .s = "hi",
- });
- }
- fn dump(args: anytype) !void {
- try expect(args.int == 1234);
- try expect(args.float == 12.34);
- try expect(args.b);
- try expect(args.s[0] == 'h');
- try expect(args.s[1] == 'i');
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "fully anonymous list literal" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn doTheTest() !void {
- try dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi" });
- }
- fn dump(args: anytype) !void {
- try expect(args.@"0" == 1234);
- try expect(args.@"1" == 12.34);
- try expect(args.@"2");
- try expect(args.@"3"[0] == 'h');
- try expect(args.@"3"[1] == 'i');
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "anonymous struct literal assigned to variable" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- var vec = .{ @as(i32, 22), @as(i32, 55), @as(i32, 99) };
- try expect(vec.@"0" == 22);
- try expect(vec.@"1" == 55);
- try expect(vec.@"2" == 99);
-}
-
-test "comptime struct field" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const T = struct {
- a: i32,
- comptime b: i32 = 1234,
- };
-
- var foo: T = undefined;
- comptime try expect(foo.b == 1234);
-}
-
-test "anon struct literal field value initialized with fn call" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- fn doTheTest() !void {
- var x = .{foo()};
- try expectEqualSlices(u8, x[0], "hi");
- }
- fn foo() []const u8 {
- return "hi";
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "struct with union field" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const Value = struct {
- ref: u32 = 2,
- kind: union(enum) {
- None: usize,
- Bool: bool,
- },
- };
-
- var True = Value{
- .kind = .{ .Bool = true },
- };
- try expectEqual(@as(u32, 2), True.ref);
- try expectEqual(true, True.kind.Bool);
-}
-
-test "type coercion of anon struct literal to struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- const S2 = struct {
- A: u32,
- B: []const u8,
- C: void,
- D: Foo = .{},
- };
-
- const Foo = struct {
- field: i32 = 1234,
- };
-
- fn doTheTest() !void {
- var y: u32 = 42;
- const t0 = .{ .A = 123, .B = "foo", .C = {} };
- const t1 = .{ .A = y, .B = "foo", .C = {} };
- const y0: S2 = t0;
- var y1: S2 = t1;
- try expect(y0.A == 123);
- try expect(std.mem.eql(u8, y0.B, "foo"));
- try expect(y0.C == {});
- try expect(y0.D.field == 1234);
- try expect(y1.A == y);
- try expect(std.mem.eql(u8, y1.B, "foo"));
- try expect(y1.C == {});
- try expect(y1.D.field == 1234);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "type coercion of pointer to anon struct literal to pointer to struct" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- const S2 = struct {
- A: u32,
- B: []const u8,
- C: void,
- D: Foo = .{},
- };
-
- const Foo = struct {
- field: i32 = 1234,
- };
-
- fn doTheTest() !void {
- var y: u32 = 42;
- const t0 = &.{ .A = 123, .B = "foo", .C = {} };
- const t1 = &.{ .A = y, .B = "foo", .C = {} };
- const y0: *const S2 = t0;
- var y1: *const S2 = t1;
- try expect(y0.A == 123);
- try expect(std.mem.eql(u8, y0.B, "foo"));
- try expect(y0.C == {});
- try expect(y0.D.field == 1234);
- try expect(y1.A == y);
- try expect(std.mem.eql(u8, y1.B, "foo"));
- try expect(y1.C == {});
- try expect(y1.D.field == 1234);
- }
- };
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "packed struct with undefined initializers" {
- const S = struct {
- const P = packed struct {
- a: u3,
- _a: u3 = undefined,
- b: u3,
- _b: u3 = undefined,
- c: u3,
- _c: u3 = undefined,
- };
-
- fn doTheTest() !void {
- var p: P = undefined;
- p = P{ .a = 2, .b = 4, .c = 6 };
- // Make sure the compiler doesn't touch the unprefixed fields.
- // Use expect since i386-linux doesn't like expectEqual
- try expect(p.a == 2);
- try expect(p.b == 4);
- try expect(p.c == 6);
- }
- };
-
- try S.doTheTest();
- comptime try S.doTheTest();
-}
-
-test "for loop over pointers to struct, getting field from struct pointer" {
- // When enabling this test, be careful. I have observed it to pass when compiling
- // stage2 alone, but when using stage1 with -fno-stage1 -fLLVM it fails.
- // Maybe eyeball the LLVM that it generates and run in valgrind, both the compiler
- // and the generated test at runtime.
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
-
- const S = struct {
- const Foo = struct {
- name: []const u8,
- };
-
- var ok = true;
-
- fn eql(a: []const u8) bool {
- _ = a;
- return true;
- }
-
- const ArrayList = struct {
- fn toSlice(self: *ArrayList) []*Foo {
- _ = self;
- return @as([*]*Foo, undefined)[0..0];
- }
- };
-
- fn doTheTest() !void {
- var objects: ArrayList = undefined;
-
- for (objects.toSlice()) |obj| {
- if (eql(obj.name)) {
- ok = false;
- }
- }
-
- try expect(ok);
- }
- };
- try S.doTheTest();
-}
test/behavior/truncate.zig
@@ -76,3 +76,16 @@ test "truncate on comptime integer" {
var w = @truncate(u1, 1 << 100);
try expect(w == 0);
}
+
+test "truncate on vectors" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest;
+
+ const S = struct {
+ fn doTheTest() !void {
+ var v1: @Vector(4, u16) = .{ 0xaabb, 0xccdd, 0xeeff, 0x1122 };
+ var v2 = @truncate(u8, v1);
+ try expect(std.mem.eql(u8, &@as([4]u8, v2), &[4]u8{ 0xbb, 0xdd, 0xff, 0x22 }));
+ }
+ };
+ try S.doTheTest();
+}
test/behavior/truncate_stage1.zig
@@ -1,13 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-
-test "truncate on vectors" {
- const S = struct {
- fn doTheTest() !void {
- var v1: @Vector(4, u16) = .{ 0xaabb, 0xccdd, 0xeeff, 0x1122 };
- var v2 = @truncate(u8, v1);
- try expect(std.mem.eql(u8, &@as([4]u8, v2), &[4]u8{ 0xbb, 0xdd, 0xff, 0x22 }));
- }
- };
- try S.doTheTest();
-}
test/behavior/type.zig
@@ -102,3 +102,389 @@ test "Type.Pointer" {
[*c]align(8) volatile u8, [*c]align(8) const volatile u8,
});
}
+
+test "Type.Float" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } }));
+ try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } }));
+ try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } }));
+ try testing.expect(f80 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 80 } }));
+ try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } }));
+ try testTypes(&[_]type{ f16, f32, f64, f80, f128 });
+}
+
+test "Type.Array" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testing.expect([123]u8 == @Type(TypeInfo{
+ .Array = TypeInfo.Array{
+ .len = 123,
+ .child = u8,
+ .sentinel = null,
+ },
+ }));
+ try testing.expect([2]u32 == @Type(TypeInfo{
+ .Array = TypeInfo.Array{
+ .len = 2,
+ .child = u32,
+ .sentinel = null,
+ },
+ }));
+ try testing.expect([2:0]u32 == @Type(TypeInfo{
+ .Array = TypeInfo.Array{
+ .len = 2,
+ .child = u32,
+ .sentinel = &@as(u32, 0),
+ },
+ }));
+ try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool });
+}
+
+test "@Type create slice with null sentinel" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Slice = @Type(TypeInfo{
+ .Pointer = .{
+ .size = .Slice,
+ .is_const = true,
+ .is_volatile = false,
+ .is_allowzero = false,
+ .alignment = 8,
+ .address_space = .generic,
+ .child = *i32,
+ .sentinel = null,
+ },
+ });
+ try testing.expect(Slice == []align(8) const *i32);
+}
+
+test "@Type picks up the sentinel value from TypeInfo" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testTypes(&[_]type{
+ [11:0]u8, [4:10]u8,
+ [*:0]u8, [*:0]const u8,
+ [*:0]volatile u8, [*:0]const volatile u8,
+ [*:0]align(4) u8, [*:0]align(4) const u8,
+ [*:0]align(4) volatile u8, [*:0]align(4) const volatile u8,
+ [*:0]align(8) u8, [*:0]align(8) const u8,
+ [*:0]align(8) volatile u8, [*:0]align(8) const volatile u8,
+ [*:0]allowzero u8, [*:0]allowzero const u8,
+ [*:0]allowzero volatile u8, [*:0]allowzero const volatile u8,
+ [*:0]allowzero align(4) u8, [*:0]allowzero align(4) const u8,
+ [*:0]allowzero align(4) volatile u8, [*:0]allowzero align(4) const volatile u8,
+ [*:5]allowzero align(4) volatile u8, [*:5]allowzero align(4) const volatile u8,
+ [:0]u8, [:0]const u8,
+ [:0]volatile u8, [:0]const volatile u8,
+ [:0]align(4) u8, [:0]align(4) const u8,
+ [:0]align(4) volatile u8, [:0]align(4) const volatile u8,
+ [:0]align(8) u8, [:0]align(8) const u8,
+ [:0]align(8) volatile u8, [:0]align(8) const volatile u8,
+ [:0]allowzero u8, [:0]allowzero const u8,
+ [:0]allowzero volatile u8, [:0]allowzero const volatile u8,
+ [:0]allowzero align(4) u8, [:0]allowzero align(4) const u8,
+ [:0]allowzero align(4) volatile u8, [:0]allowzero align(4) const volatile u8,
+ [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8,
+ });
+}
+
+test "Type.Optional" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testTypes(&[_]type{
+ ?u8,
+ ?*u8,
+ ?[]u8,
+ ?[*]u8,
+ ?[*c]u8,
+ });
+}
+
+test "Type.ErrorUnion" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testTypes(&[_]type{
+ error{}!void,
+ error{Error}!void,
+ });
+}
+
+test "Type.Opaque" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Opaque = @Type(.{
+ .Opaque = .{
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ try testing.expect(Opaque != opaque {});
+ try testing.expectEqualSlices(
+ TypeInfo.Declaration,
+ &[_]TypeInfo.Declaration{},
+ @typeInfo(Opaque).Opaque.decls,
+ );
+}
+
+test "Type.Vector" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testTypes(&[_]type{
+ @Vector(0, u8),
+ @Vector(4, u8),
+ @Vector(8, *u8),
+ std.meta.Vector(0, u8),
+ std.meta.Vector(4, u8),
+ std.meta.Vector(8, *u8),
+ });
+}
+
+test "Type.AnyFrame" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ try testTypes(&[_]type{
+ anyframe,
+ anyframe->u8,
+ anyframe->anyframe->u8,
+ });
+}
+
+fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
+
+test "Type.ErrorSet" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ // error sets don't compare equal so just check if they compile
+ _ = @Type(@typeInfo(error{}));
+ _ = @Type(@typeInfo(error{A}));
+ _ = @Type(@typeInfo(error{ A, B, C }));
+}
+
+test "Type.Struct" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
+ const infoA = @typeInfo(A).Struct;
+ try testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout);
+ try testing.expectEqualSlices(u8, "x", infoA.fields[0].name);
+ try testing.expectEqual(u8, infoA.fields[0].field_type);
+ try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[0].default_value);
+ try testing.expectEqualSlices(u8, "y", infoA.fields[1].name);
+ try testing.expectEqual(u32, infoA.fields[1].field_type);
+ try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[1].default_value);
+ try testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls);
+ try testing.expectEqual(@as(bool, false), infoA.is_tuple);
+
+ var a = A{ .x = 0, .y = 1 };
+ try testing.expectEqual(@as(u8, 0), a.x);
+ try testing.expectEqual(@as(u32, 1), a.y);
+ a.y += 1;
+ try testing.expectEqual(@as(u32, 2), a.y);
+
+ const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 }));
+ const infoB = @typeInfo(B).Struct;
+ try testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout);
+ try testing.expectEqualSlices(u8, "x", infoB.fields[0].name);
+ try testing.expectEqual(u8, infoB.fields[0].field_type);
+ try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value);
+ try testing.expectEqualSlices(u8, "y", infoB.fields[1].name);
+ try testing.expectEqual(u32, infoB.fields[1].field_type);
+ try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoB.fields[1].default_value.?).*);
+ try testing.expectEqual(@as(usize, 0), infoB.decls.len);
+ try testing.expectEqual(@as(bool, false), infoB.is_tuple);
+
+ const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 }));
+ const infoC = @typeInfo(C).Struct;
+ try testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout);
+ try testing.expectEqualSlices(u8, "x", infoC.fields[0].name);
+ try testing.expectEqual(u8, infoC.fields[0].field_type);
+ try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*);
+ try testing.expectEqualSlices(u8, "y", infoC.fields[1].name);
+ try testing.expectEqual(u32, infoC.fields[1].field_type);
+ try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoC.fields[1].default_value.?).*);
+ try testing.expectEqual(@as(usize, 0), infoC.decls.len);
+ try testing.expectEqual(@as(bool, false), infoC.is_tuple);
+}
+
+test "Type.Enum" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Foo = @Type(.{
+ .Enum = .{
+ .layout = .Auto,
+ .tag_type = u8,
+ .fields = &[_]TypeInfo.EnumField{
+ .{ .name = "a", .value = 1 },
+ .{ .name = "b", .value = 5 },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ .is_exhaustive = true,
+ },
+ });
+ try testing.expectEqual(true, @typeInfo(Foo).Enum.is_exhaustive);
+ try testing.expectEqual(@as(u8, 1), @enumToInt(Foo.a));
+ try testing.expectEqual(@as(u8, 5), @enumToInt(Foo.b));
+ const Bar = @Type(.{
+ .Enum = .{
+ .layout = .Extern,
+ .tag_type = u32,
+ .fields = &[_]TypeInfo.EnumField{
+ .{ .name = "a", .value = 1 },
+ .{ .name = "b", .value = 5 },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ .is_exhaustive = false,
+ },
+ });
+ try testing.expectEqual(false, @typeInfo(Bar).Enum.is_exhaustive);
+ try testing.expectEqual(@as(u32, 1), @enumToInt(Bar.a));
+ try testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b));
+ try testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6)));
+}
+
+test "Type.Union" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Untagged = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = null,
+ .fields = &[_]TypeInfo.UnionField{
+ .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) },
+ .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ var untagged = Untagged{ .int = 1 };
+ untagged.float = 2.0;
+ untagged.int = 3;
+ try testing.expectEqual(@as(i32, 3), untagged.int);
+
+ const PackedUntagged = @Type(.{
+ .Union = .{
+ .layout = .Packed,
+ .tag_type = null,
+ .fields = &[_]TypeInfo.UnionField{
+ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ var packed_untagged = PackedUntagged{ .signed = -1 };
+ try testing.expectEqual(@as(i32, -1), packed_untagged.signed);
+ try testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned);
+
+ const Tag = @Type(.{
+ .Enum = .{
+ .layout = .Auto,
+ .tag_type = u1,
+ .fields = &[_]TypeInfo.EnumField{
+ .{ .name = "signed", .value = 0 },
+ .{ .name = "unsigned", .value = 1 },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ .is_exhaustive = true,
+ },
+ });
+ const Tagged = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = Tag,
+ .fields = &[_]TypeInfo.UnionField{
+ .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
+ .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ var tagged = Tagged{ .signed = -1 };
+ try testing.expectEqual(Tag.signed, tagged);
+ tagged = .{ .unsigned = 1 };
+ try testing.expectEqual(Tag.unsigned, tagged);
+}
+
+test "Type.Union from Type.Enum" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const Tag = @Type(.{
+ .Enum = .{
+ .layout = .Auto,
+ .tag_type = u0,
+ .fields = &[_]TypeInfo.EnumField{
+ .{ .name = "working_as_expected", .value = 0 },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ .is_exhaustive = true,
+ },
+ });
+ const T = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = Tag,
+ .fields = &[_]TypeInfo.UnionField{
+ .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ _ = T;
+ _ = @typeInfo(T).Union;
+}
+
+test "Type.Union from regular enum" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ const E = enum { working_as_expected };
+ const T = @Type(.{
+ .Union = .{
+ .layout = .Auto,
+ .tag_type = E,
+ .fields = &[_]TypeInfo.UnionField{
+ .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
+ },
+ .decls = &[_]TypeInfo.Declaration{},
+ },
+ });
+ _ = T;
+ _ = @typeInfo(T).Union;
+}
+
+test "Type.Fn" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ // wasm doesn't support align attributes on functions
+ if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest;
+
+ const foo = struct {
+ fn func(a: usize, b: bool) align(4) callconv(.C) usize {
+ _ = a;
+ _ = b;
+ return 0;
+ }
+ }.func;
+ const Foo = @Type(@typeInfo(@TypeOf(foo)));
+ const foo_2: Foo = foo;
+ _ = foo_2;
+}
+
+test "Type.BoundFn" {
+ if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+ // wasm doesn't support align attributes on functions
+ if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest;
+
+ const TestStruct = packed struct {
+ pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void {
+ _ = self;
+ }
+ };
+ const test_instance: TestStruct = undefined;
+ try testing.expect(std.meta.eql(
+ @typeName(@TypeOf(test_instance.foo)),
+ @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))),
+ ));
+}
test/behavior/type_stage1.zig
@@ -1,362 +0,0 @@
-const std = @import("std");
-const builtin = @import("builtin");
-const TypeInfo = std.builtin.TypeInfo;
-const testing = std.testing;
-
-fn testTypes(comptime types: []const type) !void {
- inline for (types) |testType| {
- try testing.expect(testType == @Type(@typeInfo(testType)));
- }
-}
-
-test "Type.Float" {
- try testing.expect(f16 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 16 } }));
- try testing.expect(f32 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 32 } }));
- try testing.expect(f64 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 64 } }));
- try testing.expect(f80 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 80 } }));
- try testing.expect(f128 == @Type(TypeInfo{ .Float = TypeInfo.Float{ .bits = 128 } }));
- try testTypes(&[_]type{ f16, f32, f64, f80, f128 });
-}
-
-test "Type.Array" {
- try testing.expect([123]u8 == @Type(TypeInfo{
- .Array = TypeInfo.Array{
- .len = 123,
- .child = u8,
- .sentinel = null,
- },
- }));
- try testing.expect([2]u32 == @Type(TypeInfo{
- .Array = TypeInfo.Array{
- .len = 2,
- .child = u32,
- .sentinel = null,
- },
- }));
- try testing.expect([2:0]u32 == @Type(TypeInfo{
- .Array = TypeInfo.Array{
- .len = 2,
- .child = u32,
- .sentinel = &@as(u32, 0),
- },
- }));
- try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool });
-}
-
-test "@Type create slice with null sentinel" {
- const Slice = @Type(TypeInfo{
- .Pointer = .{
- .size = .Slice,
- .is_const = true,
- .is_volatile = false,
- .is_allowzero = false,
- .alignment = 8,
- .address_space = .generic,
- .child = *i32,
- .sentinel = null,
- },
- });
- try testing.expect(Slice == []align(8) const *i32);
-}
-
-test "@Type picks up the sentinel value from TypeInfo" {
- try testTypes(&[_]type{
- [11:0]u8, [4:10]u8,
- [*:0]u8, [*:0]const u8,
- [*:0]volatile u8, [*:0]const volatile u8,
- [*:0]align(4) u8, [*:0]align(4) const u8,
- [*:0]align(4) volatile u8, [*:0]align(4) const volatile u8,
- [*:0]align(8) u8, [*:0]align(8) const u8,
- [*:0]align(8) volatile u8, [*:0]align(8) const volatile u8,
- [*:0]allowzero u8, [*:0]allowzero const u8,
- [*:0]allowzero volatile u8, [*:0]allowzero const volatile u8,
- [*:0]allowzero align(4) u8, [*:0]allowzero align(4) const u8,
- [*:0]allowzero align(4) volatile u8, [*:0]allowzero align(4) const volatile u8,
- [*:5]allowzero align(4) volatile u8, [*:5]allowzero align(4) const volatile u8,
- [:0]u8, [:0]const u8,
- [:0]volatile u8, [:0]const volatile u8,
- [:0]align(4) u8, [:0]align(4) const u8,
- [:0]align(4) volatile u8, [:0]align(4) const volatile u8,
- [:0]align(8) u8, [:0]align(8) const u8,
- [:0]align(8) volatile u8, [:0]align(8) const volatile u8,
- [:0]allowzero u8, [:0]allowzero const u8,
- [:0]allowzero volatile u8, [:0]allowzero const volatile u8,
- [:0]allowzero align(4) u8, [:0]allowzero align(4) const u8,
- [:0]allowzero align(4) volatile u8, [:0]allowzero align(4) const volatile u8,
- [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8,
- });
-}
-
-test "Type.Optional" {
- try testTypes(&[_]type{
- ?u8,
- ?*u8,
- ?[]u8,
- ?[*]u8,
- ?[*c]u8,
- });
-}
-
-test "Type.ErrorUnion" {
- try testTypes(&[_]type{
- error{}!void,
- error{Error}!void,
- });
-}
-
-test "Type.Opaque" {
- const Opaque = @Type(.{
- .Opaque = .{
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- try testing.expect(Opaque != opaque {});
- try testing.expectEqualSlices(
- TypeInfo.Declaration,
- &[_]TypeInfo.Declaration{},
- @typeInfo(Opaque).Opaque.decls,
- );
-}
-
-test "Type.Vector" {
- try testTypes(&[_]type{
- @Vector(0, u8),
- @Vector(4, u8),
- @Vector(8, *u8),
- std.meta.Vector(0, u8),
- std.meta.Vector(4, u8),
- std.meta.Vector(8, *u8),
- });
-}
-
-test "Type.AnyFrame" {
- try testTypes(&[_]type{
- anyframe,
- anyframe->u8,
- anyframe->anyframe->u8,
- });
-}
-
-fn add(a: i32, b: i32) i32 {
- return a + b;
-}
-
-test "Type.ErrorSet" {
- // error sets don't compare equal so just check if they compile
- _ = @Type(@typeInfo(error{}));
- _ = @Type(@typeInfo(error{A}));
- _ = @Type(@typeInfo(error{ A, B, C }));
-}
-
-test "Type.Struct" {
- const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
- const infoA = @typeInfo(A).Struct;
- try testing.expectEqual(TypeInfo.ContainerLayout.Auto, infoA.layout);
- try testing.expectEqualSlices(u8, "x", infoA.fields[0].name);
- try testing.expectEqual(u8, infoA.fields[0].field_type);
- try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[0].default_value);
- try testing.expectEqualSlices(u8, "y", infoA.fields[1].name);
- try testing.expectEqual(u32, infoA.fields[1].field_type);
- try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[1].default_value);
- try testing.expectEqualSlices(TypeInfo.Declaration, &[_]TypeInfo.Declaration{}, infoA.decls);
- try testing.expectEqual(@as(bool, false), infoA.is_tuple);
-
- var a = A{ .x = 0, .y = 1 };
- try testing.expectEqual(@as(u8, 0), a.x);
- try testing.expectEqual(@as(u32, 1), a.y);
- a.y += 1;
- try testing.expectEqual(@as(u32, 2), a.y);
-
- const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 }));
- const infoB = @typeInfo(B).Struct;
- try testing.expectEqual(TypeInfo.ContainerLayout.Extern, infoB.layout);
- try testing.expectEqualSlices(u8, "x", infoB.fields[0].name);
- try testing.expectEqual(u8, infoB.fields[0].field_type);
- try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value);
- try testing.expectEqualSlices(u8, "y", infoB.fields[1].name);
- try testing.expectEqual(u32, infoB.fields[1].field_type);
- try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoB.fields[1].default_value.?).*);
- try testing.expectEqual(@as(usize, 0), infoB.decls.len);
- try testing.expectEqual(@as(bool, false), infoB.is_tuple);
-
- const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 }));
- const infoC = @typeInfo(C).Struct;
- try testing.expectEqual(TypeInfo.ContainerLayout.Packed, infoC.layout);
- try testing.expectEqualSlices(u8, "x", infoC.fields[0].name);
- try testing.expectEqual(u8, infoC.fields[0].field_type);
- try testing.expectEqual(@as(u8, 3), @ptrCast(*const u8, infoC.fields[0].default_value.?).*);
- try testing.expectEqualSlices(u8, "y", infoC.fields[1].name);
- try testing.expectEqual(u32, infoC.fields[1].field_type);
- try testing.expectEqual(@as(u32, 5), @ptrCast(*const u32, infoC.fields[1].default_value.?).*);
- try testing.expectEqual(@as(usize, 0), infoC.decls.len);
- try testing.expectEqual(@as(bool, false), infoC.is_tuple);
-}
-
-test "Type.Enum" {
- const Foo = @Type(.{
- .Enum = .{
- .layout = .Auto,
- .tag_type = u8,
- .fields = &[_]TypeInfo.EnumField{
- .{ .name = "a", .value = 1 },
- .{ .name = "b", .value = 5 },
- },
- .decls = &[_]TypeInfo.Declaration{},
- .is_exhaustive = true,
- },
- });
- try testing.expectEqual(true, @typeInfo(Foo).Enum.is_exhaustive);
- try testing.expectEqual(@as(u8, 1), @enumToInt(Foo.a));
- try testing.expectEqual(@as(u8, 5), @enumToInt(Foo.b));
- const Bar = @Type(.{
- .Enum = .{
- .layout = .Extern,
- .tag_type = u32,
- .fields = &[_]TypeInfo.EnumField{
- .{ .name = "a", .value = 1 },
- .{ .name = "b", .value = 5 },
- },
- .decls = &[_]TypeInfo.Declaration{},
- .is_exhaustive = false,
- },
- });
- try testing.expectEqual(false, @typeInfo(Bar).Enum.is_exhaustive);
- try testing.expectEqual(@as(u32, 1), @enumToInt(Bar.a));
- try testing.expectEqual(@as(u32, 5), @enumToInt(Bar.b));
- try testing.expectEqual(@as(u32, 6), @enumToInt(@intToEnum(Bar, 6)));
-}
-
-test "Type.Union" {
- const Untagged = @Type(.{
- .Union = .{
- .layout = .Auto,
- .tag_type = null,
- .fields = &[_]TypeInfo.UnionField{
- .{ .name = "int", .field_type = i32, .alignment = @alignOf(f32) },
- .{ .name = "float", .field_type = f32, .alignment = @alignOf(f32) },
- },
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- var untagged = Untagged{ .int = 1 };
- untagged.float = 2.0;
- untagged.int = 3;
- try testing.expectEqual(@as(i32, 3), untagged.int);
-
- const PackedUntagged = @Type(.{
- .Union = .{
- .layout = .Packed,
- .tag_type = null,
- .fields = &[_]TypeInfo.UnionField{
- .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
- .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
- },
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- var packed_untagged = PackedUntagged{ .signed = -1 };
- try testing.expectEqual(@as(i32, -1), packed_untagged.signed);
- try testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned);
-
- const Tag = @Type(.{
- .Enum = .{
- .layout = .Auto,
- .tag_type = u1,
- .fields = &[_]TypeInfo.EnumField{
- .{ .name = "signed", .value = 0 },
- .{ .name = "unsigned", .value = 1 },
- },
- .decls = &[_]TypeInfo.Declaration{},
- .is_exhaustive = true,
- },
- });
- const Tagged = @Type(.{
- .Union = .{
- .layout = .Auto,
- .tag_type = Tag,
- .fields = &[_]TypeInfo.UnionField{
- .{ .name = "signed", .field_type = i32, .alignment = @alignOf(i32) },
- .{ .name = "unsigned", .field_type = u32, .alignment = @alignOf(u32) },
- },
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- var tagged = Tagged{ .signed = -1 };
- try testing.expectEqual(Tag.signed, tagged);
- tagged = .{ .unsigned = 1 };
- try testing.expectEqual(Tag.unsigned, tagged);
-}
-
-test "Type.Union from Type.Enum" {
- const Tag = @Type(.{
- .Enum = .{
- .layout = .Auto,
- .tag_type = u0,
- .fields = &[_]TypeInfo.EnumField{
- .{ .name = "working_as_expected", .value = 0 },
- },
- .decls = &[_]TypeInfo.Declaration{},
- .is_exhaustive = true,
- },
- });
- const T = @Type(.{
- .Union = .{
- .layout = .Auto,
- .tag_type = Tag,
- .fields = &[_]TypeInfo.UnionField{
- .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
- },
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- _ = T;
- _ = @typeInfo(T).Union;
-}
-
-test "Type.Union from regular enum" {
- const E = enum { working_as_expected };
- const T = @Type(.{
- .Union = .{
- .layout = .Auto,
- .tag_type = E,
- .fields = &[_]TypeInfo.UnionField{
- .{ .name = "working_as_expected", .field_type = u32, .alignment = @alignOf(u32) },
- },
- .decls = &[_]TypeInfo.Declaration{},
- },
- });
- _ = T;
- _ = @typeInfo(T).Union;
-}
-
-test "Type.Fn" {
- // wasm doesn't support align attributes on functions
- if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest;
-
- const foo = struct {
- fn func(a: usize, b: bool) align(4) callconv(.C) usize {
- _ = a;
- _ = b;
- return 0;
- }
- }.func;
- const Foo = @Type(@typeInfo(@TypeOf(foo)));
- const foo_2: Foo = foo;
- _ = foo_2;
-}
-
-test "Type.BoundFn" {
- // wasm doesn't support align attributes on functions
- if (builtin.target.cpu.arch == .wasm32 or builtin.target.cpu.arch == .wasm64) return error.SkipZigTest;
-
- const TestStruct = packed struct {
- pub fn foo(self: *const @This()) align(4) callconv(.Unspecified) void {
- _ = self;
- }
- };
- const test_instance: TestStruct = undefined;
- try testing.expect(std.meta.eql(
- @typeName(@TypeOf(test_instance.foo)),
- @typeName(@Type(@typeInfo(@TypeOf(test_instance.foo)))),
- ));
-}
test/behavior.zig
@@ -46,7 +46,6 @@ test {
if (builtin.zig_backend != .stage2_arm and builtin.zig_backend != .stage2_x86_64) {
// Tests that pass (partly) for stage1, llvm backend, C backend, wasm backend.
- _ = @import("behavior/array_llvm.zig");
_ = @import("behavior/bitcast.zig");
_ = @import("behavior/bugs/624.zig");
_ = @import("behavior/bugs/704.zig");
@@ -61,7 +60,6 @@ test {
_ = @import("behavior/bugs/4954.zig");
_ = @import("behavior/byval_arg_var.zig");
_ = @import("behavior/call.zig");
- _ = @import("behavior/cast_llvm.zig");
_ = @import("behavior/defer.zig");
_ = @import("behavior/enum.zig");
_ = @import("behavior/error.zig");
@@ -98,7 +96,6 @@ test {
// Tests that pass for stage1 and the llvm backend.
_ = @import("behavior/atomics.zig");
_ = @import("behavior/bugs/9584.zig");
- _ = @import("behavior/error_llvm.zig");
_ = @import("behavior/eval.zig");
_ = @import("behavior/floatop.zig");
_ = @import("behavior/math.zig");
@@ -107,7 +104,6 @@ test {
_ = @import("behavior/popcount.zig");
_ = @import("behavior/saturating_arithmetic.zig");
_ = @import("behavior/sizeof_and_typeof.zig");
- _ = @import("behavior/struct_llvm.zig");
_ = @import("behavior/switch.zig");
_ = @import("behavior/widening.zig");
@@ -156,14 +152,11 @@ test {
_ = @import("behavior/reflection.zig");
_ = @import("behavior/select.zig");
_ = @import("behavior/shuffle.zig");
- _ = @import("behavior/sizeof_and_typeof_stage1.zig");
_ = @import("behavior/struct_contains_null_ptr_itself.zig");
_ = @import("behavior/struct_contains_slice_of_itself.zig");
_ = @import("behavior/switch_prong_err_enum.zig");
_ = @import("behavior/switch_prong_implicit_cast.zig");
- _ = @import("behavior/truncate_stage1.zig");
_ = @import("behavior/tuple.zig");
- _ = @import("behavior/type_stage1.zig");
_ = @import("behavior/typename.zig");
_ = @import("behavior/union_with_members.zig");
_ = @import("behavior/var_args.zig");