aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
committerAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
commitd2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch)
treee9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /test
parent06614b3fa09954464c2e2f32756cacedc178a282 (diff)
parent63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff)
downloadzig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz
zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'test')
-rw-r--r--test/assemble_and_link.zig2
-rw-r--r--test/behavior.zig15
-rw-r--r--test/build_examples.zig16
-rw-r--r--test/cases/align.zig141
-rw-r--r--test/cases/alignof.zig6
-rw-r--r--test/cases/array.zig84
-rw-r--r--test/cases/atomics.zig52
-rw-r--r--test/cases/bitcast.zig8
-rw-r--r--test/cases/bool.zig8
-rw-r--r--test/cases/bugs/1111.zig12
-rw-r--r--test/cases/bugs/1230.zig14
-rw-r--r--test/cases/bugs/394.zig15
-rw-r--r--test/cases/bugs/655.zig6
-rw-r--r--test/cases/bugs/656.zig11
-rw-r--r--test/cases/bugs/828.zig24
-rw-r--r--test/cases/bugs/920.zig65
-rw-r--r--test/cases/byval_arg_var.zig27
-rw-r--r--test/cases/cancel.zig92
-rw-r--r--test/cases/cast.zig262
-rw-r--r--test/cases/const_slice_child.zig9
-rw-r--r--test/cases/coroutine_await_struct.zig47
-rw-r--r--test/cases/coroutines.zig108
-rw-r--r--test/cases/defer.zig41
-rw-r--r--test/cases/enum.zig644
-rw-r--r--test/cases/enum_with_members.zig8
-rw-r--r--test/cases/error.zig112
-rw-r--r--test/cases/eval.zig279
-rw-r--r--test/cases/field_parent_ptr.zig6
-rw-r--r--test/cases/fn.zig103
-rw-r--r--test/cases/fn_in_struct_in_comptime.zig17
-rw-r--r--test/cases/for.zig26
-rw-r--r--test/cases/generics.zig48
-rw-r--r--test/cases/if.zig1
-rw-r--r--test/cases/import/a_namespace.zig4
-rw-r--r--test/cases/incomplete_struct_param_tld.zig12
-rw-r--r--test/cases/ir_block_deps.zig4
-rw-r--r--test/cases/math.zig203
-rw-r--r--test/cases/merge_error_sets.zig21
-rw-r--r--test/cases/misc.zig303
-rw-r--r--test/cases/namespace_depends_on_compile_var/index.zig2
-rw-r--r--test/cases/new_stack_call.zig26
-rw-r--r--test/cases/null.zig86
-rw-r--r--test/cases/optional.zig30
-rw-r--r--test/cases/pointers.zig44
-rw-r--r--test/cases/popcount.zig24
-rw-r--r--test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig2
-rw-r--r--test/cases/reflection.zig31
-rw-r--r--test/cases/slice.zig10
-rw-r--r--test/cases/struct.zig131
-rw-r--r--test/cases/struct_contains_null_ptr_itself.zig5
-rw-r--r--test/cases/struct_contains_slice_of_itself.zig14
-rw-r--r--test/cases/switch.zig33
-rw-r--r--test/cases/switch_prong_err_enum.zig6
-rw-r--r--test/cases/switch_prong_implicit_cast.zig4
-rw-r--r--test/cases/syntax.zig8
-rw-r--r--test/cases/this.zig4
-rw-r--r--test/cases/try.zig5
-rw-r--r--test/cases/type_info.zig259
-rw-r--r--test/cases/undefined.zig8
-rw-r--r--test/cases/underscore.zig28
-rw-r--r--test/cases/union.zig139
-rw-r--r--test/cases/var_args.zig37
-rw-r--r--test/cases/void.zig14
-rw-r--r--test/cases/while.zig75
-rw-r--r--test/cases/widening.zig27
-rw-r--r--test/compare_output.zig38
-rw-r--r--test/compile_errors.zig3294
-rw-r--r--test/gen_h.zig52
-rw-r--r--test/runtime_safety.zig123
-rw-r--r--test/stage2/compare_output.zig25
-rw-r--r--test/stage2/compile_errors.zig30
-rw-r--r--test/standalone/brace_expansion/build.zig2
-rw-r--r--test/standalone/brace_expansion/main.zig38
-rw-r--r--test/standalone/issue_339/build.zig2
-rw-r--r--test/standalone/issue_339/test.zig5
-rw-r--r--test/standalone/issue_794/build.zig2
-rw-r--r--test/standalone/load_dynamic_library/add.zig3
-rw-r--r--test/standalone/load_dynamic_library/build.zig21
-rw-r--r--test/standalone/load_dynamic_library/main.zig17
-rw-r--r--test/standalone/pkg_import/build.zig2
-rw-r--r--test/standalone/pkg_import/pkg.zig4
-rw-r--r--test/standalone/use_alias/build.zig2
-rw-r--r--test/standalone/use_alias/main.zig2
-rw-r--r--test/tests.zig357
-rw-r--r--test/translate_c.zig307
85 files changed, 6120 insertions, 2114 deletions
diff --git a/test/assemble_and_link.zig b/test/assemble_and_link.zig
index 2593f3306a..8c727e87b5 100644
--- a/test/assemble_and_link.zig
+++ b/test/assemble_and_link.zig
@@ -1,7 +1,7 @@
const builtin = @import("builtin");
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.CompareOutputContext) void {
+pub fn addCases(cases: *tests.CompareOutputContext) void {
if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {
cases.addAsm("hello world linux x86_64",
\\.text
diff --git a/test/behavior.zig b/test/behavior.zig
index de39b20dad..e993d7e0dc 100644
--- a/test/behavior.zig
+++ b/test/behavior.zig
@@ -8,12 +8,18 @@ comptime {
_ = @import("cases/atomics.zig");
_ = @import("cases/bitcast.zig");
_ = @import("cases/bool.zig");
+ _ = @import("cases/bugs/1111.zig");
+ _ = @import("cases/bugs/1230.zig");
_ = @import("cases/bugs/394.zig");
_ = @import("cases/bugs/655.zig");
_ = @import("cases/bugs/656.zig");
_ = @import("cases/bugs/828.zig");
+ _ = @import("cases/bugs/920.zig");
+ _ = @import("cases/byval_arg_var.zig");
+ _ = @import("cases/cancel.zig");
_ = @import("cases/cast.zig");
_ = @import("cases/const_slice_child.zig");
+ _ = @import("cases/coroutine_await_struct.zig");
_ = @import("cases/coroutines.zig");
_ = @import("cases/defer.zig");
_ = @import("cases/enum.zig");
@@ -22,6 +28,7 @@ comptime {
_ = @import("cases/eval.zig");
_ = @import("cases/field_parent_ptr.zig");
_ = @import("cases/fn.zig");
+ _ = @import("cases/fn_in_struct_in_comptime.zig");
_ = @import("cases/for.zig");
_ = @import("cases/generics.zig");
_ = @import("cases/if.zig");
@@ -29,9 +36,14 @@ comptime {
_ = @import("cases/incomplete_struct_param_tld.zig");
_ = @import("cases/ir_block_deps.zig");
_ = @import("cases/math.zig");
+ _ = @import("cases/merge_error_sets.zig");
_ = @import("cases/misc.zig");
_ = @import("cases/namespace_depends_on_compile_var/index.zig");
+ _ = @import("cases/new_stack_call.zig");
_ = @import("cases/null.zig");
+ _ = @import("cases/optional.zig");
+ _ = @import("cases/pointers.zig");
+ _ = @import("cases/popcount.zig");
_ = @import("cases/pub_enum/index.zig");
_ = @import("cases/ref_var_in_if_after_if_2nd_switch_prong.zig");
_ = @import("cases/reflection.zig");
@@ -46,9 +58,12 @@ comptime {
_ = @import("cases/syntax.zig");
_ = @import("cases/this.zig");
_ = @import("cases/try.zig");
+ _ = @import("cases/type_info.zig");
_ = @import("cases/undefined.zig");
+ _ = @import("cases/underscore.zig");
_ = @import("cases/union.zig");
_ = @import("cases/var_args.zig");
_ = @import("cases/void.zig");
_ = @import("cases/while.zig");
+ _ = @import("cases/widening.zig");
}
diff --git a/test/build_examples.zig b/test/build_examples.zig
index a3b44b9136..79192c3e9a 100644
--- a/test/build_examples.zig
+++ b/test/build_examples.zig
@@ -2,20 +2,30 @@ const tests = @import("tests.zig");
const builtin = @import("builtin");
const is_windows = builtin.os == builtin.Os.windows;
-pub fn addCases(cases: &tests.BuildExamplesContext) void {
+pub fn addCases(cases: *tests.BuildExamplesContext) void {
cases.add("example/hello_world/hello.zig");
cases.addC("example/hello_world/hello_libc.zig");
cases.add("example/cat/main.zig");
cases.add("example/guess_number/main.zig");
if (!is_windows) {
// TODO get this test passing on windows
- // See https://github.com/zig-lang/zig/issues/538
+ // See https://github.com/ziglang/zig/issues/538
cases.addBuildFile("example/shared_library/build.zig");
cases.addBuildFile("example/mix_o_files/build.zig");
}
- cases.addBuildFile("test/standalone/issue_339/build.zig");
+ if (builtin.os != builtin.Os.macosx) {
+ // TODO https://github.com/ziglang/zig/issues/1126
+ cases.addBuildFile("test/standalone/issue_339/build.zig");
+ }
cases.addBuildFile("test/standalone/issue_794/build.zig");
cases.addBuildFile("test/standalone/pkg_import/build.zig");
cases.addBuildFile("test/standalone/use_alias/build.zig");
cases.addBuildFile("test/standalone/brace_expansion/build.zig");
+ if (false) {
+ // TODO this test is disabled because it is failing on the CI server's linux. when this is fixed
+ // enable it for at least linux
+ // TODO hook up the DynLib API for windows using LoadLibraryA
+ // TODO figure out how to make this work on darwin - probably libSystem has dlopen/dlsym in it
+ cases.addBuildFile("test/standalone/load_dynamic_library/build.zig");
+ }
}
diff --git a/test/cases/align.zig b/test/cases/align.zig
index ad3a66a2e0..64f0788efc 100644
--- a/test/cases/align.zig
+++ b/test/cases/align.zig
@@ -5,34 +5,34 @@ var foo: u8 align(4) = 100;
test "global variable alignment" {
assert(@typeOf(&foo).alignment == 4);
- assert(@typeOf(&foo) == &align(4) u8);
- const slice = (&foo)[0..1];
+ assert(@typeOf(&foo) == *align(4) u8);
+ const slice = (*[1]u8)(&foo)[0..];
assert(@typeOf(slice) == []align(4) u8);
}
-fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
+fn derp() align(@sizeOf(usize) * 2) i32 {
+ return 1234;
+}
fn noop1() align(1) void {}
fn noop4() align(4) void {}
test "function alignment" {
assert(derp() == 1234);
- assert(@typeOf(noop1) == fn() align(1) void);
- assert(@typeOf(noop4) == fn() align(4) void);
+ assert(@typeOf(noop1) == fn () align(1) void);
+ assert(@typeOf(noop4) == fn () align(4) void);
noop1();
noop4();
}
-
var baz: packed struct {
a: u32,
b: u32,
} = undefined;
test "packed struct alignment" {
- assert(@typeOf(&baz.b) == &align(1) u32);
+ assert(@typeOf(&baz.b) == *align(1) u32);
}
-
const blah: packed struct {
a: u3,
b: u3,
@@ -40,11 +40,11 @@ const blah: packed struct {
} = undefined;
test "bit field alignment" {
- assert(@typeOf(&blah.b) == &align(1:3:6) const u3);
+ assert(@typeOf(&blah.b) == *align(1:3:6) const u3);
}
test "default alignment allows unspecified in type syntax" {
- assert(&u32 == &align(@alignOf(u32)) u32);
+ assert(*u32 == *align(@alignOf(u32)) u32);
}
test "implicitly decreasing pointer alignment" {
@@ -53,30 +53,44 @@ test "implicitly decreasing pointer alignment" {
assert(addUnaligned(&a, &b) == 7);
}
-fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { return *a + *b; }
+fn addUnaligned(a: *align(1) const u32, b: *align(1) const u32) u32 {
+ return a.* + b.*;
+}
test "implicitly decreasing slice alignment" {
const a: u32 align(4) = 3;
const b: u32 align(8) = 4;
- assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
+ assert(addUnalignedSlice((*[1]u32)(&a)[0..], (*[1]u32)(&b)[0..]) == 7);
+}
+fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 {
+ return a[0] + b[0];
}
-fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; }
test "specifying alignment allows pointer cast" {
testBytesAlign(0x33);
}
fn testBytesAlign(b: u8) void {
- var bytes align(4) = []u8{b, b, b, b};
- const ptr = @ptrCast(&u32, &bytes[0]);
- assert(*ptr == 0x33333333);
+ var bytes align(4) = []u8{
+ b,
+ b,
+ b,
+ b,
+ };
+ const ptr = @ptrCast(*u32, &bytes[0]);
+ assert(ptr.* == 0x33333333);
}
test "specifying alignment allows slice cast" {
testBytesAlignSlice(0x33);
}
fn testBytesAlignSlice(b: u8) void {
- var bytes align(4) = []u8{b, b, b, b};
- const slice = ([]u32)(bytes[0..]);
+ var bytes align(4) = []u8{
+ b,
+ b,
+ b,
+ b,
+ };
+ const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
assert(slice[0] == 0x33333333);
}
@@ -85,15 +99,18 @@ test "@alignCast pointers" {
expectsOnly1(&x);
assert(x == 2);
}
-fn expectsOnly1(x: &align(1) u32) void {
+fn expectsOnly1(x: *align(1) u32) void {
expects4(@alignCast(4, x));
}
-fn expects4(x: &align(4) u32) void {
- *x += 1;
+fn expects4(x: *align(4) u32) void {
+ x.* += 1;
}
test "@alignCast slices" {
- var array align(4) = []u32{1, 1};
+ var array align(4) = []u32{
+ 1,
+ 1,
+ };
const slice = array[0..];
sliceExpectsOnly1(slice);
assert(slice[0] == 2);
@@ -105,7 +122,6 @@ fn sliceExpects4(slice: []align(4) u32) void {
slice[0] += 1;
}
-
test "implicitly decreasing fn alignment" {
testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
testImplicitlyDecreaseFnAlign(alignedBig, 5678);
@@ -115,21 +131,25 @@ fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {
assert(ptr() == answer);
}
-fn alignedSmall() align(8) i32 { return 1234; }
-fn alignedBig() align(16) i32 { return 5678; }
-
+fn alignedSmall() align(8) i32 {
+ return 1234;
+}
+fn alignedBig() align(16) i32 {
+ return 5678;
+}
test "@alignCast functions" {
assert(fnExpectsOnly1(simple4) == 0x19);
}
-fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 {
+fn fnExpectsOnly1(ptr: fn () align(1) i32) i32 {
return fnExpects4(@alignCast(4, ptr));
}
-fn fnExpects4(ptr: fn()align(4) i32) i32 {
+fn fnExpects4(ptr: fn () align(4) i32) i32 {
return ptr();
}
-fn simple4() align(4) i32 { return 0x19; }
-
+fn simple4() align(4) i32 {
+ return 0x19;
+}
test "generic function with align param" {
assert(whyWouldYouEverDoThis(1) == 0x1);
@@ -137,52 +157,53 @@ test "generic function with align param" {
assert(whyWouldYouEverDoThis(8) == 0x1);
}
-fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { return 0x1; }
-
+fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 {
+ return 0x1;
+}
test "@ptrCast preserves alignment of bigger source" {
var x: u32 align(16) = 1234;
- const ptr = @ptrCast(&u8, &x);
- assert(@typeOf(ptr) == &align(16) u8);
+ const ptr = @ptrCast(*u8, &x);
+ assert(@typeOf(ptr) == *align(16) u8);
}
-
-test "compile-time known array index has best alignment possible" {
+test "runtime known array index has best alignment possible" {
// take full advantage of over-alignment
- var array align(4) = []u8 {1, 2, 3, 4};
- assert(@typeOf(&array[0]) == &align(4) u8);
- assert(@typeOf(&array[1]) == &u8);
- assert(@typeOf(&array[2]) == &align(2) u8);
- assert(@typeOf(&array[3]) == &u8);
+ var array align(4) = []u8{ 1, 2, 3, 4 };
+ assert(@typeOf(&array[0]) == *align(4) u8);
+ assert(@typeOf(&array[1]) == *u8);
+ assert(@typeOf(&array[2]) == *align(2) u8);
+ assert(@typeOf(&array[3]) == *u8);
// because align is too small but we still figure out to use 2
- var bigger align(2) = []u64{1, 2, 3, 4};
- assert(@typeOf(&bigger[0]) == &align(2) u64);
- assert(@typeOf(&bigger[1]) == &align(2) u64);
- assert(@typeOf(&bigger[2]) == &align(2) u64);
- assert(@typeOf(&bigger[3]) == &align(2) u64);
+ var bigger align(2) = []u64{ 1, 2, 3, 4 };
+ assert(@typeOf(&bigger[0]) == *align(2) u64);
+ assert(@typeOf(&bigger[1]) == *align(2) u64);
+ assert(@typeOf(&bigger[2]) == *align(2) u64);
+ assert(@typeOf(&bigger[3]) == *align(2) u64);
// because pointer is align 2 and u32 align % 2 == 0 we can assume align 2
- var smaller align(2) = []u32{1, 2, 3, 4};
- testIndex(&smaller[0], 0, &align(2) u32);
- testIndex(&smaller[0], 1, &align(2) u32);
- testIndex(&smaller[0], 2, &align(2) u32);
- testIndex(&smaller[0], 3, &align(2) u32);
+ var smaller align(2) = []u32{ 1, 2, 3, 4 };
+ comptime assert(@typeOf(smaller[0..]) == []align(2) u32);
+ comptime assert(@typeOf(smaller[0..].ptr) == [*]align(2) u32);
+ testIndex(smaller[0..].ptr, 0, *align(2) u32);
+ testIndex(smaller[0..].ptr, 1, *align(2) u32);
+ testIndex(smaller[0..].ptr, 2, *align(2) u32);
+ testIndex(smaller[0..].ptr, 3, *align(2) u32);
// has to use ABI alignment because index known at runtime only
- testIndex2(&array[0], 0, &u8);
- testIndex2(&array[0], 1, &u8);
- testIndex2(&array[0], 2, &u8);
- testIndex2(&array[0], 3, &u8);
+ testIndex2(array[0..].ptr, 0, *u8);
+ testIndex2(array[0..].ptr, 1, *u8);
+ testIndex2(array[0..].ptr, 2, *u8);
+ testIndex2(array[0..].ptr, 3, *u8);
}
-fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) void {
- assert(@typeOf(&smaller[index]) == T);
+fn testIndex(smaller: [*]align(2) u32, index: usize, comptime T: type) void {
+ comptime assert(@typeOf(&smaller[index]) == T);
}
-fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {
- assert(@typeOf(&ptr[index]) == T);
+fn testIndex2(ptr: [*]align(4) u8, index: usize, comptime T: type) void {
+ comptime assert(@typeOf(&ptr[index]) == T);
}
-
test "alignstack" {
assert(fnWithAlignedStack() == 1234);
}
diff --git a/test/cases/alignof.zig b/test/cases/alignof.zig
index 27b95c7fdc..130a2a5b44 100644
--- a/test/cases/alignof.zig
+++ b/test/cases/alignof.zig
@@ -1,7 +1,11 @@
const assert = @import("std").debug.assert;
const builtin = @import("builtin");
-const Foo = struct { x: u32, y: u32, z: u32, };
+const Foo = struct {
+ x: u32,
+ y: u32,
+ z: u32,
+};
test "@alignOf(T) before referencing T" {
comptime assert(@alignOf(Foo) != @maxValue(usize));
diff --git a/test/cases/array.zig b/test/cases/array.zig
index 577161dd16..b72491bcc0 100644
--- a/test/cases/array.zig
+++ b/test/cases/array.zig
@@ -2,9 +2,9 @@ const assert = @import("std").debug.assert;
const mem = @import("std").mem;
test "arrays" {
- var array : [5]u32 = undefined;
+ var array: [5]u32 = undefined;
- var i : u32 = 0;
+ var i: u32 = 0;
while (i < 5) {
array[i] = i + 1;
i = array[i];
@@ -34,24 +34,41 @@ test "void arrays" {
}
test "array literal" {
- const hex_mult = []u16{4096, 256, 16, 1};
+ const hex_mult = []u16{
+ 4096,
+ 256,
+ 16,
+ 1,
+ };
assert(hex_mult.len == 4);
assert(hex_mult[1] == 256);
}
test "array dot len const expr" {
- assert(comptime x: {break :x some_array.len == 4;});
+ assert(comptime x: {
+ break :x some_array.len == 4;
+ });
}
const ArrayDotLenConstExpr = struct {
y: [some_array.len]u8,
};
-const some_array = []u8 {0, 1, 2, 3};
-
+const some_array = []u8{
+ 0,
+ 1,
+ 2,
+ 3,
+};
test "nested arrays" {
- const array_of_strings = [][]const u8 {"hello", "this", "is", "my", "thing"};
+ const array_of_strings = [][]const u8{
+ "hello",
+ "this",
+ "is",
+ "my",
+ "thing",
+ };
for (array_of_strings) |s, i| {
if (i == 0) assert(mem.eql(u8, s, "hello"));
if (i == 1) assert(mem.eql(u8, s, "this"));
@@ -61,7 +78,6 @@ test "nested arrays" {
}
}
-
var s_array: [8]Sub = undefined;
const Sub = struct {
b: u8,
@@ -70,7 +86,7 @@ const Str = struct {
a: []Sub,
};
test "set global var array via slice embedded in struct" {
- var s = Str { .a = s_array[0..]};
+ var s = Str{ .a = s_array[0..] };
s.a[0].b = 1;
s.a[1].b = 2;
@@ -82,7 +98,10 @@ test "set global var array via slice embedded in struct" {
}
test "array literal with specified size" {
- var array = [2]u8{1, 2};
+ var array = [2]u8{
+ 1,
+ 2,
+ };
assert(array[0] == 1);
assert(array[1] == 2);
}
@@ -96,3 +115,48 @@ test "array len property" {
var x: [5]i32 = undefined;
assert(@typeOf(x).len == 5);
}
+
+test "array len field" {
+ var arr = [4]u8{ 0, 0, 0, 0 };
+ var ptr = &arr;
+ assert(arr.len == 4);
+ comptime assert(arr.len == 4);
+ assert(ptr.len == 4);
+ comptime assert(ptr.len == 4);
+}
+
+test "single-item pointer to array indexing and slicing" {
+ testSingleItemPtrArrayIndexSlice();
+ comptime testSingleItemPtrArrayIndexSlice();
+}
+
+fn testSingleItemPtrArrayIndexSlice() void {
+ var array = "aaaa";
+ doSomeMangling(&array);
+ assert(mem.eql(u8, "azya", array));
+}
+
+fn doSomeMangling(array: *[4]u8) void {
+ array[1] = 'z';
+ array[2..3][0] = 'y';
+}
+
+test "implicit cast single-item pointer" {
+ testImplicitCastSingleItemPtr();
+ comptime testImplicitCastSingleItemPtr();
+}
+
+fn testImplicitCastSingleItemPtr() void {
+ var byte: u8 = 100;
+ const slice = (*[1]u8)(&byte)[0..];
+ slice[0] += 1;
+ assert(byte == 101);
+}
+
+fn testArrayByValAtComptime(b: [2]u8) u8 { return b[0]; }
+
+test "comptime evalutating function that takes array by value" {
+ const arr = []u8{0,1};
+ _ = comptime testArrayByValAtComptime(arr);
+ _ = comptime testArrayByValAtComptime(arr);
+}
diff --git a/test/cases/atomics.zig b/test/cases/atomics.zig
index e8e81b76e6..67c9ab3dd1 100644
--- a/test/cases/atomics.zig
+++ b/test/cases/atomics.zig
@@ -1,12 +1,24 @@
-const assert = @import("std").debug.assert;
+const std = @import("std");
+const assert = std.debug.assert;
const builtin = @import("builtin");
const AtomicRmwOp = builtin.AtomicRmwOp;
const AtomicOrder = builtin.AtomicOrder;
test "cmpxchg" {
var x: i32 = 1234;
- while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
+ if (@cmpxchgWeak(i32, &x, 99, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
+ assert(x1 == 1234);
+ } else {
+ @panic("cmpxchg should have failed");
+ }
+
+ while (@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
+ assert(x1 == 1234);
+ }
assert(x == 5678);
+
+ assert(@cmpxchgStrong(i32, &x, 5678, 42, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
+ assert(x == 42);
}
test "fence" {
@@ -15,13 +27,45 @@ test "fence" {
x = 5678;
}
-test "atomicrmw" {
+test "atomicrmw and atomicload" {
var data: u8 = 200;
testAtomicRmw(&data);
assert(data == 42);
+ testAtomicLoad(&data);
}
-fn testAtomicRmw(ptr: &u8) void {
+fn testAtomicRmw(ptr: *u8) void {
const prev_value = @atomicRmw(u8, ptr, AtomicRmwOp.Xchg, 42, AtomicOrder.SeqCst);
assert(prev_value == 200);
+ comptime {
+ var x: i32 = 1234;
+ const y: i32 = 12345;
+ assert(@atomicLoad(i32, &x, AtomicOrder.SeqCst) == 1234);
+ assert(@atomicLoad(i32, &y, AtomicOrder.SeqCst) == 12345);
+ }
+}
+
+fn testAtomicLoad(ptr: *u8) void {
+ const x = @atomicLoad(u8, ptr, AtomicOrder.SeqCst);
+ assert(x == 42);
+}
+
+test "cmpxchg with ptr" {
+ var data1: i32 = 1234;
+ var data2: i32 = 5678;
+ var data3: i32 = 9101;
+ var x: *i32 = &data1;
+ if (@cmpxchgWeak(*i32, &x, &data2, &data3, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
+ assert(x1 == &data1);
+ } else {
+ @panic("cmpxchg should have failed");
+ }
+
+ while (@cmpxchgWeak(*i32, &x, &data1, &data3, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) |x1| {
+ assert(x1 == &data1);
+ }
+ assert(x == &data3);
+
+ assert(@cmpxchgStrong(*i32, &x, &data3, &data2, AtomicOrder.SeqCst, AtomicOrder.SeqCst) == null);
+ assert(x == &data2);
}
diff --git a/test/cases/bitcast.zig b/test/cases/bitcast.zig
index f1f2ccd672..878140954a 100644
--- a/test/cases/bitcast.zig
+++ b/test/cases/bitcast.zig
@@ -10,5 +10,9 @@ fn testBitCast_i32_u32() void {
assert(conv2(@maxValue(u32)) == -1);
}
-fn conv(x: i32) u32 { return @bitCast(u32, x); }
-fn conv2(x: u32) i32 { return @bitCast(i32, x); }
+fn conv(x: i32) u32 {
+ return @bitCast(u32, x);
+}
+fn conv2(x: u32) i32 {
+ return @bitCast(i32, x);
+}
diff --git a/test/cases/bool.zig b/test/cases/bool.zig
index 07d30454ee..3e4ac9c1cf 100644
--- a/test/cases/bool.zig
+++ b/test/cases/bool.zig
@@ -8,14 +8,14 @@ test "bool literals" {
test "cast bool to int" {
const t = true;
const f = false;
- assert(i32(t) == i32(1));
- assert(i32(f) == i32(0));
+ assert(@boolToInt(t) == u32(1));
+ assert(@boolToInt(f) == u32(0));
nonConstCastBoolToInt(t, f);
}
fn nonConstCastBoolToInt(t: bool, f: bool) void {
- assert(i32(t) == i32(1));
- assert(i32(f) == i32(0));
+ assert(@boolToInt(t) == u32(1));
+ assert(@boolToInt(f) == u32(0));
}
test "bool cmp" {
diff --git a/test/cases/bugs/1111.zig b/test/cases/bugs/1111.zig
new file mode 100644
index 0000000000..f62107f9a3
--- /dev/null
+++ b/test/cases/bugs/1111.zig
@@ -0,0 +1,12 @@
+const Foo = extern enum {
+ Bar = -1,
+};
+
+test "issue 1111 fixed" {
+ const v = Foo.Bar;
+
+ switch (v) {
+ Foo.Bar => return,
+ else => return,
+ }
+}
diff --git a/test/cases/bugs/1230.zig b/test/cases/bugs/1230.zig
new file mode 100644
index 0000000000..b782a77f0b
--- /dev/null
+++ b/test/cases/bugs/1230.zig
@@ -0,0 +1,14 @@
+const assert = @import("std").debug.assert;
+
+const S = extern struct {
+ x: i32,
+};
+
+extern fn ret_struct() S {
+ return S{ .x = 42 };
+}
+
+test "extern return small struct (bug 1230)" {
+ const s = ret_struct();
+ assert(s.x == 42);
+}
diff --git a/test/cases/bugs/394.zig b/test/cases/bugs/394.zig
index 071619d59c..b0afec2357 100644
--- a/test/cases/bugs/394.zig
+++ b/test/cases/bugs/394.zig
@@ -1,9 +1,18 @@
-const E = union(enum) { A: [9]u8, B: u64, };
-const S = struct { x: u8, y: E, };
+const E = union(enum) {
+ A: [9]u8,
+ B: u64,
+};
+const S = struct {
+ x: u8,
+ y: E,
+};
const assert = @import("std").debug.assert;
test "bug 394 fixed" {
- const x = S { .x = 3, .y = E {.B = 1 } };
+ const x = S{
+ .x = 3,
+ .y = E{ .B = 1 },
+ };
assert(x.x == 3);
}
diff --git a/test/cases/bugs/655.zig b/test/cases/bugs/655.zig
index e6a275004c..50374d4e6d 100644
--- a/test/cases/bugs/655.zig
+++ b/test/cases/bugs/655.zig
@@ -3,10 +3,10 @@ const other_file = @import("655_other_file.zig");
test "function with &const parameter with type dereferenced by namespace" {
const x: other_file.Integer = 1234;
- comptime std.debug.assert(@typeOf(&x) == &const other_file.Integer);
+ comptime std.debug.assert(@typeOf(&x) == *const other_file.Integer);
foo(x);
}
-fn foo(x: &const other_file.Integer) void {
- std.debug.assert(*x == 1234);
+fn foo(x: *const other_file.Integer) void {
+ std.debug.assert(x.* == 1234);
}
diff --git a/test/cases/bugs/656.zig b/test/cases/bugs/656.zig
index ce3eec8046..f93f0ac4d5 100644
--- a/test/cases/bugs/656.zig
+++ b/test/cases/bugs/656.zig
@@ -9,17 +9,18 @@ const Value = struct {
align_expr: ?u32,
};
-test "nullable if after an if in a switch prong of a switch with 2 prongs in an else" {
+test "optional if after an if in a switch prong of a switch with 2 prongs in an else" {
foo(false, true);
}
fn foo(a: bool, b: bool) void {
- var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };
- if (a) {
- } else {
+ var prefix_op = PrefixOp{
+ .AddrOf = Value{ .align_expr = 1234 },
+ };
+ if (a) {} else {
switch (prefix_op) {
PrefixOp.AddrOf => |addr_of_info| {
- if (b) { }
+ if (b) {}
if (addr_of_info.align_expr) |align_expr| {
assert(align_expr == 1234);
}
diff --git a/test/cases/bugs/828.zig b/test/cases/bugs/828.zig
index c46548cb7a..50ae0fd279 100644
--- a/test/cases/bugs/828.zig
+++ b/test/cases/bugs/828.zig
@@ -1,31 +1,27 @@
const CountBy = struct {
a: usize,
-
- const One = CountBy {
- .a = 1,
- };
-
- pub fn counter(self: &const CountBy) Counter {
- return Counter {
- .i = 0,
- };
+
+ const One = CountBy{ .a = 1 };
+
+ pub fn counter(self: *const CountBy) Counter {
+ return Counter{ .i = 0 };
}
};
const Counter = struct {
i: usize,
-
- pub fn count(self: &Counter) bool {
+
+ pub fn count(self: *Counter) bool {
self.i += 1;
return self.i <= 10;
}
};
-fn constCount(comptime cb: &const CountBy, comptime unused: u32) void {
+fn constCount(comptime cb: *const CountBy, comptime unused: u32) void {
comptime {
var cnt = cb.counter();
- if(cnt.i != 0) @compileError("Counter instance reused!");
- while(cnt.count()){}
+ if (cnt.i != 0) @compileError("Counter instance reused!");
+ while (cnt.count()) {}
}
}
diff --git a/test/cases/bugs/920.zig b/test/cases/bugs/920.zig
new file mode 100644
index 0000000000..2903f05a29
--- /dev/null
+++ b/test/cases/bugs/920.zig
@@ -0,0 +1,65 @@
+const std = @import("std");
+const math = std.math;
+const Random = std.rand.Random;
+
+const ZigTable = struct {
+ r: f64,
+ x: [257]f64,
+ f: [257]f64,
+
+ pdf: fn (f64) f64,
+ is_symmetric: bool,
+ zero_case: fn (*Random, f64) f64,
+};
+
+fn ZigTableGen(comptime is_symmetric: bool, comptime r: f64, comptime v: f64, comptime f: fn (f64) f64, comptime f_inv: fn (f64) f64, comptime zero_case: fn (*Random, f64) f64) ZigTable {
+ var tables: ZigTable = undefined;
+
+ tables.is_symmetric = is_symmetric;
+ tables.r = r;
+ tables.pdf = f;
+ tables.zero_case = zero_case;
+
+ tables.x[0] = v / f(r);
+ tables.x[1] = r;
+
+ for (tables.x[2..256]) |*entry, i| {
+ const last = tables.x[2 + i - 1];
+ entry.* = f_inv(v / last + f(last));
+ }
+ tables.x[256] = 0;
+
+ for (tables.f[0..]) |*entry, i| {
+ entry.* = f(tables.x[i]);
+ }
+
+ return tables;
+}
+
+const norm_r = 3.6541528853610088;
+const norm_v = 0.00492867323399;
+
+fn norm_f(x: f64) f64 {
+ return math.exp(-x * x / 2.0);
+}
+fn norm_f_inv(y: f64) f64 {
+ return math.sqrt(-2.0 * math.ln(y));
+}
+fn norm_zero_case(random: *Random, u: f64) f64 {
+ return 0.0;
+}
+
+const NormalDist = blk: {
+ @setEvalBranchQuota(30000);
+ break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);
+};
+
+test "bug 920 fixed" {
+ const NormalDist1 = blk: {
+ break :blk ZigTableGen(true, norm_r, norm_v, norm_f, norm_f_inv, norm_zero_case);
+ };
+
+ for (NormalDist1.f) |_, i| {
+ std.debug.assert(NormalDist1.f[i] == NormalDist.f[i]);
+ }
+}
diff --git a/test/cases/byval_arg_var.zig b/test/cases/byval_arg_var.zig
new file mode 100644
index 0000000000..826b9cc9e5
--- /dev/null
+++ b/test/cases/byval_arg_var.zig
@@ -0,0 +1,27 @@
+const std = @import("std");
+
+var result: []const u8 = "wrong";
+
+test "aoeu" {
+ start();
+ blowUpStack(10);
+
+ std.debug.assert(std.mem.eql(u8, result, "string literal"));
+}
+
+fn start() void {
+ foo("string literal");
+}
+
+fn foo(x: var) void {
+ bar(x);
+}
+
+fn bar(x: var) void {
+ result = x;
+}
+
+fn blowUpStack(x: u32) void {
+ if (x == 0) return;
+ blowUpStack(x - 1);
+}
diff --git a/test/cases/cancel.zig b/test/cases/cancel.zig
new file mode 100644
index 0000000000..c0f74fd34f
--- /dev/null
+++ b/test/cases/cancel.zig
@@ -0,0 +1,92 @@
+const std = @import("std");
+
+var defer_f1: bool = false;
+var defer_f2: bool = false;
+var defer_f3: bool = false;
+
+test "cancel forwards" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
+ const p = async<&da.allocator> f1() catch unreachable;
+ cancel p;
+ std.debug.assert(defer_f1);
+ std.debug.assert(defer_f2);
+ std.debug.assert(defer_f3);
+}
+
+async fn f1() void {
+ defer {
+ defer_f1 = true;
+ }
+ await (async f2() catch unreachable);
+}
+
+async fn f2() void {
+ defer {
+ defer_f2 = true;
+ }
+ await (async f3() catch unreachable);
+}
+
+async fn f3() void {
+ defer {
+ defer_f3 = true;
+ }
+ suspend;
+}
+
+var defer_b1: bool = false;
+var defer_b2: bool = false;
+var defer_b3: bool = false;
+var defer_b4: bool = false;
+
+test "cancel backwards" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
+ const p = async<&da.allocator> b1() catch unreachable;
+ cancel p;
+ std.debug.assert(defer_b1);
+ std.debug.assert(defer_b2);
+ std.debug.assert(defer_b3);
+ std.debug.assert(defer_b4);
+}
+
+async fn b1() void {
+ defer {
+ defer_b1 = true;
+ }
+ await (async b2() catch unreachable);
+}
+
+var b4_handle: promise = undefined;
+
+async fn b2() void {
+ const b3_handle = async b3() catch unreachable;
+ resume b4_handle;
+ cancel b4_handle;
+ defer {
+ defer_b2 = true;
+ }
+ const value = await b3_handle;
+ @panic("unreachable");
+}
+
+async fn b3() i32 {
+ defer {
+ defer_b3 = true;
+ }
+ await (async b4() catch unreachable);
+ return 1234;
+}
+
+async fn b4() void {
+ defer {
+ defer_b4 = true;
+ }
+ suspend {
+ b4_handle = @handle();
+ }
+ suspend;
+}
diff --git a/test/cases/cast.zig b/test/cases/cast.zig
index 024ece0055..63cc6313e1 100644
--- a/test/cases/cast.zig
+++ b/test/cases/cast.zig
@@ -1,23 +1,24 @@
-const assert = @import("std").debug.assert;
-const mem = @import("std").mem;
+const std = @import("std");
+const assert = std.debug.assert;
+const mem = std.mem;
test "int to ptr cast" {
const x = usize(13);
- const y = @intToPtr(&u8, x);
+ const y = @intToPtr(*u8, x);
const z = @ptrToInt(y);
assert(z == 13);
}
test "integer literal to pointer cast" {
- const vga_mem = @intToPtr(&u16, 0xB8000);
+ const vga_mem = @intToPtr(*u16, 0xB8000);
assert(@ptrToInt(vga_mem) == 0xB8000);
}
test "pointer reinterpret const float to int" {
const float: f64 = 5.99999999999994648725e-01;
const float_ptr = &float;
- const int_ptr = @ptrCast(&const i32, float_ptr);
- const int_val = *int_ptr;
+ const int_ptr = @ptrCast(*const i32, float_ptr);
+ const int_val = int_ptr.*;
assert(int_val == 858993411);
}
@@ -28,26 +29,26 @@ test "implicitly cast a pointer to a const pointer of it" {
assert(x == 2);
}
-fn funcWithConstPtrPtr(x: &const &i32) void {
- **x += 1;
+fn funcWithConstPtrPtr(x: *const *i32) void {
+ x.*.* += 1;
}
test "implicitly cast a container to a const pointer of it" {
- const z = Struct(void) { .x = void{} };
+ const z = Struct(void){ .x = void{} };
assert(0 == @sizeOf(@typeOf(z)));
assert(void{} == Struct(void).pointer(z).x);
assert(void{} == Struct(void).pointer(&z).x);
assert(void{} == Struct(void).maybePointer(z).x);
assert(void{} == Struct(void).maybePointer(&z).x);
assert(void{} == Struct(void).maybePointer(null).x);
- const s = Struct(u8) { .x = 42 };
+ const s = Struct(u8){ .x = 42 };
assert(0 != @sizeOf(@typeOf(s)));
assert(42 == Struct(u8).pointer(s).x);
assert(42 == Struct(u8).pointer(&s).x);
assert(42 == Struct(u8).maybePointer(s).x);
assert(42 == Struct(u8).maybePointer(&s).x);
assert(0 == Struct(u8).maybePointer(null).x);
- const u = Union { .x = 42 };
+ const u = Union{ .x = 42 };
assert(42 == Union.pointer(u).x);
assert(42 == Union.pointer(&u).x);
assert(42 == Union.maybePointer(u).x);
@@ -66,13 +67,13 @@ fn Struct(comptime T: type) type {
const Self = this;
x: T,
- fn pointer(self: &const Self) Self {
- return *self;
+ fn pointer(self: *const Self) Self {
+ return self.*;
}
- fn maybePointer(self: ?&const Self) Self {
- const none = Self { .x = if (T == void) void{} else 0 };
- return *(self ?? &none);
+ fn maybePointer(self: ?*const Self) Self {
+ const none = Self{ .x = if (T == void) void{} else 0 };
+ return (self orelse &none).*;
}
};
}
@@ -80,13 +81,13 @@ fn Struct(comptime T: type) type {
const Union = union {
x: u8,
- fn pointer(self: &const Union) Union {
- return *self;
+ fn pointer(self: *const Union) Union {
+ return self.*;
}
- fn maybePointer(self: ?&const Union) Union {
- const none = Union { .x = 0 };
- return *(self ?? &none);
+ fn maybePointer(self: ?*const Union) Union {
+ const none = Union{ .x = 0 };
+ return (self orelse &none).*;
}
};
@@ -94,12 +95,12 @@ const Enum = enum {
None,
Some,
- fn pointer(self: &const Enum) Enum {
- return *self;
+ fn pointer(self: *const Enum) Enum {
+ return self.*;
}
- fn maybePointer(self: ?&const Enum) Enum {
- return *(self ?? &Enum.None);
+ fn maybePointer(self: ?*const Enum) Enum {
+ return (self orelse &Enum.None).*;
}
};
@@ -107,20 +108,20 @@ test "implicitly cast indirect pointer to maybe-indirect pointer" {
const S = struct {
const Self = this;
x: u8,
- fn constConst(p: &const &const Self) u8 {
- return (*p).x;
+ fn constConst(p: *const *const Self) u8 {
+ return p.*.x;
}
- fn maybeConstConst(p: ?&const &const Self) u8 {
- return (*??p).x;
+ fn maybeConstConst(p: ?*const *const Self) u8 {
+ return p.?.*.x;
}
- fn constConstConst(p: &const &const &const Self) u8 {
- return (**p).x;
+ fn constConstConst(p: *const *const *const Self) u8 {
+ return p.*.*.x;
}
- fn maybeConstConstConst(p: ?&const &const &const Self) u8 {
- return (**??p).x;
+ fn maybeConstConstConst(p: ?*const *const *const Self) u8 {
+ return p.?.*.*.x;
}
};
- const s = S { .x = 42 };
+ const s = S{ .x = 42 };
const p = &s;
const q = &p;
const r = &q;
@@ -139,8 +140,8 @@ test "explicit cast from integer to error type" {
comptime testCastIntToErr(error.ItBroke);
}
fn testCastIntToErr(err: error) void {
- const x = usize(err);
- const y = error(x);
+ const x = @errorToInt(err);
+ const y = @intToError(x);
assert(error.ItBroke == y);
}
@@ -154,7 +155,6 @@ fn boolToStr(b: bool) []const u8 {
return if (b) "true" else "false";
}
-
test "peer resolve array and const slice" {
testPeerResolveArrayConstSlice(true);
comptime testPeerResolveArrayConstSlice(true);
@@ -167,67 +167,66 @@ fn testPeerResolveArrayConstSlice(b: bool) void {
}
test "integer literal to &const int" {
- const x: &const i32 = 3;
- assert(*x == 3);
+ const x: *const i32 = 3;
+ assert(x.* == 3);
}
test "string literal to &const []const u8" {
- const x: &const []const u8 = "hello";
- assert(mem.eql(u8, *x, "hello"));
+ const x: *const []const u8 = "hello";
+ assert(mem.eql(u8, x.*, "hello"));
}
test "implicitly cast from T to error!?T" {
- castToMaybeTypeError(1);
- comptime castToMaybeTypeError(1);
+ castToOptionalTypeError(1);
+ comptime castToOptionalTypeError(1);
}
const A = struct {
a: i32,
};
-fn castToMaybeTypeError(z: i32) void {
+fn castToOptionalTypeError(z: i32) void {
const x = i32(1);
const y: error!?i32 = x;
- assert(??(try y) == 1);
+ assert((try y).? == 1);
const f = z;
const g: error!?i32 = f;
const a = A{ .a = z };
const b: error!?A = a;
- assert((??(b catch unreachable)).a == 1);
+ assert((b catch unreachable).?.a == 1);
}
test "implicitly cast from int to error!?T" {
- implicitIntLitToMaybe();
- comptime implicitIntLitToMaybe();
+ implicitIntLitToOptional();
+ comptime implicitIntLitToOptional();
}
-fn implicitIntLitToMaybe() void {
+fn implicitIntLitToOptional() void {
const f: ?i32 = 1;
const g: error!?i32 = 1;
}
-
test "return null from fn() error!?&T" {
- const a = returnNullFromMaybeTypeErrorRef();
- const b = returnNullLitFromMaybeTypeErrorRef();
+ const a = returnNullFromOptionalTypeErrorRef();
+ const b = returnNullLitFromOptionalTypeErrorRef();
assert((try a) == null and (try b) == null);
}
-fn returnNullFromMaybeTypeErrorRef() error!?&A {
- const a: ?&A = null;
+fn returnNullFromOptionalTypeErrorRef() error!?*A {
+ const a: ?*A = null;
return a;
}
-fn returnNullLitFromMaybeTypeErrorRef() error!?&A {
+fn returnNullLitFromOptionalTypeErrorRef() error!?*A {
return null;
}
test "peer type resolution: ?T and T" {
- assert(??peerTypeTAndMaybeT(true, false) == 0);
- assert(??peerTypeTAndMaybeT(false, false) == 3);
+ assert(peerTypeTAndOptionalT(true, false).? == 0);
+ assert(peerTypeTAndOptionalT(false, false).? == 3);
comptime {
- assert(??peerTypeTAndMaybeT(true, false) == 0);
- assert(??peerTypeTAndMaybeT(false, false) == 3);
+ assert(peerTypeTAndOptionalT(true, false).? == 0);
+ assert(peerTypeTAndOptionalT(false, false).? == 3);
}
}
-fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
+fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
if (c) {
return if (b) null else usize(0);
}
@@ -235,7 +234,6 @@ fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
return usize(3);
}
-
test "peer type resolution: [0]u8 and []const u8" {
assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
@@ -246,22 +244,21 @@ test "peer type resolution: [0]u8 and []const u8" {
}
fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
if (a) {
- return []const u8 {};
+ return []const u8{};
}
return slice[0..1];
}
test "implicitly cast from [N]T to ?[]const T" {
- assert(mem.eql(u8, ??castToMaybeSlice(), "hi"));
- comptime assert(mem.eql(u8, ??castToMaybeSlice(), "hi"));
+ assert(mem.eql(u8, castToOptionalSlice().?, "hi"));
+ comptime assert(mem.eql(u8, castToOptionalSlice().?, "hi"));
}
-fn castToMaybeSlice() ?[]const u8 {
+fn castToOptionalSlice() ?[]const u8 {
return "hi";
}
-
test "implicitly cast from [0]T to error![]T" {
testCastZeroArrayToErrSliceMut();
comptime testCastZeroArrayToErrSliceMut();
@@ -316,25 +313,15 @@ test "implicit cast from &const [N]T to []const T" {
fn testCastConstArrayRefToConstSlice() void {
const blah = "aoeu";
const const_array_ref = &blah;
- assert(@typeOf(const_array_ref) == &const [4]u8);
+ assert(@typeOf(const_array_ref) == *const [4]u8);
const slice: []const u8 = const_array_ref;
assert(mem.eql(u8, slice, "aoeu"));
}
-test "var args implicitly casts by value arg to const ref" {
- foo("hello");
-}
-
-fn foo(args: ...) void {
- assert(@typeOf(args[0]) == &const [5]u8);
-}
-
-
test "peer type resolution: error and [N]T" {
// TODO: implicit error!T to error!U where T can implicitly cast to U
//assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
//comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
-
assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
}
@@ -353,11 +340,26 @@ fn testPeerErrorAndArray2(x: u8) error![]const u8 {
};
}
-test "explicit cast float number literal to integer if no fraction component" {
+test "@floatToInt" {
+ testFloatToInts();
+ comptime testFloatToInts();
+}
+
+fn testFloatToInts() void {
const x = i32(1e4);
assert(x == 10000);
- const y = i32(f32(1e4));
+ const y = @floatToInt(i32, f32(1e4));
assert(y == 10000);
+ expectFloatToInt(f16, 255.1, u8, 255);
+ expectFloatToInt(f16, 127.2, i8, 127);
+ expectFloatToInt(f16, -128.2, i8, -128);
+ expectFloatToInt(f32, 255.1, u8, 255);
+ expectFloatToInt(f32, 127.2, i8, 127);
+ expectFloatToInt(f32, -128.2, i8, -128);
+}
+
+fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) void {
+ assert(@floatToInt(I, f) == i);
}
test "cast u128 to f128 and back" {
@@ -378,10 +380,108 @@ fn cast128Float(x: u128) f128 {
}
test "const slice widen cast" {
- const bytes align(4) = []u8{0x12, 0x12, 0x12, 0x12};
+ const bytes align(4) = []u8{
+ 0x12,
+ 0x12,
+ 0x12,
+ 0x12,
+ };
- const u32_value = ([]const u32)(bytes[0..])[0];
+ const u32_value = @bytesToSlice(u32, bytes[0..])[0];
assert(u32_value == 0x12121212);
assert(@bitCast(u32, bytes) == 0x12121212);
}
+
+test "single-item pointer of array to slice and to unknown length pointer" {
+ testCastPtrOfArrayToSliceAndPtr();
+ comptime testCastPtrOfArrayToSliceAndPtr();
+}
+
+fn testCastPtrOfArrayToSliceAndPtr() void {
+ var array = "ao" ++ "eu"; // TODO https://github.com/ziglang/zig/issues/1076
+ const x: [*]u8 = &array;
+ x[0] += 1;
+ assert(mem.eql(u8, array[0..], "boeu"));
+ const y: []u8 = &array;
+ y[0] += 1;
+ assert(mem.eql(u8, array[0..], "coeu"));
+}
+
+test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
+ const window_name = [1][*]const u8{c"window name"};
+ const x: [*]const ?[*]const u8 = &window_name;
+ assert(mem.eql(u8, std.cstr.toSliceConst(x[0].?), "window name"));
+}
+
+test "@intCast comptime_int" {
+ const result = @intCast(i32, 1234);
+ assert(@typeOf(result) == i32);
+ assert(result == 1234);
+}
+
+test "@floatCast comptime_int and comptime_float" {
+ {
+ const result = @floatCast(f16, 1234);
+ assert(@typeOf(result) == f16);
+ assert(result == 1234.0);
+ }
+ {
+ const result = @floatCast(f16, 1234.0);
+ assert(@typeOf(result) == f16);
+ assert(result == 1234.0);
+ }
+ {
+ const result = @floatCast(f32, 1234);
+ assert(@typeOf(result) == f32);
+ assert(result == 1234.0);
+ }
+ {
+ const result = @floatCast(f32, 1234.0);
+ assert(@typeOf(result) == f32);
+ assert(result == 1234.0);
+ }
+}
+
+test "comptime_int @intToFloat" {
+ {
+ const result = @intToFloat(f16, 1234);
+ assert(@typeOf(result) == f16);
+ assert(result == 1234.0);
+ }
+ {
+ const result = @intToFloat(f32, 1234);
+ assert(@typeOf(result) == f32);
+ assert(result == 1234.0);
+ }
+}
+
+test "@bytesToSlice keeps pointer alignment" {
+ var bytes = []u8{ 0x01, 0x02, 0x03, 0x04 };
+ const numbers = @bytesToSlice(u32, bytes[0..]);
+ comptime assert(@typeOf(numbers) == []align(@alignOf(@typeOf(bytes))) u32);
+}
+
+test "@intCast i32 to u7" {
+ var x: u128 = @maxValue(u128);
+ var y: i32 = 120;
+ var z = x >> @intCast(u7, y);
+ assert(z == 0xff);
+}
+
+test "implicit cast undefined to optional" {
+ assert(MakeType(void).getNull() == null);
+ assert(MakeType(void).getNonNull() != null);
+}
+
+fn MakeType(comptime T: type) type {
+ return struct {
+ fn getNull() ?T {
+ return null;
+ }
+
+ fn getNonNull() ?T {
+ return T(undefined);
+ }
+ };
+}
diff --git a/test/cases/const_slice_child.zig b/test/cases/const_slice_child.zig
index 456b115234..07d02d5df0 100644
--- a/test/cases/const_slice_child.zig
+++ b/test/cases/const_slice_child.zig
@@ -1,15 +1,16 @@
const debug = @import("std").debug;
const assert = debug.assert;
-var argv: &const &const u8 = undefined;
+var argv: [*]const [*]const u8 = undefined;
test "const slice child" {
- const strs = ([]&const u8) {
+ const strs = ([][*]const u8){
c"one",
c"two",
c"three",
};
- argv = &strs[0];
+ // TODO this should implicitly cast
+ argv = @ptrCast([*]const [*]const u8, &strs);
bar(strs.len);
}
@@ -29,7 +30,7 @@ fn bar(argc: usize) void {
foo(args);
}
-fn strlen(ptr: &const u8) usize {
+fn strlen(ptr: [*]const u8) usize {
var count: usize = 0;
while (ptr[count] != 0) : (count += 1) {}
return count;
diff --git a/test/cases/coroutine_await_struct.zig b/test/cases/coroutine_await_struct.zig
new file mode 100644
index 0000000000..79168715d8
--- /dev/null
+++ b/test/cases/coroutine_await_struct.zig
@@ -0,0 +1,47 @@
+const std = @import("std");
+const builtin = @import("builtin");
+const assert = std.debug.assert;
+
+const Foo = struct {
+ x: i32,
+};
+
+var await_a_promise: promise = undefined;
+var await_final_result = Foo{ .x = 0 };
+
+test "coroutine await struct" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
+ await_seq('a');
+ const p = async<&da.allocator> await_amain() catch unreachable;
+ await_seq('f');
+ resume await_a_promise;
+ await_seq('i');
+ assert(await_final_result.x == 1234);
+ assert(std.mem.eql(u8, await_points, "abcdefghi"));
+}
+async fn await_amain() void {
+ await_seq('b');
+ const p = async await_another() catch unreachable;
+ await_seq('e');
+ await_final_result = await p;
+ await_seq('h');
+}
+async fn await_another() Foo {
+ await_seq('c');
+ suspend {
+ await_seq('d');
+ await_a_promise = @handle();
+ }
+ await_seq('g');
+ return Foo{ .x = 1234 };
+}
+
+var await_points = []u8{0} ** "abcdefghi".len;
+var await_seq_index: usize = 0;
+
+fn await_seq(c: u8) void {
+ await_points[await_seq_index] = c;
+ await_seq_index += 1;
+}
diff --git a/test/cases/coroutines.zig b/test/cases/coroutines.zig
index 6d28b98c9d..bd6b6abf6f 100644
--- a/test/cases/coroutines.zig
+++ b/test/cases/coroutines.zig
@@ -5,12 +5,14 @@ const assert = std.debug.assert;
var x: i32 = 1;
test "create a coroutine and cancel it" {
- const p = try async<std.debug.global_allocator> simpleAsyncFn();
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
+ const p = try async<&da.allocator> simpleAsyncFn();
comptime assert(@typeOf(p) == promise->void);
cancel p;
assert(x == 2);
}
-
async fn simpleAsyncFn() void {
x += 1;
suspend;
@@ -18,8 +20,11 @@ async fn simpleAsyncFn() void {
}
test "coroutine suspend, resume, cancel" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
seq('a');
- const p = try async<std.debug.global_allocator> testAsyncSeq();
+ const p = try async<&da.allocator> testAsyncSeq();
seq('c');
resume p;
seq('f');
@@ -28,7 +33,6 @@ test "coroutine suspend, resume, cancel" {
assert(std.mem.eql(u8, points, "abcdefg"));
}
-
async fn testAsyncSeq() void {
defer seq('e');
@@ -45,7 +49,10 @@ fn seq(c: u8) void {
}
test "coroutine suspend with block" {
- const p = try async<std.debug.global_allocator> testSuspendBlock();
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
+ const p = try async<&da.allocator> testSuspendBlock();
std.debug.assert(!result);
resume a_promise;
std.debug.assert(result);
@@ -54,12 +61,16 @@ test "coroutine suspend with block" {
var a_promise: promise = undefined;
var result = false;
-
async fn testSuspendBlock() void {
- suspend |p| {
- comptime assert(@typeOf(p) == promise->void);
- a_promise = p;
+ suspend {
+ comptime assert(@typeOf(@handle()) == promise->void);
+ a_promise = @handle();
}
+
+ //Test to make sure that @handle() works as advertised (issue #1296)
+ //var our_handle: promise = @handle();
+ assert( a_promise == @handle() );
+
result = true;
}
@@ -67,15 +78,17 @@ var await_a_promise: promise = undefined;
var await_final_result: i32 = 0;
test "coroutine await" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
await_seq('a');
- const p = async<std.debug.global_allocator> await_amain() catch unreachable;
+ const p = async<&da.allocator> await_amain() catch unreachable;
await_seq('f');
resume await_a_promise;
await_seq('i');
assert(await_final_result == 1234);
assert(std.mem.eql(u8, await_points, "abcdefghi"));
}
-
async fn await_amain() void {
await_seq('b');
const p = async await_another() catch unreachable;
@@ -83,12 +96,11 @@ async fn await_amain() void {
await_final_result = await p;
await_seq('h');
}
-
async fn await_another() i32 {
await_seq('c');
- suspend |p| {
+ suspend {
await_seq('d');
- await_a_promise = p;
+ await_a_promise = @handle();
}
await_seq('g');
return 1234;
@@ -102,25 +114,25 @@ fn await_seq(c: u8) void {
await_seq_index += 1;
}
-
var early_final_result: i32 = 0;
test "coroutine await early return" {
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+
early_seq('a');
- const p = async<std.debug.global_allocator> early_amain() catch unreachable;
+ const p = async<&da.allocator> early_amain() catch @panic("out of memory");
early_seq('f');
assert(early_final_result == 1234);
assert(std.mem.eql(u8, early_points, "abcdef"));
}
-
async fn early_amain() void {
early_seq('b');
- const p = async early_another() catch unreachable;
+ const p = async early_another() catch @panic("out of memory");
early_seq('d');
early_final_result = await p;
early_seq('e');
}
-
async fn early_another() i32 {
early_seq('c');
return 1234;
@@ -142,7 +154,6 @@ test "coro allocation failure" {
error.OutOfMemory => {},
}
}
-
async fn asyncFuncThatNeverGetsRun() void {
@panic("coro frame allocation should fail");
}
@@ -155,7 +166,9 @@ test "async function with dot syntax" {
suspend;
}
};
- const p = try async<std.debug.global_allocator> S.foo();
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+ const p = try async<&da.allocator> S.foo();
cancel p;
assert(S.y == 2);
}
@@ -163,29 +176,29 @@ test "async function with dot syntax" {
test "async fn pointer in a struct field" {
var data: i32 = 1;
const Foo = struct {
- bar: async<&std.mem.Allocator> fn(&i32) void,
+ bar: async<*std.mem.Allocator> fn (*i32) void,
};
- var foo = Foo {
- .bar = simpleAsyncFn2,
- };
- const p = (async<std.debug.global_allocator> foo.bar(&data)) catch unreachable;
+ var foo = Foo{ .bar = simpleAsyncFn2 };
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+ const p = (async<&da.allocator> foo.bar(&data)) catch unreachable;
assert(data == 2);
cancel p;
assert(data == 4);
}
-
-async<&std.mem.Allocator> fn simpleAsyncFn2(y: &i32) void {
- defer *y += 2;
- *y += 1;
+async<*std.mem.Allocator> fn simpleAsyncFn2(y: *i32) void {
+ defer y.* += 2;
+ y.* += 1;
suspend;
}
test "async fn with inferred error set" {
- const p = (async<std.debug.global_allocator> failing()) catch unreachable;
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+ const p = (async<&da.allocator> failing()) catch unreachable;
resume p;
cancel p;
}
-
async fn failing() !void {
suspend;
return error.Fail;
@@ -194,7 +207,9 @@ async fn failing() !void {
test "error return trace across suspend points - early return" {
const p = nonFailing();
resume p;
- const p2 = try async<std.debug.global_allocator> printTrace(p);
+ var da = std.heap.DirectAllocator.init();
+ defer da.deinit();
+ const p2 = try async<&da.allocator> printTrace(p);
cancel p2;
}
@@ -205,22 +220,39 @@ test "error return trace across suspend points - async return" {
cancel p2;
}
-fn nonFailing() promise->error!void {
+// TODO https://github.com/ziglang/zig/issues/760
+fn nonFailing() (promise->error!void) {
return async<std.debug.global_allocator> suspendThenFail() catch unreachable;
}
-
async fn suspendThenFail() error!void {
suspend;
return error.Fail;
}
-
async fn printTrace(p: promise->error!void) void {
(await p) catch |e| {
std.debug.assert(e == error.Fail);
if (@errorReturnTrace()) |trace| {
assert(trace.index == 1);
- } else if (builtin.mode != builtin.Mode.ReleaseFast) {
- @panic("expected return trace");
+ } else switch (builtin.mode) {
+ builtin.Mode.Debug, builtin.Mode.ReleaseSafe => @panic("expected return trace"),
+ builtin.Mode.ReleaseFast, builtin.Mode.ReleaseSmall => {},
}
};
}
+
+test "break from suspend" {
+ var buf: [500]u8 = undefined;
+ var a = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
+ var my_result: i32 = 1;
+ const p = try async<a> testBreakFromSuspend(&my_result);
+ cancel p;
+ std.debug.assert(my_result == 2);
+}
+async fn testBreakFromSuspend(my_result: *i32) void {
+ suspend {
+ resume @handle();
+ }
+ my_result.* += 1;
+ suspend;
+ my_result.* += 1;
+}
diff --git a/test/cases/defer.zig b/test/cases/defer.zig
index a989af18c2..7d4d1bc3d8 100644
--- a/test/cases/defer.zig
+++ b/test/cases/defer.zig
@@ -5,9 +5,18 @@ var index: usize = undefined;
fn runSomeErrorDefers(x: bool) !bool {
index = 0;
- defer {result[index] = 'a'; index += 1;}
- errdefer {result[index] = 'b'; index += 1;}
- defer {result[index] = 'c'; index += 1;}
+ defer {
+ result[index] = 'a';
+ index += 1;
+ }
+ errdefer {
+ result[index] = 'b';
+ index += 1;
+ }
+ defer {
+ result[index] = 'c';
+ index += 1;
+ }
return if (x) x else error.FalseNotAllowed;
}
@@ -41,3 +50,29 @@ fn testBreakContInDefer(x: usize) void {
assert(i == 5);
}
}
+
+test "defer and labeled break" {
+ var i = usize(0);
+
+ blk: {
+ defer i += 1;
+ break :blk;
+ }
+
+ assert(i == 1);
+}
+
+test "errdefer does not apply to fn inside fn" {
+ if (testNestedFnErrDefer()) |_| @panic("expected error") else |e| assert(e == error.Bad);
+}
+
+fn testNestedFnErrDefer() error!void {
+ var a: i32 = 0;
+ errdefer a += 1;
+ const S = struct {
+ fn baz() error {
+ return error.Bad;
+ }
+ };
+ return S.baz();
+}
diff --git a/test/cases/enum.zig b/test/cases/enum.zig
index 644c989b04..50edfda536 100644
--- a/test/cases/enum.zig
+++ b/test/cases/enum.zig
@@ -2,8 +2,13 @@ const assert = @import("std").debug.assert;
const mem = @import("std").mem;
test "enum type" {
- const foo1 = Foo{ .One = 13};
- const foo2 = Foo{. Two = Point { .x = 1234, .y = 5678, }};
+ const foo1 = Foo{ .One = 13 };
+ const foo2 = Foo{
+ .Two = Point{
+ .x = 1234,
+ .y = 5678,
+ },
+ };
const bar = Bar.B;
assert(bar == Bar.B);
@@ -41,26 +46,25 @@ const Bar = enum {
};
fn returnAnInt(x: i32) Foo {
- return Foo { .One = x };
+ return Foo{ .One = x };
}
-
test "constant enum with payload" {
- var empty = AnEnumWithPayload {.Empty = {}};
- var full = AnEnumWithPayload {.Full = 13};
+ var empty = AnEnumWithPayload{ .Empty = {} };
+ var full = AnEnumWithPayload{ .Full = 13 };
shouldBeEmpty(empty);
shouldBeNotEmpty(full);
}
-fn shouldBeEmpty(x: &const AnEnumWithPayload) void {
- switch (*x) {
+fn shouldBeEmpty(x: *const AnEnumWithPayload) void {
+ switch (x.*) {
AnEnumWithPayload.Empty => {},
else => unreachable,
}
}
-fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {
- switch (*x) {
+fn shouldBeNotEmpty(x: *const AnEnumWithPayload) void {
+ switch (x.*) {
AnEnumWithPayload.Empty => unreachable,
else => {},
}
@@ -71,8 +75,6 @@ const AnEnumWithPayload = union(enum) {
Full: i32,
};
-
-
const Number = enum {
Zero,
One,
@@ -90,15 +92,14 @@ test "enum to int" {
}
fn shouldEqual(n: Number, expected: u3) void {
- assert(u3(n) == expected);
+ assert(@enumToInt(n) == expected);
}
-
test "int to enum" {
testIntToEnumEval(3);
}
fn testIntToEnumEval(x: i32) void {
- assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
+ assert(@intToEnum(IntToEnumNumber, @intCast(u3, x)) == IntToEnumNumber.Three);
}
const IntToEnumNumber = enum {
Zero,
@@ -108,7 +109,6 @@ const IntToEnumNumber = enum {
Four,
};
-
test "@tagName" {
assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
@@ -124,7 +124,6 @@ const BareNumber = enum {
Three,
};
-
test "enum alignment" {
comptime {
assert(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
@@ -137,47 +136,529 @@ const AlignTestEnum = union(enum) {
B: u64,
};
-const ValueCount1 = enum { I0 };
-const ValueCount2 = enum { I0, I1 };
+const ValueCount1 = enum {
+ I0,
+};
+const ValueCount2 = enum {
+ I0,
+ I1,
+};
const ValueCount256 = enum {
- I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,
- I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,
- I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,
- I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,
- I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,
- I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,
- I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,
- I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,
- I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,
- I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,
- I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,
- I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,
- I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,
- I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,
- I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,
- I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,
- I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,
- I250, I251, I252, I253, I254, I255
+ I0,
+ I1,
+ I2,
+ I3,
+ I4,
+ I5,
+ I6,
+ I7,
+ I8,
+ I9,
+ I10,
+ I11,
+ I12,
+ I13,
+ I14,
+ I15,
+ I16,
+ I17,
+ I18,
+ I19,
+ I20,
+ I21,
+ I22,
+ I23,
+ I24,
+ I25,
+ I26,
+ I27,
+ I28,
+ I29,
+ I30,
+ I31,
+ I32,
+ I33,
+ I34,
+ I35,
+ I36,
+ I37,
+ I38,
+ I39,
+ I40,
+ I41,
+ I42,
+ I43,
+ I44,
+ I45,
+ I46,
+ I47,
+ I48,
+ I49,
+ I50,
+ I51,
+ I52,
+ I53,
+ I54,
+ I55,
+ I56,
+ I57,
+ I58,
+ I59,
+ I60,
+ I61,
+ I62,
+ I63,
+ I64,
+ I65,
+ I66,
+ I67,
+ I68,
+ I69,
+ I70,
+ I71,
+ I72,
+ I73,
+ I74,
+ I75,
+ I76,
+ I77,
+ I78,
+ I79,
+ I80,
+ I81,
+ I82,
+ I83,
+ I84,
+ I85,
+ I86,
+ I87,
+ I88,
+ I89,
+ I90,
+ I91,
+ I92,
+ I93,
+ I94,
+ I95,
+ I96,
+ I97,
+ I98,
+ I99,
+ I100,
+ I101,
+ I102,
+ I103,
+ I104,
+ I105,
+ I106,
+ I107,
+ I108,
+ I109,
+ I110,
+ I111,
+ I112,
+ I113,
+ I114,
+ I115,
+ I116,
+ I117,
+ I118,
+ I119,
+ I120,
+ I121,
+ I122,
+ I123,
+ I124,
+ I125,
+ I126,
+ I127,
+ I128,
+ I129,
+ I130,
+ I131,
+ I132,
+ I133,
+ I134,
+ I135,
+ I136,
+ I137,
+ I138,
+ I139,
+ I140,
+ I141,
+ I142,
+ I143,
+ I144,
+ I145,
+ I146,
+ I147,
+ I148,
+ I149,
+ I150,
+ I151,
+ I152,
+ I153,
+ I154,
+ I155,
+ I156,
+ I157,
+ I158,
+ I159,
+ I160,
+ I161,
+ I162,
+ I163,
+ I164,
+ I165,
+ I166,
+ I167,
+ I168,
+ I169,
+ I170,
+ I171,
+ I172,
+ I173,
+ I174,
+ I175,
+ I176,
+ I177,
+ I178,
+ I179,
+ I180,
+ I181,
+ I182,
+ I183,
+ I184,
+ I185,
+ I186,
+ I187,
+ I188,
+ I189,
+ I190,
+ I191,
+ I192,
+ I193,
+ I194,
+ I195,
+ I196,
+ I197,
+ I198,
+ I199,
+ I200,
+ I201,
+ I202,
+ I203,
+ I204,
+ I205,
+ I206,
+ I207,
+ I208,
+ I209,
+ I210,
+ I211,
+ I212,
+ I213,
+ I214,
+ I215,
+ I216,
+ I217,
+ I218,
+ I219,
+ I220,
+ I221,
+ I222,
+ I223,
+ I224,
+ I225,
+ I226,
+ I227,
+ I228,
+ I229,
+ I230,
+ I231,
+ I232,
+ I233,
+ I234,
+ I235,
+ I236,
+ I237,
+ I238,
+ I239,
+ I240,
+ I241,
+ I242,
+ I243,
+ I244,
+ I245,
+ I246,
+ I247,
+ I248,
+ I249,
+ I250,
+ I251,
+ I252,
+ I253,
+ I254,
+ I255,
};
const ValueCount257 = enum {
- I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15,
- I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31,
- I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47,
- I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63,
- I64, I65, I66, I67, I68, I69, I70, I71, I72, I73, I74, I75, I76, I77, I78, I79,
- I80, I81, I82, I83, I84, I85, I86, I87, I88, I89, I90, I91, I92, I93, I94, I95,
- I96, I97, I98, I99, I100, I101, I102, I103, I104, I105, I106, I107, I108, I109,
- I110, I111, I112, I113, I114, I115, I116, I117, I118, I119, I120, I121, I122, I123,
- I124, I125, I126, I127, I128, I129, I130, I131, I132, I133, I134, I135, I136, I137,
- I138, I139, I140, I141, I142, I143, I144, I145, I146, I147, I148, I149, I150, I151,
- I152, I153, I154, I155, I156, I157, I158, I159, I160, I161, I162, I163, I164, I165,
- I166, I167, I168, I169, I170, I171, I172, I173, I174, I175, I176, I177, I178, I179,
- I180, I181, I182, I183, I184, I185, I186, I187, I188, I189, I190, I191, I192, I193,
- I194, I195, I196, I197, I198, I199, I200, I201, I202, I203, I204, I205, I206, I207,
- I208, I209, I210, I211, I212, I213, I214, I215, I216, I217, I218, I219, I220, I221,
- I222, I223, I224, I225, I226, I227, I228, I229, I230, I231, I232, I233, I234, I235,
- I236, I237, I238, I239, I240, I241, I242, I243, I244, I245, I246, I247, I248, I249,
- I250, I251, I252, I253, I254, I255, I256
+ I0,
+ I1,
+ I2,
+ I3,
+ I4,
+ I5,
+ I6,
+ I7,
+ I8,
+ I9,
+ I10,
+ I11,
+ I12,
+ I13,
+ I14,
+ I15,
+ I16,
+ I17,
+ I18,
+ I19,
+ I20,
+ I21,
+ I22,
+ I23,
+ I24,
+ I25,
+ I26,
+ I27,
+ I28,
+ I29,
+ I30,
+ I31,
+ I32,
+ I33,
+ I34,
+ I35,
+ I36,
+ I37,
+ I38,
+ I39,
+ I40,
+ I41,
+ I42,
+ I43,
+ I44,
+ I45,
+ I46,
+ I47,
+ I48,
+ I49,
+ I50,
+ I51,
+ I52,
+ I53,
+ I54,
+ I55,
+ I56,
+ I57,
+ I58,
+ I59,
+ I60,
+ I61,
+ I62,
+ I63,
+ I64,
+ I65,
+ I66,
+ I67,
+ I68,
+ I69,
+ I70,
+ I71,
+ I72,
+ I73,
+ I74,
+ I75,
+ I76,
+ I77,
+ I78,
+ I79,
+ I80,
+ I81,
+ I82,
+ I83,
+ I84,
+ I85,
+ I86,
+ I87,
+ I88,
+ I89,
+ I90,
+ I91,
+ I92,
+ I93,
+ I94,
+ I95,
+ I96,
+ I97,
+ I98,
+ I99,
+ I100,
+ I101,
+ I102,
+ I103,
+ I104,
+ I105,
+ I106,
+ I107,
+ I108,
+ I109,
+ I110,
+ I111,
+ I112,
+ I113,
+ I114,
+ I115,
+ I116,
+ I117,
+ I118,
+ I119,
+ I120,
+ I121,
+ I122,
+ I123,
+ I124,
+ I125,
+ I126,
+ I127,
+ I128,
+ I129,
+ I130,
+ I131,
+ I132,
+ I133,
+ I134,
+ I135,
+ I136,
+ I137,
+ I138,
+ I139,
+ I140,
+ I141,
+ I142,
+ I143,
+ I144,
+ I145,
+ I146,
+ I147,
+ I148,
+ I149,
+ I150,
+ I151,
+ I152,
+ I153,
+ I154,
+ I155,
+ I156,
+ I157,
+ I158,
+ I159,
+ I160,
+ I161,
+ I162,
+ I163,
+ I164,
+ I165,
+ I166,
+ I167,
+ I168,
+ I169,
+ I170,
+ I171,
+ I172,
+ I173,
+ I174,
+ I175,
+ I176,
+ I177,
+ I178,
+ I179,
+ I180,
+ I181,
+ I182,
+ I183,
+ I184,
+ I185,
+ I186,
+ I187,
+ I188,
+ I189,
+ I190,
+ I191,
+ I192,
+ I193,
+ I194,
+ I195,
+ I196,
+ I197,
+ I198,
+ I199,
+ I200,
+ I201,
+ I202,
+ I203,
+ I204,
+ I205,
+ I206,
+ I207,
+ I208,
+ I209,
+ I210,
+ I211,
+ I212,
+ I213,
+ I214,
+ I215,
+ I216,
+ I217,
+ I218,
+ I219,
+ I220,
+ I221,
+ I222,
+ I223,
+ I224,
+ I225,
+ I226,
+ I227,
+ I228,
+ I229,
+ I230,
+ I231,
+ I232,
+ I233,
+ I234,
+ I235,
+ I236,
+ I237,
+ I238,
+ I239,
+ I240,
+ I241,
+ I242,
+ I243,
+ I244,
+ I245,
+ I246,
+ I247,
+ I248,
+ I249,
+ I250,
+ I251,
+ I252,
+ I253,
+ I254,
+ I255,
+ I256,
};
test "enum sizes" {
@@ -189,11 +670,11 @@ test "enum sizes" {
}
}
-const Small2 = enum (u2) {
+const Small2 = enum(u2) {
One,
Two,
};
-const Small = enum (u2) {
+const Small = enum(u2) {
One,
Two,
Three,
@@ -213,8 +694,7 @@ test "set enum tag type" {
}
}
-
-const A = enum (u3) {
+const A = enum(u3) {
One,
Two,
Three,
@@ -225,7 +705,7 @@ const A = enum (u3) {
Four2,
};
-const B = enum (u3) {
+const B = enum(u3) {
One3,
Two3,
Three3,
@@ -236,7 +716,7 @@ const B = enum (u3) {
Four23,
};
-const C = enum (u2) {
+const C = enum(u2) {
One4,
Two4,
Three4,
@@ -249,7 +729,7 @@ const BitFieldOfEnums = packed struct {
c: C,
};
-const bit_field_1 = BitFieldOfEnums {
+const bit_field_1 = BitFieldOfEnums{
.a = A.Two,
.b = B.Three3,
.c = C.Four4,
@@ -270,15 +750,15 @@ test "bit field access with enum fields" {
assert(data.b == B.Four3);
}
-fn getA(data: &const BitFieldOfEnums) A {
+fn getA(data: *const BitFieldOfEnums) A {
return data.a;
}
-fn getB(data: &const BitFieldOfEnums) B {
+fn getB(data: *const BitFieldOfEnums) B {
return data.b;
}
-fn getC(data: &const BitFieldOfEnums) C {
+fn getC(data: *const BitFieldOfEnums) C {
return data.c;
}
@@ -288,7 +768,7 @@ test "casting enum to its tag type" {
}
fn testCastEnumToTagType(value: Small2) void {
- assert(u2(value) == 1);
+ assert(@enumToInt(value) == 1);
}
const MultipleChoice = enum(u32) {
@@ -304,7 +784,7 @@ test "enum with specified tag values" {
}
fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
- assert(u32(x) == 60);
+ assert(@enumToInt(x) == 60);
assert(1234 == switch (x) {
MultipleChoice.A => 1,
MultipleChoice.B => 2,
@@ -331,7 +811,7 @@ test "enum with specified and unspecified tag values" {
}
fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
- assert(u32(x) == 1000);
+ assert(@enumToInt(x) == 1000);
assert(1234 == switch (x) {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
@@ -346,8 +826,8 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
}
test "cast integer literal to enum" {
- assert(MultipleChoice2(0) == MultipleChoice2.Unspecified1);
- assert(MultipleChoice2(40) == MultipleChoice2.B);
+ assert(@intToEnum(MultipleChoice2, 0) == MultipleChoice2.Unspecified1);
+ assert(@intToEnum(MultipleChoice2, 40) == MultipleChoice2.B);
}
const EnumWithOneMember = enum {
@@ -385,10 +865,30 @@ const EnumWithTagValues = enum(u4) {
D = 1 << 3,
};
test "enum with tag values don't require parens" {
- assert(u4(EnumWithTagValues.C) == 0b0100);
+ assert(@enumToInt(EnumWithTagValues.C) == 0b0100);
}
test "enum with 1 field but explicit tag type should still have the tag type" {
- const Enum = enum(u8) { B = 2 };
+ const Enum = enum(u8) {
+ B = 2,
+ };
comptime @import("std").debug.assert(@sizeOf(Enum) == @sizeOf(u8));
}
+
+test "empty extern enum with members" {
+ const E = extern enum {
+ A,
+ B,
+ C,
+ };
+ assert(@sizeOf(E) == @sizeOf(c_int));
+}
+
+test "aoeu" {
+ const LocalFoo = enum {
+ A = 1,
+ B = 0,
+ };
+ var b = LocalFoo.B;
+ assert(mem.eql(u8, @tagName(b), "B"));
+}
diff --git a/test/cases/enum_with_members.zig b/test/cases/enum_with_members.zig
index 0c2ae1c383..18174186a9 100644
--- a/test/cases/enum_with_members.zig
+++ b/test/cases/enum_with_members.zig
@@ -6,8 +6,8 @@ const ET = union(enum) {
SINT: i32,
UINT: u32,
- pub fn print(a: &const ET, buf: []u8) error!usize {
- return switch (*a) {
+ pub fn print(a: *const ET, buf: []u8) error!usize {
+ return switch (a.*) {
ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
};
@@ -15,8 +15,8 @@ const ET = union(enum) {
};
test "enum with members" {
- const a = ET { .SINT = -42 };
- const b = ET { .UINT = 42 };
+ const a = ET{ .SINT = -42 };
+ const b = ET{ .UINT = 42 };
var buf: [20]u8 = undefined;
assert((a.print(buf[0..]) catch unreachable) == 3);
diff --git a/test/cases/error.zig b/test/cases/error.zig
index e64bf02c91..45971fd40d 100644
--- a/test/cases/error.zig
+++ b/test/cases/error.zig
@@ -30,14 +30,12 @@ test "@errorName" {
assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
}
-
test "error values" {
- const a = i32(error.err1);
- const b = i32(error.err2);
+ const a = @errorToInt(error.err1);
+ const b = @errorToInt(error.err2);
assert(a != b);
}
-
test "redefinition of error values allowed" {
shouldBeNotEqual(error.AnError, error.SecondError);
}
@@ -45,7 +43,6 @@ fn shouldBeNotEqual(a: error, b: error) void {
if (a == b) unreachable;
}
-
test "error binary operator" {
const a = errBinaryOperatorG(true) catch 3;
const b = errBinaryOperatorG(false) catch 3;
@@ -56,20 +53,20 @@ fn errBinaryOperatorG(x: bool) error!isize {
return if (x) error.ItBroke else isize(10);
}
-
test "unwrap simple value from error" {
const i = unwrapSimpleValueFromErrorDo() catch unreachable;
assert(i == 13);
}
-fn unwrapSimpleValueFromErrorDo() error!isize { return 13; }
-
+fn unwrapSimpleValueFromErrorDo() error!isize {
+ return 13;
+}
test "error return in assignment" {
doErrReturnInAssignment() catch unreachable;
}
fn doErrReturnInAssignment() error!void {
- var x : i32 = undefined;
+ var x: i32 = undefined;
x = try makeANonErr();
}
@@ -95,7 +92,10 @@ test "error set type " {
comptime testErrorSetType();
}
-const MyErrSet = error {OutOfMemory, FileNotFound};
+const MyErrSet = error{
+ OutOfMemory,
+ FileNotFound,
+};
fn testErrorSetType() void {
assert(@memberCount(MyErrSet) == 2);
@@ -109,18 +109,23 @@ fn testErrorSetType() void {
}
}
-
test "explicit error set cast" {
testExplicitErrorSetCast(Set1.A);
comptime testExplicitErrorSetCast(Set1.A);
}
-const Set1 = error{A, B};
-const Set2 = error{A, C};
+const Set1 = error{
+ A,
+ B,
+};
+const Set2 = error{
+ A,
+ C,
+};
fn testExplicitErrorSetCast(set1: Set1) void {
- var x = Set2(set1);
- var y = Set1(x);
+ var x = @errSetCast(Set2, set1);
+ var y = @errSetCast(Set1, x);
assert(y == error.A);
}
@@ -129,24 +134,27 @@ test "comptime test error for empty error set" {
comptime testComptimeTestErrorEmptySet(1234);
}
-const EmptyErrorSet = error {};
+const EmptyErrorSet = error{};
fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
if (x) |v| assert(v == 1234) else |err| @compileError("bad");
}
-test "syntax: nullable operator in front of error union operator" {
+test "syntax: optional operator in front of error union operator" {
comptime {
assert(?error!i32 == ?(error!i32));
}
}
test "comptime err to int of error set with only 1 possible value" {
- testErrToIntWithOnePossibleValue(error.A, u32(error.A));
- comptime testErrToIntWithOnePossibleValue(error.A, u32(error.A));
-}
-fn testErrToIntWithOnePossibleValue(x: error{A}, comptime value: u32) void {
- if (u32(x) != value) {
+ testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
+ comptime testErrToIntWithOnePossibleValue(error.A, @errorToInt(error.A));
+}
+fn testErrToIntWithOnePossibleValue(
+ x: error{A},
+ comptime value: u32,
+) void {
+ if (@errorToInt(x) != value) {
@compileError("bad");
}
}
@@ -175,3 +183,63 @@ fn baz_1() !i32 {
fn quux_1() !i32 {
return error.C;
}
+
+test "error: fn returning empty error set can be passed as fn returning any error" {
+ entry();
+ comptime entry();
+}
+
+fn entry() void {
+ foo2(bar2);
+}
+
+fn foo2(f: fn () error!void) void {
+ const x = f();
+}
+
+fn bar2() (error{}!void) {}
+
+test "error: Zero sized error set returned with value payload crash" {
+ _ = foo3(0);
+ _ = comptime foo3(0);
+}
+
+const Error = error{};
+fn foo3(b: usize) Error!usize {
+ return b;
+}
+
+test "error: Infer error set from literals" {
+ _ = nullLiteral("n") catch |err| handleErrors(err);
+ _ = floatLiteral("n") catch |err| handleErrors(err);
+ _ = intLiteral("n") catch |err| handleErrors(err);
+ _ = comptime nullLiteral("n") catch |err| handleErrors(err);
+ _ = comptime floatLiteral("n") catch |err| handleErrors(err);
+ _ = comptime intLiteral("n") catch |err| handleErrors(err);
+}
+
+fn handleErrors(err: var) noreturn {
+ switch (err) {
+ error.T => {},
+ }
+
+ unreachable;
+}
+
+fn nullLiteral(str: []const u8) !?i64 {
+ if (str[0] == 'n') return null;
+
+ return error.T;
+}
+
+fn floatLiteral(str: []const u8) !?f64 {
+ if (str[0] == 'n') return 1.0;
+
+ return error.T;
+}
+
+fn intLiteral(str: []const u8) !?i64 {
+ if (str[0] == 'n') return 1;
+
+ return error.T;
+}
diff --git a/test/cases/eval.zig b/test/cases/eval.zig
index d6f7afe864..9da475994d 100644
--- a/test/cases/eval.zig
+++ b/test/cases/eval.zig
@@ -5,16 +5,14 @@ const builtin = @import("builtin");
test "compile time recursion" {
assert(some_data.len == 21);
}
-var some_data: [usize(fibonacci(7))]u8 = undefined;
+var some_data: [@intCast(usize, fibonacci(7))]u8 = undefined;
fn fibonacci(x: i32) i32 {
if (x <= 1) return 1;
return fibonacci(x - 1) + fibonacci(x - 2);
}
-
-
fn unwrapAndAddOne(blah: ?i32) i32 {
- return ??blah + 1;
+ return blah.? + 1;
}
const should_be_1235 = unwrapAndAddOne(1234);
test "static add one" {
@@ -40,13 +38,13 @@ test "inline variable gets result of const if" {
assert(gimme1or2(false) == 2);
}
-
test "static function evaluation" {
assert(statically_added_number == 3);
}
const statically_added_number = staticAdd(1, 2);
-fn staticAdd(a: i32, b: i32) i32 { return a + b; }
-
+fn staticAdd(a: i32, b: i32) i32 {
+ return a + b;
+}
test "const expr eval on single expr blocks" {
assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
@@ -64,9 +62,6 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
return result;
}
-
-
-
test "statically initialized list" {
assert(static_point_list[0].x == 1);
assert(static_point_list[0].y == 2);
@@ -77,15 +72,17 @@ const Point = struct {
x: i32,
y: i32,
};
-const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };
+const static_point_list = []Point{
+ makePoint(1, 2),
+ makePoint(3, 4),
+};
fn makePoint(x: i32, y: i32) Point {
- return Point {
+ return Point{
.x = x,
.y = y,
};
}
-
test "static eval list init" {
assert(static_vec3.data[2] == 1.0);
assert(vec3(0.0, 0.0, 3.0).data[2] == 3.0);
@@ -95,18 +92,18 @@ pub const Vec3 = struct {
data: [3]f32,
};
pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
- return Vec3 {
- .data = []f32 { x, y, z, },
- };
+ return Vec3{ .data = []f32{
+ x,
+ y,
+ z,
+ } };
}
-
test "constant expressions" {
- var array : [array_size]u8 = undefined;
+ var array: [array_size]u8 = undefined;
assert(@sizeOf(@typeOf(array)) == 20);
}
-const array_size : u8 = 20;
-
+const array_size: u8 = 20;
test "constant struct with negation" {
assert(vertices[0].x == -0.6);
@@ -118,13 +115,30 @@ const Vertex = struct {
g: f32,
b: f32,
};
-const vertices = []Vertex {
- Vertex { .x = -0.6, .y = -0.4, .r = 1.0, .g = 0.0, .b = 0.0 },
- Vertex { .x = 0.6, .y = -0.4, .r = 0.0, .g = 1.0, .b = 0.0 },
- Vertex { .x = 0.0, .y = 0.6, .r = 0.0, .g = 0.0, .b = 1.0 },
+const vertices = []Vertex{
+ Vertex{
+ .x = -0.6,
+ .y = -0.4,
+ .r = 1.0,
+ .g = 0.0,
+ .b = 0.0,
+ },
+ Vertex{
+ .x = 0.6,
+ .y = -0.4,
+ .r = 0.0,
+ .g = 1.0,
+ .b = 0.0,
+ },
+ Vertex{
+ .x = 0.0,
+ .y = 0.6,
+ .r = 0.0,
+ .g = 0.0,
+ .b = 1.0,
+ },
};
-
test "statically initialized struct" {
st_init_str_foo.x += 1;
assert(st_init_str_foo.x == 14);
@@ -133,15 +147,21 @@ const StInitStrFoo = struct {
x: i32,
y: bool,
};
-var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };
-
+var st_init_str_foo = StInitStrFoo{
+ .x = 13,
+ .y = true,
+};
test "statically initalized array literal" {
- const y : [4]u8 = st_init_arr_lit_x;
+ const y: [4]u8 = st_init_arr_lit_x;
assert(y[3] == 4);
}
-const st_init_arr_lit_x = []u8{1,2,3,4};
-
+const st_init_arr_lit_x = []u8{
+ 1,
+ 2,
+ 3,
+ 4,
+};
test "const slice" {
comptime {
@@ -195,17 +215,32 @@ test "inlined block and runtime block phi" {
const CmdFn = struct {
name: []const u8,
- func: fn(i32) i32,
+ func: fn (i32) i32,
};
const cmd_fns = []CmdFn{
- CmdFn {.name = "one", .func = one},
- CmdFn {.name = "two", .func = two},
- CmdFn {.name = "three", .func = three},
+ CmdFn{
+ .name = "one",
+ .func = one,
+ },
+ CmdFn{
+ .name = "two",
+ .func = two,
+ },
+ CmdFn{
+ .name = "three",
+ .func = three,
+ },
};
-fn one(value: i32) i32 { return value + 1; }
-fn two(value: i32) i32 { return value + 2; }
-fn three(value: i32) i32 { return value + 3; }
+fn one(value: i32) i32 {
+ return value + 1;
+}
+fn two(value: i32) i32 {
+ return value + 2;
+}
+fn three(value: i32) i32 {
+ return value + 3;
+}
fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
var result: i32 = start_value;
@@ -229,7 +264,7 @@ test "eval @setRuntimeSafety at compile-time" {
assert(result == 1234);
}
-fn fnWithSetRuntimeSafety() i32{
+fn fnWithSetRuntimeSafety() i32 {
@setRuntimeSafety(true);
return 1234;
}
@@ -244,16 +279,15 @@ fn fnWithFloatMode() f32 {
return 1234.0;
}
-
const SimpleStruct = struct {
field: i32,
- fn method(self: &const SimpleStruct) i32 {
+ fn method(self: *const SimpleStruct) i32 {
return self.field + 3;
}
};
-var simple_struct = SimpleStruct{ .field = 1234, };
+var simple_struct = SimpleStruct{ .field = 1234 };
const bound_fn = simple_struct.method;
@@ -261,8 +295,6 @@ test "call method on bound fn referring to var instance" {
assert(bound_fn() == 1237);
}
-
-
test "ptr to local array argument at comptime" {
comptime {
var bytes: [10]u8 = undefined;
@@ -277,7 +309,6 @@ fn modifySomeBytes(bytes: []u8) void {
bytes[9] = 'b';
}
-
test "comparisons 0 <= uint and 0 > uint should be comptime" {
testCompTimeUIntComparisons(1234);
}
@@ -296,8 +327,6 @@ fn testCompTimeUIntComparisons(x: u32) void {
}
}
-
-
test "const ptr to variable data changes at runtime" {
assert(foo_ref.name[0] == 'a');
foo_ref.name = "b";
@@ -308,11 +337,9 @@ const Foo = struct {
name: []const u8,
};
-var foo_contents = Foo { .name = "a", };
+var foo_contents = Foo{ .name = "a" };
const foo_ref = &foo_contents;
-
-
test "create global array with for loop" {
assert(global_array[5] == 5 * 5);
assert(global_array[9] == 9 * 9);
@@ -321,7 +348,7 @@ test "create global array with for loop" {
const global_array = x: {
var result: [10]usize = undefined;
for (result) |*item, index| {
- *item = index * index;
+ item.* = index * index;
}
break :x result;
};
@@ -329,7 +356,7 @@ const global_array = x: {
test "compile-time downcast when the bits fit" {
comptime {
const spartan_count: u16 = 255;
- const byte = u8(spartan_count);
+ const byte = @intCast(u8, spartan_count);
assert(byte == 255);
}
}
@@ -340,7 +367,7 @@ test "const global shares pointer with other same one" {
assertEqualPtrs(&hi1[0], &hi2[0]);
comptime assert(&hi1[0] == &hi2[0]);
}
-fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) void {
+fn assertEqualPtrs(ptr1: *const u8, ptr2: *const u8) void {
assert(ptr1 == ptr2);
}
@@ -379,7 +406,7 @@ test "f128 at compile time is lossy" {
pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
return struct {
- pub const Node = struct { };
+ pub const Node = struct {};
};
}
@@ -391,9 +418,9 @@ test "string literal used as comptime slice is memoized" {
}
test "comptime slice of undefined pointer of length 0" {
- const slice1 = (&i32)(undefined)[0..0];
+ const slice1 = ([*]i32)(undefined)[0..0];
assert(slice1.len == 0);
- const slice2 = (&i32)(undefined)[100..100];
+ const slice2 = ([*]i32)(undefined)[100..100];
assert(slice2.len == 0);
}
@@ -401,10 +428,10 @@ fn copyWithPartialInline(s: []u32, b: []u8) void {
comptime var i: usize = 0;
inline while (i < 4) : (i += 1) {
s[i] = 0;
- s[i] |= u32(b[i*4+0]) << 24;
- s[i] |= u32(b[i*4+1]) << 16;
- s[i] |= u32(b[i*4+2]) << 8;
- s[i] |= u32(b[i*4+3]) << 0;
+ s[i] |= u32(b[i * 4 + 0]) << 24;
+ s[i] |= u32(b[i * 4 + 1]) << 16;
+ s[i] |= u32(b[i * 4 + 2]) << 8;
+ s[i] |= u32(b[i * 4 + 3]) << 0;
}
}
@@ -413,7 +440,7 @@ test "binary math operator in partially inlined function" {
var b: [16]u8 = undefined;
for (b) |*r, i|
- *r = u8(i + 1);
+ r.* = @intCast(u8, i + 1);
copyWithPartialInline(s[0..], b[0..]);
assert(s[0] == 0x1020304);
@@ -422,7 +449,6 @@ test "binary math operator in partially inlined function" {
assert(s[3] == 0xd0e0f10);
}
-
test "comptime function with the same args is memoized" {
comptime {
assert(MakeType(i32) == MakeType(i32));
@@ -446,15 +472,15 @@ test "comptime function with mutable pointer is not memoized" {
}
}
-fn increment(value: &i32) void {
- *value += 1;
+fn increment(value: *i32) void {
+ value.* += 1;
}
fn generateTable(comptime T: type) [1010]T {
- var res : [1010]T = undefined;
- var i : usize = 0;
+ var res: [1010]T = undefined;
+ var i: usize = 0;
while (i < 1010) : (i += 1) {
- res[i] = T(i);
+ res[i] = @intCast(T, i);
}
return res;
}
@@ -482,7 +508,7 @@ test "comptime slice of slice preserves comptime var" {
test "comptime slice of pointer preserves comptime var" {
comptime {
var buff: [10]u8 = undefined;
- var a = &buff[0];
+ var a = buff[0..].ptr;
a[0..1][0] = 1;
assert(buff[0..][0..][0] == 1);
}
@@ -491,14 +517,13 @@ test "comptime slice of pointer preserves comptime var" {
const SingleFieldStruct = struct {
x: i32,
- fn read_x(self: &const SingleFieldStruct) i32 {
+ fn read_x(self: *const SingleFieldStruct) i32 {
return self.x;
}
};
test "const ptr to comptime mutable data is not memoized" {
-
comptime {
- var foo = SingleFieldStruct {.x = 1};
+ var foo = SingleFieldStruct{ .x = 1 };
assert(foo.read_x() == 1);
foo.x = 2;
assert(foo.read_x() == 2);
@@ -513,3 +538,117 @@ test "array concat of slices gives slice" {
assert(std.mem.eql(u8, c, "aoeuasdf"));
}
}
+
+test "comptime shlWithOverflow" {
+ const ct_shifted: u64 = comptime amt: {
+ var amt = u64(0);
+ _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
+ break :amt amt;
+ };
+
+ const rt_shifted: u64 = amt: {
+ var amt = u64(0);
+ _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
+ break :amt amt;
+ };
+
+ assert(ct_shifted == rt_shifted);
+}
+
+test "runtime 128 bit integer division" {
+ var a: u128 = 152313999999999991610955792383;
+ var b: u128 = 10000000000000000000;
+ var c = a / b;
+ assert(c == 15231399999);
+}
+
+pub const Info = struct {
+ version: u8,
+};
+
+pub const diamond_info = Info{ .version = 0 };
+
+test "comptime modification of const struct field" {
+ comptime {
+ var res = diamond_info;
+ res.version = 1;
+ assert(diamond_info.version == 0);
+ assert(res.version == 1);
+ }
+}
+
+test "pointer to type" {
+ comptime {
+ var T: type = i32;
+ assert(T == i32);
+ var ptr = &T;
+ assert(@typeOf(ptr) == *type);
+ ptr.* = f32;
+ assert(T == f32);
+ assert(*T == *f32);
+ }
+}
+
+test "slice of type" {
+ comptime {
+ var types_array = []type{ i32, f64, type };
+ for (types_array) |T, i| {
+ switch (i) {
+ 0 => assert(T == i32),
+ 1 => assert(T == f64),
+ 2 => assert(T == type),
+ else => unreachable,
+ }
+ }
+ for (types_array[0..]) |T, i| {
+ switch (i) {
+ 0 => assert(T == i32),
+ 1 => assert(T == f64),
+ 2 => assert(T == type),
+ else => unreachable,
+ }
+ }
+ }
+}
+
+const Wrapper = struct {
+ T: type,
+};
+
+fn wrap(comptime T: type) Wrapper {
+ return Wrapper{ .T = T };
+}
+
+test "function which returns struct with type field causes implicit comptime" {
+ const ty = wrap(i32).T;
+ assert(ty == i32);
+}
+
+test "call method with comptime pass-by-non-copying-value self parameter" {
+ const S = struct {
+ a: u8,
+
+ fn b(comptime s: this) u8 {
+ return s.a;
+ }
+ };
+
+ const s = S{ .a = 2 };
+ var b = s.b();
+ assert(b == 2);
+}
+
+test "@tagName of @typeId" {
+ const str = @tagName(@typeId(u8));
+ assert(std.mem.eql(u8, str, "Int"));
+}
+
+test "setting backward branch quota just before a generic fn call" {
+ @setEvalBranchQuota(1001);
+ loopNTimes(1001);
+}
+
+fn loopNTimes(comptime n: usize) void {
+ comptime var i = 0;
+ inline while (i < n) : (i += 1) {}
+}
diff --git a/test/cases/field_parent_ptr.zig b/test/cases/field_parent_ptr.zig
index 2e519098cc..00d4e0f367 100644
--- a/test/cases/field_parent_ptr.zig
+++ b/test/cases/field_parent_ptr.zig
@@ -17,14 +17,14 @@ const Foo = struct {
d: i32,
};
-const foo = Foo {
+const foo = Foo{
.a = true,
.b = 0.123,
.c = 1234,
.d = -10,
};
-fn testParentFieldPtr(c: &const i32) void {
+fn testParentFieldPtr(c: *const i32) void {
assert(c == &foo.c);
const base = @fieldParentPtr(Foo, "c", c);
@@ -32,7 +32,7 @@ fn testParentFieldPtr(c: &const i32) void {
assert(&base.c == c);
}
-fn testParentFieldPtrFirst(a: &const bool) void {
+fn testParentFieldPtrFirst(a: *const bool) void {
assert(a == &foo.a);
const base = @fieldParentPtr(Foo, "a", a);
diff --git a/test/cases/fn.zig b/test/cases/fn.zig
index 5388deac10..47f7d5e688 100644
--- a/test/cases/fn.zig
+++ b/test/cases/fn.zig
@@ -7,7 +7,6 @@ fn testParamsAdd(a: i32, b: i32) i32 {
return a + b;
}
-
test "local variables" {
testLocVars(2);
}
@@ -16,7 +15,6 @@ fn testLocVars(b: i32) void {
if (a + b != 3) unreachable;
}
-
test "void parameters" {
voidFun(1, void{}, 2, {});
}
@@ -27,9 +25,8 @@ fn voidFun(a: i32, b: void, c: i32, d: void) void {
return vv;
}
-
test "mutable local variables" {
- var zero : i32 = 0;
+ var zero: i32 = 0;
assert(zero == 0);
var i = i32(0);
@@ -41,7 +38,7 @@ test "mutable local variables" {
test "separate block scopes" {
{
- const no_conflict : i32 = 5;
+ const no_conflict: i32 = 5;
assert(no_conflict == 5);
}
@@ -56,8 +53,7 @@ test "call function with empty string" {
acceptsString("");
}
-fn acceptsString(foo: []u8) void { }
-
+fn acceptsString(foo: []u8) void {}
fn @"weird function name"() i32 {
return 1234;
@@ -70,31 +66,43 @@ test "implicit cast function unreachable return" {
wantsFnWithVoid(fnWithUnreachable);
}
-fn wantsFnWithVoid(f: fn() void) void { }
+fn wantsFnWithVoid(f: fn () void) void {}
fn fnWithUnreachable() noreturn {
unreachable;
}
-
test "function pointers" {
- const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };
+ const fns = []@typeOf(fn1){
+ fn1,
+ fn2,
+ fn3,
+ fn4,
+ };
for (fns) |f, i| {
- assert(f() == u32(i) + 5);
+ assert(f() == @intCast(u32, i) + 5);
}
}
-fn fn1() u32 {return 5;}
-fn fn2() u32 {return 6;}
-fn fn3() u32 {return 7;}
-fn fn4() u32 {return 8;}
-
+fn fn1() u32 {
+ return 5;
+}
+fn fn2() u32 {
+ return 6;
+}
+fn fn3() u32 {
+ return 7;
+}
+fn fn4() u32 {
+ return 8;
+}
test "inline function call" {
assert(@inlineCall(add, 3, 9) == 12);
}
-fn add(a: i32, b: i32) i32 { return a + b; }
-
+fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
test "number literal as an argument" {
numberLiteralArg(3);
@@ -110,4 +118,61 @@ test "assign inline fn to const variable" {
a();
}
-inline fn inlineFn() void { }
+inline fn inlineFn() void {}
+
+test "pass by non-copying value" {
+ assert(addPointCoords(Point{ .x = 1, .y = 2 }) == 3);
+}
+
+const Point = struct {
+ x: i32,
+ y: i32,
+};
+
+fn addPointCoords(pt: Point) i32 {
+ return pt.x + pt.y;
+}
+
+test "pass by non-copying value through var arg" {
+ assert(addPointCoordsVar(Point{ .x = 1, .y = 2 }) == 3);
+}
+
+fn addPointCoordsVar(pt: var) i32 {
+ comptime assert(@typeOf(pt) == Point);
+ return pt.x + pt.y;
+}
+
+test "pass by non-copying value as method" {
+ var pt = Point2{ .x = 1, .y = 2 };
+ assert(pt.addPointCoords() == 3);
+}
+
+const Point2 = struct {
+ x: i32,
+ y: i32,
+
+ fn addPointCoords(self: Point2) i32 {
+ return self.x + self.y;
+ }
+};
+
+test "pass by non-copying value as method, which is generic" {
+ var pt = Point3{ .x = 1, .y = 2 };
+ assert(pt.addPointCoords(i32) == 3);
+}
+
+const Point3 = struct {
+ x: i32,
+ y: i32,
+
+ fn addPointCoords(self: Point3, comptime T: type) i32 {
+ return self.x + self.y;
+ }
+};
+
+test "pass by non-copying value as method, at comptime" {
+ comptime {
+ var pt = Point2{ .x = 1, .y = 2 };
+ assert(pt.addPointCoords() == 3);
+ }
+}
diff --git a/test/cases/fn_in_struct_in_comptime.zig b/test/cases/fn_in_struct_in_comptime.zig
new file mode 100644
index 0000000000..fabb57e9cb
--- /dev/null
+++ b/test/cases/fn_in_struct_in_comptime.zig
@@ -0,0 +1,17 @@
+const assert = @import("std").debug.assert;
+
+fn get_foo() fn (*u8) usize {
+ comptime {
+ return struct {
+ fn func(ptr: *u8) usize {
+ var u = @ptrToInt(ptr);
+ return u;
+ }
+ }.func;
+ }
+}
+
+test "define a function in an anonymous struct in comptime" {
+ const foo = get_foo();
+ assert(foo(@intToPtr(*u8, 12345)) == 12345);
+}
diff --git a/test/cases/for.zig b/test/cases/for.zig
index 7bb0d7c9fa..59d90c1b85 100644
--- a/test/cases/for.zig
+++ b/test/cases/for.zig
@@ -3,8 +3,14 @@ const assert = std.debug.assert;
const mem = std.mem;
test "continue in for loop" {
- const array = []i32 {1, 2, 3, 4, 5};
- var sum : i32 = 0;
+ const array = []i32{
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ };
+ var sum: i32 = 0;
for (array) |x| {
sum += x;
if (x < 3) {
@@ -24,23 +30,23 @@ test "for loop with pointer elem var" {
}
fn mangleString(s: []u8) void {
for (s) |*c| {
- *c += 1;
+ c.* += 1;
}
}
test "basic for loop" {
- const expected_result = []u8{9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };
+ const expected_result = []u8{ 9, 8, 7, 6, 0, 1, 2, 3, 9, 8, 7, 6, 0, 1, 2, 3 };
var buffer: [expected_result.len]u8 = undefined;
var buf_index: usize = 0;
- const array = []u8 {9, 8, 7, 6};
+ const array = []u8{ 9, 8, 7, 6 };
for (array) |item| {
buffer[buf_index] = item;
buf_index += 1;
}
for (array) |item, index| {
- buffer[buf_index] = u8(index);
+ buffer[buf_index] = @intCast(u8, index);
buf_index += 1;
}
const unknown_size: []const u8 = array;
@@ -49,7 +55,7 @@ test "basic for loop" {
buf_index += 1;
}
for (unknown_size) |item, index| {
- buffer[buf_index] = u8(index);
+ buffer[buf_index] = @intCast(u8, index);
buf_index += 1;
}
@@ -65,7 +71,8 @@ fn testBreakOuter() void {
var array = "aoeu";
var count: usize = 0;
outer: for (array) |_| {
- for (array) |_2| { // TODO shouldn't get error for redeclaring "_"
+ // TODO shouldn't get error for redeclaring "_"
+ for (array) |_2| {
count += 1;
break :outer;
}
@@ -82,7 +89,8 @@ fn testContinueOuter() void {
var array = "aoeu";
var counter: usize = 0;
outer: for (array) |_| {
- for (array) |_2| { // TODO shouldn't get error for redeclaring "_"
+ // TODO shouldn't get error for redeclaring "_"
+ for (array) |_2| {
counter += 1;
continue :outer;
}
diff --git a/test/cases/generics.zig b/test/cases/generics.zig
index 19b4a598d8..52aa013989 100644
--- a/test/cases/generics.zig
+++ b/test/cases/generics.zig
@@ -37,7 +37,6 @@ test "fn with comptime args" {
assert(sameButWithFloats(0.43, 0.49) == 0.49);
}
-
test "var params" {
assert(max_i32(12, 34) == 34);
assert(max_f64(1.2, 3.4) == 3.4);
@@ -60,7 +59,6 @@ fn max_f64(a: f64, b: f64) f64 {
return max_var(a, b);
}
-
pub fn List(comptime T: type) type {
return SmallList(T, 8);
}
@@ -82,10 +80,15 @@ test "function with return type type" {
assert(list2.prealloc_items.len == 8);
}
-
test "generic struct" {
- var a1 = GenNode(i32) {.value = 13, .next = null,};
- var b1 = GenNode(bool) {.value = true, .next = null,};
+ var a1 = GenNode(i32){
+ .value = 13,
+ .next = null,
+ };
+ var b1 = GenNode(bool){
+ .value = true,
+ .next = null,
+ };
assert(a1.value == 13);
assert(a1.value == a1.getVal());
assert(b1.getVal());
@@ -93,8 +96,10 @@ test "generic struct" {
fn GenNode(comptime T: type) type {
return struct {
value: T,
- next: ?&GenNode(T),
- fn getVal(n: &const GenNode(T)) T { return n.value; }
+ next: ?*GenNode(T),
+ fn getVal(n: *const GenNode(T)) T {
+ return n.value;
+ }
};
}
@@ -107,7 +112,6 @@ fn GenericDataThing(comptime count: isize) type {
};
}
-
test "use generic param in generic param" {
assert(aGenericFn(i32, 3, 4) == 7);
}
@@ -115,21 +119,31 @@ fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
return a + b;
}
-
test "generic fn with implicit cast" {
- assert(getFirstByte(u8, []u8 {13}) == 13);
- assert(getFirstByte(u16, []u16 {0, 13}) == 0);
+ assert(getFirstByte(u8, []u8{13}) == 13);
+ assert(getFirstByte(u16, []u16{
+ 0,
+ 13,
+ }) == 0);
+}
+fn getByte(ptr: ?*const u8) u8 {
+ return ptr.?.*;
}
-fn getByte(ptr: ?&const u8) u8 {return *??ptr;}
fn getFirstByte(comptime T: type, mem: []const T) u8 {
- return getByte(@ptrCast(&const u8, &mem[0]));
+ return getByte(@ptrCast(*const u8, &mem[0]));
}
+const foos = []fn (var) bool{
+ foo1,
+ foo2,
+};
-const foos = []fn(var) bool { foo1, foo2 };
-
-fn foo1(arg: var) bool { return arg; }
-fn foo2(arg: var) bool { return !arg; }
+fn foo1(arg: var) bool {
+ return arg;
+}
+fn foo2(arg: var) bool {
+ return !arg;
+}
test "array of generic fns" {
assert(foos[0](true));
diff --git a/test/cases/if.zig b/test/cases/if.zig
index 2caae7448c..808936bfa5 100644
--- a/test/cases/if.zig
+++ b/test/cases/if.zig
@@ -23,7 +23,6 @@ fn firstEqlThird(a: i32, b: i32, c: i32) void {
}
}
-
test "else if expression" {
assert(elseIfExpressionF(1) == 1);
}
diff --git a/test/cases/import/a_namespace.zig b/test/cases/import/a_namespace.zig
index 5cf906cf91..042f1867a5 100644
--- a/test/cases/import/a_namespace.zig
+++ b/test/cases/import/a_namespace.zig
@@ -1 +1,3 @@
-pub fn foo() i32 { return 1234; }
+pub fn foo() i32 {
+ return 1234;
+}
diff --git a/test/cases/incomplete_struct_param_tld.zig b/test/cases/incomplete_struct_param_tld.zig
index a907ca748a..552d6ef185 100644
--- a/test/cases/incomplete_struct_param_tld.zig
+++ b/test/cases/incomplete_struct_param_tld.zig
@@ -11,21 +11,19 @@ const B = struct {
const C = struct {
x: i32,
- fn d(c: &const C) i32 {
+ fn d(c: *const C) i32 {
return c.x;
}
};
-fn foo(a: &const A) i32 {
+fn foo(a: *const A) i32 {
return a.b.c.d();
}
test "incomplete struct param top level declaration" {
- const a = A {
- .b = B {
- .c = C {
- .x = 13,
- },
+ const a = A{
+ .b = B{
+ .c = C{ .x = 13 },
},
};
assert(foo(a) == 13);
diff --git a/test/cases/ir_block_deps.zig b/test/cases/ir_block_deps.zig
index 202df19f62..c017eca508 100644
--- a/test/cases/ir_block_deps.zig
+++ b/test/cases/ir_block_deps.zig
@@ -11,7 +11,9 @@ fn foo(id: u64) !i32 {
};
}
-fn getErrInt() error!i32 { return 0; }
+fn getErrInt() error!i32 {
+ return 0;
+}
test "ir block deps" {
assert((foo(1) catch unreachable) == 0);
diff --git a/test/cases/math.zig b/test/cases/math.zig
index 574aa39bb1..195ada15dd 100644
--- a/test/cases/math.zig
+++ b/test/cases/math.zig
@@ -6,15 +6,20 @@ test "division" {
}
fn testDivision() void {
assert(div(u32, 13, 3) == 4);
+ assert(div(f16, 1.0, 2.0) == 0.5);
assert(div(f32, 1.0, 2.0) == 0.5);
assert(divExact(u32, 55, 11) == 5);
assert(divExact(i32, -55, 11) == -5);
+ assert(divExact(f16, 55.0, 11.0) == 5.0);
+ assert(divExact(f16, -55.0, 11.0) == -5.0);
assert(divExact(f32, 55.0, 11.0) == 5.0);
assert(divExact(f32, -55.0, 11.0) == -5.0);
assert(divFloor(i32, 5, 3) == 1);
assert(divFloor(i32, -5, 3) == -2);
+ assert(divFloor(f16, 5.0, 3.0) == 1.0);
+ assert(divFloor(f16, -5.0, 3.0) == -2.0);
assert(divFloor(f32, 5.0, 3.0) == 1.0);
assert(divFloor(f32, -5.0, 3.0) == -2.0);
assert(divFloor(i32, -0x80000000, -2) == 0x40000000);
@@ -24,30 +29,35 @@ fn testDivision() void {
assert(divTrunc(i32, 5, 3) == 1);
assert(divTrunc(i32, -5, 3) == -1);
+ assert(divTrunc(f16, 5.0, 3.0) == 1.0);
+ assert(divTrunc(f16, -5.0, 3.0) == -1.0);
assert(divTrunc(f32, 5.0, 3.0) == 1.0);
assert(divTrunc(f32, -5.0, 3.0) == -1.0);
+ assert(divTrunc(f64, 5.0, 3.0) == 1.0);
+ assert(divTrunc(f64, -5.0, 3.0) == -1.0);
comptime {
assert(
- 1194735857077236777412821811143690633098347576 %
- 508740759824825164163191790951174292733114988 ==
- 177254337427586449086438229241342047632117600);
- assert(@rem(-1194735857077236777412821811143690633098347576,
- 508740759824825164163191790951174292733114988) ==
- -177254337427586449086438229241342047632117600);
- assert(1194735857077236777412821811143690633098347576 /
- 508740759824825164163191790951174292733114988 ==
- 2);
- assert(@divTrunc(-1194735857077236777412821811143690633098347576,
- 508740759824825164163191790951174292733114988) ==
- -2);
- assert(@divTrunc(1194735857077236777412821811143690633098347576,
- -508740759824825164163191790951174292733114988) ==
- -2);
- assert(@divTrunc(-1194735857077236777412821811143690633098347576,
- -508740759824825164163191790951174292733114988) ==
- 2);
- assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);
+ 1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600,
+ );
+ assert(
+ @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600,
+ );
+ assert(
+ 1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2,
+ );
+ assert(
+ @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2,
+ );
+ assert(
+ @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2,
+ );
+ assert(
+ @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2,
+ );
+ assert(
+ 4126227191251978491697987544882340798050766755606969681711 % 10 == 1,
+ );
}
}
fn div(comptime T: type, a: T, b: T) T {
@@ -114,18 +124,28 @@ fn ctz(x: var) usize {
test "assignment operators" {
var i: u32 = 0;
- i += 5; assert(i == 5);
- i -= 2; assert(i == 3);
- i *= 20; assert(i == 60);
- i /= 3; assert(i == 20);
- i %= 11; assert(i == 9);
- i <<= 1; assert(i == 18);
- i >>= 2; assert(i == 4);
+ i += 5;
+ assert(i == 5);
+ i -= 2;
+ assert(i == 3);
+ i *= 20;
+ assert(i == 60);
+ i /= 3;
+ assert(i == 20);
+ i %= 11;
+ assert(i == 9);
+ i <<= 1;
+ assert(i == 18);
+ i >>= 2;
+ assert(i == 4);
i = 6;
- i &= 5; assert(i == 4);
- i ^= 6; assert(i == 2);
+ i &= 5;
+ assert(i == 4);
+ i ^= 6;
+ assert(i == 2);
i = 6;
- i |= 3; assert(i == 7);
+ i |= 3;
+ assert(i == 7);
}
test "three expr in a row" {
@@ -138,7 +158,7 @@ fn testThreeExprInARow(f: bool, t: bool) void {
assertFalse(1 | 2 | 4 != 7);
assertFalse(3 ^ 6 ^ 8 != 13);
assertFalse(7 & 14 & 28 != 4);
- assertFalse(9 << 1 << 2 != 9 << 3);
+ assertFalse(9 << 1 << 2 != 9 << 3);
assertFalse(90 >> 1 >> 2 != 90 >> 3);
assertFalse(100 - 1 + 1000 != 1099);
assertFalse(5 * 4 / 2 % 3 != 1);
@@ -150,7 +170,6 @@ fn assertFalse(b: bool) void {
assert(!b);
}
-
test "const number literal" {
const one = 1;
const eleven = ten + one;
@@ -159,8 +178,6 @@ test "const number literal" {
}
const ten = 10;
-
-
test "unsigned wrapping" {
testUnsignedWrappingEval(@maxValue(u32));
comptime testUnsignedWrappingEval(@maxValue(u32));
@@ -203,7 +220,7 @@ fn test_u64_div() void {
assert(result.remainder == 100663296);
}
fn divWithResult(a: u64, b: u64) DivResult {
- return DivResult {
+ return DivResult{
.quotient = a / b,
.remainder = a % b,
};
@@ -214,8 +231,12 @@ const DivResult = struct {
};
test "binary not" {
- assert(comptime x: {break :x ~u16(0b1010101010101010) == 0b0101010101010101;});
- assert(comptime x: {break :x ~u64(2147483647) == 18446744071562067968;});
+ assert(comptime x: {
+ break :x ~u16(0b1010101010101010) == 0b0101010101010101;
+ });
+ assert(comptime x: {
+ break :x ~u64(2147483647) == 18446744071562067968;
+ });
testBinaryNot(0b1010101010101010);
}
@@ -275,6 +296,14 @@ test "quad hex float literal parsing in range" {
const d = 0x1.edcbff8ad76ab5bf46463233214fp-435;
}
+test "quad hex float literal parsing accurate" {
+ const a: f128 = 0x1.1111222233334444555566667777p+0;
+
+ // implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing.
+ const expected: u128 = 0x3fff1111222233334444555566667777;
+ assert(@bitCast(u128, a) == expected);
+}
+
test "hex float literal within range" {
const a = 0x1.0p16383;
const b = 0x0.1p16387;
@@ -317,38 +346,55 @@ fn testShrExact(x: u8) void {
assert(shifted == 0b00101101);
}
-test "big number addition" {
+test "comptime_int addition" {
comptime {
- assert(
- 35361831660712422535336160538497375248 +
- 101752735581729509668353361206450473702 ==
- 137114567242441932203689521744947848950);
- assert(
- 594491908217841670578297176641415611445982232488944558774612 +
- 390603545391089362063884922208143568023166603618446395589768 ==
- 985095453608931032642182098849559179469148836107390954364380);
+ assert(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
+ assert(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
}
}
-test "big number multiplication" {
+test "comptime_int multiplication" {
comptime {
assert(
- 45960427431263824329884196484953148229 *
- 128339149605334697009938835852565949723 ==
- 5898522172026096622534201617172456926982464453350084962781392314016180490567);
+ 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,
+ );
assert(
- 594491908217841670578297176641415611445982232488944558774612 *
- 390603545391089362063884922208143568023166603618446395589768 ==
- 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016);
+ 594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016,
+ );
}
}
-test "big number shifting" {
+test "comptime_int shifting" {
comptime {
assert((u128(1) << 127) == 0x80000000000000000000000000000000);
}
}
+test "comptime_int multi-limb shift and mask" {
+ comptime {
+ var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
+
+ assert(u32(a & 0xffffffff) == 0xaaaaaaab);
+ a >>= 32;
+ assert(u32(a & 0xffffffff) == 0xeeeeeeef);
+ a >>= 32;
+ assert(u32(a & 0xffffffff) == 0xa0000001);
+ a >>= 32;
+ assert(u32(a & 0xffffffff) == 0xefffffff);
+ a >>= 32;
+
+ assert(a == 0);
+ }
+}
+
+test "comptime_int multi-limb partial shift right" {
+ comptime {
+ var a = 0x1ffffffffeeeeeeee;
+ a >>= 16;
+ assert(a == 0x1ffffffffeeee);
+ }
+}
+
test "xor" {
test_xor();
comptime test_xor();
@@ -362,7 +408,7 @@ fn test_xor() void {
assert(0xFF ^ 0xFF == 0x00);
}
-test "big number xor" {
+test "comptime_int xor" {
comptime {
assert(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
assert(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
@@ -380,7 +426,9 @@ test "f128" {
comptime test_f128();
}
-fn make_f128(x: f128) f128 { return x; }
+fn make_f128(x: f128) f128 {
+ return x;
+}
fn test_f128() void {
assert(@sizeOf(f128) == 16);
@@ -402,3 +450,48 @@ test "comptime float rem int" {
assert(x == 1.0);
}
}
+
+test "remainder division" {
+ comptime remdiv(f16);
+ comptime remdiv(f32);
+ comptime remdiv(f64);
+ comptime remdiv(f128);
+ remdiv(f16);
+ remdiv(f64);
+ remdiv(f128);
+}
+
+fn remdiv(comptime T: type) void {
+ assert(T(1) == T(1) % T(2));
+ assert(T(1) == T(7) % T(3));
+}
+
+test "@sqrt" {
+ testSqrt(f64, 12.0);
+ comptime testSqrt(f64, 12.0);
+ testSqrt(f32, 13.0);
+ comptime testSqrt(f32, 13.0);
+ testSqrt(f16, 13.0);
+ comptime testSqrt(f16, 13.0);
+
+ const x = 14.0;
+ const y = x * x;
+ const z = @sqrt(@typeOf(y), y);
+ comptime assert(z == x);
+}
+
+fn testSqrt(comptime T: type, x: T) void {
+ assert(@sqrt(T, x * x) == x);
+}
+
+test "comptime_int param and return" {
+ const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
+ assert(a == 137114567242441932203689521744947848950);
+
+ const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768);
+ assert(b == 985095453608931032642182098849559179469148836107390954364380);
+}
+
+fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
+ return a + b;
+}
diff --git a/test/cases/merge_error_sets.zig b/test/cases/merge_error_sets.zig
new file mode 100644
index 0000000000..189bd16a4d
--- /dev/null
+++ b/test/cases/merge_error_sets.zig
@@ -0,0 +1,21 @@
+const A = error{
+ PathNotFound,
+ NotDir,
+};
+const B = error{OutOfMemory};
+
+const C = A || B;
+
+fn foo() C!void {
+ return error.NotDir;
+}
+
+test "merge error sets" {
+ if (foo()) {
+ @panic("unexpected");
+ } else |err| switch (err) {
+ error.OutOfMemory => @panic("unexpected"),
+ error.PathNotFound => @panic("unexpected"),
+ error.NotDir => {},
+ }
+}
diff --git a/test/cases/misc.zig b/test/cases/misc.zig
index 95a9a46bff..1c0189571b 100644
--- a/test/cases/misc.zig
+++ b/test/cases/misc.zig
@@ -4,6 +4,7 @@ const cstr = @import("std").cstr;
const builtin = @import("builtin");
// normal comment
+
/// this is a documentation comment
/// doc comment line 2
fn emptyFunctionWithComments() void {}
@@ -16,8 +17,7 @@ comptime {
@export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
}
-extern fn disabledExternFn() void {
-}
+extern fn disabledExternFn() void {}
test "call disabled extern fn" {
disabledExternFn();
@@ -53,15 +53,11 @@ test "@IntType builtin" {
}
test "floating point primitive bit counts" {
+ assert(f16.bit_count == 16);
assert(f32.bit_count == 32);
assert(f64.bit_count == 64);
}
-const u1 = @IntType(false, 1);
-const u63 = @IntType(false, 63);
-const i1 = @IntType(true, 1);
-const i63 = @IntType(true, 63);
-
test "@minValue and @maxValue" {
assert(@maxValue(u1) == 1);
assert(@maxValue(u8) == 255);
@@ -110,17 +106,29 @@ fn testShortCircuit(f: bool, t: bool) void {
var hit_3 = f;
var hit_4 = f;
- if (t or x: {assert(f); break :x f;}) {
+ if (t or x: {
+ assert(f);
+ break :x f;
+ }) {
hit_1 = t;
}
- if (f or x: { hit_2 = t; break :x f; }) {
+ if (f or x: {
+ hit_2 = t;
+ break :x f;
+ }) {
assert(f);
}
- if (t and x: { hit_3 = t; break :x f; }) {
+ if (t and x: {
+ hit_3 = t;
+ break :x f;
+ }) {
assert(f);
}
- if (f and x: {assert(f); break :x f;}) {
+ if (f and x: {
+ assert(f);
+ break :x f;
+ }) {
assert(f);
} else {
hit_4 = t;
@@ -146,8 +154,8 @@ test "return string from function" {
assert(mem.eql(u8, first4KeysOfHomeRow(), "aoeu"));
}
-const g1 : i32 = 1233 + 1;
-var g2 : i32 = 0;
+const g1: i32 = 1233 + 1;
+var g2: i32 = 0;
test "global variables" {
assert(g2 == 0);
@@ -155,24 +163,25 @@ test "global variables" {
assert(g2 == 1234);
}
-
test "memcpy and memset intrinsics" {
- var foo : [20]u8 = undefined;
- var bar : [20]u8 = undefined;
+ var foo: [20]u8 = undefined;
+ var bar: [20]u8 = undefined;
- @memset(&foo[0], 'A', foo.len);
- @memcpy(&bar[0], &foo[0], bar.len);
+ @memset(foo[0..].ptr, 'A', foo.len);
+ @memcpy(bar[0..].ptr, foo[0..].ptr, bar.len);
if (bar[11] != 'A') unreachable;
}
test "builtin static eval" {
- const x : i32 = comptime x: {break :x 1 + 2 + 3;};
+ const x: i32 = comptime x: {
+ break :x 1 + 2 + 3;
+ };
assert(x == comptime 6);
}
test "slicing" {
- var array : [20]i32 = undefined;
+ var array: [20]i32 = undefined;
array[5] = 1234;
@@ -181,21 +190,21 @@ test "slicing" {
if (slice.len != 5) unreachable;
const ptr = &slice[0];
- if (ptr[0] != 1234) unreachable;
+ if (ptr.* != 1234) unreachable;
var slice_rest = array[10..];
if (slice_rest.len != 10) unreachable;
}
-
test "constant equal function pointers" {
const alias = emptyFn;
- assert(comptime x: {break :x emptyFn == alias;});
+ assert(comptime x: {
+ break :x emptyFn == alias;
+ });
}
fn emptyFn() void {}
-
test "hex escape" {
assert(mem.eql(u8, "\x68\x65\x6c\x6c\x6f", "hello"));
}
@@ -238,35 +247,32 @@ test "multiline C string" {
assert(cstr.cmp(s1, s2) == 0);
}
-
test "type equality" {
- assert(&const u8 != &u8);
+ assert(*const u8 != *u8);
}
-
const global_a: i32 = 1234;
-const global_b: &const i32 = &global_a;
-const global_c: &const f32 = @ptrCast(&const f32, global_b);
+const global_b: *const i32 = &global_a;
+const global_c: *const f32 = @ptrCast(*const f32, global_b);
test "compile time global reinterpret" {
- const d = @ptrCast(&const i32, global_c);
- assert(*d == 1234);
+ const d = @ptrCast(*const i32, global_c);
+ assert(d.* == 1234);
}
test "explicit cast maybe pointers" {
- const a: ?&i32 = undefined;
- const b: ?&f32 = @ptrCast(?&f32, a);
+ const a: ?*i32 = undefined;
+ const b: ?*f32 = @ptrCast(?*f32, a);
}
test "generic malloc free" {
const a = memAlloc(u8, 10) catch unreachable;
memFree(u8, a);
}
-var some_mem : [100]u8 = undefined;
+var some_mem: [100]u8 = undefined;
fn memAlloc(comptime T: type, n: usize) error![]T {
- return @ptrCast(&T, &some_mem[0])[0..n];
+ return @ptrCast([*]T, &some_mem[0])[0..n];
}
-fn memFree(comptime T: type, memory: []T) void { }
-
+fn memFree(comptime T: type, memory: []T) void {}
test "cast undefined" {
const array: [100]u8 = undefined;
@@ -275,32 +281,35 @@ test "cast undefined" {
}
fn testCastUndefined(x: []const u8) void {}
-
test "cast small unsigned to larger signed" {
assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
}
-fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; }
-fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; }
-
+fn castSmallUnsignedToLargerSigned1(x: u8) i16 {
+ return x;
+}
+fn castSmallUnsignedToLargerSigned2(x: u16) i64 {
+ return x;
+}
test "implicit cast after unreachable" {
assert(outer() == 1234);
}
-fn inner() i32 { return 1234; }
+fn inner() i32 {
+ return 1234;
+}
fn outer() i64 {
return inner();
}
-
test "pointer dereferencing" {
var x = i32(3);
const y = &x;
- *y += 1;
+ y.* += 1;
assert(x == 4);
- assert(*y == 4);
+ assert(y.* == 4);
}
test "call result of if else expression" {
@@ -310,9 +319,12 @@ test "call result of if else expression" {
fn f2(x: bool) []const u8 {
return (if (x) fA else fB)();
}
-fn fA() []const u8 { return "a"; }
-fn fB() []const u8 { return "b"; }
-
+fn fA() []const u8 {
+ return "a";
+}
+fn fB() []const u8 {
+ return "b";
+}
test "const expression eval handling of variables" {
var x = true;
@@ -321,8 +333,6 @@ test "const expression eval handling of variables" {
}
}
-
-
test "constant enum initialization with differing sizes" {
test3_1(test3_foo);
test3_2(test3_bar);
@@ -336,10 +346,15 @@ const Test3Point = struct {
x: i32,
y: i32,
};
-const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};
-const test3_bar = Test3Foo { .Two = 13};
-fn test3_1(f: &const Test3Foo) void {
- switch (*f) {
+const test3_foo = Test3Foo{
+ .Three = Test3Point{
+ .x = 3,
+ .y = 4,
+ },
+};
+const test3_bar = Test3Foo{ .Two = 13 };
+fn test3_1(f: *const Test3Foo) void {
+ switch (f.*) {
Test3Foo.Three => |pt| {
assert(pt.x == 3);
assert(pt.y == 4);
@@ -347,8 +362,8 @@ fn test3_1(f: &const Test3Foo) void {
else => unreachable,
}
}
-fn test3_2(f: &const Test3Foo) void {
- switch (*f) {
+fn test3_2(f: *const Test3Foo) void {
+ switch (f.*) {
Test3Foo.Two => |x| {
assert(x == 13);
},
@@ -356,58 +371,61 @@ fn test3_2(f: &const Test3Foo) void {
}
}
-
test "character literals" {
assert('\'' == single_quote);
}
const single_quote = '\'';
-
-
test "take address of parameter" {
testTakeAddressOfParameter(12.34);
}
fn testTakeAddressOfParameter(f: f32) void {
const f_ptr = &f;
- assert(*f_ptr == 12.34);
+ assert(f_ptr.* == 12.34);
}
-
test "pointer comparison" {
const a = ([]const u8)("a");
const b = &a;
assert(ptrEql(b, b));
}
-fn ptrEql(a: &const []const u8, b: &const []const u8) bool {
+fn ptrEql(a: *const []const u8, b: *const []const u8) bool {
return a == b;
}
-
test "C string concatenation" {
const a = c"OK" ++ c" IT " ++ c"WORKED";
const b = c"OK IT WORKED";
const len = cstr.len(b);
const len_with_null = len + 1;
- {var i: u32 = 0; while (i < len_with_null) : (i += 1) {
- assert(a[i] == b[i]);
- }}
+ {
+ var i: u32 = 0;
+ while (i < len_with_null) : (i += 1) {
+ assert(a[i] == b[i]);
+ }
+ }
assert(a[len] == 0);
assert(b[len] == 0);
}
test "cast slice to u8 slice" {
assert(@sizeOf(i32) == 4);
- var big_thing_array = []i32{1, 2, 3, 4};
+ var big_thing_array = []i32{
+ 1,
+ 2,
+ 3,
+ 4,
+ };
const big_thing_slice: []i32 = big_thing_array[0..];
- const bytes = ([]u8)(big_thing_slice);
+ const bytes = @sliceToBytes(big_thing_slice);
assert(bytes.len == 4 * 4);
bytes[4] = 0;
bytes[5] = 0;
bytes[6] = 0;
bytes[7] = 0;
assert(big_thing_slice[1] == 0);
- const big_thing_again = ([]align(1) i32)(bytes);
+ const big_thing_again = @bytesToSlice(i32, bytes);
assert(big_thing_again[2] == 3);
big_thing_again[2] = -1;
assert(bytes[8] == @maxValue(u8));
@@ -421,39 +439,48 @@ test "pointer to void return type" {
}
fn testPointerToVoidReturnType() error!void {
const a = testPointerToVoidReturnType2();
- return *a;
+ return a.*;
}
const test_pointer_to_void_return_type_x = void{};
-fn testPointerToVoidReturnType2() &const void {
+fn testPointerToVoidReturnType2() *const void {
return &test_pointer_to_void_return_type_x;
}
-
test "non const ptr to aliased type" {
const int = i32;
- assert(?&int == ?&i32);
+ assert(?*int == ?*i32);
}
-
-
test "array 2D const double ptr" {
- const rect_2d_vertexes = [][1]f32 {
+ const rect_2d_vertexes = [][1]f32{
[]f32{1.0},
[]f32{2.0},
};
testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
}
-fn testArray2DConstDoublePtr(ptr: &const f32) void {
- assert(ptr[0] == 1.0);
- assert(ptr[1] == 2.0);
+fn testArray2DConstDoublePtr(ptr: *const f32) void {
+ const ptr2 = @ptrCast([*]const f32, ptr);
+ assert(ptr2[0] == 1.0);
+ assert(ptr2[1] == 2.0);
}
const Tid = builtin.TypeId;
-const AStruct = struct { x: i32, };
-const AnEnum = enum { One, Two, };
-const AUnionEnum = union(enum) { One: i32, Two: void, };
-const AUnion = union { One: void, Two: void };
+const AStruct = struct {
+ x: i32,
+};
+const AnEnum = enum {
+ One,
+ Two,
+};
+const AUnionEnum = union(enum) {
+ One: i32,
+ Two: void,
+};
+const AUnion = union {
+ One: void,
+ Two: void,
+};
test "@typeId" {
comptime {
@@ -467,40 +494,33 @@ test "@typeId" {
assert(@typeId(u64) == Tid.Int);
assert(@typeId(f32) == Tid.Float);
assert(@typeId(f64) == Tid.Float);
- assert(@typeId(&f32) == Tid.Pointer);
+ assert(@typeId(*f32) == Tid.Pointer);
assert(@typeId([2]u8) == Tid.Array);
assert(@typeId(AStruct) == Tid.Struct);
- assert(@typeId(@typeOf(1)) == Tid.IntLiteral);
- assert(@typeId(@typeOf(1.0)) == Tid.FloatLiteral);
- assert(@typeId(@typeOf(undefined)) == Tid.UndefinedLiteral);
- assert(@typeId(@typeOf(null)) == Tid.NullLiteral);
- assert(@typeId(?i32) == Tid.Nullable);
+ assert(@typeId(@typeOf(1)) == Tid.ComptimeInt);
+ assert(@typeId(@typeOf(1.0)) == Tid.ComptimeFloat);
+ assert(@typeId(@typeOf(undefined)) == Tid.Undefined);
+ assert(@typeId(@typeOf(null)) == Tid.Null);
+ assert(@typeId(?i32) == Tid.Optional);
assert(@typeId(error!i32) == Tid.ErrorUnion);
assert(@typeId(error) == Tid.ErrorSet);
assert(@typeId(AnEnum) == Tid.Enum);
assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
assert(@typeId(AUnionEnum) == Tid.Union);
assert(@typeId(AUnion) == Tid.Union);
- assert(@typeId(fn()void) == Tid.Fn);
+ assert(@typeId(fn () void) == Tid.Fn);
assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
- assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);
+ assert(@typeId(@typeOf(x: {
+ break :x this;
+ })) == Tid.Block);
// TODO bound fn
// TODO arg tuple
// TODO opaque
}
}
-test "@canImplicitCast" {
- comptime {
- assert(@canImplicitCast(i64, i32(3)));
- assert(!@canImplicitCast(i32, f32(1.234)));
- assert(@canImplicitCast([]const u8, "aoeu"));
- }
-}
-
test "@typeName" {
- const Struct = struct {
- };
+ const Struct = struct {};
const Union = union {
unused: u8,
};
@@ -509,8 +529,8 @@ test "@typeName" {
};
comptime {
assert(mem.eql(u8, @typeName(i64), "i64"));
- assert(mem.eql(u8, @typeName(&usize), "&usize"));
- // https://github.com/zig-lang/zig/issues/675
+ assert(mem.eql(u8, @typeName(*usize), "*usize"));
+ // https://github.com/ziglang/zig/issues/675
assert(mem.eql(u8, @typeName(TypeFromFn(u8)), "TypeFromFn(u8)"));
assert(mem.eql(u8, @typeName(Struct), "Struct"));
assert(mem.eql(u8, @typeName(Union), "Union"));
@@ -524,15 +544,20 @@ fn TypeFromFn(comptime T: type) type {
test "volatile load and store" {
var number: i32 = 1234;
- const ptr = (&volatile i32)(&number);
- *ptr += 1;
- assert(*ptr == 1235);
+ const ptr = (*volatile i32)(&number);
+ ptr.* += 1;
+ assert(ptr.* == 1235);
}
test "slice string literal has type []const u8" {
comptime {
assert(@typeOf("aoeu"[0..]) == []const u8);
- const array = []i32{1, 2, 3, 4};
+ const array = []i32{
+ 1,
+ 2,
+ 3,
+ 4,
+ };
assert(@typeOf(array[0..]) == []const i32);
}
}
@@ -543,37 +568,36 @@ test "global variable initialized to global variable array element" {
const GDTEntry = struct {
field: i32,
};
-var gdt = []GDTEntry {
- GDTEntry {.field = 1},
- GDTEntry {.field = 2},
+var gdt = []GDTEntry{
+ GDTEntry{ .field = 1 },
+ GDTEntry{ .field = 2 },
};
var global_ptr = &gdt[0];
-
// can't really run this test but we can make sure it has no compile error
// and generates code
-const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
+const vram = @intToPtr([*]volatile u8, 0x20000000)[0..0x8000];
export fn writeToVRam() void {
vram[0] = 'X';
}
test "pointer child field" {
- assert((&u32).Child == u32);
+ assert((*u32).Child == u32);
}
const OpaqueA = @OpaqueType();
const OpaqueB = @OpaqueType();
test "@OpaqueType" {
- assert(&OpaqueA != &OpaqueB);
+ assert(*OpaqueA != *OpaqueB);
assert(mem.eql(u8, @typeName(OpaqueA), "OpaqueA"));
assert(mem.eql(u8, @typeName(OpaqueB), "OpaqueB"));
}
test "variable is allowed to be a pointer to an opaque type" {
var x: i32 = 1234;
- _ = hereIsAnOpaqueType(@ptrCast(&OpaqueA, &x));
+ _ = hereIsAnOpaqueType(@ptrCast(*OpaqueA, &x));
}
-fn hereIsAnOpaqueType(ptr: &OpaqueA) &OpaqueA {
+fn hereIsAnOpaqueType(ptr: *OpaqueA) *OpaqueA {
var a = ptr;
return a;
}
@@ -584,7 +608,7 @@ test "comptime if inside runtime while which unconditionally breaks" {
}
fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
while (cond) {
- if (false) { }
+ if (false) {}
break;
}
}
@@ -607,7 +631,7 @@ fn testStructInFn() void {
kind: BlockKind,
};
- var block = Block { .kind = 1234 };
+ var block = Block{ .kind = 1234 };
block.kind += 1;
@@ -617,7 +641,9 @@ fn testStructInFn() void {
fn fnThatClosesOverLocalConst() type {
const c = 1;
return struct {
- fn g() i32 { return c; }
+ fn g() i32 {
+ return c;
+ }
};
}
@@ -635,22 +661,27 @@ fn thisIsAColdFn() void {
@setCold(true);
}
-
-const PackedStruct = packed struct { a: u8, b: u8, };
-const PackedUnion = packed union { a: u8, b: u32, };
-const PackedEnum = packed enum { A, B, };
+const PackedStruct = packed struct {
+ a: u8,
+ b: u8,
+};
+const PackedUnion = packed union {
+ a: u8,
+ b: u32,
+};
+const PackedEnum = packed enum {
+ A,
+ B,
+};
test "packed struct, enum, union parameters in extern function" {
- testPackedStuff(
- PackedStruct{.a = 1, .b = 2},
- PackedUnion{.a = 1},
- PackedEnum.A,
- );
-}
-
-export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
+ testPackedStuff(PackedStruct{
+ .a = 1,
+ .b = 2,
+ }, PackedUnion{ .a = 1 }, PackedEnum.A);
}
+export fn testPackedStuff(a: *const PackedStruct, b: *const PackedUnion, c: PackedEnum) void {}
test "slicing zero length array" {
const s1 = ""[0..];
@@ -661,9 +692,13 @@ test "slicing zero length array" {
assert(mem.eql(u32, s2, []u32{}));
}
-
-const addr1 = @ptrCast(&const u8, emptyFn);
+const addr1 = @ptrCast(*const u8, emptyFn);
test "comptime cast fn to ptr" {
- const addr2 = @ptrCast(&const u8, emptyFn);
+ const addr2 = @ptrCast(*const u8, emptyFn);
comptime assert(addr1 == addr2);
}
+
+test "equality compare fn ptrs" {
+ var a = emptyFn;
+ assert(a == a);
+}
diff --git a/test/cases/namespace_depends_on_compile_var/index.zig b/test/cases/namespace_depends_on_compile_var/index.zig
index 95209dcef3..ccc49d9367 100644
--- a/test/cases/namespace_depends_on_compile_var/index.zig
+++ b/test/cases/namespace_depends_on_compile_var/index.zig
@@ -8,7 +8,7 @@ test "namespace depends on compile var" {
assert(!some_namespace.a_bool);
}
}
-const some_namespace = switch(builtin.os) {
+const some_namespace = switch (builtin.os) {
builtin.Os.linux => @import("a.zig"),
else => @import("b.zig"),
};
diff --git a/test/cases/new_stack_call.zig b/test/cases/new_stack_call.zig
new file mode 100644
index 0000000000..5912550d54
--- /dev/null
+++ b/test/cases/new_stack_call.zig
@@ -0,0 +1,26 @@
+const std = @import("std");
+const assert = std.debug.assert;
+
+var new_stack_bytes: [1024]u8 = undefined;
+
+test "calling a function with a new stack" {
+ const arg = 1234;
+
+ const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
+ const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
+ _ = targetFunction(arg);
+
+ assert(arg == 1234);
+ assert(a < b);
+}
+
+fn targetFunction(x: i32) usize {
+ assert(x == 1234);
+
+ var local_variable: i32 = 42;
+ const ptr = &local_variable;
+ ptr.* += 1;
+
+ assert(local_variable == 43);
+ return @ptrToInt(ptr);
+}
diff --git a/test/cases/null.zig b/test/cases/null.zig
index 35d72b729c..c86dd34b06 100644
--- a/test/cases/null.zig
+++ b/test/cases/null.zig
@@ -1,7 +1,7 @@
const assert = @import("std").debug.assert;
-test "nullable type" {
- const x : ?bool = true;
+test "optional type" {
+ const x: ?bool = true;
if (x) |y| {
if (y) {
@@ -13,15 +13,15 @@ test "nullable type" {
unreachable;
}
- const next_x : ?i32 = null;
+ const next_x: ?i32 = null;
- const z = next_x ?? 1234;
+ const z = next_x orelse 1234;
assert(z == 1234);
- const final_x : ?i32 = 13;
+ const final_x: ?i32 = 13;
- const num = final_x ?? unreachable;
+ const num = final_x orelse unreachable;
assert(num == 13);
}
@@ -30,42 +30,43 @@ test "test maybe object and get a pointer to the inner value" {
var maybe_bool: ?bool = true;
if (maybe_bool) |*b| {
- *b = false;
+ b.* = false;
}
- assert(??maybe_bool == false);
+ assert(maybe_bool.? == false);
}
-
test "rhs maybe unwrap return" {
const x: ?bool = true;
- const y = x ?? return;
+ const y = x orelse return;
}
-
test "maybe return" {
maybeReturnImpl();
comptime maybeReturnImpl();
}
fn maybeReturnImpl() void {
- assert(??foo(1235));
- if (foo(null) != null)
- unreachable;
- assert(!??foo(1234));
+ assert(foo(1235).?);
+ if (foo(null) != null) unreachable;
+ assert(!foo(1234).?);
}
fn foo(x: ?i32) ?bool {
- const value = x ?? return null;
+ const value = x orelse return null;
return value > 1234;
}
-
test "if var maybe pointer" {
- assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
-}
-fn shouldBeAPlus1(p: &const Particle) u64 {
- var maybe_particle: ?Particle = *p;
+ assert(shouldBeAPlus1(Particle{
+ .a = 14,
+ .b = 1,
+ .c = 1,
+ .d = 1,
+ }) == 15);
+}
+fn shouldBeAPlus1(p: *const Particle) u64 {
+ var maybe_particle: ?Particle = p.*;
if (maybe_particle) |*particle| {
particle.a += 1;
}
@@ -81,7 +82,6 @@ const Particle = struct {
d: u64,
};
-
test "null literal outside function" {
const is_null = here_is_a_null_literal.context == null;
assert(is_null);
@@ -92,10 +92,7 @@ test "null literal outside function" {
const SillyStruct = struct {
context: ?i32,
};
-const here_is_a_null_literal = SillyStruct {
- .context = null,
-};
-
+const here_is_a_null_literal = SillyStruct{ .context = null };
test "test null runtime" {
testTestNullRuntime(null);
@@ -105,12 +102,12 @@ fn testTestNullRuntime(x: ?i32) void {
assert(!(x != null));
}
-test "nullable void" {
- nullableVoidImpl();
- comptime nullableVoidImpl();
+test "optional void" {
+ optionalVoidImpl();
+ comptime optionalVoidImpl();
}
-fn nullableVoidImpl() void {
+fn optionalVoidImpl() void {
assert(bar(null) == null);
assert(bar({}) != null);
}
@@ -123,21 +120,19 @@ fn bar(x: ?void) ?void {
}
}
-
-
-const StructWithNullable = struct {
+const StructWithOptional = struct {
field: ?i32,
};
-var struct_with_nullable: StructWithNullable = undefined;
+var struct_with_optional: StructWithOptional = undefined;
-test "unwrap nullable which is field of global var" {
- struct_with_nullable.field = null;
- if (struct_with_nullable.field) |payload| {
+test "unwrap optional which is field of global var" {
+ struct_with_optional.field = null;
+ if (struct_with_optional.field) |payload| {
unreachable;
}
- struct_with_nullable.field = 1234;
- if (struct_with_nullable.field) |payload| {
+ struct_with_optional.field = 1234;
+ if (struct_with_optional.field) |payload| {
assert(payload == 1234);
} else {
unreachable;
@@ -145,6 +140,17 @@ test "unwrap nullable which is field of global var" {
}
test "null with default unwrap" {
- const x: i32 = null ?? 1;
+ const x: i32 = null orelse 1;
assert(x == 1);
}
+
+test "optional types" {
+ comptime {
+ const opt_type_struct = StructWithOptionalType{ .t = u8 };
+ assert(opt_type_struct.t != null and opt_type_struct.t.? == u8);
+ }
+}
+
+const StructWithOptionalType = struct {
+ t: ?type,
+};
diff --git a/test/cases/optional.zig b/test/cases/optional.zig
new file mode 100644
index 0000000000..d43682bbec
--- /dev/null
+++ b/test/cases/optional.zig
@@ -0,0 +1,30 @@
+const assert = @import("std").debug.assert;
+
+pub const EmptyStruct = struct {};
+
+test "optional pointer to size zero struct" {
+ var e = EmptyStruct{};
+ var o: ?*EmptyStruct = &e;
+ assert(o != null);
+}
+
+test "equality compare nullable pointers" {
+ testNullPtrsEql();
+ comptime testNullPtrsEql();
+}
+
+fn testNullPtrsEql() void {
+ var number: i32 = 1234;
+
+ var x: ?*i32 = null;
+ var y: ?*i32 = null;
+ assert(x == y);
+ y = &number;
+ assert(x != y);
+ assert(x != &number);
+ assert(&number != x);
+ x = &number;
+ assert(x == y);
+ assert(x == &number);
+ assert(&number == x);
+}
diff --git a/test/cases/pointers.zig b/test/cases/pointers.zig
new file mode 100644
index 0000000000..47afb60a2e
--- /dev/null
+++ b/test/cases/pointers.zig
@@ -0,0 +1,44 @@
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "dereference pointer" {
+ comptime testDerefPtr();
+ testDerefPtr();
+}
+
+fn testDerefPtr() void {
+ var x: i32 = 1234;
+ var y = &x;
+ y.* += 1;
+ assert(x == 1235);
+}
+
+test "pointer arithmetic" {
+ var ptr = c"abcd";
+
+ assert(ptr[0] == 'a');
+ ptr += 1;
+ assert(ptr[0] == 'b');
+ ptr += 1;
+ assert(ptr[0] == 'c');
+ ptr += 1;
+ assert(ptr[0] == 'd');
+ ptr += 1;
+ assert(ptr[0] == 0);
+ ptr -= 1;
+ assert(ptr[0] == 'd');
+ ptr -= 1;
+ assert(ptr[0] == 'c');
+ ptr -= 1;
+ assert(ptr[0] == 'b');
+ ptr -= 1;
+ assert(ptr[0] == 'a');
+}
+
+test "double pointer parsing" {
+ comptime assert(PtrOf(PtrOf(i32)) == **i32);
+}
+
+fn PtrOf(comptime T: type) type {
+ return *T;
+}
diff --git a/test/cases/popcount.zig b/test/cases/popcount.zig
new file mode 100644
index 0000000000..7dc7f28c0e
--- /dev/null
+++ b/test/cases/popcount.zig
@@ -0,0 +1,24 @@
+const assert = @import("std").debug.assert;
+
+test "@popCount" {
+ comptime testPopCount();
+ testPopCount();
+}
+
+fn testPopCount() void {
+ {
+ var x: u32 = 0xaa;
+ assert(@popCount(x) == 4);
+ }
+ {
+ var x: u32 = 0xaaaaaaaa;
+ assert(@popCount(x) == 16);
+ }
+ {
+ var x: i16 = -1;
+ assert(@popCount(x) == 16);
+ }
+ comptime {
+ assert(@popCount(0b11111111000110001100010000100001000011000011100101010001) == 24);
+ }
+}
diff --git a/test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig b/test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig
index 76cff3731a..3c94bb0d49 100644
--- a/test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig
+++ b/test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig
@@ -23,7 +23,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
if (c) {
const output_path = b;
- if (c2) { }
+ if (c2) {}
a(output_path);
}
diff --git a/test/cases/reflection.zig b/test/cases/reflection.zig
index 18a766d9fc..3d3af3c889 100644
--- a/test/cases/reflection.zig
+++ b/test/cases/reflection.zig
@@ -1,10 +1,11 @@
const assert = @import("std").debug.assert;
const mem = @import("std").mem;
+const reflection = this;
-test "reflection: array, pointer, nullable, error union type child" {
+test "reflection: array, pointer, optional, error union type child" {
comptime {
assert(([10]u8).Child == u8);
- assert((&u8).Child == u8);
+ assert((*u8).Child == u8);
assert((error!u8).Payload == u8);
assert((?u8).Child == u8);
}
@@ -22,7 +23,9 @@ test "reflection: function return type, var args, and param types" {
}
}
-fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; }
+fn dummy(a: bool, b: i32, c: f32) i32 {
+ return 1234;
+}
fn dummy_varargs(args: ...) void {}
test "reflection: struct member types and names" {
@@ -53,10 +56,32 @@ test "reflection: enum member types and names" {
assert(mem.eql(u8, @memberName(Bar, 2), "Three"));
assert(mem.eql(u8, @memberName(Bar, 3), "Four"));
}
+}
+test "reflection: @field" {
+ var f = Foo{
+ .one = 42,
+ .two = true,
+ .three = void{},
+ };
+
+ assert(f.one == f.one);
+ assert(@field(f, "o" ++ "ne") == f.one);
+ assert(@field(f, "t" ++ "wo") == f.two);
+ assert(@field(f, "th" ++ "ree") == f.three);
+ assert(@field(Foo, "const" ++ "ant") == Foo.constant);
+ assert(@field(Bar, "O" ++ "ne") == Bar.One);
+ assert(@field(Bar, "T" ++ "wo") == Bar.Two);
+ assert(@field(Bar, "Th" ++ "ree") == Bar.Three);
+ assert(@field(Bar, "F" ++ "our") == Bar.Four);
+ assert(@field(reflection, "dum" ++ "my")(true, 1, 2) == dummy(true, 1, 2));
+ @field(f, "o" ++ "ne") = 4;
+ assert(f.one == 4);
}
const Foo = struct {
+ const constant = 52;
+
one: i32,
two: bool,
three: void,
diff --git a/test/cases/slice.zig b/test/cases/slice.zig
index ea708ba3b5..b4b43bdd19 100644
--- a/test/cases/slice.zig
+++ b/test/cases/slice.zig
@@ -1,7 +1,7 @@
const assert = @import("std").debug.assert;
const mem = @import("std").mem;
-const x = @intToPtr(&i32, 0x1000)[0..0x500];
+const x = @intToPtr([*]i32, 0x1000)[0..0x500];
const y = x[0x100..];
test "compile time slice of pointer to hard coded address" {
assert(@ptrToInt(x.ptr) == 0x1000);
@@ -18,7 +18,11 @@ test "slice child property" {
}
test "runtime safety lets us slice from len..len" {
- var an_array = []u8{1, 2, 3};
+ var an_array = []u8{
+ 1,
+ 2,
+ 3,
+ };
assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
}
@@ -27,7 +31,7 @@ fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
}
test "implicitly cast array of size 0 to slice" {
- var msg = []u8 {};
+ var msg = []u8{};
assertLenIsZero(msg);
}
diff --git a/test/cases/struct.zig b/test/cases/struct.zig
index c3df97678b..20d46999d5 100644
--- a/test/cases/struct.zig
+++ b/test/cases/struct.zig
@@ -2,9 +2,11 @@ const assert = @import("std").debug.assert;
const builtin = @import("builtin");
const StructWithNoFields = struct {
- fn add(a: i32, b: i32) i32 { return a + b; }
+ fn add(a: i32, b: i32) i32 {
+ return a + b;
+ }
};
-const empty_global_instance = StructWithNoFields {};
+const empty_global_instance = StructWithNoFields{};
test "call struct static method" {
const result = StructWithNoFields.add(3, 4);
@@ -25,7 +27,7 @@ test "invake static method in global scope" {
}
test "void struct fields" {
- const foo = VoidStructFieldsFoo {
+ const foo = VoidStructFieldsFoo{
.a = void{},
.b = 1,
.c = void{},
@@ -34,15 +36,14 @@ test "void struct fields" {
assert(@sizeOf(VoidStructFieldsFoo) == 4);
}
const VoidStructFieldsFoo = struct {
- a : void,
- b : i32,
- c : void,
+ a: void,
+ b: i32,
+ c: void,
};
-
test "structs" {
var foo: StructFoo = undefined;
- @memset(@ptrCast(&u8, &foo), 0, @sizeOf(StructFoo));
+ @memset(@ptrCast([*]u8, &foo), 0, @sizeOf(StructFoo));
foo.a += 1;
foo.b = foo.a == 1;
testFoo(foo);
@@ -50,21 +51,20 @@ test "structs" {
assert(foo.c == 100);
}
const StructFoo = struct {
- a : i32,
- b : bool,
- c : f32,
+ a: i32,
+ b: bool,
+ c: f32,
};
-fn testFoo(foo: &const StructFoo) void {
+fn testFoo(foo: *const StructFoo) void {
assert(foo.b);
}
-fn testMutation(foo: &StructFoo) void {
+fn testMutation(foo: *StructFoo) void {
foo.c = 100;
}
-
const Node = struct {
val: Val,
- next: &Node,
+ next: *Node,
};
const Val = struct {
@@ -72,10 +72,10 @@ const Val = struct {
};
test "struct point to self" {
- var root : Node = undefined;
+ var root: Node = undefined;
root.val.x = 1;
- var node : Node = undefined;
+ var node: Node = undefined;
node.next = &root;
node.val.x = 2;
@@ -85,8 +85,8 @@ test "struct point to self" {
}
test "struct byval assign" {
- var foo1 : StructFoo = undefined;
- var foo2 : StructFoo = undefined;
+ var foo1: StructFoo = undefined;
+ var foo2: StructFoo = undefined;
foo1.a = 1234;
foo2.a = 0;
@@ -96,51 +96,52 @@ test "struct byval assign" {
}
fn structInitializer() void {
- const val = Val { .x = 42 };
+ const val = Val{ .x = 42 };
assert(val.x == 42);
}
-
test "fn call of struct field" {
- assert(callStructField(Foo {.ptr = aFunc,}) == 13);
+ assert(callStructField(Foo{ .ptr = aFunc }) == 13);
}
const Foo = struct {
- ptr: fn() i32,
+ ptr: fn () i32,
};
-fn aFunc() i32 { return 13; }
+fn aFunc() i32 {
+ return 13;
+}
-fn callStructField(foo: &const Foo) i32 {
+fn callStructField(foo: *const Foo) i32 {
return foo.ptr();
}
-
test "store member function in variable" {
- const instance = MemberFnTestFoo { .x = 1234, };
+ const instance = MemberFnTestFoo{ .x = 1234 };
const memberFn = MemberFnTestFoo.member;
const result = memberFn(instance);
assert(result == 1234);
}
const MemberFnTestFoo = struct {
x: i32,
- fn member(foo: &const MemberFnTestFoo) i32 { return foo.x; }
+ fn member(foo: *const MemberFnTestFoo) i32 {
+ return foo.x;
+ }
};
-
test "call member function directly" {
- const instance = MemberFnTestFoo { .x = 1234, };
+ const instance = MemberFnTestFoo{ .x = 1234 };
const result = MemberFnTestFoo.member(instance);
assert(result == 1234);
}
test "member functions" {
- const r = MemberFnRand {.seed = 1234};
+ const r = MemberFnRand{ .seed = 1234 };
assert(r.getSeed() == 1234);
}
const MemberFnRand = struct {
seed: u32,
- pub fn getSeed(r: &const MemberFnRand) u32 {
+ pub fn getSeed(r: *const MemberFnRand) u32 {
return r.seed;
}
};
@@ -154,7 +155,7 @@ const Bar = struct {
y: i32,
};
fn makeBar(x: i32, y: i32) Bar {
- return Bar {
+ return Bar{
.x = x,
.y = y,
};
@@ -165,22 +166,21 @@ test "empty struct method call" {
assert(es.method() == 1234);
}
const EmptyStruct = struct {
- fn method(es: &const EmptyStruct) i32 {
+ fn method(es: *const EmptyStruct) i32 {
return 1234;
}
};
-
test "return empty struct from fn" {
_ = testReturnEmptyStructFromFn();
}
const EmptyStruct2 = struct {};
fn testReturnEmptyStructFromFn() EmptyStruct2 {
- return EmptyStruct2 {};
+ return EmptyStruct2{};
}
test "pass slice of empty struct to fn" {
- assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
+ assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{EmptyStruct2{}}) == 1);
}
fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
return slice.len;
@@ -192,7 +192,7 @@ const APackedStruct = packed struct {
};
test "packed struct" {
- var foo = APackedStruct {
+ var foo = APackedStruct{
.x = 1,
.y = 2,
};
@@ -201,14 +201,13 @@ test "packed struct" {
assert(four == 4);
}
-
const BitField1 = packed struct {
a: u3,
b: u3,
c: u2,
};
-const bit_field_1 = BitField1 {
+const bit_field_1 = BitField1{
.a = 1,
.b = 2,
.c = 3,
@@ -229,19 +228,18 @@ test "bit field access" {
assert(data.b == 3);
}
-fn getA(data: &const BitField1) u3 {
+fn getA(data: *const BitField1) u3 {
return data.a;
}
-fn getB(data: &const BitField1) u3 {
+fn getB(data: *const BitField1) u3 {
return data.b;
}
-fn getC(data: &const BitField1) u2 {
+fn getC(data: *const BitField1) u2 {
return data.c;
}
-const u24 = @IntType(false, 24);
const Foo24Bits = packed struct {
field: u24,
};
@@ -258,7 +256,7 @@ test "packed struct 24bits" {
assert(@sizeOf(Foo96Bits) == 12);
}
- var value = Foo96Bits {
+ var value = Foo96Bits{
.a = 0,
.b = 0,
.c = 0,
@@ -303,7 +301,7 @@ test "packed array 24bits" {
var bytes = []u8{0} ** (@sizeOf(FooArray24Bits) + 1);
bytes[bytes.len - 1] = 0xaa;
- const ptr = &([]FooArray24Bits)(bytes[0..bytes.len - 1])[0];
+ const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
assert(ptr.a == 0);
assert(ptr.b[0].field == 0);
assert(ptr.b[1].field == 0);
@@ -352,7 +350,7 @@ test "aligned array of packed struct" {
}
var bytes = []u8{0xbb} ** @sizeOf(FooArrayOfAligned);
- const ptr = &([]FooArrayOfAligned)(bytes[0..bytes.len])[0];
+ const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];
assert(ptr.a[0].a == 0xbb);
assert(ptr.a[0].b == 0xbb);
@@ -360,16 +358,20 @@ test "aligned array of packed struct" {
assert(ptr.a[1].b == 0xbb);
}
-
-
test "runtime struct initialization of bitfield" {
- const s1 = Nibbles { .x = x1, .y = x1 };
- const s2 = Nibbles { .x = u4(x2), .y = u4(x2) };
+ const s1 = Nibbles{
+ .x = x1,
+ .y = x1,
+ };
+ const s2 = Nibbles{
+ .x = @intCast(u4, x2),
+ .y = @intCast(u4, x2),
+ };
assert(s1.x == x1);
assert(s1.y == x1);
- assert(s2.x == u4(x2));
- assert(s2.y == u4(x2));
+ assert(s2.x == @intCast(u4, x2));
+ assert(s2.y == @intCast(u4, x2));
}
var x1 = u4(1);
@@ -393,8 +395,8 @@ const Bitfields = packed struct {
test "native bit field understands endianness" {
var all: u64 = 0x7765443322221111;
var bytes: [8]u8 = undefined;
- @memcpy(&bytes[0], @ptrCast(&u8, &all), 8);
- var bitfields = *@ptrCast(&Bitfields, &bytes[0]);
+ @memcpy(bytes[0..].ptr, @ptrCast([*]u8, &all), 8);
+ var bitfields = @ptrCast(*Bitfields, bytes[0..].ptr).*;
assert(bitfields.f1 == 0x1111);
assert(bitfields.f2 == 0x2222);
@@ -412,9 +414,26 @@ test "align 1 field before self referential align 8 field as slice return type"
const Expr = union(enum) {
Literal: u8,
- Question: &Expr,
+ Question: *Expr,
};
fn alloc(comptime T: type) []T {
return []T{};
}
+
+test "call method with mutable reference to struct with no fields" {
+ const S = struct {
+ fn doC(s: *const this) bool {
+ return true;
+ }
+ fn do(s: *this) bool {
+ return true;
+ }
+ };
+
+ var s = S{};
+ assert(S.doC(&s));
+ assert(s.doC());
+ assert(S.do(&s));
+ assert(s.do());
+}
diff --git a/test/cases/struct_contains_null_ptr_itself.zig b/test/cases/struct_contains_null_ptr_itself.zig
index 5864ef4038..21175974b3 100644
--- a/test/cases/struct_contains_null_ptr_itself.zig
+++ b/test/cases/struct_contains_null_ptr_itself.zig
@@ -2,13 +2,13 @@ const std = @import("std");
const assert = std.debug.assert;
test "struct contains null pointer which contains original struct" {
- var x: ?&NodeLineComment = null;
+ var x: ?*NodeLineComment = null;
assert(x == null);
}
pub const Node = struct {
id: Id,
- comment: ?&NodeLineComment,
+ comment: ?*NodeLineComment,
pub const Id = enum {
Root,
@@ -19,4 +19,3 @@ pub const Node = struct {
pub const NodeLineComment = struct {
base: Node,
};
-
diff --git a/test/cases/struct_contains_slice_of_itself.zig b/test/cases/struct_contains_slice_of_itself.zig
index 45ec56c1e2..07987ae32b 100644
--- a/test/cases/struct_contains_slice_of_itself.zig
+++ b/test/cases/struct_contains_slice_of_itself.zig
@@ -7,30 +7,30 @@ const Node = struct {
test "struct contains slice of itself" {
var other_nodes = []Node{
- Node {
+ Node{
.payload = 31,
.children = []Node{},
},
- Node {
+ Node{
.payload = 32,
.children = []Node{},
},
};
- var nodes = []Node {
- Node {
+ var nodes = []Node{
+ Node{
.payload = 1,
.children = []Node{},
},
- Node {
+ Node{
.payload = 2,
.children = []Node{},
},
- Node {
+ Node{
.payload = 3,
.children = other_nodes[0..],
},
};
- const root = Node {
+ const root = Node{
.payload = 1234,
.children = nodes[0..],
};
diff --git a/test/cases/switch.zig b/test/cases/switch.zig
index a0ac646160..c6a4b60f09 100644
--- a/test/cases/switch.zig
+++ b/test/cases/switch.zig
@@ -6,7 +6,7 @@ test "switch with numbers" {
fn testSwitchWithNumbers(x: u32) void {
const result = switch (x) {
- 1, 2, 3, 4 ... 8 => false,
+ 1, 2, 3, 4...8 => false,
13 => true,
else => false,
};
@@ -22,9 +22,9 @@ test "switch with all ranges" {
fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
return switch (x) {
- 0 ... 100 => 1,
- 101 ... 200 => 2,
- 201 ... 300 => 3,
+ 0...100 => 1,
+ 101...200 => 2,
+ 201...300 => 3,
else => y,
};
}
@@ -61,7 +61,6 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
}
}
-
test "switch statement" {
nonConstSwitch(SwitchStatmentFoo.C);
}
@@ -81,19 +80,18 @@ const SwitchStatmentFoo = enum {
D,
};
-
test "switch prong with variable" {
- switchProngWithVarFn(SwitchProngWithVarEnum { .One = 13});
- switchProngWithVarFn(SwitchProngWithVarEnum { .Two = 13.0});
- switchProngWithVarFn(SwitchProngWithVarEnum { .Meh = {}});
+ switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
+ switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
+ switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} });
}
const SwitchProngWithVarEnum = union(enum) {
One: i32,
Two: f32,
Meh: void,
};
-fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {
- switch(*a) {
+fn switchProngWithVarFn(a: *const SwitchProngWithVarEnum) void {
+ switch (a.*) {
SwitchProngWithVarEnum.One => |x| {
assert(x == 13);
},
@@ -112,9 +110,9 @@ test "switch on enum using pointer capture" {
}
fn testSwitchEnumPtrCapture() void {
- var value = SwitchProngWithVarEnum { .One = 1234 };
+ var value = SwitchProngWithVarEnum{ .One = 1234 };
switch (value) {
- SwitchProngWithVarEnum.One => |*x| *x += 1,
+ SwitchProngWithVarEnum.One => |*x| x.* += 1,
else => unreachable,
}
switch (value) {
@@ -135,14 +133,13 @@ fn returnsFive() i32 {
return 5;
}
-
const Number = union(enum) {
One: u64,
Two: u8,
Three: f32,
};
-const number = Number { .Three = 1.23 };
+const number = Number{ .Three = 1.23 };
fn returnsFalse() bool {
switch (number) {
@@ -196,11 +193,11 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
fn testSwitchHandleAllCasesRange(x: u8) u8 {
return switch (x) {
- 0 ... 100 => u8(0),
- 101 ... 200 => 1,
+ 0...100 => u8(0),
+ 101...200 => 1,
201, 203 => 2,
202 => 4,
- 204 ... 255 => 3,
+ 204...255 => 3,
};
}
diff --git a/test/cases/switch_prong_err_enum.zig b/test/cases/switch_prong_err_enum.zig
index 136e8834e6..f060ac2c57 100644
--- a/test/cases/switch_prong_err_enum.zig
+++ b/test/cases/switch_prong_err_enum.zig
@@ -14,14 +14,16 @@ const FormValue = union(enum) {
fn doThing(form_id: u64) error!FormValue {
return switch (form_id) {
- 17 => FormValue { .Address = try readOnce() },
+ 17 => FormValue{ .Address = try readOnce() },
else => error.InvalidDebugInfo,
};
}
test "switch prong returns error enum" {
switch (doThing(17) catch unreachable) {
- FormValue.Address => |payload| { assert(payload == 1); },
+ FormValue.Address => |payload| {
+ assert(payload == 1);
+ },
else => unreachable,
}
assert(read_count == 1);
diff --git a/test/cases/switch_prong_implicit_cast.zig b/test/cases/switch_prong_implicit_cast.zig
index 335feeef43..56d37e290f 100644
--- a/test/cases/switch_prong_implicit_cast.zig
+++ b/test/cases/switch_prong_implicit_cast.zig
@@ -7,8 +7,8 @@ const FormValue = union(enum) {
fn foo(id: u64) !FormValue {
return switch (id) {
- 2 => FormValue { .Two = true },
- 1 => FormValue { .One = {} },
+ 2 => FormValue{ .Two = true },
+ 1 => FormValue{ .One = {} },
else => return error.Whatever,
};
}
diff --git a/test/cases/syntax.zig b/test/cases/syntax.zig
index 6c851c0ff3..b497b060c4 100644
--- a/test/cases/syntax.zig
+++ b/test/cases/syntax.zig
@@ -1,12 +1,11 @@
// Test trailing comma syntax
+// zig fmt: off
const struct_trailing_comma = struct { x: i32, y: i32, };
const struct_no_comma = struct { x: i32, y: i32 };
-const struct_no_comma_void_type = struct { x: i32, y };
const struct_fn_no_comma = struct { fn m() void {} y: i32 };
const enum_no_comma = enum { A, B };
-const enum_no_comma_type = enum { A, B: i32 };
fn container_init() void {
const S = struct { x: i32, y: i32 };
@@ -36,16 +35,11 @@ fn switch_prongs(x: i32) void {
const fn_no_comma = fn(i32, i32)void;
const fn_trailing_comma = fn(i32, i32,)void;
-const fn_vararg_trailing_comma = fn(i32, i32, ...,)void;
fn fn_calls() void {
fn add(x: i32, y: i32,) i32 { x + y };
_ = add(1, 2);
_ = add(1, 2,);
-
- fn swallow(x: ...,) void {};
- _ = swallow(1,2,3,);
- _ = swallow();
}
fn asm_lists() void {
diff --git a/test/cases/this.zig b/test/cases/this.zig
index 8ed5e1ae1a..ba51d0ac90 100644
--- a/test/cases/this.zig
+++ b/test/cases/this.zig
@@ -8,7 +8,7 @@ fn Point(comptime T: type) type {
x: T,
y: T,
- fn addOne(self: &Self) void {
+ fn addOne(self: *Self) void {
self.x += 1;
self.y += 1;
}
@@ -29,7 +29,7 @@ test "this refer to module call private fn" {
}
test "this refer to container" {
- var pt = Point(i32) {
+ var pt = Point(i32){
.x = 12,
.y = 34,
};
diff --git a/test/cases/try.zig b/test/cases/try.zig
index 4a0425e22e..cf5fa5862a 100644
--- a/test/cases/try.zig
+++ b/test/cases/try.zig
@@ -3,13 +3,10 @@ const assert = @import("std").debug.assert;
test "try on error union" {
tryOnErrorUnionImpl();
comptime tryOnErrorUnionImpl();
-
}
fn tryOnErrorUnionImpl() void {
- const x = if (returnsTen()) |val|
- val + 1
- else |err| switch (err) {
+ const x = if (returnsTen()) |val| val + 1 else |err| switch (err) {
error.ItBroke, error.NoMem => 1,
error.CrappedOut => i32(2),
else => unreachable,
diff --git a/test/cases/type_info.zig b/test/cases/type_info.zig
new file mode 100644
index 0000000000..b8fc4cf14e
--- /dev/null
+++ b/test/cases/type_info.zig
@@ -0,0 +1,259 @@
+const assert = @import("std").debug.assert;
+const mem = @import("std").mem;
+const TypeInfo = @import("builtin").TypeInfo;
+const TypeId = @import("builtin").TypeId;
+
+test "type info: tag type, void info" {
+ testBasic();
+ comptime testBasic();
+}
+
+fn testBasic() void {
+ assert(@TagType(TypeInfo) == TypeId);
+ const void_info = @typeInfo(void);
+ assert(TypeId(void_info) == TypeId.Void);
+ assert(void_info.Void == {});
+}
+
+test "type info: integer, floating point type info" {
+ testIntFloat();
+ comptime testIntFloat();
+}
+
+fn testIntFloat() void {
+ const u8_info = @typeInfo(u8);
+ assert(TypeId(u8_info) == TypeId.Int);
+ assert(!u8_info.Int.is_signed);
+ assert(u8_info.Int.bits == 8);
+
+ const f64_info = @typeInfo(f64);
+ assert(TypeId(f64_info) == TypeId.Float);
+ assert(f64_info.Float.bits == 64);
+}
+
+test "type info: pointer type info" {
+ testPointer();
+ comptime testPointer();
+}
+
+fn testPointer() void {
+ const u32_ptr_info = @typeInfo(*u32);
+ assert(TypeId(u32_ptr_info) == TypeId.Pointer);
+ assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.One);
+ assert(u32_ptr_info.Pointer.is_const == false);
+ assert(u32_ptr_info.Pointer.is_volatile == false);
+ assert(u32_ptr_info.Pointer.alignment == @alignOf(u32));
+ assert(u32_ptr_info.Pointer.child == u32);
+}
+
+test "type info: unknown length pointer type info" {
+ testUnknownLenPtr();
+ comptime testUnknownLenPtr();
+}
+
+fn testUnknownLenPtr() void {
+ const u32_ptr_info = @typeInfo([*]const volatile f64);
+ assert(TypeId(u32_ptr_info) == TypeId.Pointer);
+ assert(u32_ptr_info.Pointer.size == TypeInfo.Pointer.Size.Many);
+ assert(u32_ptr_info.Pointer.is_const == true);
+ assert(u32_ptr_info.Pointer.is_volatile == true);
+ assert(u32_ptr_info.Pointer.alignment == @alignOf(f64));
+ assert(u32_ptr_info.Pointer.child == f64);
+}
+
+test "type info: slice type info" {
+ testSlice();
+ comptime testSlice();
+}
+
+fn testSlice() void {
+ const u32_slice_info = @typeInfo([]u32);
+ assert(TypeId(u32_slice_info) == TypeId.Pointer);
+ assert(u32_slice_info.Pointer.size == TypeInfo.Pointer.Size.Slice);
+ assert(u32_slice_info.Pointer.is_const == false);
+ assert(u32_slice_info.Pointer.is_volatile == false);
+ assert(u32_slice_info.Pointer.alignment == 4);
+ assert(u32_slice_info.Pointer.child == u32);
+}
+
+test "type info: array type info" {
+ testArray();
+ comptime testArray();
+}
+
+fn testArray() void {
+ const arr_info = @typeInfo([42]bool);
+ assert(TypeId(arr_info) == TypeId.Array);
+ assert(arr_info.Array.len == 42);
+ assert(arr_info.Array.child == bool);
+}
+
+test "type info: optional type info" {
+ testOptional();
+ comptime testOptional();
+}
+
+fn testOptional() void {
+ const null_info = @typeInfo(?void);
+ assert(TypeId(null_info) == TypeId.Optional);
+ assert(null_info.Optional.child == void);
+}
+
+test "type info: promise info" {
+ testPromise();
+ comptime testPromise();
+}
+
+fn testPromise() void {
+ const null_promise_info = @typeInfo(promise);
+ assert(TypeId(null_promise_info) == TypeId.Promise);
+ assert(null_promise_info.Promise.child == null);
+
+ const promise_info = @typeInfo(promise->usize);
+ assert(TypeId(promise_info) == TypeId.Promise);
+ assert(promise_info.Promise.child.? == usize);
+}
+
+test "type info: error set, error union info" {
+ testErrorSet();
+ comptime testErrorSet();
+}
+
+fn testErrorSet() void {
+ const TestErrorSet = error{
+ First,
+ Second,
+ Third,
+ };
+
+ const error_set_info = @typeInfo(TestErrorSet);
+ assert(TypeId(error_set_info) == TypeId.ErrorSet);
+ assert(error_set_info.ErrorSet.errors.len == 3);
+ assert(mem.eql(u8, error_set_info.ErrorSet.errors[0].name, "First"));
+ assert(error_set_info.ErrorSet.errors[2].value == @errorToInt(TestErrorSet.Third));
+
+ const error_union_info = @typeInfo(TestErrorSet!usize);
+ assert(TypeId(error_union_info) == TypeId.ErrorUnion);
+ assert(error_union_info.ErrorUnion.error_set == TestErrorSet);
+ assert(error_union_info.ErrorUnion.payload == usize);
+}
+
+test "type info: enum info" {
+ testEnum();
+ comptime testEnum();
+}
+
+fn testEnum() void {
+ const Os = @import("builtin").Os;
+
+ const os_info = @typeInfo(Os);
+ assert(TypeId(os_info) == TypeId.Enum);
+ assert(os_info.Enum.layout == TypeInfo.ContainerLayout.Auto);
+ assert(os_info.Enum.fields.len == 32);
+ assert(mem.eql(u8, os_info.Enum.fields[1].name, "ananas"));
+ assert(os_info.Enum.fields[10].value == 10);
+ assert(os_info.Enum.tag_type == u5);
+ assert(os_info.Enum.defs.len == 0);
+}
+
+test "type info: union info" {
+ testUnion();
+ comptime testUnion();
+}
+
+fn testUnion() void {
+ const typeinfo_info = @typeInfo(TypeInfo);
+ assert(TypeId(typeinfo_info) == TypeId.Union);
+ assert(typeinfo_info.Union.layout == TypeInfo.ContainerLayout.Auto);
+ assert(typeinfo_info.Union.tag_type.? == TypeId);
+ assert(typeinfo_info.Union.fields.len == 25);
+ assert(typeinfo_info.Union.fields[4].enum_field != null);
+ assert(typeinfo_info.Union.fields[4].enum_field.?.value == 4);
+ assert(typeinfo_info.Union.fields[4].field_type == @typeOf(@typeInfo(u8).Int));
+ assert(typeinfo_info.Union.defs.len == 20);
+
+ const TestNoTagUnion = union {
+ Foo: void,
+ Bar: u32,
+ };
+
+ const notag_union_info = @typeInfo(TestNoTagUnion);
+ assert(TypeId(notag_union_info) == TypeId.Union);
+ assert(notag_union_info.Union.tag_type == null);
+ assert(notag_union_info.Union.layout == TypeInfo.ContainerLayout.Auto);
+ assert(notag_union_info.Union.fields.len == 2);
+ assert(notag_union_info.Union.fields[0].enum_field == null);
+ assert(notag_union_info.Union.fields[1].field_type == u32);
+
+ const TestExternUnion = extern union {
+ foo: *c_void,
+ };
+
+ const extern_union_info = @typeInfo(TestExternUnion);
+ assert(extern_union_info.Union.layout == TypeInfo.ContainerLayout.Extern);
+ assert(extern_union_info.Union.tag_type == null);
+ assert(extern_union_info.Union.fields[0].enum_field == null);
+ assert(extern_union_info.Union.fields[0].field_type == *c_void);
+}
+
+test "type info: struct info" {
+ testStruct();
+ comptime testStruct();
+}
+
+fn testStruct() void {
+ const struct_info = @typeInfo(TestStruct);
+ assert(TypeId(struct_info) == TypeId.Struct);
+ assert(struct_info.Struct.layout == TypeInfo.ContainerLayout.Packed);
+ assert(struct_info.Struct.fields.len == 3);
+ assert(struct_info.Struct.fields[1].offset == null);
+ assert(struct_info.Struct.fields[2].field_type == *TestStruct);
+ assert(struct_info.Struct.defs.len == 2);
+ assert(struct_info.Struct.defs[0].is_pub);
+ assert(!struct_info.Struct.defs[0].data.Fn.is_extern);
+ assert(struct_info.Struct.defs[0].data.Fn.lib_name == null);
+ assert(struct_info.Struct.defs[0].data.Fn.return_type == void);
+ assert(struct_info.Struct.defs[0].data.Fn.fn_type == fn (*const TestStruct) void);
+}
+
+const TestStruct = packed struct {
+ const Self = this;
+
+ fieldA: usize,
+ fieldB: void,
+ fieldC: *Self,
+
+ pub fn foo(self: *const Self) void {}
+};
+
+test "type info: function type info" {
+ testFunction();
+ comptime testFunction();
+}
+
+fn testFunction() void {
+ const fn_info = @typeInfo(@typeOf(foo));
+ assert(TypeId(fn_info) == TypeId.Fn);
+ assert(fn_info.Fn.calling_convention == TypeInfo.CallingConvention.Unspecified);
+ assert(fn_info.Fn.is_generic);
+ assert(fn_info.Fn.args.len == 2);
+ assert(fn_info.Fn.is_var_args);
+ assert(fn_info.Fn.return_type == null);
+ assert(fn_info.Fn.async_allocator_type == null);
+
+ const test_instance: TestStruct = undefined;
+ const bound_fn_info = @typeInfo(@typeOf(test_instance.foo));
+ assert(TypeId(bound_fn_info) == TypeId.BoundFn);
+ assert(bound_fn_info.BoundFn.args[0].arg_type.? == *const TestStruct);
+}
+
+fn foo(comptime a: usize, b: bool, args: ...) usize {
+ return 0;
+}
+
+test "typeInfo with comptime parameter in struct fn def" {
+ const S = struct {
+ pub fn func(comptime x: f32) void {}
+ };
+ comptime var info = @typeInfo(S);
+}
diff --git a/test/cases/undefined.zig b/test/cases/undefined.zig
index bc81f9cf84..83c620d211 100644
--- a/test/cases/undefined.zig
+++ b/test/cases/undefined.zig
@@ -27,12 +27,12 @@ test "init static array to undefined" {
const Foo = struct {
x: i32,
- fn setFooXMethod(foo: &Foo) void {
+ fn setFooXMethod(foo: *Foo) void {
foo.x = 3;
}
};
-fn setFooX(foo: &Foo) void {
+fn setFooX(foo: *Foo) void {
foo.x = 2;
}
@@ -63,6 +63,6 @@ test "assign undefined to struct with method" {
}
test "type name of undefined" {
- const x = undefined;
- assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
+ const x = undefined;
+ assert(mem.eql(u8, @typeName(@typeOf(x)), "(undefined)"));
}
diff --git a/test/cases/underscore.zig b/test/cases/underscore.zig
new file mode 100644
index 0000000000..44451e3723
--- /dev/null
+++ b/test/cases/underscore.zig
@@ -0,0 +1,28 @@
+const std = @import("std");
+const assert = std.debug.assert;
+
+test "ignore lval with underscore" {
+ _ = false;
+}
+
+test "ignore lval with underscore (for loop)" {
+ for ([]void{}) |_, i| {
+ for ([]void{}) |_, j| {
+ break;
+ }
+ break;
+ }
+}
+
+test "ignore lval with underscore (while loop)" {
+ while (optionalReturnError()) |_| {
+ while (optionalReturnError()) |_| {
+ break;
+ } else |_| { }
+ break;
+ } else |_| { }
+}
+
+fn optionalReturnError() !?u32 {
+ return error.optionalReturnError;
+}
diff --git a/test/cases/union.zig b/test/cases/union.zig
index dc2a7c3414..08969e64fe 100644
--- a/test/cases/union.zig
+++ b/test/cases/union.zig
@@ -10,41 +10,54 @@ const Agg = struct {
val2: Value,
};
-const v1 = Value { .Int = 1234 };
-const v2 = Value { .Array = []u8{3} ** 9 };
+const v1 = Value{ .Int = 1234 };
+const v2 = Value{ .Array = []u8{3} ** 9 };
-const err = (error!Agg)(Agg {
+const err = (error!Agg)(Agg{
.val1 = v1,
.val2 = v2,
});
-const array = []Value { v1, v2, v1, v2};
-
+const array = []Value{
+ v1,
+ v2,
+ v1,
+ v2,
+};
test "unions embedded in aggregate types" {
switch (array[1]) {
Value.Array => |arr| assert(arr[4] == 3),
else => unreachable,
}
- switch((err catch unreachable).val1) {
+ switch ((err catch unreachable).val1) {
Value.Int => |x| assert(x == 1234),
else => unreachable,
}
}
-
const Foo = union {
float: f64,
int: i32,
};
test "basic unions" {
- var foo = Foo { .int = 1 };
+ var foo = Foo{ .int = 1 };
assert(foo.int == 1);
- foo = Foo {.float = 12.34};
+ foo = Foo{ .float = 12.34 };
assert(foo.float == 12.34);
}
+test "comptime union field access" {
+ comptime {
+ var foo = Foo{ .int = 0 };
+ assert(foo.int == 0);
+
+ foo = Foo{ .float = 42.42 };
+ assert(foo.float == 42.42);
+ }
+}
+
test "init union with runtime value" {
var foo: Foo = undefined;
@@ -55,12 +68,12 @@ test "init union with runtime value" {
assert(foo.int == 42);
}
-fn setFloat(foo: &Foo, x: f64) void {
- *foo = Foo { .float = x };
+fn setFloat(foo: *Foo, x: f64) void {
+ foo.* = Foo{ .float = x };
}
-fn setInt(foo: &Foo, x: i32) void {
- *foo = Foo { .int = x };
+fn setInt(foo: *Foo, x: i32) void {
+ foo.* = Foo{ .int = x };
}
const FooExtern = extern union {
@@ -69,13 +82,12 @@ const FooExtern = extern union {
};
test "basic extern unions" {
- var foo = FooExtern { .int = 1 };
+ var foo = FooExtern{ .int = 1 };
assert(foo.int == 1);
foo.float = 12.34;
assert(foo.float == 12.34);
}
-
const Letter = enum {
A,
B,
@@ -93,12 +105,12 @@ test "union with specified enum tag" {
}
fn doTest() void {
- assert(bar(Payload {.A = 1234}) == -10);
+ assert(bar(Payload{ .A = 1234 }) == -10);
}
-fn bar(value: &const Payload) i32 {
- assert(Letter(*value) == Letter.A);
- return switch (*value) {
+fn bar(value: *const Payload) i32 {
+ assert(Letter(value.*) == Letter.A);
+ return switch (value.*) {
Payload.A => |x| return x - 1244,
Payload.B => |x| if (x == 12.34) i32(20) else 21,
Payload.C => |x| if (x) i32(30) else 31,
@@ -114,7 +126,7 @@ const MultipleChoice = union(enum(u32)) {
test "simple union(enum(u32))" {
var x = MultipleChoice.C;
assert(x == MultipleChoice.C);
- assert(u32(@TagType(MultipleChoice)(x)) == 60);
+ assert(@enumToInt(@TagType(MultipleChoice)(x)) == 60);
}
const MultipleChoice2 = union(enum(u32)) {
@@ -131,13 +143,13 @@ const MultipleChoice2 = union(enum(u32)) {
test "union(enum(u32)) with specified and unspecified tag values" {
comptime assert(@TagType(@TagType(MultipleChoice2)) == u32);
- testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 {.C = 123});
- comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );
+ testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
+ comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 });
}
-fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {
- assert(u32(@TagType(MultipleChoice2)(*x)) == 60);
- assert(1123 == switch (*x) {
+fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: *const MultipleChoice2) void {
+ assert(@enumToInt(@TagType(MultipleChoice2)(x.*)) == 60);
+ assert(1123 == switch (x.*) {
MultipleChoice2.A => 1,
MultipleChoice2.B => 2,
MultipleChoice2.C => |v| i32(1000) + v,
@@ -150,18 +162,17 @@ fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void
});
}
-
const ExternPtrOrInt = extern union {
- ptr: &u8,
- int: u64
+ ptr: *u8,
+ int: u64,
};
test "extern union size" {
comptime assert(@sizeOf(ExternPtrOrInt) == 8);
}
const PackedPtrOrInt = packed union {
- ptr: &u8,
- int: u64
+ ptr: *u8,
+ int: u64,
};
test "extern union size" {
comptime assert(@sizeOf(PackedPtrOrInt) == 8);
@@ -174,8 +185,16 @@ test "union with only 1 field which is void should be zero bits" {
comptime assert(@sizeOf(ZeroBits) == 0);
}
-const TheTag = enum {A, B, C};
-const TheUnion = union(TheTag) { A: i32, B: i32, C: i32 };
+const TheTag = enum {
+ A,
+ B,
+ C,
+};
+const TheUnion = union(TheTag) {
+ A: i32,
+ B: i32,
+ C: i32,
+};
test "union field access gives the enum values" {
assert(TheUnion.A == TheTag.A);
assert(TheUnion.B == TheTag.B);
@@ -183,20 +202,28 @@ test "union field access gives the enum values" {
}
test "cast union to tag type of union" {
- testCastUnionToTagType(TheUnion {.B = 1234});
- comptime testCastUnionToTagType(TheUnion {.B = 1234});
+ testCastUnionToTagType(TheUnion{ .B = 1234 });
+ comptime testCastUnionToTagType(TheUnion{ .B = 1234 });
}
-fn testCastUnionToTagType(x: &const TheUnion) void {
- assert(TheTag(*x) == TheTag.B);
+fn testCastUnionToTagType(x: *const TheUnion) void {
+ assert(TheTag(x.*) == TheTag.B);
}
test "cast tag type of union to union" {
var x: Value2 = Letter2.B;
assert(Letter2(x) == Letter2.B);
}
-const Letter2 = enum { A, B, C };
-const Value2 = union(Letter2) { A: i32, B, C, };
+const Letter2 = enum {
+ A,
+ B,
+ C,
+};
+const Value2 = union(Letter2) {
+ A: i32,
+ B,
+ C,
+};
test "implicit cast union to its tag type" {
var x: Value2 = Letter2.B;
@@ -216,20 +243,17 @@ const TheUnion2 = union(enum) {
Item2: i32,
};
-fn assertIsTheUnion2Item1(value: &const TheUnion2) void {
- assert(*value == TheUnion2.Item1);
+fn assertIsTheUnion2Item1(value: *const TheUnion2) void {
+ assert(value.* == TheUnion2.Item1);
}
-
pub const PackThis = union(enum) {
Invalid: bool,
StringLiteral: u2,
};
test "constant packed union" {
- testConstPackedUnion([]PackThis {
- PackThis { .StringLiteral = 1 },
- });
+ testConstPackedUnion([]PackThis{PackThis{ .StringLiteral = 1 }});
}
fn testConstPackedUnion(expected_tokens: []const PackThis) void {
@@ -242,7 +266,7 @@ test "switch on union with only 1 field" {
switch (r) {
PartialInst.Compiled => {
var z: PartialInstWithPayload = undefined;
- z = PartialInstWithPayload { .Compiled = 1234 };
+ z = PartialInstWithPayload{ .Compiled = 1234 };
switch (z) {
PartialInstWithPayload.Compiled => |x| {
assert(x == 1234);
@@ -262,3 +286,28 @@ const PartialInstWithPayload = union(enum) {
Compiled: i32,
};
+test "access a member of tagged union with conflicting enum tag name" {
+ const Bar = union(enum) {
+ A: A,
+ B: B,
+
+ const A = u8;
+ const B = void;
+ };
+
+ comptime assert(Bar.A == u8);
+}
+
+test "tagged union initialization with runtime void" {
+ assert(testTaggedUnionInit({}));
+}
+
+const TaggedUnionWithAVoid = union(enum) {
+ A,
+ B: i32,
+};
+
+fn testTaggedUnionInit(x: var) bool {
+ const y = TaggedUnionWithAVoid{ .A = x };
+ return @TagType(TaggedUnionWithAVoid)(y) == TaggedUnionWithAVoid.A;
+}
diff --git a/test/cases/var_args.zig b/test/cases/var_args.zig
index cead9eb8bf..3eb6e30448 100644
--- a/test/cases/var_args.zig
+++ b/test/cases/var_args.zig
@@ -2,9 +2,12 @@ const assert = @import("std").debug.assert;
fn add(args: ...) i32 {
var sum = i32(0);
- {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
- sum += args[i];
- }}
+ {
+ comptime var i: usize = 0;
+ inline while (i < args.len) : (i += 1) {
+ sum += args[i];
+ }
+ }
return sum;
}
@@ -55,31 +58,23 @@ fn extraFn(extra: u32, args: ...) usize {
return args.len;
}
+const foos = []fn (...) bool{
+ foo1,
+ foo2,
+};
-const foos = []fn(...) bool { foo1, foo2 };
-
-fn foo1(args: ...) bool { return true; }
-fn foo2(args: ...) bool { return false; }
+fn foo1(args: ...) bool {
+ return true;
+}
+fn foo2(args: ...) bool {
+ return false;
+}
test "array of var args functions" {
assert(foos[0]());
assert(!foos[1]());
}
-
-test "pass array and slice of same array to var args should have same pointers" {
- const array = "hi";
- const slice: []const u8 = array;
- return assertSlicePtrsEql(array, slice);
-}
-
-fn assertSlicePtrsEql(args: ...) void {
- const s1 = ([]const u8)(args[0]);
- const s2 = args[1];
- assert(s1.ptr == s2.ptr);
-}
-
-
test "pass zero length array to var args param" {
doNothingWithFirstArg("");
}
diff --git a/test/cases/void.zig b/test/cases/void.zig
index f4d72209e4..7121ac664b 100644
--- a/test/cases/void.zig
+++ b/test/cases/void.zig
@@ -8,7 +8,7 @@ const Foo = struct {
test "compare void with void compile time known" {
comptime {
- const foo = Foo {
+ const foo = Foo{
.a = {},
.b = 1,
.c = {},
@@ -16,3 +16,15 @@ test "compare void with void compile time known" {
assert(foo.a == {});
}
}
+
+test "iterate over a void slice" {
+ var j: usize = 0;
+ for (times(10)) |_, i| {
+ assert(i == j);
+ j += 1;
+ }
+}
+
+fn times(n: usize) []const void {
+ return ([*]void)(undefined)[0..n];
+}
diff --git a/test/cases/while.zig b/test/cases/while.zig
index 33d5a5623a..fe53522ea6 100644
--- a/test/cases/while.zig
+++ b/test/cases/while.zig
@@ -1,7 +1,7 @@
const assert = @import("std").debug.assert;
test "while loop" {
- var i : i32 = 0;
+ var i: i32 = 0;
while (i < 4) {
i += 1;
}
@@ -35,7 +35,7 @@ test "continue and break" {
}
var continue_and_break_counter: i32 = 0;
fn runContinueAndBreakTest() void {
- var i : i32 = 0;
+ var i: i32 = 0;
while (true) {
continue_and_break_counter += 2;
i += 1;
@@ -58,10 +58,13 @@ fn returnWithImplicitCastFromWhileLoopTest() error!void {
test "while with continue expression" {
var sum: i32 = 0;
- {var i: i32 = 0; while (i < 10) : (i += 1) {
- if (i == 5) continue;
- sum += i;
- }}
+ {
+ var i: i32 = 0;
+ while (i < 10) : (i += 1) {
+ if (i == 5) continue;
+ sum += i;
+ }
+ }
assert(sum == 40);
}
@@ -78,7 +81,7 @@ test "while with else" {
assert(got_else == 1);
}
-test "while with nullable as condition" {
+test "while with optional as condition" {
numbers_left = 10;
var sum: i32 = 0;
while (getNumberOrNull()) |value| {
@@ -87,7 +90,7 @@ test "while with nullable as condition" {
assert(sum == 45);
}
-test "while with nullable as condition with else" {
+test "while with optional as condition with else" {
numbers_left = 10;
var sum: i32 = 0;
var got_else: i32 = 0;
@@ -117,61 +120,63 @@ test "while with error union condition" {
var numbers_left: i32 = undefined;
fn getNumberOrErr() error!i32 {
- return if (numbers_left == 0)
- error.OutOfNumbers
- else x: {
+ return if (numbers_left == 0) error.OutOfNumbers else x: {
numbers_left -= 1;
break :x numbers_left;
};
}
fn getNumberOrNull() ?i32 {
- return if (numbers_left == 0)
- null
- else x: {
+ return if (numbers_left == 0) null else x: {
numbers_left -= 1;
break :x numbers_left;
};
}
-test "while on nullable with else result follow else prong" {
+test "while on optional with else result follow else prong" {
const result = while (returnNull()) |value| {
break value;
- } else i32(2);
+ } else
+ i32(2);
assert(result == 2);
}
-test "while on nullable with else result follow break prong" {
- const result = while (returnMaybe(10)) |value| {
+test "while on optional with else result follow break prong" {
+ const result = while (returnOptional(10)) |value| {
break value;
- } else i32(2);
+ } else
+ i32(2);
assert(result == 10);
}
test "while on error union with else result follow else prong" {
const result = while (returnError()) |value| {
break value;
- } else |err| i32(2);
+ } else |err|
+ i32(2);
assert(result == 2);
}
test "while on error union with else result follow break prong" {
const result = while (returnSuccess(10)) |value| {
break value;
- } else |err| i32(2);
+ } else |err|
+ i32(2);
assert(result == 10);
}
test "while on bool with else result follow else prong" {
const result = while (returnFalse()) {
break i32(10);
- } else i32(2);
+ } else
+ i32(2);
assert(result == 2);
}
test "while on bool with else result follow break prong" {
const result = while (returnTrue()) {
break i32(10);
- } else i32(2);
+ } else
+ i32(2);
assert(result == 10);
}
@@ -202,9 +207,21 @@ fn testContinueOuter() void {
}
}
-fn returnNull() ?i32 { return null; }
-fn returnMaybe(x: i32) ?i32 { return x; }
-fn returnError() error!i32 { return error.YouWantedAnError; }
-fn returnSuccess(x: i32) error!i32 { return x; }
-fn returnFalse() bool { return false; }
-fn returnTrue() bool { return true; }
+fn returnNull() ?i32 {
+ return null;
+}
+fn returnOptional(x: i32) ?i32 {
+ return x;
+}
+fn returnError() error!i32 {
+ return error.YouWantedAnError;
+}
+fn returnSuccess(x: i32) error!i32 {
+ return x;
+}
+fn returnFalse() bool {
+ return false;
+}
+fn returnTrue() bool {
+ return true;
+}
diff --git a/test/cases/widening.zig b/test/cases/widening.zig
new file mode 100644
index 0000000000..cf6ab4ca0f
--- /dev/null
+++ b/test/cases/widening.zig
@@ -0,0 +1,27 @@
+const std = @import("std");
+const assert = std.debug.assert;
+const mem = std.mem;
+
+test "integer widening" {
+ var a: u8 = 250;
+ var b: u16 = a;
+ var c: u32 = b;
+ var d: u64 = c;
+ var e: u64 = d;
+ var f: u128 = e;
+ assert(f == a);
+}
+
+test "implicit unsigned integer to signed integer" {
+ var a: u8 = 250;
+ var b: i16 = a;
+ assert(b == 250);
+}
+
+test "float widening" {
+ var a: f16 = 12.34;
+ var b: f32 = a;
+ var c: f64 = b;
+ var d: f128 = c;
+ assert(d == a);
+}
diff --git a/test/compare_output.zig b/test/compare_output.zig
index 9595bf8259..a18a78b419 100644
--- a/test/compare_output.zig
+++ b/test/compare_output.zig
@@ -3,10 +3,10 @@ const std = @import("std");
const os = std.os;
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.CompareOutputContext) void {
+pub fn addCases(cases: *tests.CompareOutputContext) void {
cases.addC("hello world with libc",
\\const c = @cImport(@cInclude("stdio.h"));
- \\export fn main(argc: c_int, argv: &&u8) c_int {
+ \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ _ = c.puts(c"Hello, world!");
\\ return 0;
\\}
@@ -131,7 +131,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const is_windows = builtin.os == builtin.Os.windows;
\\const c = @cImport({
\\ if (is_windows) {
- \\ // See https://github.com/zig-lang/zig/issues/515
+ \\ // See https://github.com/ziglang/zig/issues/515
\\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
\\ @cInclude("io.h");
\\ @cInclude("fcntl.h");
@@ -139,7 +139,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @cInclude("stdio.h");
\\});
\\
- \\export fn main(argc: c_int, argv: &&u8) c_int {
+ \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ if (is_windows) {
\\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY);
@@ -284,12 +284,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.addC("expose function pointer to C land",
\\const c = @cImport(@cInclude("stdlib.h"));
\\
- \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
- \\ const a_int = @ptrCast(&align(1) const i32, a ?? unreachable);
- \\ const b_int = @ptrCast(&align(1) const i32, b ?? unreachable);
- \\ if (*a_int < *b_int) {
+ \\export fn compare_fn(a: ?*const c_void, b: ?*const c_void) c_int {
+ \\ const a_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), a));
+ \\ const b_int = @ptrCast(*const i32, @alignCast(@alignOf(i32), b));
+ \\ if (a_int.* < b_int.*) {
\\ return -1;
- \\ } else if (*a_int > *b_int) {
+ \\ } else if (a_int.* > b_int.*) {
\\ return 1;
\\ } else {
\\ return 0;
@@ -297,9 +297,9 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\}
\\
\\export fn main() c_int {
- \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
+ \\ var array = []u32{ 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
\\
- \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
+ \\ c.qsort(@ptrCast(?*c_void, array[0..].ptr), @intCast(c_ulong, array.len), @sizeOf(i32), compare_fn);
\\
\\ for (array) |item, i| {
\\ if (item != i) {
@@ -316,7 +316,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const is_windows = builtin.os == builtin.Os.windows;
\\const c = @cImport({
\\ if (is_windows) {
- \\ // See https://github.com/zig-lang/zig/issues/515
+ \\ // See https://github.com/ziglang/zig/issues/515
\\ @cDefine("_NO_CRT_STDIO_INLINE", "1");
\\ @cInclude("io.h");
\\ @cInclude("fcntl.h");
@@ -324,15 +324,15 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @cInclude("stdio.h");
\\});
\\
- \\export fn main(argc: c_int, argv: &&u8) c_int {
+ \\export fn main(argc: c_int, argv: [*][*]u8) c_int {
\\ if (is_windows) {
\\ // we want actual \n, not \r\n
\\ _ = c._setmode(1, c._O_BINARY);
\\ }
\\ const small: f32 = 3.25;
\\ const x: f64 = small;
- \\ const y = i32(x);
- \\ const z = f64(y);
+ \\ const y = @floatToInt(i32, x);
+ \\ const z = @intToFloat(f64, y);
\\ _ = c.printf(c"%.2f\n%d\n%.2f\n%.2f\n", x, y, z, f64(-0.4));
\\ return 0;
\\}
@@ -344,13 +344,13 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const Foo = struct {
\\ field1: Bar,
\\
- \\ fn method(a: &const Foo) bool { return true; }
+ \\ fn method(a: *const Foo) bool { return true; }
\\};
\\
\\const Bar = struct {
\\ field2: i32,
\\
- \\ fn method(b: &const Bar) bool { return true; }
+ \\ fn method(b: *const Bar) bool { return true; }
\\};
\\
\\pub fn main() void {
@@ -475,7 +475,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\
);
- tc.setCommandLineArgs([][]const u8 {
+ tc.setCommandLineArgs([][]const u8{
"first arg",
"'a' 'b' \\",
"bare",
@@ -516,7 +516,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\
);
- tc.setCommandLineArgs([][]const u8 {
+ tc.setCommandLineArgs([][]const u8{
"first arg",
"'a' 'b' \\",
"bare",
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index b22816a9a8..56b2c51d74 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -1,25 +1,484 @@
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.CompileErrorContext) void {
- cases.add("assign inline fn to non-comptime var",
+pub fn addCases(cases: *tests.CompileErrorContext) void {
+ cases.add(
+ "@handle() called outside of function definition",
+ \\var handle_undef: promise = undefined;
+ \\var handle_dummy: promise = @handle();
+ \\export fn entry() bool {
+ \\ return handle_undef == handle_dummy;
+ \\}
+ ,
+ ".tmp_source.zig:2:29: error: @handle() called outside of function definition",
+ );
+
+ cases.add(
+ "@handle() in non-async function",
+ \\export fn entry() bool {
+ \\ var handle_undef: promise = undefined;
+ \\ return handle_undef == @handle();
+ \\}
+ ,
+ ".tmp_source.zig:3:28: error: @handle() in non-async function",
+ );
+
+ cases.add(
+ "`_` is not a declarable symbol",
+ \\export fn f1() usize {
+ \\ var _: usize = 2;
+ \\ return _;
+ \\}
+ ,
+ ".tmp_source.zig:2:5: error: `_` is not a declarable symbol",
+ ".tmp_source.zig:3:12: error: use of undeclared identifier '_'",
+ );
+
+ cases.add(
+ "`_` should not be usable inside for",
+ \\export fn returns() void {
+ \\ for ([]void{}) |_, i| {
+ \\ for ([]void{}) |_, j| {
+ \\ return _;
+ \\ }
+ \\ }
+ \\}
+ ,
+ ".tmp_source.zig:4:20: error: use of undeclared identifier '_'",
+ );
+
+ cases.add(
+ "`_` should not be usable inside while",
+ \\export fn returns() void {
+ \\ while (optionalReturn()) |_| {
+ \\ while (optionalReturn()) |_| {
+ \\ return _;
+ \\ }
+ \\ }
+ \\}
+ \\fn optionalReturn() ?u32 {
+ \\ return 1;
+ \\}
+ ,
+ ".tmp_source.zig:4:20: error: use of undeclared identifier '_'",
+ );
+
+ cases.add(
+ "`_` should not be usable inside while else",
+ \\export fn returns() void {
+ \\ while (optionalReturnError()) |_| {
+ \\ while (optionalReturnError()) |_| {
+ \\ return;
+ \\ } else |_| {
+ \\ if (_ == error.optionalReturnError) return;
+ \\ }
+ \\ }
+ \\}
+ \\fn optionalReturnError() !?u32 {
+ \\ return error.optionalReturnError;
+ \\}
+ ,
+ ".tmp_source.zig:6:17: error: use of undeclared identifier '_'",
+ );
+
+ cases.add(
+ "while loop body expression ignored",
+ \\fn returns() usize {
+ \\ return 2;
+ \\}
+ \\export fn f1() void {
+ \\ while (true) returns();
+ \\}
+ \\export fn f2() void {
+ \\ var x: ?i32 = null;
+ \\ while (x) |_| returns();
+ \\}
+ \\export fn f3() void {
+ \\ var x: error!i32 = error.Bad;
+ \\ while (x) |_| returns() else |_| unreachable;
+ \\}
+ ,
+ ".tmp_source.zig:5:25: error: expression value is ignored",
+ ".tmp_source.zig:9:26: error: expression value is ignored",
+ ".tmp_source.zig:13:26: error: expression value is ignored",
+ );
+
+ cases.add(
+ "missing parameter name of generic function",
+ \\fn dump(var) void {}
+ \\export fn entry() void {
+ \\ var a: u8 = 9;
+ \\ dump(a);
+ \\}
+ ,
+ ".tmp_source.zig:1:9: error: missing parameter name",
+ );
+
+ cases.add(
+ "non-inline for loop on a type that requires comptime",
+ \\const Foo = struct {
+ \\ name: []const u8,
+ \\ T: type,
+ \\};
+ \\export fn entry() void {
+ \\ const xx: [2]Foo = undefined;
+ \\ for (xx) |f| {}
+ \\}
+ ,
+ ".tmp_source.zig:7:15: error: variable of type 'Foo' must be const or comptime",
+ );
+
+ cases.add(
+ "generic fn as parameter without comptime keyword",
+ \\fn f(_: fn (var) void) void {}
+ \\fn g(_: var) void {}
+ \\export fn entry() void {
+ \\ f(g);
+ \\}
+ ,
+ ".tmp_source.zig:1:9: error: parameter of type 'fn(var)var' must be declared comptime",
+ );
+
+ cases.add(
+ "optional pointer to void in extern struct",
+ \\comptime {
+ \\ _ = @IntType(false, @maxValue(u32) + 1);
+ \\}
+ ,
+ ".tmp_source.zig:2:40: error: integer value 4294967296 cannot be implicitly casted to type 'u32'",
+ );
+
+ cases.add(
+ "optional pointer to void in extern struct",
+ \\const Foo = extern struct {
+ \\ x: ?*const void,
+ \\};
+ \\const Bar = extern struct {
+ \\ foo: Foo,
+ \\ y: i32,
+ \\};
+ \\export fn entry(bar: *Bar) void {}
+ ,
+ ".tmp_source.zig:2:5: error: extern structs cannot contain fields of type '?*const void'",
+ );
+
+ cases.add(
+ "use of comptime-known undefined function value",
+ \\const Cmd = struct {
+ \\ exec: fn () void,
+ \\};
+ \\export fn entry() void {
+ \\ const command = Cmd{ .exec = undefined };
+ \\ command.exec();
+ \\}
+ ,
+ ".tmp_source.zig:6:12: error: use of undefined value",
+ );
+
+ cases.add(
+ "use of comptime-known undefined function value",
+ \\const Cmd = struct {
+ \\ exec: fn () void,
+ \\};
+ \\export fn entry() void {
+ \\ const command = Cmd{ .exec = undefined };
+ \\ command.exec();
+ \\}
+ ,
+ ".tmp_source.zig:6:12: error: use of undefined value",
+ );
+
+ cases.add(
+ "bad @alignCast at comptime",
+ \\comptime {
+ \\ const ptr = @intToPtr(*i32, 0x1);
+ \\ const aligned = @alignCast(4, ptr);
+ \\}
+ ,
+ ".tmp_source.zig:3:35: error: pointer address 0x1 is not aligned to 4 bytes",
+ );
+
+ cases.add(
+ "@ptrToInt on *void",
+ \\export fn entry() bool {
+ \\ return @ptrToInt(&{}) == @ptrToInt(&{});
+ \\}
+ ,
+ ".tmp_source.zig:2:23: error: pointer to size 0 type has no address",
+ );
+
+ cases.add(
+ "@popCount - non-integer",
+ \\export fn entry(x: f32) u32 {
+ \\ return @popCount(x);
+ \\}
+ ,
+ ".tmp_source.zig:2:22: error: expected integer type, found 'f32'",
+ );
+
+ cases.add(
+ "@popCount - negative comptime_int",
+ \\comptime {
+ \\ _ = @popCount(-1);
+ \\}
+ ,
+ ".tmp_source.zig:2:9: error: @popCount on negative comptime_int value -1",
+ );
+
+ cases.addCase(x: {
+ const tc = cases.create(
+ "wrong same named struct",
+ \\const a = @import("a.zig");
+ \\const b = @import("b.zig");
+ \\
+ \\export fn entry() void {
+ \\ var a1: a.Foo = undefined;
+ \\ bar(&a1);
+ \\}
+ \\
+ \\fn bar(x: *b.Foo) void {}
+ ,
+ ".tmp_source.zig:6:10: error: expected type '*Foo', found '*Foo'",
+ ".tmp_source.zig:6:10: note: pointer type child 'Foo' cannot cast into pointer type child 'Foo'",
+ "a.zig:1:17: note: Foo declared here",
+ "b.zig:1:17: note: Foo declared here",
+ );
+
+ tc.addSourceFile("a.zig",
+ \\pub const Foo = struct {
+ \\ x: i32,
+ \\};
+ );
+
+ tc.addSourceFile("b.zig",
+ \\pub const Foo = struct {
+ \\ z: f64,
+ \\};
+ );
+
+ break :x tc;
+ });
+
+ cases.add(
+ "enum field value references enum",
+ \\pub const Foo = extern enum {
+ \\ A = Foo.B,
+ \\ C = D,
+ \\};
+ \\export fn entry() void {
+ \\ var s: Foo = Foo.E;
+ \\}
+ ,
+ ".tmp_source.zig:1:17: error: 'Foo' depends on itself",
+ );
+
+ cases.add(
+ "@floatToInt comptime safety",
+ \\comptime {
+ \\ _ = @floatToInt(i8, f32(-129.1));
+ \\}
+ \\comptime {
+ \\ _ = @floatToInt(u8, f32(-1.1));
+ \\}
+ \\comptime {
+ \\ _ = @floatToInt(u8, f32(256.1));
+ \\}
+ ,
+ ".tmp_source.zig:2:9: error: integer value '-129' cannot be stored in type 'i8'",
+ ".tmp_source.zig:5:9: error: integer value '-1' cannot be stored in type 'u8'",
+ ".tmp_source.zig:8:9: error: integer value '256' cannot be stored in type 'u8'",
+ );
+
+ cases.add(
+ "use c_void as return type of fn ptr",
+ \\export fn entry() void {
+ \\ const a: fn () c_void = undefined;
+ \\}
+ ,
+ ".tmp_source.zig:2:20: error: return type cannot be opaque",
+ );
+
+ cases.add(
+ "non int passed to @intToFloat",
+ \\export fn entry() void {
+ \\ const x = @intToFloat(f32, 1.1);
+ \\}
+ ,
+ ".tmp_source.zig:2:32: error: expected int type, found 'comptime_float'",
+ );
+
+ cases.add(
+ "use implicit casts to assign null to non-nullable pointer",
+ \\export fn entry() void {
+ \\ var x: i32 = 1234;
+ \\ var p: *i32 = &x;
+ \\ var pp: *?*i32 = &p;
+ \\ pp.* = null;
+ \\ var y = p.*;
+ \\}
+ ,
+ ".tmp_source.zig:4:23: error: expected type '*?*i32', found '**i32'",
+ );
+
+ cases.add(
+ "attempted implicit cast from T to [*]const T",
+ \\export fn entry() void {
+ \\ const x: [*]const bool = true;
+ \\}
+ ,
+ ".tmp_source.zig:2:30: error: expected type '[*]const bool', found 'bool'",
+ );
+
+ cases.add(
+ "dereference unknown length pointer",
+ \\export fn entry(x: [*]i32) i32 {
+ \\ return x.*;
+ \\}
+ ,
+ ".tmp_source.zig:2:13: error: index syntax required for unknown-length pointer type '[*]i32'",
+ );
+
+ cases.add(
+ "field access of unknown length pointer",
+ \\const Foo = extern struct {
+ \\ a: i32,
+ \\};
+ \\
+ \\export fn entry(foo: [*]Foo) void {
+ \\ foo.a += 1;
+ \\}
+ ,
+ ".tmp_source.zig:6:8: error: type '[*]Foo' does not support field access",
+ );
+
+ cases.add(
+ "unknown length pointer to opaque",
+ \\export const T = [*]@OpaqueType();
+ ,
+ ".tmp_source.zig:1:18: error: unknown-length pointer to opaque",
+ );
+
+ cases.add(
+ "error when evaluating return type",
+ \\const Foo = struct {
+ \\ map: i32(i32),
+ \\
+ \\ fn init() Foo {
+ \\ return undefined;
+ \\ }
+ \\};
+ \\export fn entry() void {
+ \\ var rule_set = try Foo.init();
+ \\}
+ ,
+ ".tmp_source.zig:2:13: error: expected type 'i32', found 'type'",
+ );
+
+ cases.add(
+ "slicing single-item pointer",
+ \\export fn entry(ptr: *i32) void {
+ \\ const slice = ptr[0..2];
+ \\}
+ ,
+ ".tmp_source.zig:2:22: error: slice of single-item pointer",
+ );
+
+ cases.add(
+ "indexing single-item pointer",
+ \\export fn entry(ptr: *i32) i32 {
+ \\ return ptr[1];
+ \\}
+ ,
+ ".tmp_source.zig:2:15: error: index of single-item pointer",
+ );
+
+ cases.add(
+ "nested error set mismatch",
+ \\const NextError = error{NextError};
+ \\const OtherError = error{OutOfMemory};
+ \\
+ \\export fn entry() void {
+ \\ const a: ?NextError!i32 = foo();
+ \\}
+ \\
+ \\fn foo() ?OtherError!i32 {
+ \\ return null;
+ \\}
+ ,
+ ".tmp_source.zig:5:34: error: expected type '?NextError!i32', found '?OtherError!i32'",
+ ".tmp_source.zig:5:34: note: optional type child 'OtherError!i32' cannot cast into optional type child 'NextError!i32'",
+ ".tmp_source.zig:5:34: note: error set 'OtherError' cannot cast into error set 'NextError'",
+ ".tmp_source.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set",
+ );
+
+ cases.add(
+ "invalid deref on switch target",
+ \\comptime {
+ \\ var tile = Tile.Empty;
+ \\ switch (tile.*) {
+ \\ Tile.Empty => {},
+ \\ Tile.Filled => {},
+ \\ }
+ \\}
+ \\const Tile = enum {
+ \\ Empty,
+ \\ Filled,
+ \\};
+ ,
+ ".tmp_source.zig:3:17: error: invalid deref on switch target",
+ );
+
+ cases.add(
+ "invalid field access in comptime",
+ \\comptime { var x = doesnt_exist.whatever; }
+ ,
+ ".tmp_source.zig:1:20: error: use of undeclared identifier 'doesnt_exist'",
+ );
+
+ cases.add(
+ "suspend inside suspend block",
+ \\const std = @import("std",);
+ \\
+ \\export fn entry() void {
+ \\ var buf: [500]u8 = undefined;
+ \\ var a = &std.heap.FixedBufferAllocator.init(buf[0..]).allocator;
+ \\ const p = (async<a> foo()) catch unreachable;
+ \\ cancel p;
+ \\}
+ \\
+ \\async fn foo() void {
+ \\ suspend {
+ \\ suspend {
+ \\ }
+ \\ }
+ \\}
+ ,
+ ".tmp_source.zig:12:9: error: cannot suspend inside suspend block",
+ ".tmp_source.zig:11:5: note: other suspend block here",
+ );
+
+ cases.add(
+ "assign inline fn to non-comptime var",
\\export fn entry() void {
\\ var a = b;
\\}
\\inline fn b() void { }
,
".tmp_source.zig:2:5: error: functions marked inline must be stored in const or comptime var",
- ".tmp_source.zig:4:8: note: declared here");
+ ".tmp_source.zig:4:8: note: declared here",
+ );
- cases.add("wrong type passed to @panic",
+ cases.add(
+ "wrong type passed to @panic",
\\export fn entry() void {
\\ var e = error.Foo;
\\ @panic(e);
\\}
,
- ".tmp_source.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'");
-
+ ".tmp_source.zig:3:12: error: expected type '[]const u8', found 'error{Foo}'",
+ );
- cases.add("@tagName used on union with no associated enum tag",
+ cases.add(
+ "@tagName used on union with no associated enum tag",
\\const FloatInt = extern union {
\\ Float: f32,
\\ Int: i32,
@@ -30,10 +489,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:7:19: error: union has no associated enum",
- ".tmp_source.zig:1:18: note: declared here");
+ ".tmp_source.zig:1:18: note: declared here",
+ );
- cases.add("returning error from void async function",
- \\const std = @import("std");
+ cases.add(
+ "returning error from void async function",
+ \\const std = @import("std",);
\\export fn entry() void {
\\ const p = async<std.debug.global_allocator> amain() catch unreachable;
\\}
@@ -41,32 +502,40 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ return error.ShouldBeCompileError;
\\}
,
- ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'");
+ ".tmp_source.zig:6:17: error: expected type 'void', found 'error{ShouldBeCompileError}'",
+ );
- cases.add("var not allowed in structs",
+ cases.add(
+ "var not allowed in structs",
\\export fn entry() void {
\\ var s = (struct{v: var}){.v=i32(10)};
\\}
,
- ".tmp_source.zig:2:23: error: invalid token: 'var'");
+ ".tmp_source.zig:2:23: error: invalid token: 'var'",
+ );
- cases.add("@ptrCast discards const qualifier",
+ cases.add(
+ "@ptrCast discards const qualifier",
\\export fn entry() void {
\\ const x: i32 = 1234;
- \\ const y = @ptrCast(&i32, &x);
+ \\ const y = @ptrCast(*i32, &x);
\\}
,
- ".tmp_source.zig:3:15: error: cast discards const qualifier");
+ ".tmp_source.zig:3:15: error: cast discards const qualifier",
+ );
- cases.add("comptime slice of undefined pointer non-zero len",
+ cases.add(
+ "comptime slice of undefined pointer non-zero len",
\\export fn entry() void {
- \\ const slice = (&i32)(undefined)[0..1];
+ \\ const slice = ([*]i32)(undefined)[0..1];
\\}
,
- ".tmp_source.zig:2:36: error: non-zero length slice of undefined pointer");
+ ".tmp_source.zig:2:38: error: non-zero length slice of undefined pointer",
+ );
- cases.add("type checking function pointers",
- \\fn a(b: fn (&const u8) void) void {
+ cases.add(
+ "type checking function pointers",
+ \\fn a(b: fn (*const u8) void) void {
\\ b('a');
\\}
\\fn c(d: u8) void {
@@ -76,9 +545,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ a(c);
\\}
,
- ".tmp_source.zig:8:7: error: expected type 'fn(&const u8) void', found 'fn(u8) void'");
+ ".tmp_source.zig:8:7: error: expected type 'fn(*const u8) void', found 'fn(u8) void'",
+ );
- cases.add("no else prong on switch on global error set",
+ cases.add(
+ "no else prong on switch on global error set",
\\export fn entry() void {
\\ foo(error.A);
\\}
@@ -88,18 +559,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:5:5: error: else prong required when switching on type 'error'");
+ ".tmp_source.zig:5:5: error: else prong required when switching on type 'error'",
+ );
- cases.add("inferred error set with no returned error",
+ cases.add(
+ "inferred error set with no returned error",
\\export fn entry() void {
\\ foo() catch unreachable;
\\}
\\fn foo() !void {
\\}
,
- ".tmp_source.zig:4:11: error: function with inferred error set must return at least one possible error");
+ ".tmp_source.zig:4:11: error: function with inferred error set must return at least one possible error",
+ );
- cases.add("error not handled in switch",
+ cases.add(
+ "error not handled in switch",
\\export fn entry() void {
\\ foo(452) catch |err| switch (err) {
\\ error.Foo => {},
@@ -115,9 +590,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:2:26: error: error.Baz not handled in switch",
- ".tmp_source.zig:2:26: error: error.Bar not handled in switch");
+ ".tmp_source.zig:2:26: error: error.Bar not handled in switch",
+ );
- cases.add("duplicate error in switch",
+ cases.add(
+ "duplicate error in switch",
\\export fn entry() void {
\\ foo(452) catch |err| switch (err) {
\\ error.Foo => {},
@@ -135,9 +612,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:5:14: error: duplicate switch value: '@typeOf(foo).ReturnType.ErrorSet.Foo'",
- ".tmp_source.zig:3:14: note: other value is here");
+ ".tmp_source.zig:3:14: note: other value is here",
+ );
+
+ cases.add("invalid cast from integral type to enum",
+ \\const E = enum(usize) { One, Two };
+ \\
+ \\export fn entry() void {
+ \\ foo(1);
+ \\}
+ \\
+ \\fn foo(x: usize) void {
+ \\ switch (x) {
+ \\ E.One => {},
+ \\ }
+ \\}
+ , ".tmp_source.zig:9:10: error: expected type 'usize', found 'E'");
- cases.add("range operator in switch used on error set",
+ cases.add(
+ "range operator in switch used on error set",
\\export fn entry() void {
\\ try foo(452) catch |err| switch (err) {
\\ error.A ... error.B => {},
@@ -152,31 +645,39 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:3:17: error: operator not allowed for errors");
+ ".tmp_source.zig:3:17: error: operator not allowed for errors",
+ );
- cases.add("inferring error set of function pointer",
+ cases.add(
+ "inferring error set of function pointer",
\\comptime {
\\ const z: ?fn()!void = null;
\\}
,
- ".tmp_source.zig:2:15: error: inferring error set of return type valid only for function definitions");
+ ".tmp_source.zig:2:15: error: inferring error set of return type valid only for function definitions",
+ );
- cases.add("access non-existent member of error set",
+ cases.add(
+ "access non-existent member of error set",
\\const Foo = error{A};
\\comptime {
\\ const z = Foo.Bar;
\\}
,
- ".tmp_source.zig:3:18: error: no error named 'Bar' in 'Foo'");
+ ".tmp_source.zig:3:18: error: no error named 'Bar' in 'Foo'",
+ );
- cases.add("error union operator with non error set LHS",
+ cases.add(
+ "error union operator with non error set LHS",
\\comptime {
\\ const z = i32!i32;
\\}
,
- ".tmp_source.zig:2:15: error: expected error set type, found type 'i32'");
+ ".tmp_source.zig:2:15: error: expected error set type, found type 'i32'",
+ );
- cases.add("error equality but sets have no common members",
+ cases.add(
+ "error equality but sets have no common members",
\\const Set1 = error{A, C};
\\const Set2 = error{B, D};
\\export fn entry() void {
@@ -188,26 +689,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors");
+ ".tmp_source.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors",
+ );
- cases.add("only equality binary operator allowed for error sets",
+ cases.add(
+ "only equality binary operator allowed for error sets",
\\comptime {
\\ const z = error.A > error.B;
\\}
,
- ".tmp_source.zig:2:23: error: operator not allowed for errors");
+ ".tmp_source.zig:2:23: error: operator not allowed for errors",
+ );
- cases.add("explicit error set cast known at comptime violates error sets",
+ cases.add(
+ "explicit error set cast known at comptime violates error sets",
\\const Set1 = error {A, B};
\\const Set2 = error {A, C};
\\comptime {
\\ var x = Set1.B;
- \\ var y = Set2(x);
+ \\ var y = @errSetCast(Set2, x);
\\}
,
- ".tmp_source.zig:5:17: error: error.B not a member of error set 'Set2'");
+ ".tmp_source.zig:5:13: error: error.B not a member of error set 'Set2'",
+ );
- cases.add("cast error union of global error set to error union of smaller error set",
+ cases.add(
+ "cast error union of global error set to error union of smaller error set",
\\const SmallErrorSet = error{A};
\\export fn entry() void {
\\ var x: SmallErrorSet!i32 = foo();
@@ -216,10 +723,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ return error.B;
\\}
,
- ".tmp_source.zig:3:35: error: expected 'SmallErrorSet!i32', found 'error!i32'",
- ".tmp_source.zig:3:35: note: unable to cast global error set into smaller set");
+ ".tmp_source.zig:3:35: error: expected type 'SmallErrorSet!i32', found 'error!i32'",
+ ".tmp_source.zig:3:35: note: error set 'error' cannot cast into error set 'SmallErrorSet'",
+ ".tmp_source.zig:3:35: note: cannot cast global error set into smaller set",
+ );
- cases.add("cast global error set to error set",
+ cases.add(
+ "cast global error set to error set",
\\const SmallErrorSet = error{A};
\\export fn entry() void {
\\ var x: SmallErrorSet = foo();
@@ -228,10 +738,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ return error.B;
\\}
,
- ".tmp_source.zig:3:31: error: expected 'SmallErrorSet', found 'error'",
- ".tmp_source.zig:3:31: note: unable to cast global error set into smaller set");
+ ".tmp_source.zig:3:31: error: expected type 'SmallErrorSet', found 'error'",
+ ".tmp_source.zig:3:31: note: cannot cast global error set into smaller set",
+ );
- cases.add("recursive inferred error set",
+ cases.add(
+ "recursive inferred error set",
\\export fn entry() void {
\\ foo() catch unreachable;
\\}
@@ -239,9 +751,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ try foo();
\\}
,
- ".tmp_source.zig:5:5: error: cannot resolve inferred error set '@typeOf(foo).ReturnType.ErrorSet': function 'foo' not fully analyzed yet");
+ ".tmp_source.zig:5:5: error: cannot resolve inferred error set '@typeOf(foo).ReturnType.ErrorSet': function 'foo' not fully analyzed yet",
+ );
- cases.add("implicit cast of error set not a subset",
+ cases.add(
+ "implicit cast of error set not a subset",
\\const Set1 = error{A, B};
\\const Set2 = error{A, C};
\\export fn entry() void {
@@ -251,36 +765,53 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x: Set2 = set1;
\\}
,
- ".tmp_source.zig:7:19: error: expected 'Set2', found 'Set1'",
- ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set");
+ ".tmp_source.zig:7:19: error: expected type 'Set2', found 'Set1'",
+ ".tmp_source.zig:1:23: note: 'error.B' not a member of destination error set",
+ );
- cases.add("int to err global invalid number",
- \\const Set1 = error{A, B};
+ cases.add(
+ "int to err global invalid number",
+ \\const Set1 = error{
+ \\ A,
+ \\ B,
+ \\};
\\comptime {
- \\ var x: usize = 3;
- \\ var y = error(x);
+ \\ var x: u16 = 3;
+ \\ var y = @intToError(x);
\\}
,
- ".tmp_source.zig:4:18: error: integer value 3 represents no error");
+ ".tmp_source.zig:7:13: error: integer value 3 represents no error",
+ );
- cases.add("int to err non global invalid number",
- \\const Set1 = error{A, B};
- \\const Set2 = error{A, C};
+ cases.add(
+ "int to err non global invalid number",
+ \\const Set1 = error{
+ \\ A,
+ \\ B,
+ \\};
+ \\const Set2 = error{
+ \\ A,
+ \\ C,
+ \\};
\\comptime {
- \\ var x = usize(Set1.B);
- \\ var y = Set2(x);
+ \\ var x = @errorToInt(Set1.B);
+ \\ var y = @errSetCast(Set2, @intToError(x));
\\}
,
- ".tmp_source.zig:5:17: error: integer value 2 represents no error in 'Set2'");
+ ".tmp_source.zig:11:13: error: error.B not a member of error set 'Set2'",
+ );
- cases.add("@memberCount of error",
+ cases.add(
+ "@memberCount of error",
\\comptime {
\\ _ = @memberCount(error);
\\}
,
- ".tmp_source.zig:2:9: error: global error set member count not available at comptime");
+ ".tmp_source.zig:2:9: error: global error set member count not available at comptime",
+ );
- cases.add("duplicate error value in error set",
+ cases.add(
+ "duplicate error value in error set",
\\const Foo = error {
\\ Bar,
\\ Bar,
@@ -290,22 +821,30 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:3:5: error: duplicate error: 'Bar'",
- ".tmp_source.zig:2:5: note: other error here");
+ ".tmp_source.zig:2:5: note: other error here",
+ );
- cases.add("cast negative integer literal to usize",
+ cases.add(
+ "cast negative integer literal to usize",
\\export fn entry() void {
\\ const x = usize(-10);
\\}
- , ".tmp_source.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'");
+ ,
+ ".tmp_source.zig:2:21: error: cannot cast negative value -10 to unsigned integer type 'usize'",
+ );
- cases.add("use invalid number literal as array index",
+ cases.add(
+ "use invalid number literal as array index",
\\var v = 25;
\\export fn entry() void {
\\ var arr: [v]u8 = undefined;
\\}
- , ".tmp_source.zig:1:1: error: unable to infer variable type");
+ ,
+ ".tmp_source.zig:1:1: error: unable to infer variable type",
+ );
- cases.add("duplicate struct field",
+ cases.add(
+ "duplicate struct field",
\\const Foo = struct {
\\ Bar: i32,
\\ Bar: usize,
@@ -315,9 +854,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:3:5: error: duplicate struct field: 'Bar'",
- ".tmp_source.zig:2:5: note: other field here");
+ ".tmp_source.zig:2:5: note: other field here",
+ );
- cases.add("duplicate union field",
+ cases.add(
+ "duplicate union field",
\\const Foo = union {
\\ Bar: i32,
\\ Bar: usize,
@@ -327,9 +868,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:3:5: error: duplicate union field: 'Bar'",
- ".tmp_source.zig:2:5: note: other field here");
+ ".tmp_source.zig:2:5: note: other field here",
+ );
- cases.add("duplicate enum field",
+ cases.add(
+ "duplicate enum field",
\\const Foo = enum {
\\ Bar,
\\ Bar,
@@ -340,77 +883,108 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:3:5: error: duplicate enum field: 'Bar'",
- ".tmp_source.zig:2:5: note: other field here");
+ ".tmp_source.zig:2:5: note: other field here",
+ );
- cases.add("calling function with naked calling convention",
+ cases.add(
+ "calling function with naked calling convention",
\\export fn entry() void {
\\ foo();
\\}
\\nakedcc fn foo() void { }
,
".tmp_source.zig:2:5: error: unable to call function with naked calling convention",
- ".tmp_source.zig:4:9: note: declared here");
+ ".tmp_source.zig:4:9: note: declared here",
+ );
- cases.add("function with invalid return type",
+ cases.add(
+ "function with invalid return type",
\\export fn foo() boid {}
- , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");
+ ,
+ ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'",
+ );
- cases.add("function with non-extern non-packed enum parameter",
+ cases.add(
+ "function with non-extern non-packed enum parameter",
\\const Foo = enum { A, B, C };
\\export fn entry(foo: Foo) void { }
- , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
+ ,
+ ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
+ );
- cases.add("function with non-extern non-packed struct parameter",
+ cases.add(
+ "function with non-extern non-packed struct parameter",
\\const Foo = struct {
\\ A: i32,
\\ B: f32,
\\ C: bool,
\\};
\\export fn entry(foo: Foo) void { }
- , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
+ ,
+ ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
+ );
- cases.add("function with non-extern non-packed union parameter",
+ cases.add(
+ "function with non-extern non-packed union parameter",
\\const Foo = union {
\\ A: i32,
\\ B: f32,
\\ C: bool,
\\};
\\export fn entry(foo: Foo) void { }
- , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
+ ,
+ ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'",
+ );
- cases.add("switch on enum with 1 field with no prongs",
+ cases.add(
+ "switch on enum with 1 field with no prongs",
\\const Foo = enum { M };
\\
\\export fn entry() void {
\\ var f = Foo.M;
\\ switch (f) {}
\\}
- , ".tmp_source.zig:5:5: error: enumeration value 'Foo.M' not handled in switch");
+ ,
+ ".tmp_source.zig:5:5: error: enumeration value 'Foo.M' not handled in switch",
+ );
- cases.add("shift by negative comptime integer",
+ cases.add(
+ "shift by negative comptime integer",
\\comptime {
\\ var a = 1 >> -1;
\\}
- , ".tmp_source.zig:2:18: error: shift by negative value -1");
+ ,
+ ".tmp_source.zig:2:18: error: shift by negative value -1",
+ );
- cases.add("@panic called at compile time",
+ cases.add(
+ "@panic called at compile time",
\\export fn entry() void {
\\ comptime {
- \\ @panic("aoeu");
+ \\ @panic("aoeu",);
\\ }
\\}
- , ".tmp_source.zig:3:9: error: encountered @panic at compile-time");
+ ,
+ ".tmp_source.zig:3:9: error: encountered @panic at compile-time",
+ );
- cases.add("wrong return type for main",
+ cases.add(
+ "wrong return type for main",
\\pub fn main() f32 { }
- , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
+ ,
+ "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
+ );
- cases.add("double ?? on main return value",
+ cases.add(
+ "double ?? on main return value",
\\pub fn main() ??void {
\\}
- , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'");
+ ,
+ "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'",
+ );
- cases.add("bad identifier in function with struct defined inside function which references local const",
+ cases.add(
+ "bad identifier in function with struct defined inside function which references local const",
\\export fn entry() void {
\\ const BlockKind = u32;
\\
@@ -420,9 +994,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\ bogus;
\\}
- , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'");
+ ,
+ ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'",
+ );
- cases.add("labeled break not found",
+ cases.add(
+ "labeled break not found",
\\export fn entry() void {
\\ blah: while (true) {
\\ while (true) {
@@ -430,9 +1007,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\ }
\\}
- , ".tmp_source.zig:4:13: error: label not found: 'outer'");
+ ,
+ ".tmp_source.zig:4:13: error: label not found: 'outer'",
+ );
- cases.add("labeled continue not found",
+ cases.add(
+ "labeled continue not found",
\\export fn entry() void {
\\ var i: usize = 0;
\\ blah: while (i < 10) : (i += 1) {
@@ -441,400 +1021,554 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\ }
\\}
- , ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'");
+ ,
+ ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'",
+ );
- cases.add("attempt to use 0 bit type in extern fn",
- \\extern fn foo(ptr: extern fn(&void) void) void;
+ cases.add(
+ "attempt to use 0 bit type in extern fn",
+ \\extern fn foo(ptr: extern fn(*void) void) void;
\\
\\export fn entry() void {
\\ foo(bar);
\\}
\\
- \\extern fn bar(x: &void) void { }
- , ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'");
+ \\extern fn bar(x: *void) void { }
+ ,
+ ".tmp_source.zig:7:18: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'ccc'",
+ );
- cases.add("implicit semicolon - block statement",
+ cases.add(
+ "implicit semicolon - block statement",
\\export fn entry() void {
\\ {}
\\ var good = {};
\\ ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - block expr",
+ cases.add(
+ "implicit semicolon - block expr",
\\export fn entry() void {
\\ _ = {};
\\ var good = {};
\\ _ = {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - comptime statement",
+ cases.add(
+ "implicit semicolon - comptime statement",
\\export fn entry() void {
\\ comptime {}
\\ var good = {};
\\ comptime ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - comptime expression",
+ cases.add(
+ "implicit semicolon - comptime expression",
\\export fn entry() void {
\\ _ = comptime {};
\\ var good = {};
\\ _ = comptime {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - defer",
+ cases.add(
+ "implicit semicolon - defer",
\\export fn entry() void {
\\ defer {}
\\ var good = {};
\\ defer ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if statement",
+ cases.add(
+ "implicit semicolon - if statement",
\\export fn entry() void {
\\ if(true) {}
\\ var good = {};
\\ if(true) ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if expression",
+ cases.add(
+ "implicit semicolon - if expression",
\\export fn entry() void {
\\ _ = if(true) {};
\\ var good = {};
\\ _ = if(true) {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else statement",
+ cases.add(
+ "implicit semicolon - if-else statement",
\\export fn entry() void {
\\ if(true) {} else {}
\\ var good = {};
\\ if(true) ({}) else ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else expression",
+ cases.add(
+ "implicit semicolon - if-else expression",
\\export fn entry() void {
\\ _ = if(true) {} else {};
\\ var good = {};
\\ _ = if(true) {} else {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else-if statement",
+ cases.add(
+ "implicit semicolon - if-else-if statement",
\\export fn entry() void {
\\ if(true) {} else if(true) {}
\\ var good = {};
\\ if(true) ({}) else if(true) ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else-if expression",
+ cases.add(
+ "implicit semicolon - if-else-if expression",
\\export fn entry() void {
\\ _ = if(true) {} else if(true) {};
\\ var good = {};
\\ _ = if(true) {} else if(true) {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else-if-else statement",
+ cases.add(
+ "implicit semicolon - if-else-if-else statement",
\\export fn entry() void {
\\ if(true) {} else if(true) {} else {}
\\ var good = {};
\\ if(true) ({}) else if(true) ({}) else ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - if-else-if-else expression",
+ cases.add(
+ "implicit semicolon - if-else-if-else expression",
\\export fn entry() void {
\\ _ = if(true) {} else if(true) {} else {};
\\ var good = {};
\\ _ = if(true) {} else if(true) {} else {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - test statement",
+ cases.add(
+ "implicit semicolon - test statement",
\\export fn entry() void {
\\ if (foo()) |_| {}
\\ var good = {};
\\ if (foo()) |_| ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - test expression",
+ cases.add(
+ "implicit semicolon - test expression",
\\export fn entry() void {
\\ _ = if (foo()) |_| {};
\\ var good = {};
\\ _ = if (foo()) |_| {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - while statement",
+ cases.add(
+ "implicit semicolon - while statement",
\\export fn entry() void {
\\ while(true) {}
\\ var good = {};
\\ while(true) ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - while expression",
+ cases.add(
+ "implicit semicolon - while expression",
\\export fn entry() void {
\\ _ = while(true) {};
\\ var good = {};
\\ _ = while(true) {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - while-continue statement",
+ cases.add(
+ "implicit semicolon - while-continue statement",
\\export fn entry() void {
\\ while(true):({}) {}
\\ var good = {};
\\ while(true):({}) ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - while-continue expression",
+ cases.add(
+ "implicit semicolon - while-continue expression",
\\export fn entry() void {
\\ _ = while(true):({}) {};
\\ var good = {};
\\ _ = while(true):({}) {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - for statement",
+ cases.add(
+ "implicit semicolon - for statement",
\\export fn entry() void {
\\ for(foo()) {}
\\ var good = {};
\\ for(foo()) ({})
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("implicit semicolon - for expression",
+ cases.add(
+ "implicit semicolon - for expression",
\\export fn entry() void {
\\ _ = for(foo()) {};
\\ var good = {};
\\ _ = for(foo()) {}
\\ var bad = {};
\\}
- , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
+ ,
+ ".tmp_source.zig:5:5: error: expected token ';', found 'var'",
+ );
- cases.add("multiple function definitions",
+ cases.add(
+ "multiple function definitions",
\\fn a() void {}
\\fn a() void {}
\\export fn entry() void { a(); }
- , ".tmp_source.zig:2:1: error: redefinition of 'a'");
+ ,
+ ".tmp_source.zig:2:1: error: redefinition of 'a'",
+ );
- cases.add("unreachable with return",
+ cases.add(
+ "unreachable with return",
\\fn a() noreturn {return;}
\\export fn entry() void { a(); }
- , ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'");
+ ,
+ ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'",
+ );
- cases.add("control reaches end of non-void function",
+ cases.add(
+ "control reaches end of non-void function",
\\fn a() i32 {}
\\export fn entry() void { _ = a(); }
- , ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'");
+ ,
+ ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'",
+ );
- cases.add("undefined function call",
+ cases.add(
+ "undefined function call",
\\export fn a() void {
\\ b();
\\}
- , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
+ ,
+ ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
+ );
- cases.add("wrong number of arguments",
+ cases.add(
+ "wrong number of arguments",
\\export fn a() void {
\\ b(1);
\\}
\\fn b(a: i32, b: i32, c: i32) void { }
- , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
+ ,
+ ".tmp_source.zig:2:6: error: expected 3 arguments, found 1",
+ );
- cases.add("invalid type",
+ cases.add(
+ "invalid type",
\\fn a() bogus {}
\\export fn entry() void { _ = a(); }
- , ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'");
+ ,
+ ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'",
+ );
- cases.add("pointer to noreturn",
- \\fn a() &noreturn {}
+ cases.add(
+ "pointer to noreturn",
+ \\fn a() *noreturn {}
\\export fn entry() void { _ = a(); }
- , ".tmp_source.zig:1:9: error: pointer to noreturn not allowed");
+ ,
+ ".tmp_source.zig:1:8: error: pointer to noreturn not allowed",
+ );
- cases.add("unreachable code",
+ cases.add(
+ "unreachable code",
\\export fn a() void {
\\ return;
\\ b();
\\}
\\
\\fn b() void {}
- , ".tmp_source.zig:3:5: error: unreachable code");
+ ,
+ ".tmp_source.zig:3:5: error: unreachable code",
+ );
- cases.add("bad import",
- \\const bogus = @import("bogus-does-not-exist.zig");
+ cases.add(
+ "bad import",
+ \\const bogus = @import("bogus-does-not-exist.zig",);
\\export fn entry() void { bogus.bogo(); }
- , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
+ ,
+ ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'",
+ );
- cases.add("undeclared identifier",
+ cases.add(
+ "undeclared identifier",
\\export fn a() void {
\\ return
\\ b +
\\ c;
\\}
,
- ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'",
- ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");
+ ".tmp_source.zig:3:5: error: use of undeclared identifier 'b'",
+ ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'",
+ );
- cases.add("parameter redeclaration",
+ cases.add(
+ "parameter redeclaration",
\\fn f(a : i32, a : i32) void {
\\}
\\export fn entry() void { f(1, 2); }
- , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
+ ,
+ ".tmp_source.zig:1:15: error: redeclaration of variable 'a'",
+ );
- cases.add("local variable redeclaration",
+ cases.add(
+ "local variable redeclaration",
\\export fn f() void {
\\ const a : i32 = 0;
\\ const a = 0;
\\}
- , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
+ ,
+ ".tmp_source.zig:3:5: error: redeclaration of variable 'a'",
+ );
- cases.add("local variable redeclares parameter",
+ cases.add(
+ "local variable redeclares parameter",
\\fn f(a : i32) void {
\\ const a = 0;
\\}
\\export fn entry() void { f(1); }
- , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
+ ,
+ ".tmp_source.zig:2:5: error: redeclaration of variable 'a'",
+ );
- cases.add("variable has wrong type",
+ cases.add(
+ "variable has wrong type",
\\export fn f() i32 {
\\ const a = c"a";
\\ return a;
\\}
- , ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'");
+ ,
+ ".tmp_source.zig:3:12: error: expected type 'i32', found '[*]const u8'",
+ );
- cases.add("if condition is bool, not int",
+ cases.add(
+ "if condition is bool, not int",
\\export fn f() void {
\\ if (0) {}
\\}
- , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
+ ,
+ ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'",
+ );
- cases.add("assign unreachable",
+ cases.add(
+ "assign unreachable",
\\export fn f() void {
\\ const a = return;
\\}
- , ".tmp_source.zig:2:5: error: unreachable code");
+ ,
+ ".tmp_source.zig:2:5: error: unreachable code",
+ );
- cases.add("unreachable variable",
+ cases.add(
+ "unreachable variable",
\\export fn f() void {
\\ const a: noreturn = {};
\\}
- , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
+ ,
+ ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed",
+ );
- cases.add("unreachable parameter",
+ cases.add(
+ "unreachable parameter",
\\fn f(a: noreturn) void {}
\\export fn entry() void { f(); }
- , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
+ ,
+ ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed",
+ );
- cases.add("bad assignment target",
+ cases.add(
+ "bad assignment target",
\\export fn f() void {
\\ 3 = 3;
\\}
- , ".tmp_source.zig:2:7: error: cannot assign to constant");
+ ,
+ ".tmp_source.zig:2:7: error: cannot assign to constant",
+ );
- cases.add("assign to constant variable",
+ cases.add(
+ "assign to constant variable",
\\export fn f() void {
\\ const a = 3;
\\ a = 4;
\\}
- , ".tmp_source.zig:3:7: error: cannot assign to constant");
+ ,
+ ".tmp_source.zig:3:7: error: cannot assign to constant",
+ );
- cases.add("use of undeclared identifier",
+ cases.add(
+ "use of undeclared identifier",
\\export fn f() void {
\\ b = 3;
\\}
- , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
+ ,
+ ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'",
+ );
- cases.add("const is a statement, not an expression",
+ cases.add(
+ "const is a statement, not an expression",
\\export fn f() void {
\\ (const a = 0);
\\}
- , ".tmp_source.zig:2:6: error: invalid token: 'const'");
+ ,
+ ".tmp_source.zig:2:6: error: invalid token: 'const'",
+ );
- cases.add("array access of undeclared identifier",
+ cases.add(
+ "array access of undeclared identifier",
\\export fn f() void {
\\ i[i] = i[i];
\\}
- , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
- ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
+ ,
+ ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
+ ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'",
+ );
- cases.add("array access of non array",
+ cases.add(
+ "array access of non array",
\\export fn f() void {
\\ var bad : bool = undefined;
\\ bad[bad] = bad[bad];
\\}
- , ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
- ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
+ ,
+ ".tmp_source.zig:3:8: error: array access of non-array type 'bool'",
+ ".tmp_source.zig:3:19: error: array access of non-array type 'bool'",
+ );
- cases.add("array access with non integer index",
+ cases.add(
+ "array access with non integer index",
\\export fn f() void {
\\ var array = "aoeu";
\\ var bad = false;
\\ array[bad] = array[bad];
\\}
- , ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
- ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'");
+ ,
+ ".tmp_source.zig:4:11: error: expected type 'usize', found 'bool'",
+ ".tmp_source.zig:4:24: error: expected type 'usize', found 'bool'",
+ );
- cases.add("write to const global variable",
+ cases.add(
+ "write to const global variable",
\\const x : i32 = 99;
\\fn f() void {
\\ x = 1;
\\}
\\export fn entry() void { f(); }
- , ".tmp_source.zig:3:7: error: cannot assign to constant");
-
+ ,
+ ".tmp_source.zig:3:7: error: cannot assign to constant",
+ );
- cases.add("missing else clause",
+ cases.add(
+ "missing else clause",
\\fn f(b: bool) void {
\\ const x : i32 = if (b) h: { break :h 1; };
\\ const y = if (b) h: { break :h i32(1); };
\\}
\\export fn entry() void { f(true); }
- , ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
- ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
+ ,
+ ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
+ ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'",
+ );
- cases.add("direct struct loop",
+ cases.add(
+ "direct struct loop",
\\const A = struct { a : A, };
\\export fn entry() usize { return @sizeOf(A); }
- , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
+ ,
+ ".tmp_source.zig:1:11: error: struct 'A' contains itself",
+ );
- cases.add("indirect struct loop",
+ cases.add(
+ "indirect struct loop",
\\const A = struct { b : B, };
\\const B = struct { c : C, };
\\const C = struct { a : A, };
\\export fn entry() usize { return @sizeOf(A); }
- , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
+ ,
+ ".tmp_source.zig:1:11: error: struct 'A' contains itself",
+ );
- cases.add("invalid struct field",
+ cases.add(
+ "invalid struct field",
\\const A = struct { x : i32, };
\\export fn f() void {
\\ var a : A = undefined;
@@ -842,27 +1576,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ const y = a.bar;
\\}
,
- ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",
- ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'");
+ ".tmp_source.zig:4:6: error: no member named 'foo' in struct 'A'",
+ ".tmp_source.zig:5:16: error: no member named 'bar' in struct 'A'",
+ );
- cases.add("redefinition of struct",
+ cases.add(
+ "redefinition of struct",
\\const A = struct { x : i32, };
\\const A = struct { y : i32, };
- , ".tmp_source.zig:2:1: error: redefinition of 'A'");
+ ,
+ ".tmp_source.zig:2:1: error: redefinition of 'A'",
+ );
- cases.add("redefinition of enums",
+ cases.add(
+ "redefinition of enums",
\\const A = enum {};
\\const A = enum {};
- , ".tmp_source.zig:2:1: error: redefinition of 'A'");
+ ,
+ ".tmp_source.zig:2:1: error: redefinition of 'A'",
+ );
- cases.add("redefinition of global variables",
+ cases.add(
+ "redefinition of global variables",
\\var a : i32 = 1;
\\var a : i32 = 2;
,
- ".tmp_source.zig:2:1: error: redefinition of 'a'",
- ".tmp_source.zig:1:1: note: previous definition is here");
+ ".tmp_source.zig:2:1: error: redefinition of 'a'",
+ ".tmp_source.zig:1:1: note: previous definition is here",
+ );
- cases.add("duplicate field in struct value expression",
+ cases.add(
+ "duplicate field in struct value expression",
\\const A = struct {
\\ x : i32,
\\ y : i32,
@@ -876,9 +1620,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ .z = 4,
\\ };
\\}
- , ".tmp_source.zig:11:9: error: duplicate field");
+ ,
+ ".tmp_source.zig:11:9: error: duplicate field",
+ );
- cases.add("missing field in struct value expression",
+ cases.add(
+ "missing field in struct value expression",
\\const A = struct {
\\ x : i32,
\\ y : i32,
@@ -892,9 +1639,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ .y = 2,
\\ };
\\}
- , ".tmp_source.zig:9:17: error: missing field: 'x'");
+ ,
+ ".tmp_source.zig:9:17: error: missing field: 'x'",
+ );
- cases.add("invalid field in struct value expression",
+ cases.add(
+ "invalid field in struct value expression",
\\const A = struct {
\\ x : i32,
\\ y : i32,
@@ -907,66 +1657,95 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ .foo = 42,
\\ };
\\}
- , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");
+ ,
+ ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'",
+ );
- cases.add("invalid break expression",
+ cases.add(
+ "invalid break expression",
\\export fn f() void {
\\ break;
\\}
- , ".tmp_source.zig:2:5: error: break expression outside loop");
+ ,
+ ".tmp_source.zig:2:5: error: break expression outside loop",
+ );
- cases.add("invalid continue expression",
+ cases.add(
+ "invalid continue expression",
\\export fn f() void {
\\ continue;
\\}
- , ".tmp_source.zig:2:5: error: continue expression outside loop");
+ ,
+ ".tmp_source.zig:2:5: error: continue expression outside loop",
+ );
- cases.add("invalid maybe type",
+ cases.add(
+ "invalid maybe type",
\\export fn f() void {
\\ if (true) |x| { }
\\}
- , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");
+ ,
+ ".tmp_source.zig:2:9: error: expected optional type, found 'bool'",
+ );
- cases.add("cast unreachable",
+ cases.add(
+ "cast unreachable",
\\fn f() i32 {
\\ return i32(return 1);
\\}
\\export fn entry() void { _ = f(); }
- , ".tmp_source.zig:2:15: error: unreachable code");
+ ,
+ ".tmp_source.zig:2:15: error: unreachable code",
+ );
- cases.add("invalid builtin fn",
+ cases.add(
+ "invalid builtin fn",
\\fn f() @bogus(foo) {
\\}
\\export fn entry() void { _ = f(); }
- , ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'");
+ ,
+ ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'",
+ );
- cases.add("top level decl dependency loop",
+ cases.add(
+ "top level decl dependency loop",
\\const a : @typeOf(b) = 0;
\\const b : @typeOf(a) = 0;
\\export fn entry() void {
\\ const c = a + b;
\\}
- , ".tmp_source.zig:1:1: error: 'a' depends on itself");
+ ,
+ ".tmp_source.zig:1:1: error: 'a' depends on itself",
+ );
- cases.add("noalias on non pointer param",
+ cases.add(
+ "noalias on non pointer param",
\\fn f(noalias x: i32) void {}
\\export fn entry() void { f(1234); }
- , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
+ ,
+ ".tmp_source.zig:1:6: error: noalias on non-pointer parameter",
+ );
- cases.add("struct init syntax for array",
+ cases.add(
+ "struct init syntax for array",
\\const foo = []u16{.x = 1024,};
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
+ ,
+ ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax",
+ );
- cases.add("type variables must be constant",
+ cases.add(
+ "type variables must be constant",
\\var foo = u8;
\\export fn entry() foo {
\\ return 1;
\\}
- , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");
-
+ ,
+ ".tmp_source.zig:1:1: error: variable of type 'type' must be constant",
+ );
- cases.add("variables shadowing types",
+ cases.add(
+ "variables shadowing types",
\\const Foo = struct {};
\\const Bar = struct {};
\\
@@ -978,12 +1757,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ f(1234);
\\}
,
- ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
- ".tmp_source.zig:1:1: note: previous definition is here",
- ".tmp_source.zig:5:5: error: redefinition of 'Bar'",
- ".tmp_source.zig:2:1: note: previous definition is here");
+ ".tmp_source.zig:4:6: error: redefinition of 'Foo'",
+ ".tmp_source.zig:1:1: note: previous definition is here",
+ ".tmp_source.zig:5:5: error: redefinition of 'Bar'",
+ ".tmp_source.zig:2:1: note: previous definition is here",
+ );
- cases.add("switch expression - missing enumeration prong",
+ cases.add(
+ "switch expression - missing enumeration prong",
\\const Number = enum {
\\ One,
\\ Two,
@@ -999,9 +1780,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
+ ,
+ ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch",
+ );
- cases.add("switch expression - duplicate enumeration prong",
+ cases.add(
+ "switch expression - duplicate enumeration prong",
\\const Number = enum {
\\ One,
\\ Two,
@@ -1019,10 +1803,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:13:15: error: duplicate switch value",
- ".tmp_source.zig:10:15: note: other value is here");
+ ,
+ ".tmp_source.zig:13:15: error: duplicate switch value",
+ ".tmp_source.zig:10:15: note: other value is here",
+ );
- cases.add("switch expression - duplicate enumeration prong when else present",
+ cases.add(
+ "switch expression - duplicate enumeration prong when else present",
\\const Number = enum {
\\ One,
\\ Two,
@@ -1041,10 +1828,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:13:15: error: duplicate switch value",
- ".tmp_source.zig:10:15: note: other value is here");
+ ,
+ ".tmp_source.zig:13:15: error: duplicate switch value",
+ ".tmp_source.zig:10:15: note: other value is here",
+ );
- cases.add("switch expression - multiple else prongs",
+ cases.add(
+ "switch expression - multiple else prongs",
\\fn f(x: u32) void {
\\ const value: bool = switch (x) {
\\ 1234 => false,
@@ -1055,9 +1845,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\export fn entry() void {
\\ f(1234);
\\}
- , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
+ ,
+ ".tmp_source.zig:5:9: error: multiple else prongs in switch expression",
+ );
- cases.add("switch expression - non exhaustive integer prongs",
+ cases.add(
+ "switch expression - non exhaustive integer prongs",
\\fn foo(x: u8) void {
\\ switch (x) {
\\ 0 => {},
@@ -1065,9 +1858,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
,
- ".tmp_source.zig:2:5: error: switch must handle all possibilities");
+ ".tmp_source.zig:2:5: error: switch must handle all possibilities",
+ );
- cases.add("switch expression - duplicate or overlapping integer value",
+ cases.add(
+ "switch expression - duplicate or overlapping integer value",
\\fn foo(x: u8) u8 {
\\ return switch (x) {
\\ 0 ... 100 => u8(0),
@@ -1079,10 +1874,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
,
".tmp_source.zig:6:9: error: duplicate switch value",
- ".tmp_source.zig:5:14: note: previous value is here");
+ ".tmp_source.zig:5:14: note: previous value is here",
+ );
- cases.add("switch expression - switch on pointer type with no else",
- \\fn foo(x: &u8) void {
+ cases.add(
+ "switch expression - switch on pointer type with no else",
+ \\fn foo(x: *u8) void {
\\ switch (x) {
\\ &y => {},
\\ }
@@ -1090,62 +1887,97 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\const y: u8 = 100;
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
,
- ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");
+ ".tmp_source.zig:2:5: error: else prong required when switching on type '*u8'",
+ );
- cases.add("global variable initializer must be constant expression",
+ cases.add(
+ "global variable initializer must be constant expression",
\\extern fn foo() i32;
\\const x = foo();
\\export fn entry() i32 { return x; }
- , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:2:11: error: unable to evaluate constant expression",
+ );
- cases.add("array concatenation with wrong type",
+ cases.add(
+ "array concatenation with wrong type",
\\const src = "aoeu";
\\const derp = usize(1234);
\\const a = derp ++ "foo";
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
- , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
+ ,
+ ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'",
+ );
- cases.add("non compile time array concatenation",
+ cases.add(
+ "non compile time array concatenation",
\\fn f() []u8 {
\\ return s ++ "foo";
\\}
\\var s: [10]u8 = undefined;
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:2:12: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:2:12: error: unable to evaluate constant expression",
+ );
- cases.add("@cImport with bogus include",
+ cases.add(
+ "@cImport with bogus include",
\\const c = @cImport(@cInclude("bogus.h"));
\\export fn entry() usize { return @sizeOf(@typeOf(c.bogo)); }
- , ".tmp_source.zig:1:11: error: C import failed",
- ".h:1:10: note: 'bogus.h' file not found");
+ ,
+ ".tmp_source.zig:1:11: error: C import failed",
+ ".h:1:10: note: 'bogus.h' file not found",
+ );
- cases.add("address of number literal",
+ cases.add(
+ "address of number literal",
\\const x = 3;
\\const y = &x;
- \\fn foo() &const i32 { return y; }
+ \\fn foo() *const i32 { return y; }
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:3:30: error: expected type '&const i32', found '&const (integer literal)'");
+ ,
+ ".tmp_source.zig:3:30: error: expected type '*const i32', found '*const comptime_int'",
+ );
- cases.add("integer overflow error",
+ cases.add(
+ "integer overflow error",
\\const x : u8 = 300;
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
- , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
+ ,
+ ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'",
+ );
- cases.add("incompatible number literals",
+ cases.add(
+ "invalid shift amount error",
+ \\const x : u8 = 2;
+ \\fn f() u16 {
+ \\ return x << 8;
+ \\}
+ \\export fn entry() u16 { return f(); }
+ ,
+ ".tmp_source.zig:3:14: error: RHS of shift is too large for LHS type",
+ ".tmp_source.zig:3:17: note: value 8 cannot fit into type u3",
+ );
+
+ cases.add(
+ "incompatible number literals",
\\const x = 2 == 2.0;
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
- , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
+ ,
+ ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type 'comptime_float'",
+ );
- cases.add("missing function call param",
+ cases.add(
+ "missing function call param",
\\const Foo = struct {
\\ a: i32,
\\ b: i32,
\\
- \\ fn member_a(foo: &const Foo) i32 {
+ \\ fn member_a(foo: *const Foo) i32 {
\\ return foo.a;
\\ }
- \\ fn member_b(foo: &const Foo) i32 {
+ \\ fn member_b(foo: *const Foo) i32 {
\\ return foo.b;
\\ }
\\};
@@ -1156,63 +1988,78 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ Foo.member_b,
\\};
\\
- \\fn f(foo: &const Foo, index: usize) void {
+ \\fn f(foo: *const Foo, index: usize) void {
\\ const result = members[index]();
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
+ ,
+ ".tmp_source.zig:20:34: error: expected 1 arguments, found 0",
+ );
- cases.add("missing function name and param name",
+ cases.add(
+ "missing function name and param name",
\\fn () void {}
\\fn f(i32) void {}
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
,
- ".tmp_source.zig:1:1: error: missing function name",
- ".tmp_source.zig:2:6: error: missing parameter name");
+ ".tmp_source.zig:1:1: error: missing function name",
+ ".tmp_source.zig:2:6: error: missing parameter name",
+ );
- cases.add("wrong function type",
+ cases.add(
+ "wrong function type",
\\const fns = []fn() void { a, b, c };
\\fn a() i32 {return 0;}
\\fn b() i32 {return 1;}
\\fn c() i32 {return 2;}
\\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
- , ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'");
+ ,
+ ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'",
+ );
- cases.add("extern function pointer mismatch",
+ cases.add(
+ "extern function pointer mismatch",
\\const fns = [](fn(i32)i32) { a, b, c };
\\pub fn a(x: i32) i32 {return x + 0;}
\\pub fn b(x: i32) i32 {return x + 1;}
\\export fn c(x: i32) i32 {return x + 2;}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
- , ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'");
-
+ ,
+ ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'",
+ );
- cases.add("implicit cast from f64 to f32",
+ cases.add(
+ "implicit cast from f64 to f32",
\\const x : f64 = 1.0;
\\const y : f32 = x;
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
- , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
-
+ ,
+ ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'",
+ );
- cases.add("colliding invalid top level functions",
+ cases.add(
+ "colliding invalid top level functions",
\\fn func() bogus {}
\\fn func() bogus {}
\\export fn entry() usize { return @sizeOf(@typeOf(func)); }
,
- ".tmp_source.zig:2:1: error: redefinition of 'func'",
- ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
-
+ ".tmp_source.zig:2:1: error: redefinition of 'func'",
+ ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'",
+ );
- cases.add("bogus compile var",
+ cases.add(
+ "bogus compile var",
\\const x = @import("builtin").bogus;
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
- , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");
-
+ ,
+ ".tmp_source.zig:1:29: error: no member named 'bogus' in '",
+ );
- cases.add("non constant expression in array size outside function",
+ cases.add(
+ "non constant expression in array size outside function",
\\const Foo = struct {
\\ y: [get()]u8,
\\};
@@ -1221,22 +2068,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
,
- ".tmp_source.zig:5:25: error: unable to evaluate constant expression",
- ".tmp_source.zig:2:12: note: called from here",
- ".tmp_source.zig:2:8: note: called from here");
-
+ ".tmp_source.zig:5:25: error: unable to evaluate constant expression",
+ ".tmp_source.zig:2:12: note: called from here",
+ ".tmp_source.zig:2:8: note: called from here",
+ );
- cases.add("addition with non numbers",
+ cases.add(
+ "addition with non numbers",
\\const Foo = struct {
\\ field: i32,
\\};
\\const x = Foo {.field = 1} + Foo {.field = 2};
\\
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
- , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
-
+ ,
+ ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'",
+ );
- cases.add("division by zero",
+ cases.add(
+ "division by zero",
\\const lit_int_x = 1 / 0;
\\const lit_float_x = 1.0 / 0.0;
\\const int_x = u32(1) / u32(0);
@@ -1247,49 +2097,65 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\export fn entry3() usize { return @sizeOf(@typeOf(int_x)); }
\\export fn entry4() usize { return @sizeOf(@typeOf(float_x)); }
,
- ".tmp_source.zig:1:21: error: division by zero",
- ".tmp_source.zig:2:25: error: division by zero",
- ".tmp_source.zig:3:22: error: division by zero",
- ".tmp_source.zig:4:26: error: division by zero");
-
+ ".tmp_source.zig:1:21: error: division by zero",
+ ".tmp_source.zig:2:25: error: division by zero",
+ ".tmp_source.zig:3:22: error: division by zero",
+ ".tmp_source.zig:4:26: error: division by zero",
+ );
- cases.add("normal string with newline",
+ cases.add(
+ "normal string with newline",
\\const foo = "a
\\b";
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
+ ,
+ ".tmp_source.zig:1:13: error: newline not allowed in string literal",
+ );
- cases.add("invalid comparison for function pointers",
+ cases.add(
+ "invalid comparison for function pointers",
\\fn foo() void {}
\\const invalid = foo > foo;
\\
\\export fn entry() usize { return @sizeOf(@typeOf(invalid)); }
- , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'");
+ ,
+ ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'",
+ );
- cases.add("generic function instance with non-constant expression",
+ cases.add(
+ "generic function instance with non-constant expression",
\\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
\\fn test1(a: i32, b: i32) i32 {
\\ return foo(a, b);
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(test1)); }
- , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:3:16: error: unable to evaluate constant expression",
+ );
- cases.add("assign null to non-nullable pointer",
- \\const a: &u8 = null;
+ cases.add(
+ "assign null to non-optional pointer",
+ \\const a: *u8 = null;
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
- , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
+ ,
+ ".tmp_source.zig:1:16: error: expected type '*u8', found '(null)'",
+ );
- cases.add("indexing an array of size zero",
+ cases.add(
+ "indexing an array of size zero",
\\const array = []u8{};
\\export fn foo() void {
\\ const pointer = &array[0];
\\}
- , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
+ ,
+ ".tmp_source.zig:3:27: error: index 0 outside array of size 0",
+ );
- cases.add("compile time division by zero",
+ cases.add(
+ "compile time division by zero",
\\const y = foo(0);
\\fn foo(x: u32) u32 {
\\ return 1 / x;
@@ -1297,17 +2163,431 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
,
- ".tmp_source.zig:3:14: error: division by zero",
- ".tmp_source.zig:1:14: note: called from here");
+ ".tmp_source.zig:3:14: error: division by zero",
+ ".tmp_source.zig:1:14: note: called from here",
+ );
- cases.add("branch on undefined value",
+ cases.add(
+ "branch on undefined value",
\\const x = if (undefined) true else false;
\\
\\export fn entry() usize { return @sizeOf(@typeOf(x)); }
- , ".tmp_source.zig:1:15: error: use of undefined value");
+ ,
+ ".tmp_source.zig:1:15: error: use of undefined value",
+ );
+
+ cases.add(
+ "div on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a / a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "div assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a /= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "mod on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a % a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "mod assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a %= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "add on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a + a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "add assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a += a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "add wrap on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a +% a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "add wrap assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a +%= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "sub on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a - a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "sub assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a -= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "sub wrap on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a -% a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "sub wrap assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a -%= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "mult on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a * a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "mult assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a *= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "mult wrap on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a *% a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "mult wrap assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a *%= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "shift left on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a << 2;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "shift left assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a <<= 2;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "shift right on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a >> 2;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "shift left assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a >>= 2;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin and on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a & a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin and assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a &= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin or on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a | a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin or assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a |= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin xor on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a ^ a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin xor assign on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ a ^= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:5: error: use of undefined value",
+ );
+
+ cases.add(
+ "equal on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a == a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "not equal on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a != a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "greater than on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a > a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "greater than equal on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a >= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+ cases.add(
+ "less than on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a < a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "less than equal on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = a <= a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "and on undefined value",
+ \\comptime {
+ \\ var a: bool = undefined;
+ \\ _ = a and a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "or on undefined value",
+ \\comptime {
+ \\ var a: bool = undefined;
+ \\ _ = a or a;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "negate on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = -a;
+ \\}
+ ,
+ ".tmp_source.zig:3:10: error: use of undefined value",
+ );
+
+ cases.add(
+ "negate wrap on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = -%a;
+ \\}
+ ,
+ ".tmp_source.zig:3:11: error: use of undefined value",
+ );
+
+ cases.add(
+ "bin not on undefined value",
+ \\comptime {
+ \\ var a: i64 = undefined;
+ \\ _ = ~a;
+ \\}
+ ,
+ ".tmp_source.zig:3:10: error: use of undefined value",
+ );
+
+ cases.add(
+ "bool not on undefined value",
+ \\comptime {
+ \\ var a: bool = undefined;
+ \\ _ = !a;
+ \\}
+ ,
+ ".tmp_source.zig:3:10: error: use of undefined value",
+ );
+
+ cases.add(
+ "orelse on undefined value",
+ \\comptime {
+ \\ var a: ?bool = undefined;
+ \\ _ = a orelse false;
+ \\}
+ ,
+ ".tmp_source.zig:3:11: error: use of undefined value",
+ );
+
+ cases.add(
+ "catch on undefined value",
+ \\comptime {
+ \\ var a: error!bool = undefined;
+ \\ _ = a catch |err| false;
+ \\}
+ ,
+ ".tmp_source.zig:3:11: error: use of undefined value",
+ );
- cases.add("endless loop in function evaluation",
+ cases.add(
+ "deref on undefined value",
+ \\comptime {
+ \\ var a: *u8 = undefined;
+ \\ _ = a.*;
+ \\}
+ ,
+ ".tmp_source.zig:3:9: error: use of undefined value",
+ );
+
+ cases.add(
+ "endless loop in function evaluation",
\\const seventh_fib_number = fibbonaci(7);
\\fn fibbonaci(x: i32) i32 {
\\ return fibbonaci(x - 1) + fibbonaci(x - 2);
@@ -1315,16 +2595,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); }
,
- ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
- ".tmp_source.zig:3:21: note: called from here");
+ ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
+ ".tmp_source.zig:3:21: note: called from here",
+ );
- cases.add("@embedFile with bogus file",
- \\const resource = @embedFile("bogus.txt");
+ cases.add(
+ "@embedFile with bogus file",
+ \\const resource = @embedFile("bogus.txt",);
\\
\\export fn entry() usize { return @sizeOf(@typeOf(resource)); }
- , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
+ ,
+ ".tmp_source.zig:1:29: error: unable to find '",
+ "bogus.txt'",
+ );
- cases.add("non-const expression in struct literal outside function",
+ cases.add(
+ "non-const expression in struct literal outside function",
\\const Foo = struct {
\\ x: i32,
\\};
@@ -1332,9 +2618,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\extern fn get_it() i32;
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
- , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:4:21: error: unable to evaluate constant expression",
+ );
- cases.add("non-const expression function call with struct return value outside function",
+ cases.add(
+ "non-const expression function call with struct return value outside function",
\\const Foo = struct {
\\ x: i32,
\\};
@@ -1347,19 +2636,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
,
- ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
- ".tmp_source.zig:4:17: note: called from here");
+ ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
+ ".tmp_source.zig:4:17: note: called from here",
+ );
- cases.add("undeclared identifier error should mark fn as impure",
+ cases.add(
+ "undeclared identifier error should mark fn as impure",
\\export fn foo() void {
\\ test_a_thing();
\\}
\\fn test_a_thing() void {
\\ bad_fn_call();
\\}
- , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
+ ,
+ ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'",
+ );
- cases.add("illegal comparison of types",
+ cases.add(
+ "illegal comparison of types",
\\fn bad_eql_1(a: []u8, b: []u8) bool {
\\ return a == b;
\\}
@@ -1367,17 +2661,19 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ One: void,
\\ Two: i32,
\\};
- \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {
- \\ return *a == *b;
+ \\fn bad_eql_2(a: *const EnumWithData, b: *const EnumWithData) bool {
+ \\ return a.* == b.*;
\\}
\\
\\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }
\\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }
,
- ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
- ".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'");
+ ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
+ ".tmp_source.zig:9:16: error: operator not allowed for type 'EnumWithData'",
+ );
- cases.add("non-const switch number literal",
+ cases.add(
+ "non-const switch number literal",
\\export fn foo() void {
\\ const x = switch (bar()) {
\\ 1, 2 => 1,
@@ -1388,25 +2684,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\fn bar() i32 {
\\ return 2;
\\}
- , ".tmp_source.zig:2:15: error: unable to infer expression type");
+ ,
+ ".tmp_source.zig:2:15: error: unable to infer expression type",
+ );
- cases.add("atomic orderings of cmpxchg - failure stricter than success",
+ cases.add(
+ "atomic orderings of cmpxchg - failure stricter than success",
\\const AtomicOrder = @import("builtin").AtomicOrder;
\\export fn f() void {
\\ var x: i32 = 1234;
- \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
+ \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
\\}
- , ".tmp_source.zig:4:72: error: failure atomic ordering must be no stricter than success");
+ ,
+ ".tmp_source.zig:4:81: error: failure atomic ordering must be no stricter than success",
+ );
- cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
+ cases.add(
+ "atomic orderings of cmpxchg - success Monotonic or stricter",
\\const AtomicOrder = @import("builtin").AtomicOrder;
\\export fn f() void {
\\ var x: i32 = 1234;
- \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
+ \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
\\}
- , ".tmp_source.zig:4:49: error: success atomic ordering must be Monotonic or stricter");
+ ,
+ ".tmp_source.zig:4:58: error: success atomic ordering must be Monotonic or stricter",
+ );
- cases.add("negation overflow in function evaluation",
+ cases.add(
+ "negation overflow in function evaluation",
\\const y = neg(-128);
\\fn neg(x: i8) i8 {
\\ return -x;
@@ -1414,10 +2719,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
,
- ".tmp_source.zig:3:12: error: negation caused overflow",
- ".tmp_source.zig:1:14: note: called from here");
+ ".tmp_source.zig:3:12: error: negation caused overflow",
+ ".tmp_source.zig:1:14: note: called from here",
+ );
- cases.add("add overflow in function evaluation",
+ cases.add(
+ "add overflow in function evaluation",
\\const y = add(65530, 10);
\\fn add(a: u16, b: u16) u16 {
\\ return a + b;
@@ -1425,11 +2732,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
,
- ".tmp_source.zig:3:14: error: operation caused overflow",
- ".tmp_source.zig:1:14: note: called from here");
-
+ ".tmp_source.zig:3:14: error: operation caused overflow",
+ ".tmp_source.zig:1:14: note: called from here",
+ );
- cases.add("sub overflow in function evaluation",
+ cases.add(
+ "sub overflow in function evaluation",
\\const y = sub(10, 20);
\\fn sub(a: u16, b: u16) u16 {
\\ return a - b;
@@ -1437,10 +2745,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
,
- ".tmp_source.zig:3:14: error: operation caused overflow",
- ".tmp_source.zig:1:14: note: called from here");
+ ".tmp_source.zig:3:14: error: operation caused overflow",
+ ".tmp_source.zig:1:14: note: called from here",
+ );
- cases.add("mul overflow in function evaluation",
+ cases.add(
+ "mul overflow in function evaluation",
\\const y = mul(300, 6000);
\\fn mul(a: u16, b: u16) u16 {
\\ return a * b;
@@ -1448,58 +2758,78 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(y)); }
,
- ".tmp_source.zig:3:14: error: operation caused overflow",
- ".tmp_source.zig:1:14: note: called from here");
+ ".tmp_source.zig:3:14: error: operation caused overflow",
+ ".tmp_source.zig:1:14: note: called from here",
+ );
- cases.add("truncate sign mismatch",
+ cases.add(
+ "truncate sign mismatch",
\\fn f() i8 {
\\ const x: u32 = 10;
\\ return @truncate(i8, x);
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");
+ ,
+ ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'",
+ );
- cases.add("try in function with non error return type",
+ cases.add(
+ "try in function with non error return type",
\\export fn f() void {
\\ try something();
\\}
\\fn something() error!void { }
,
- ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");
+ ".tmp_source.zig:2:5: error: expected type 'void', found 'error'",
+ );
- cases.add("invalid pointer for var type",
+ cases.add(
+ "invalid pointer for var type",
\\extern fn ext() usize;
\\var bytes: [ext()]u8 = undefined;
\\export fn f() void {
\\ for (bytes) |*b, i| {
- \\ *b = u8(i);
+ \\ b.* = u8(i);
\\ }
\\}
- , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:2:13: error: unable to evaluate constant expression",
+ );
- cases.add("export function with comptime parameter",
+ cases.add(
+ "export function with comptime parameter",
\\export fn foo(comptime x: i32, y: i32) i32{
\\ return x + y;
\\}
- , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
+ ,
+ ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",
+ );
- cases.add("extern function with comptime parameter",
+ cases.add(
+ "extern function with comptime parameter",
\\extern fn foo(comptime x: i32, y: i32) i32;
\\fn f() i32 {
\\ return foo(1, 2);
\\}
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
+ ,
+ ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'",
+ );
- cases.add("convert fixed size array to slice with invalid size",
+ cases.add(
+ "convert fixed size array to slice with invalid size",
\\export fn f() void {
\\ var array: [5]u8 = undefined;
- \\ var foo = ([]const u32)(array)[0];
+ \\ var foo = @bytesToSlice(u32, array)[0];
\\}
- , ".tmp_source.zig:3:28: error: unable to convert [5]u8 to []const u32: size mismatch");
+ ,
+ ".tmp_source.zig:3:15: error: unable to convert [5]u8 to []align(1) const u32: size mismatch",
+ ".tmp_source.zig:3:29: note: u32 has size 4; remaining bytes: 1",
+ );
- cases.add("non-pure function returns type",
+ cases.add(
+ "non-pure function returns type",
\\var a: u32 = 0;
\\pub fn List(comptime T: type) type {
\\ a += 1;
@@ -1518,56 +2848,77 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var list: List(i32) = undefined;
\\ list.length = 10;
\\}
- , ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
- ".tmp_source.zig:16:19: note: called from here");
+ ,
+ ".tmp_source.zig:3:7: error: unable to evaluate constant expression",
+ ".tmp_source.zig:16:19: note: called from here",
+ );
- cases.add("bogus method call on slice",
+ cases.add(
+ "bogus method call on slice",
\\var self = "aoeu";
\\fn f(m: []const u8) void {
\\ m.copy(u8, self[0..], m);
\\}
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
+ ,
+ ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'",
+ );
- cases.add("wrong number of arguments for method fn call",
+ cases.add(
+ "wrong number of arguments for method fn call",
\\const Foo = struct {
- \\ fn method(self: &const Foo, a: i32) void {}
+ \\ fn method(self: *const Foo, a: i32) void {}
\\};
- \\fn f(foo: &const Foo) void {
+ \\fn f(foo: *const Foo) void {
\\
\\ foo.method(1, 2);
\\}
\\export fn entry() usize { return @sizeOf(@typeOf(f)); }
- , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
+ ,
+ ".tmp_source.zig:6:15: error: expected 2 arguments, found 3",
+ );
- cases.add("assign through constant pointer",
+ cases.add(
+ "assign through constant pointer",
\\export fn f() void {
\\ var cstr = c"Hat";
\\ cstr[0] = 'W';
\\}
- , ".tmp_source.zig:3:11: error: cannot assign to constant");
+ ,
+ ".tmp_source.zig:3:11: error: cannot assign to constant",
+ );
- cases.add("assign through constant slice",
+ cases.add(
+ "assign through constant slice",
\\export fn f() void {
\\ var cstr: []const u8 = "Hat";
\\ cstr[0] = 'W';
\\}
- , ".tmp_source.zig:3:11: error: cannot assign to constant");
+ ,
+ ".tmp_source.zig:3:11: error: cannot assign to constant",
+ );
- cases.add("main function with bogus args type",
+ cases.add(
+ "main function with bogus args type",
\\pub fn main(args: [][]bogus) !void {}
- , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");
+ ,
+ ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'",
+ );
- cases.add("for loop missing element param",
+ cases.add(
+ "for loop missing element param",
\\fn foo(blah: []u8) void {
\\ for (blah) { }
\\}
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
+ ,
+ ".tmp_source.zig:2:5: error: for loop expression missing element parameter",
+ );
- cases.add("misspelled type with pointer only reference",
+ cases.add(
+ "misspelled type with pointer only reference",
\\const JasonHM = u8;
- \\const JasonList = &JsonNode;
+ \\const JasonList = *JsonNode;
\\
\\const JsonOA = union(enum) {
\\ JSONArray: JsonList,
@@ -1596,9 +2947,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
+ ,
+ ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'",
+ );
- cases.add("method call with first arg type primitive",
+ cases.add(
+ "method call with first arg type primitive",
\\const Foo = struct {
\\ x: i32,
\\
@@ -1614,14 +2968,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\ derp.init();
\\}
- , ".tmp_source.zig:14:5: error: expected type 'i32', found '&const Foo'");
+ ,
+ ".tmp_source.zig:14:5: error: expected type 'i32', found 'Foo'",
+ );
- cases.add("method call with first arg type wrong container",
+ cases.add(
+ "method call with first arg type wrong container",
\\pub const List = struct {
\\ len: usize,
- \\ allocator: &Allocator,
+ \\ allocator: *Allocator,
\\
- \\ pub fn init(allocator: &Allocator) List {
+ \\ pub fn init(allocator: *Allocator) List {
\\ return List {
\\ .len = 0,
\\ .allocator = allocator,
@@ -1641,26 +2998,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x = List.init(&global_allocator);
\\ x.init();
\\}
- , ".tmp_source.zig:23:5: error: expected type '&Allocator', found '&List'");
+ ,
+ ".tmp_source.zig:23:5: error: expected type '*Allocator', found '*List'",
+ );
- cases.add("binary not on number literal",
+ cases.add(
+ "binary not on number literal",
\\const TINY_QUANTUM_SHIFT = 4;
\\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
\\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
\\
\\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
- , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
+ ,
+ ".tmp_source.zig:3:60: error: unable to perform binary not operation on type 'comptime_int'",
+ );
cases.addCase(x: {
- const tc = cases.create("multiple files with private function error",
- \\const foo = @import("foo.zig");
+ const tc = cases.create(
+ "multiple files with private function error",
+ \\const foo = @import("foo.zig",);
\\
\\export fn callPrivFunction() void {
\\ foo.privateFunction();
\\}
,
".tmp_source.zig:4:8: error: 'privateFunction' is private",
- "foo.zig:1:1: note: declared here");
+ "foo.zig:1:1: note: declared here",
+ );
tc.addSourceFile("foo.zig",
\\fn privateFunction() void { }
@@ -1669,14 +3033,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
break :x tc;
});
- cases.add("container init with non-type",
+ cases.add(
+ "container init with non-type",
\\const zero: i32 = 0;
\\const a = zero{1};
\\
\\export fn entry() usize { return @sizeOf(@typeOf(a)); }
- , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
+ ,
+ ".tmp_source.zig:2:11: error: expected type, found 'i32'",
+ );
- cases.add("assign to constant field",
+ cases.add(
+ "assign to constant field",
\\const Foo = struct {
\\ field: i32,
\\};
@@ -1684,15 +3052,18 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ const f = Foo {.field = 1234,};
\\ f.field = 0;
\\}
- , ".tmp_source.zig:6:13: error: cannot assign to constant");
+ ,
+ ".tmp_source.zig:6:13: error: cannot assign to constant",
+ );
- cases.add("return from defer expression",
+ cases.add(
+ "return from defer expression",
\\pub fn testTrickyDefer() !void {
\\ defer canFail() catch {};
\\
\\ defer try canFail();
\\
- \\ const a = maybeInt() ?? return;
+ \\ const a = maybeInt() orelse return;
\\}
\\
\\fn canFail() error!void { }
@@ -1702,9 +3073,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(testTrickyDefer)); }
- , ".tmp_source.zig:4:11: error: cannot return from defer expression");
+ ,
+ ".tmp_source.zig:4:11: error: cannot return from defer expression",
+ );
- cases.add("attempt to access var args out of bounds",
+ cases.add(
+ "attempt to access var args out of bounds",
\\fn add(args: ...) i32 {
\\ return args[0] + args[1];
\\}
@@ -1715,10 +3089,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
,
- ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",
- ".tmp_source.zig:6:15: note: called from here");
+ ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",
+ ".tmp_source.zig:6:15: note: called from here",
+ );
- cases.add("pass integer literal to var args",
+ cases.add(
+ "pass integer literal to var args",
\\fn add(args: ...) i32 {
\\ var sum = i32(0);
\\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
@@ -1732,32 +3108,44 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
- , ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted");
+ ,
+ ".tmp_source.zig:10:16: error: compiler bug: integer and float literals in var args function must be casted",
+ );
- cases.add("assign too big number to u16",
+ cases.add(
+ "assign too big number to u16",
\\export fn foo() void {
\\ var vga_mem: u16 = 0xB8000;
\\}
- , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
+ ,
+ ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'",
+ );
- cases.add("global variable alignment non power of 2",
+ cases.add(
+ "global variable alignment non power of 2",
\\const some_data: [100]u8 align(3) = undefined;
\\export fn entry() usize { return @sizeOf(@typeOf(some_data)); }
- , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
+ ,
+ ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2",
+ );
- cases.add("function alignment non power of 2",
+ cases.add(
+ "function alignment non power of 2",
\\extern fn foo() align(3) void;
\\export fn entry() void { return foo(); }
- , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
+ ,
+ ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2",
+ );
- cases.add("compile log",
+ cases.add(
+ "compile log",
\\export fn foo() void {
- \\ comptime bar(12, "hi");
+ \\ comptime bar(12, "hi",);
\\}
\\fn bar(a: i32, b: []const u8) void {
- \\ @compileLog("begin");
+ \\ @compileLog("begin",);
\\ @compileLog("a", a, "b", b);
- \\ @compileLog("end");
+ \\ @compileLog("end",);
\\}
,
".tmp_source.zig:5:5: error: found compile log statement",
@@ -1765,27 +3153,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
".tmp_source.zig:6:5: error: found compile log statement",
".tmp_source.zig:2:17: note: called from here",
".tmp_source.zig:7:5: error: found compile log statement",
- ".tmp_source.zig:2:17: note: called from here");
+ ".tmp_source.zig:2:17: note: called from here",
+ );
- cases.add("casting bit offset pointer to regular pointer",
+ cases.add(
+ "casting bit offset pointer to regular pointer",
\\const BitField = packed struct {
\\ a: u3,
\\ b: u3,
\\ c: u2,
\\};
\\
- \\fn foo(bit_field: &const BitField) u3 {
+ \\fn foo(bit_field: *const BitField) u3 {
\\ return bar(&bit_field.b);
\\}
\\
- \\fn bar(x: &const u3) u3 {
- \\ return *x;
+ \\fn bar(x: *const u3) u3 {
+ \\ return x.*;
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
+ ,
+ ".tmp_source.zig:8:26: error: expected type '*const u3', found '*align(1:3:6) const u3'",
+ );
- cases.add("referring to a struct that is invalid",
+ cases.add(
+ "referring to a struct that is invalid",
\\const UsbDeviceRequest = struct {
\\ Type: u8,
\\};
@@ -1798,10 +3191,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ if (!ok) unreachable;
\\}
,
- ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
- ".tmp_source.zig:6:20: note: called from here");
+ ".tmp_source.zig:10:14: error: unable to evaluate constant expression",
+ ".tmp_source.zig:6:20: note: called from here",
+ );
- cases.add("control flow uses comptime var at runtime",
+ cases.add(
+ "control flow uses comptime var at runtime",
\\export fn foo() void {
\\ comptime var i = 0;
\\ while (i < 5) : (i += 1) {
@@ -1811,88 +3206,118 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\fn bar() void { }
,
- ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
- ".tmp_source.zig:3:24: note: compile-time variable assigned here");
+ ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
+ ".tmp_source.zig:3:24: note: compile-time variable assigned here",
+ );
- cases.add("ignored return value",
+ cases.add(
+ "ignored return value",
\\export fn foo() void {
\\ bar();
\\}
\\fn bar() i32 { return 0; }
- , ".tmp_source.zig:2:8: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:8: error: expression value is ignored",
+ );
- cases.add("ignored assert-err-ok return value",
+ cases.add(
+ "ignored assert-err-ok return value",
\\export fn foo() void {
\\ bar() catch unreachable;
\\}
\\fn bar() error!i32 { return 0; }
- , ".tmp_source.zig:2:11: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:11: error: expression value is ignored",
+ );
- cases.add("ignored statement value",
+ cases.add(
+ "ignored statement value",
\\export fn foo() void {
\\ 1;
\\}
- , ".tmp_source.zig:2:5: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:5: error: expression value is ignored",
+ );
- cases.add("ignored comptime statement value",
+ cases.add(
+ "ignored comptime statement value",
\\export fn foo() void {
\\ comptime {1;}
\\}
- , ".tmp_source.zig:2:15: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:15: error: expression value is ignored",
+ );
- cases.add("ignored comptime value",
+ cases.add(
+ "ignored comptime value",
\\export fn foo() void {
\\ comptime 1;
\\}
- , ".tmp_source.zig:2:5: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:5: error: expression value is ignored",
+ );
- cases.add("ignored defered statement value",
+ cases.add(
+ "ignored defered statement value",
\\export fn foo() void {
\\ defer {1;}
\\}
- , ".tmp_source.zig:2:12: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:12: error: expression value is ignored",
+ );
- cases.add("ignored defered function call",
+ cases.add(
+ "ignored defered function call",
\\export fn foo() void {
\\ defer bar();
\\}
\\fn bar() error!i32 { return 0; }
- , ".tmp_source.zig:2:14: error: expression value is ignored");
+ ,
+ ".tmp_source.zig:2:14: error: expression value is ignored",
+ );
- cases.add("dereference an array",
+ cases.add(
+ "dereference an array",
\\var s_buffer: [10]u8 = undefined;
\\pub fn pass(in: []u8) []u8 {
\\ var out = &s_buffer;
- \\ *out[0] = in[0];
- \\ return (*out)[0..1];
+ \\ out.*.* = in[0];
+ \\ return out.*[0..1];
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
- , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
+ ,
+ ".tmp_source.zig:4:10: error: attempt to dereference non pointer type '[10]u8'",
+ );
- cases.add("pass const ptr to mutable ptr fn",
+ cases.add(
+ "pass const ptr to mutable ptr fn",
\\fn foo() bool {
- \\ const a = ([]const u8)("a");
+ \\ const a = ([]const u8)("a",);
\\ const b = &a;
\\ return ptrEql(b, b);
\\}
- \\fn ptrEql(a: &[]const u8, b: &[]const u8) bool {
+ \\fn ptrEql(a: *[]const u8, b: *[]const u8) bool {
\\ return true;
\\}
\\
\\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");
+ ,
+ ".tmp_source.zig:4:19: error: expected type '*[]const u8', found '*const []const u8'",
+ );
cases.addCase(x: {
- const tc = cases.create("export collision",
- \\const foo = @import("foo.zig");
+ const tc = cases.create(
+ "export collision",
+ \\const foo = @import("foo.zig",);
\\
\\export fn bar() usize {
\\ return foo.baz;
\\}
,
"foo.zig:1:8: error: exported symbol collision: 'bar'",
- ".tmp_source.zig:3:8: note: other symbol here");
+ ".tmp_source.zig:3:8: note: other symbol here",
+ );
tc.addSourceFile("foo.zig",
\\export fn bar() void {}
@@ -1902,35 +3327,28 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
break :x tc;
});
- cases.add("pass non-copyable type by value to function",
- \\const Point = struct { x: i32, y: i32, };
- \\fn foo(p: Point) void { }
- \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
-
- cases.add("implicit cast from array to mutable slice",
+ cases.add(
+ "implicit cast from array to mutable slice",
\\var global_array: [10]i32 = undefined;
\\fn foo(param: []i32) void {}
\\export fn entry() void {
\\ foo(global_array);
\\}
- , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
+ ,
+ ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'",
+ );
- cases.add("ptrcast to non-pointer",
- \\export fn entry(a: &i32) usize {
+ cases.add(
+ "ptrcast to non-pointer",
+ \\export fn entry(a: *i32) usize {
\\ return @ptrCast(usize, a);
\\}
- , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
-
- cases.add("too many error values to cast to small integer",
- \\const Error = error { A, B, C, D, E, F, G, H };
- \\fn foo(e: Error) u2 {
- \\ return u2(e);
- \\}
- \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
- , ".tmp_source.zig:3:14: error: too many error values to fit in 'u2'");
+ ,
+ ".tmp_source.zig:2:21: error: expected pointer, found 'usize'",
+ );
- cases.add("asm at compile time",
+ cases.add(
+ "asm at compile time",
\\comptime {
\\ doSomeAsm();
\\}
@@ -1942,48 +3360,66 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ \\.set aoeu, derp;
\\ );
\\}
- , ".tmp_source.zig:6:5: error: unable to evaluate constant expression");
+ ,
+ ".tmp_source.zig:6:5: error: unable to evaluate constant expression",
+ );
- cases.add("invalid member of builtin enum",
- \\const builtin = @import("builtin");
+ cases.add(
+ "invalid member of builtin enum",
+ \\const builtin = @import("builtin",);
\\export fn entry() void {
\\ const foo = builtin.Arch.x86;
\\}
- , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");
+ ,
+ ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'",
+ );
- cases.add("int to ptr of 0 bits",
+ cases.add(
+ "int to ptr of 0 bits",
\\export fn foo() void {
\\ var x: usize = 0x1000;
- \\ var y: &void = @intToPtr(&void, x);
+ \\ var y: *void = @intToPtr(*void, x);
\\}
- , ".tmp_source.zig:3:31: error: type '&void' has 0 bits and cannot store information");
+ ,
+ ".tmp_source.zig:3:30: error: type '*void' has 0 bits and cannot store information",
+ );
- cases.add("@fieldParentPtr - non struct",
+ cases.add(
+ "@fieldParentPtr - non struct",
\\const Foo = i32;
- \\export fn foo(a: &i32) &Foo {
+ \\export fn foo(a: *i32) *Foo {
\\ return @fieldParentPtr(Foo, "a", a);
\\}
- , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
+ ,
+ ".tmp_source.zig:3:28: error: expected struct type, found 'i32'",
+ );
- cases.add("@fieldParentPtr - bad field name",
+ cases.add(
+ "@fieldParentPtr - bad field name",
\\const Foo = extern struct {
\\ derp: i32,
\\};
- \\export fn foo(a: &i32) &Foo {
+ \\export fn foo(a: *i32) *Foo {
\\ return @fieldParentPtr(Foo, "a", a);
\\}
- , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
+ ,
+ ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'",
+ );
- cases.add("@fieldParentPtr - field pointer is not pointer",
+ cases.add(
+ "@fieldParentPtr - field pointer is not pointer",
\\const Foo = extern struct {
\\ a: i32,
\\};
- \\export fn foo(a: i32) &Foo {
+ \\export fn foo(a: i32) *Foo {
\\ return @fieldParentPtr(Foo, "a", a);
\\}
- , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
+ ,
+ ".tmp_source.zig:5:38: error: expected pointer, found 'i32'",
+ );
- cases.add("@fieldParentPtr - comptime field ptr not based on struct",
+ cases.add(
+ "@fieldParentPtr - comptime field ptr not based on struct",
\\const Foo = struct {
\\ a: i32,
\\ b: i32,
@@ -1991,12 +3427,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\const foo = Foo { .a = 1, .b = 2, };
\\
\\comptime {
- \\ const field_ptr = @intToPtr(&i32, 0x1234);
+ \\ const field_ptr = @intToPtr(*i32, 0x1234);
\\ const another_foo_ptr = @fieldParentPtr(Foo, "b", field_ptr);
\\}
- , ".tmp_source.zig:9:55: error: pointer value not based on parent struct");
+ ,
+ ".tmp_source.zig:9:55: error: pointer value not based on parent struct",
+ );
- cases.add("@fieldParentPtr - comptime wrong field index",
+ cases.add(
+ "@fieldParentPtr - comptime wrong field index",
\\const Foo = struct {
\\ a: i32,
\\ b: i32,
@@ -2006,76 +3445,100 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\comptime {
\\ const another_foo_ptr = @fieldParentPtr(Foo, "b", &foo.a);
\\}
- , ".tmp_source.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'");
+ ,
+ ".tmp_source.zig:8:29: error: field 'b' has index 1 but pointer value is index 0 of struct 'Foo'",
+ );
- cases.add("@offsetOf - non struct",
+ cases.add(
+ "@offsetOf - non struct",
\\const Foo = i32;
\\export fn foo() usize {
- \\ return @offsetOf(Foo, "a");
+ \\ return @offsetOf(Foo, "a",);
\\}
- , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");
+ ,
+ ".tmp_source.zig:3:22: error: expected struct type, found 'i32'",
+ );
- cases.add("@offsetOf - bad field name",
+ cases.add(
+ "@offsetOf - bad field name",
\\const Foo = struct {
\\ derp: i32,
\\};
\\export fn foo() usize {
- \\ return @offsetOf(Foo, "a");
+ \\ return @offsetOf(Foo, "a",);
\\}
- , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");
+ ,
+ ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'",
+ );
- cases.addExe("missing main fn in executable",
+ cases.addExe(
+ "missing main fn in executable",
\\
- , "error: no member named 'main' in '");
+ ,
+ "error: no member named 'main' in '",
+ );
- cases.addExe("private main fn",
+ cases.addExe(
+ "private main fn",
\\fn main() void {}
,
"error: 'main' is private",
- ".tmp_source.zig:1:1: note: declared here");
+ ".tmp_source.zig:1:1: note: declared here",
+ );
- cases.add("setting a section on an extern variable",
+ cases.add(
+ "setting a section on an extern variable",
\\extern var foo: i32 section(".text2");
\\export fn entry() i32 {
\\ return foo;
\\}
,
- ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");
+ ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'",
+ );
- cases.add("setting a section on a local variable",
+ cases.add(
+ "setting a section on a local variable",
\\export fn entry() i32 {
\\ var foo: i32 section(".text2") = 1234;
\\ return foo;
\\}
,
- ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");
+ ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'",
+ );
- cases.add("setting a section on an extern fn",
+ cases.add(
+ "setting a section on an extern fn",
\\extern fn foo() section(".text2") void;
\\export fn entry() void {
\\ foo();
\\}
,
- ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");
+ ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'",
+ );
- cases.add("returning address of local variable - simple",
- \\export fn foo() &i32 {
+ cases.add(
+ "returning address of local variable - simple",
+ \\export fn foo() *i32 {
\\ var a: i32 = undefined;
\\ return &a;
\\}
,
- ".tmp_source.zig:3:13: error: function returns address of local variable");
+ ".tmp_source.zig:3:13: error: function returns address of local variable",
+ );
- cases.add("returning address of local variable - phi",
- \\export fn foo(c: bool) &i32 {
+ cases.add(
+ "returning address of local variable - phi",
+ \\export fn foo(c: bool) *i32 {
\\ var a: i32 = undefined;
\\ var b: i32 = undefined;
\\ return if (c) &a else &b;
\\}
,
- ".tmp_source.zig:4:12: error: function returns address of local variable");
+ ".tmp_source.zig:4:12: error: function returns address of local variable",
+ );
- cases.add("inner struct member shadowing outer struct member",
+ cases.add(
+ "inner struct member shadowing outer struct member",
\\fn A() type {
\\ return struct {
\\ b: B(),
@@ -2097,57 +3560,71 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:9:17: error: redefinition of 'Self'",
- ".tmp_source.zig:5:9: note: previous definition is here");
+ ".tmp_source.zig:5:9: note: previous definition is here",
+ );
- cases.add("while expected bool, got nullable",
+ cases.add(
+ "while expected bool, got optional",
\\export fn foo() void {
\\ while (bar()) {}
\\}
\\fn bar() ?i32 { return 1; }
,
- ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");
+ ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'",
+ );
- cases.add("while expected bool, got error union",
+ cases.add(
+ "while expected bool, got error union",
\\export fn foo() void {
\\ while (bar()) {}
\\}
\\fn bar() error!i32 { return 1; }
,
- ".tmp_source.zig:2:15: error: expected type 'bool', found 'error!i32'");
+ ".tmp_source.zig:2:15: error: expected type 'bool', found 'error!i32'",
+ );
- cases.add("while expected nullable, got bool",
+ cases.add(
+ "while expected optional, got bool",
\\export fn foo() void {
\\ while (bar()) |x| {}
\\}
\\fn bar() bool { return true; }
,
- ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");
+ ".tmp_source.zig:2:15: error: expected optional type, found 'bool'",
+ );
- cases.add("while expected nullable, got error union",
+ cases.add(
+ "while expected optional, got error union",
\\export fn foo() void {
\\ while (bar()) |x| {}
\\}
\\fn bar() error!i32 { return 1; }
,
- ".tmp_source.zig:2:15: error: expected nullable type, found 'error!i32'");
+ ".tmp_source.zig:2:15: error: expected optional type, found 'error!i32'",
+ );
- cases.add("while expected error union, got bool",
+ cases.add(
+ "while expected error union, got bool",
\\export fn foo() void {
\\ while (bar()) |x| {} else |err| {}
\\}
\\fn bar() bool { return true; }
,
- ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");
+ ".tmp_source.zig:2:15: error: expected error union type, found 'bool'",
+ );
- cases.add("while expected error union, got nullable",
+ cases.add(
+ "while expected error union, got optional",
\\export fn foo() void {
\\ while (bar()) |x| {} else |err| {}
\\}
\\fn bar() ?i32 { return 1; }
,
- ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");
+ ".tmp_source.zig:2:15: error: expected error union type, found '?i32'",
+ );
- cases.add("inline fn calls itself indirectly",
+ cases.add(
+ "inline fn calls itself indirectly",
\\export fn foo() void {
\\ bar();
\\}
@@ -2161,91 +3638,113 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\extern fn quux() void;
,
- ".tmp_source.zig:4:8: error: unable to inline function");
+ ".tmp_source.zig:4:8: error: unable to inline function",
+ );
- cases.add("save reference to inline function",
+ cases.add(
+ "save reference to inline function",
\\export fn foo() void {
\\ quux(@ptrToInt(bar));
\\}
\\inline fn bar() void { }
\\extern fn quux(usize) void;
,
- ".tmp_source.zig:4:8: error: unable to inline function");
+ ".tmp_source.zig:4:8: error: unable to inline function",
+ );
- cases.add("signed integer division",
+ cases.add(
+ "signed integer division",
\\export fn foo(a: i32, b: i32) i32 {
\\ return a / b;
\\}
,
- ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");
+ ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact",
+ );
- cases.add("signed integer remainder division",
+ cases.add(
+ "signed integer remainder division",
\\export fn foo(a: i32, b: i32) i32 {
\\ return a % b;
\\}
,
- ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod");
+ ".tmp_source.zig:2:14: error: remainder division with 'i32' and 'i32': signed integers and floats must use @rem or @mod",
+ );
- cases.add("cast negative value to unsigned integer",
+ cases.add(
+ "cast negative value to unsigned integer",
\\comptime {
\\ const value: i32 = -1;
- \\ const unsigned = u32(value);
+ \\ const unsigned = @intCast(u32, value);
\\}
,
- ".tmp_source.zig:3:25: error: attempt to cast negative value to unsigned integer");
+ ".tmp_source.zig:3:22: error: attempt to cast negative value to unsigned integer",
+ );
- cases.add("compile-time division by zero",
+ cases.add(
+ "compile-time division by zero",
\\comptime {
\\ const a: i32 = 1;
\\ const b: i32 = 0;
\\ const c = a / b;
\\}
,
- ".tmp_source.zig:4:17: error: division by zero");
+ ".tmp_source.zig:4:17: error: division by zero",
+ );
- cases.add("compile-time remainder division by zero",
+ cases.add(
+ "compile-time remainder division by zero",
\\comptime {
\\ const a: i32 = 1;
\\ const b: i32 = 0;
\\ const c = a % b;
\\}
,
- ".tmp_source.zig:4:17: error: division by zero");
+ ".tmp_source.zig:4:17: error: division by zero",
+ );
- cases.add("compile-time integer cast truncates bits",
+ cases.add(
+ "compile-time integer cast truncates bits",
\\comptime {
\\ const spartan_count: u16 = 300;
- \\ const byte = u8(spartan_count);
+ \\ const byte = @intCast(u8, spartan_count);
\\}
,
- ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
+ ".tmp_source.zig:3:18: error: cast from 'u16' to 'u8' truncates bits",
+ );
- cases.add("@setRuntimeSafety twice for same scope",
+ cases.add(
+ "@setRuntimeSafety twice for same scope",
\\export fn foo() void {
\\ @setRuntimeSafety(false);
\\ @setRuntimeSafety(false);
\\}
,
".tmp_source.zig:3:5: error: runtime safety set twice for same scope",
- ".tmp_source.zig:2:5: note: first set here");
+ ".tmp_source.zig:2:5: note: first set here",
+ );
- cases.add("@setFloatMode twice for same scope",
+ cases.add(
+ "@setFloatMode twice for same scope",
\\export fn foo() void {
\\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
\\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
\\}
,
".tmp_source.zig:3:5: error: float mode set twice for same scope",
- ".tmp_source.zig:2:5: note: first set here");
+ ".tmp_source.zig:2:5: note: first set here",
+ );
- cases.add("array access of type",
+ cases.add(
+ "array access of type",
\\export fn foo() void {
\\ var b: u8[40] = undefined;
\\}
,
- ".tmp_source.zig:2:14: error: array access of non-array type 'type'");
+ ".tmp_source.zig:2:14: error: array access of non-array type 'type'",
+ );
- cases.add("cannot break out of defer expression",
+ cases.add(
+ "cannot break out of defer expression",
\\export fn foo() void {
\\ while (true) {
\\ defer {
@@ -2254,9 +3753,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:4:13: error: cannot break out of defer expression");
+ ".tmp_source.zig:4:13: error: cannot break out of defer expression",
+ );
- cases.add("cannot continue out of defer expression",
+ cases.add(
+ "cannot continue out of defer expression",
\\export fn foo() void {
\\ while (true) {
\\ defer {
@@ -2265,9 +3766,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:4:13: error: cannot continue out of defer expression");
+ ".tmp_source.zig:4:13: error: cannot continue out of defer expression",
+ );
- cases.add("calling a var args function only known at runtime",
+ cases.add(
+ "calling a var args function only known at runtime",
\\var foos = []fn(...) void { foo1, foo2 };
\\
\\fn foo1(args: ...) void {}
@@ -2277,9 +3780,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ foos[0]();
\\}
,
- ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");
+ ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value",
+ );
- cases.add("calling a generic function only known at runtime",
+ cases.add(
+ "calling a generic function only known at runtime",
\\var foos = []fn(var) void { foo1, foo2 };
\\
\\fn foo1(arg: var) void {}
@@ -2289,10 +3794,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ foos[0](true);
\\}
,
- ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");
+ ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value",
+ );
- cases.add("@compileError shows traceback of references that caused it",
- \\const foo = @compileError("aoeu");
+ cases.add(
+ "@compileError shows traceback of references that caused it",
+ \\const foo = @compileError("aoeu",);
\\
\\const bar = baz + foo;
\\const baz = 1;
@@ -2303,9 +3810,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
,
".tmp_source.zig:1:13: error: aoeu",
".tmp_source.zig:3:19: note: referenced here",
- ".tmp_source.zig:7:12: note: referenced here");
+ ".tmp_source.zig:7:12: note: referenced here",
+ );
- cases.add("instantiating an undefined value for an invalid struct that contains itself",
+ cases.add(
+ "instantiating an undefined value for an invalid struct that contains itself",
\\const Foo = struct {
\\ x: Foo,
\\};
@@ -2316,73 +3825,93 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ return @sizeOf(@typeOf(foo.x));
\\}
,
- ".tmp_source.zig:1:13: error: struct 'Foo' contains itself");
+ ".tmp_source.zig:1:13: error: struct 'Foo' contains itself",
+ );
- cases.add("float literal too large error",
+ cases.add(
+ "float literal too large error",
\\comptime {
\\ const a = 0x1.0p16384;
\\}
,
- ".tmp_source.zig:2:15: error: float literal out of range of any type");
+ ".tmp_source.zig:2:15: error: float literal out of range of any type",
+ );
- cases.add("float literal too small error (denormal)",
+ cases.add(
+ "float literal too small error (denormal)",
\\comptime {
\\ const a = 0x1.0p-16384;
\\}
,
- ".tmp_source.zig:2:15: error: float literal out of range of any type");
+ ".tmp_source.zig:2:15: error: float literal out of range of any type",
+ );
- cases.add("explicit cast float literal to integer when there is a fraction component",
+ cases.add(
+ "explicit cast float literal to integer when there is a fraction component",
\\export fn entry() i32 {
\\ return i32(12.34);
\\}
,
- ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");
+ ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'",
+ );
- cases.add("non pointer given to @ptrToInt",
+ cases.add(
+ "non pointer given to @ptrToInt",
\\export fn entry(x: i32) usize {
\\ return @ptrToInt(x);
\\}
,
- ".tmp_source.zig:2:22: error: expected pointer, found 'i32'");
+ ".tmp_source.zig:2:22: error: expected pointer, found 'i32'",
+ );
- cases.add("@shlExact shifts out 1 bits",
+ cases.add(
+ "@shlExact shifts out 1 bits",
\\comptime {
\\ const x = @shlExact(u8(0b01010101), 2);
\\}
,
- ".tmp_source.zig:2:15: error: operation caused overflow");
+ ".tmp_source.zig:2:15: error: operation caused overflow",
+ );
- cases.add("@shrExact shifts out 1 bits",
+ cases.add(
+ "@shrExact shifts out 1 bits",
\\comptime {
\\ const x = @shrExact(u8(0b10101010), 2);
\\}
,
- ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");
+ ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits",
+ );
- cases.add("shifting without int type or comptime known",
+ cases.add(
+ "shifting without int type or comptime known",
\\export fn entry(x: u8) u8 {
\\ return 0x11 << x;
\\}
,
- ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");
+ ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known",
+ );
- cases.add("shifting RHS is log2 of LHS int bit width",
+ cases.add(
+ "shifting RHS is log2 of LHS int bit width",
\\export fn entry(x: u8, y: u8) u8 {
\\ return x << y;
\\}
,
- ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'");
+ ".tmp_source.zig:2:17: error: expected type 'u3', found 'u8'",
+ );
- cases.add("globally shadowing a primitive type",
+ cases.add(
+ "globally shadowing a primitive type",
\\const u16 = @intType(false, 8);
\\export fn entry() void {
\\ const a: u16 = 300;
\\}
,
- ".tmp_source.zig:1:1: error: declaration shadows type 'u16'");
+ ".tmp_source.zig:1:1: error: declaration shadows type 'u16'",
+ );
- cases.add("implicitly increasing pointer alignment",
+ cases.add(
+ "implicitly increasing pointer alignment",
\\const Foo = packed struct {
\\ a: u8,
\\ b: u32,
@@ -2393,13 +3922,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ bar(&foo.b);
\\}
\\
- \\fn bar(x: &u32) void {
- \\ *x += 1;
+ \\fn bar(x: *u32) void {
+ \\ x.* += 1;
\\}
,
- ".tmp_source.zig:8:13: error: expected type '&u32', found '&align(1) u32'");
+ ".tmp_source.zig:8:13: error: expected type '*u32', found '*align(1) u32'",
+ );
- cases.add("implicitly increasing slice alignment",
+ cases.add(
+ "implicitly increasing slice alignment",
\\const Foo = packed struct {
\\ a: u8,
\\ b: u32,
@@ -2408,44 +3939,42 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\export fn entry() void {
\\ var foo = Foo { .a = 1, .b = 10 };
\\ foo.b += 1;
- \\ bar((&foo.b)[0..1]);
+ \\ bar((*[1]u32)(&foo.b)[0..]);
\\}
\\
\\fn bar(x: []u32) void {
\\ x[0] += 1;
\\}
,
- ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
+ ".tmp_source.zig:9:18: error: cast increases pointer alignment",
+ ".tmp_source.zig:9:23: note: '*align(1) u32' has alignment 1",
+ ".tmp_source.zig:9:18: note: '*[1]u32' has alignment 4",
+ );
- cases.add("increase pointer alignment in @ptrCast",
+ cases.add(
+ "increase pointer alignment in @ptrCast",
\\export fn entry() u32 {
\\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
- \\ const ptr = @ptrCast(&u32, &bytes[0]);
- \\ return *ptr;
+ \\ const ptr = @ptrCast(*u32, &bytes[0]);
+ \\ return ptr.*;
\\}
,
".tmp_source.zig:3:17: error: cast increases pointer alignment",
- ".tmp_source.zig:3:38: note: '&u8' has alignment 1",
- ".tmp_source.zig:3:27: note: '&u32' has alignment 4");
-
- cases.add("increase pointer alignment in slice resize",
- \\export fn entry() u32 {
- \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
- \\ return ([]u32)(bytes[0..])[0];
- \\}
- ,
- ".tmp_source.zig:3:19: error: cast increases pointer alignment",
- ".tmp_source.zig:3:19: note: '[]u8' has alignment 1",
- ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");
+ ".tmp_source.zig:3:38: note: '*u8' has alignment 1",
+ ".tmp_source.zig:3:26: note: '*u32' has alignment 4",
+ );
- cases.add("@alignCast expects pointer or slice",
+ cases.add(
+ "@alignCast expects pointer or slice",
\\export fn entry() void {
\\ @alignCast(4, u32(3));
\\}
,
- ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");
+ ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'",
+ );
- cases.add("passing an under-aligned function pointer",
+ cases.add(
+ "passing an under-aligned function pointer",
\\export fn entry() void {
\\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
\\}
@@ -2454,26 +3983,32 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
\\fn alignedSmall() align(4) i32 { return 1234; }
,
- ".tmp_source.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'");
+ ".tmp_source.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'",
+ );
- cases.add("passing a not-aligned-enough pointer to cmpxchg",
+ cases.add(
+ "passing a not-aligned-enough pointer to cmpxchg",
\\const AtomicOrder = @import("builtin").AtomicOrder;
\\export fn entry() bool {
\\ var x: i32 align(1) = 1234;
- \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
+ \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
\\ return x == 5678;
\\}
,
- ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");
+ ".tmp_source.zig:4:32: error: expected type '*i32', found '*align(1) i32'",
+ );
- cases.add("wrong size to an array literal",
+ cases.add(
+ "wrong size to an array literal",
\\comptime {
\\ const array = [2]u8{1, 2, 3};
\\}
,
- ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal");
+ ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal",
+ );
- cases.add("@setEvalBranchQuota in non-root comptime execution context",
+ cases.add(
+ "@setEvalBranchQuota in non-root comptime execution context",
\\comptime {
\\ foo();
\\}
@@ -2483,72 +4018,82 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
,
".tmp_source.zig:5:5: error: @setEvalBranchQuota must be called from the top of the comptime stack",
".tmp_source.zig:2:8: note: called from here",
- ".tmp_source.zig:1:10: note: called from here");
+ ".tmp_source.zig:1:10: note: called from here",
+ );
- cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",
+ cases.add(
+ "wrong pointer implicitly casted to pointer to @OpaqueType()",
\\const Derp = @OpaqueType();
- \\extern fn bar(d: &Derp) void;
+ \\extern fn bar(d: *Derp) void;
\\export fn foo() void {
\\ var x = u8(1);
- \\ bar(@ptrCast(&c_void, &x));
+ \\ bar(@ptrCast(*c_void, &x));
\\}
,
- ".tmp_source.zig:5:9: error: expected type '&Derp', found '&c_void'");
+ ".tmp_source.zig:5:9: error: expected type '*Derp', found '*c_void'",
+ );
- cases.add("non-const variables of things that require const variables",
+ cases.add(
+ "non-const variables of things that require const variables",
\\const Opaque = @OpaqueType();
\\
- \\export fn entry(opaque: &Opaque) void {
+ \\export fn entry(opaque: *Opaque) void {
\\ var m2 = &2;
- \\ const y: u32 = *m2;
+ \\ const y: u32 = m2.*;
\\
\\ var a = undefined;
\\ var b = 1;
\\ var c = 1.0;
\\ var d = this;
\\ var e = null;
- \\ var f = *opaque;
+ \\ var f = opaque.*;
\\ var g = i32;
- \\ var h = @import("std");
+ \\ var h = @import("std",);
\\ var i = (Foo {}).bar;
\\
\\ var z: noreturn = return;
\\}
\\
\\const Foo = struct {
- \\ fn bar(self: &const Foo) void {}
+ \\ fn bar(self: *const Foo) void {}
\\};
,
- ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",
+ ".tmp_source.zig:4:4: error: variable of type '*comptime_int' must be const or comptime",
".tmp_source.zig:7:4: error: variable of type '(undefined)' must be const or comptime",
- ".tmp_source.zig:8:4: error: variable of type '(integer literal)' must be const or comptime",
- ".tmp_source.zig:9:4: error: variable of type '(float literal)' must be const or comptime",
+ ".tmp_source.zig:8:4: error: variable of type 'comptime_int' must be const or comptime",
+ ".tmp_source.zig:9:4: error: variable of type 'comptime_float' must be const or comptime",
".tmp_source.zig:10:4: error: variable of type '(block)' must be const or comptime",
".tmp_source.zig:11:4: error: variable of type '(null)' must be const or comptime",
- ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",
+ ".tmp_source.zig:12:4: error: variable of type 'Opaque' not allowed",
".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",
".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",
- ".tmp_source.zig:15:4: error: variable of type '(bound fn(&const Foo) void)' must be const or comptime",
- ".tmp_source.zig:17:4: error: unreachable code");
+ ".tmp_source.zig:15:4: error: variable of type '(bound fn(*const Foo) void)' must be const or comptime",
+ ".tmp_source.zig:17:4: error: unreachable code",
+ );
- cases.add("wrong types given to atomic order args in cmpxchg",
+ cases.add(
+ "wrong types given to atomic order args in cmpxchg",
\\export fn entry() void {
\\ var x: i32 = 1234;
- \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}
+ \\ while (!@cmpxchgWeak(i32, &x, 1234, 5678, u32(1234), u32(1234))) {}
\\}
,
- ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");
+ ".tmp_source.zig:3:50: error: expected type 'AtomicOrder', found 'u32'",
+ );
- cases.add("wrong types given to @export",
+ cases.add(
+ "wrong types given to @export",
\\extern fn entry() void { }
\\comptime {
\\ @export("entry", entry, u32(1234));
\\}
,
- ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'");
+ ".tmp_source.zig:3:32: error: expected type 'GlobalLinkage', found 'u32'",
+ );
- cases.add("struct with invalid field",
- \\const std = @import("std");
+ cases.add(
+ "struct with invalid field",
+ \\const std = @import("std",);
\\const Allocator = std.mem.Allocator;
\\const ArrayList = std.ArrayList;
\\
@@ -2572,23 +4117,29 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ };
\\}
,
- ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'");
+ ".tmp_source.zig:14:17: error: use of undeclared identifier 'HeaderValue'",
+ );
- cases.add("@setAlignStack outside function",
+ cases.add(
+ "@setAlignStack outside function",
\\comptime {
\\ @setAlignStack(16);
\\}
,
- ".tmp_source.zig:2:5: error: @setAlignStack outside function");
+ ".tmp_source.zig:2:5: error: @setAlignStack outside function",
+ );
- cases.add("@setAlignStack in naked function",
+ cases.add(
+ "@setAlignStack in naked function",
\\export nakedcc fn entry() void {
\\ @setAlignStack(16);
\\}
,
- ".tmp_source.zig:2:5: error: @setAlignStack in naked function");
+ ".tmp_source.zig:2:5: error: @setAlignStack in naked function",
+ );
- cases.add("@setAlignStack in inline function",
+ cases.add(
+ "@setAlignStack in inline function",
\\export fn entry() void {
\\ foo();
\\}
@@ -2596,25 +4147,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ @setAlignStack(16);
\\}
,
- ".tmp_source.zig:5:5: error: @setAlignStack in inline function");
+ ".tmp_source.zig:5:5: error: @setAlignStack in inline function",
+ );
- cases.add("@setAlignStack set twice",
+ cases.add(
+ "@setAlignStack set twice",
\\export fn entry() void {
\\ @setAlignStack(16);
\\ @setAlignStack(16);
\\}
,
".tmp_source.zig:3:5: error: alignstack set twice",
- ".tmp_source.zig:2:5: note: first set here");
+ ".tmp_source.zig:2:5: note: first set here",
+ );
- cases.add("@setAlignStack too big",
+ cases.add(
+ "@setAlignStack too big",
\\export fn entry() void {
\\ @setAlignStack(511 + 1);
\\}
,
- ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256");
+ ".tmp_source.zig:2:5: error: attempt to @setAlignStack(512); maximum is 256",
+ );
- cases.add("storing runtime value in compile time variable then using it",
+ cases.add(
+ "storing runtime value in compile time variable then using it",
\\const Mode = @import("builtin").Mode;
\\
\\fn Free(comptime filename: []const u8) TestCase {
@@ -2657,134 +4214,164 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ }
\\}
,
- ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable");
+ ".tmp_source.zig:37:16: error: cannot store runtime value in compile time variable",
+ );
- cases.add("field access of opaque type",
+ cases.add(
+ "field access of opaque type",
\\const MyType = @OpaqueType();
\\
\\export fn entry() bool {
\\ var x: i32 = 1;
- \\ return bar(@ptrCast(&MyType, &x));
+ \\ return bar(@ptrCast(*MyType, &x));
\\}
\\
- \\fn bar(x: &MyType) bool {
+ \\fn bar(x: *MyType) bool {
\\ return x.blah;
\\}
,
- ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
+ ".tmp_source.zig:9:13: error: type '*MyType' does not support field access",
+ );
- cases.add("carriage return special case",
+ cases.add(
+ "carriage return special case",
"fn test() bool {\r\n" ++
- " true\r\n" ++
- "}\r\n"
- ,
- ".tmp_source.zig:1:17: error: invalid carriage return, only '\\n' line endings are supported");
-
- cases.add("non-printable invalid character",
- "\xff\xfe" ++
- \\fn test() bool {\r
- \\ true\r
- \\}
- ,
- ".tmp_source.zig:1:1: error: invalid character: '\\xff'");
+ " true\r\n" ++
+ "}\r\n",
+ ".tmp_source.zig:1:17: error: invalid carriage return, only '\\n' line endings are supported",
+ );
+
+ cases.add(
+ "non-printable invalid character",
+ "\xff\xfe" ++
+ \\fn test() bool {\r
+ \\ true\r
+ \\}
+ ,
+ ".tmp_source.zig:1:1: error: invalid character: '\\xff'",
+ );
- cases.add("non-printable invalid character with escape alternative",
+ cases.add(
+ "non-printable invalid character with escape alternative",
"fn test() bool {\n" ++
- "\ttrue\n" ++
- "}\n"
- ,
- ".tmp_source.zig:2:1: error: invalid character: '\\t'");
+ "\ttrue\n" ++
+ "}\n",
+ ".tmp_source.zig:2:1: error: invalid character: '\\t'",
+ );
- cases.add("@ArgType given non function parameter",
+ cases.add(
+ "@ArgType given non function parameter",
\\comptime {
\\ _ = @ArgType(i32, 3);
\\}
,
- ".tmp_source.zig:2:18: error: expected function, found 'i32'");
+ ".tmp_source.zig:2:18: error: expected function, found 'i32'",
+ );
- cases.add("@ArgType arg index out of bounds",
+ cases.add(
+ "@ArgType arg index out of bounds",
\\comptime {
\\ _ = @ArgType(@typeOf(add), 2);
\\}
\\fn add(a: i32, b: i32) i32 { return a + b; }
,
- ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments");
+ ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments",
+ );
- cases.add("@memberType on unsupported type",
+ cases.add(
+ "@memberType on unsupported type",
\\comptime {
\\ _ = @memberType(i32, 0);
\\}
,
- ".tmp_source.zig:2:21: error: type 'i32' does not support @memberType");
+ ".tmp_source.zig:2:21: error: type 'i32' does not support @memberType",
+ );
- cases.add("@memberType on enum",
+ cases.add(
+ "@memberType on enum",
\\comptime {
\\ _ = @memberType(Foo, 0);
\\}
\\const Foo = enum {A,};
,
- ".tmp_source.zig:2:21: error: type 'Foo' does not support @memberType");
+ ".tmp_source.zig:2:21: error: type 'Foo' does not support @memberType",
+ );
- cases.add("@memberType struct out of bounds",
+ cases.add(
+ "@memberType struct out of bounds",
\\comptime {
\\ _ = @memberType(Foo, 0);
\\}
\\const Foo = struct {};
,
- ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
+ ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
+ );
- cases.add("@memberType union out of bounds",
+ cases.add(
+ "@memberType union out of bounds",
\\comptime {
\\ _ = @memberType(Foo, 1);
\\}
\\const Foo = union {A: void,};
,
- ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
+ ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
+ );
- cases.add("@memberName on unsupported type",
+ cases.add(
+ "@memberName on unsupported type",
\\comptime {
\\ _ = @memberName(i32, 0);
\\}
,
- ".tmp_source.zig:2:21: error: type 'i32' does not support @memberName");
+ ".tmp_source.zig:2:21: error: type 'i32' does not support @memberName",
+ );
- cases.add("@memberName struct out of bounds",
+ cases.add(
+ "@memberName struct out of bounds",
\\comptime {
\\ _ = @memberName(Foo, 0);
\\}
\\const Foo = struct {};
,
- ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members");
+ ".tmp_source.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
+ );
- cases.add("@memberName enum out of bounds",
+ cases.add(
+ "@memberName enum out of bounds",
\\comptime {
\\ _ = @memberName(Foo, 1);
\\}
\\const Foo = enum {A,};
,
- ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
+ ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
+ );
- cases.add("@memberName union out of bounds",
+ cases.add(
+ "@memberName union out of bounds",
\\comptime {
\\ _ = @memberName(Foo, 1);
\\}
\\const Foo = union {A:i32,};
,
- ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
+ ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
+ );
- cases.add("calling var args extern function, passing array instead of pointer",
+ cases.add(
+ "calling var args extern function, passing array instead of pointer",
\\export fn entry() void {
- \\ foo("hello");
+ \\ foo("hello",);
\\}
- \\pub extern fn foo(format: &const u8, ...) void;
+ \\pub extern fn foo(format: *const u8, ...) void;
,
- ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
+ ".tmp_source.zig:2:9: error: expected type '*const u8', found '[5]u8'",
+ );
- cases.add("constant inside comptime function has compile error",
+ cases.add(
+ "constant inside comptime function has compile error",
\\const ContextAllocator = MemoryPool(usize);
\\
\\pub fn MemoryPool(comptime T: type) type {
- \\ const free_list_t = @compileError("aoeu");
+ \\ const free_list_t = @compileError("aoeu",);
\\
\\ return struct {
\\ free_list: free_list_t,
@@ -2797,9 +4384,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
,
".tmp_source.zig:4:25: error: aoeu",
".tmp_source.zig:1:36: note: called from here",
- ".tmp_source.zig:12:20: note: referenced here");
+ ".tmp_source.zig:12:20: note: referenced here",
+ );
- cases.add("specify enum tag type that is too small",
+ cases.add(
+ "specify enum tag type that is too small",
\\const Small = enum (u2) {
\\ One,
\\ Two,
@@ -2812,9 +4401,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x = Small.One;
\\}
,
- ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'");
+ ".tmp_source.zig:1:20: error: 'u2' too small to hold all bits; must be at least 'u3'",
+ );
- cases.add("specify non-integer enum tag type",
+ cases.add(
+ "specify non-integer enum tag type",
\\const Small = enum (f32) {
\\ One,
\\ Two,
@@ -2825,9 +4416,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x = Small.One;
\\}
,
- ".tmp_source.zig:1:20: error: expected integer, found 'f32'");
+ ".tmp_source.zig:1:20: error: expected integer, found 'f32'",
+ );
- cases.add("implicitly casting enum to tag type",
+ cases.add(
+ "implicitly casting enum to tag type",
\\const Small = enum(u2) {
\\ One,
\\ Two,
@@ -2839,23 +4432,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x: u2 = Small.Two;
\\}
,
- ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'");
-
- cases.add("explicitly casting enum to non tag type",
- \\const Small = enum(u2) {
- \\ One,
- \\ Two,
- \\ Three,
- \\ Four,
- \\};
- \\
- \\export fn entry() void {
- \\ var x = u3(Small.Two);
- \\}
- ,
- ".tmp_source.zig:9:15: error: enum to integer cast to 'u3' instead of its tag type, 'u2'");
+ ".tmp_source.zig:9:22: error: expected type 'u2', found 'Small'",
+ );
- cases.add("explicitly casting non tag type to enum",
+ cases.add(
+ "explicitly casting non tag type to enum",
\\const Small = enum(u2) {
\\ One,
\\ Two,
@@ -2865,12 +4446,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\
\\export fn entry() void {
\\ var y = u3(3);
- \\ var x = Small(y);
+ \\ var x = @intToEnum(Small, y);
\\}
,
- ".tmp_source.zig:10:18: error: integer to enum cast from 'u3' instead of its tag type, 'u2'");
+ ".tmp_source.zig:10:31: error: expected type 'u2', found 'u3'",
+ );
- cases.add("non unsigned integer enum tag type",
+ cases.add(
+ "non unsigned integer enum tag type",
\\const Small = enum(i2) {
\\ One,
\\ Two,
@@ -2882,9 +4465,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var y = Small.Two;
\\}
,
- ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'");
+ ".tmp_source.zig:1:19: error: expected unsigned integer, found 'i2'",
+ );
- cases.add("struct fields with value assignments",
+ cases.add(
+ "struct fields with value assignments",
\\const MultipleChoice = struct {
\\ A: i32 = 20,
\\};
@@ -2892,9 +4477,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var x: MultipleChoice = undefined;
\\}
,
- ".tmp_source.zig:2:14: error: enums, not structs, support field assignment");
+ ".tmp_source.zig:2:14: error: enums, not structs, support field assignment",
+ );
- cases.add("union fields with value assignments",
+ cases.add(
+ "union fields with value assignments",
\\const MultipleChoice = union {
\\ A: i32 = 20,
\\};
@@ -2903,25 +4490,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:2:14: error: non-enum union field assignment",
- ".tmp_source.zig:1:24: note: consider 'union(enum)' here");
+ ".tmp_source.zig:1:24: note: consider 'union(enum)' here",
+ );
- cases.add("enum with 0 fields",
+ cases.add(
+ "enum with 0 fields",
\\const Foo = enum {};
\\export fn entry() usize {
\\ return @sizeOf(Foo);
\\}
,
- ".tmp_source.zig:1:13: error: enums must have 1 or more fields");
+ ".tmp_source.zig:1:13: error: enums must have 1 or more fields",
+ );
- cases.add("union with 0 fields",
+ cases.add(
+ "union with 0 fields",
\\const Foo = union {};
\\export fn entry() usize {
\\ return @sizeOf(Foo);
\\}
,
- ".tmp_source.zig:1:13: error: unions must have 1 or more fields");
+ ".tmp_source.zig:1:13: error: unions must have 1 or more fields",
+ );
- cases.add("enum value already taken",
+ cases.add(
+ "enum value already taken",
\\const MultipleChoice = enum(u32) {
\\ A = 20,
\\ B = 40,
@@ -2934,9 +4527,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:6:9: error: enum tag value 60 already taken",
- ".tmp_source.zig:4:9: note: other occurrence here");
+ ".tmp_source.zig:4:9: note: other occurrence here",
+ );
- cases.add("union with specified enum omits field",
+ cases.add(
+ "union with specified enum omits field",
\\const Letter = enum {
\\ A,
\\ B,
@@ -2951,9 +4546,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:6:17: error: enum field missing: 'C'",
- ".tmp_source.zig:4:5: note: declared here");
+ ".tmp_source.zig:4:5: note: declared here",
+ );
- cases.add("@TagType when union has no attached enum",
+ cases.add(
+ "@TagType when union has no attached enum",
\\const Foo = union {
\\ A: i32,
\\};
@@ -2962,9 +4559,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:5:24: error: union 'Foo' has no tag",
- ".tmp_source.zig:1:13: note: consider 'union(enum)' here");
+ ".tmp_source.zig:1:13: note: consider 'union(enum)' here",
+ );
- cases.add("non-integer tag type to automatic union enum",
+ cases.add(
+ "non-integer tag type to automatic union enum",
\\const Foo = union(enum(f32)) {
\\ A: i32,
\\};
@@ -2972,9 +4571,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ const x = @TagType(Foo);
\\}
,
- ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'");
+ ".tmp_source.zig:1:23: error: expected integer tag type, found 'f32'",
+ );
- cases.add("non-enum tag type passed to union",
+ cases.add(
+ "non-enum tag type passed to union",
\\const Foo = union(u32) {
\\ A: i32,
\\};
@@ -2982,9 +4583,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ const x = @TagType(Foo);
\\}
,
- ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'");
+ ".tmp_source.zig:1:18: error: expected enum tag type, found 'u32'",
+ );
- cases.add("union auto-enum value already taken",
+ cases.add(
+ "union auto-enum value already taken",
\\const MultipleChoice = union(enum(u32)) {
\\ A = 20,
\\ B = 40,
@@ -2997,9 +4600,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:6:9: error: enum tag value 60 already taken",
- ".tmp_source.zig:4:9: note: other occurrence here");
+ ".tmp_source.zig:4:9: note: other occurrence here",
+ );
- cases.add("union enum field does not match enum",
+ cases.add(
+ "union enum field does not match enum",
\\const Letter = enum {
\\ A,
\\ B,
@@ -3016,9 +4621,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:10:5: error: enum field not found: 'D'",
- ".tmp_source.zig:1:16: note: enum declared here");
+ ".tmp_source.zig:1:16: note: enum declared here",
+ );
- cases.add("field type supplied in an enum",
+ cases.add(
+ "field type supplied in an enum",
\\const Letter = enum {
\\ A: void,
\\ B,
@@ -3029,9 +4636,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:2:8: error: structs and unions, not enums, support field types",
- ".tmp_source.zig:1:16: note: consider 'union(enum)' here");
+ ".tmp_source.zig:1:16: note: consider 'union(enum)' here",
+ );
- cases.add("struct field missing type",
+ cases.add(
+ "struct field missing type",
\\const Letter = struct {
\\ A,
\\};
@@ -3039,9 +4648,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var a = Letter { .A = {} };
\\}
,
- ".tmp_source.zig:2:5: error: struct field missing type");
+ ".tmp_source.zig:2:5: error: struct field missing type",
+ );
- cases.add("extern union field missing type",
+ cases.add(
+ "extern union field missing type",
\\const Letter = extern union {
\\ A,
\\};
@@ -3049,9 +4660,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var a = Letter { .A = {} };
\\}
,
- ".tmp_source.zig:2:5: error: union field missing type");
+ ".tmp_source.zig:2:5: error: union field missing type",
+ );
- cases.add("extern union given enum tag type",
+ cases.add(
+ "extern union given enum tag type",
\\const Letter = enum {
\\ A,
\\ B,
@@ -3066,9 +4679,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var a = Payload { .A = 1234 };
\\}
,
- ".tmp_source.zig:6:29: error: extern union does not support enum tag type");
+ ".tmp_source.zig:6:29: error: extern union does not support enum tag type",
+ );
- cases.add("packed union given enum tag type",
+ cases.add(
+ "packed union given enum tag type",
\\const Letter = enum {
\\ A,
\\ B,
@@ -3083,9 +4698,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ var a = Payload { .A = 1234 };
\\}
,
- ".tmp_source.zig:6:29: error: packed union does not support enum tag type");
+ ".tmp_source.zig:6:29: error: packed union does not support enum tag type",
+ );
- cases.add("switch on union with no attached enum",
+ cases.add(
+ "switch on union with no attached enum",
\\const Payload = union {
\\ A: i32,
\\ B: f64,
@@ -3095,29 +4712,33 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\ const a = Payload { .A = 1234 };
\\ foo(a);
\\}
- \\fn foo(a: &const Payload) void {
- \\ switch (*a) {
+ \\fn foo(a: *const Payload) void {
+ \\ switch (a.*) {
\\ Payload.A => {},
\\ else => unreachable,
\\ }
\\}
,
- ".tmp_source.zig:11:13: error: switch on union which has no attached enum",
- ".tmp_source.zig:1:17: note: consider 'union(enum)' here");
+ ".tmp_source.zig:11:14: error: switch on union which has no attached enum",
+ ".tmp_source.zig:1:17: note: consider 'union(enum)' here",
+ );
- cases.add("enum in field count range but not matching tag",
+ cases.add(
+ "enum in field count range but not matching tag",
\\const Foo = enum(u32) {
\\ A = 10,
\\ B = 11,
\\};
\\export fn entry() void {
- \\ var x = Foo(0);
+ \\ var x = @intToEnum(Foo, 0);
\\}
,
- ".tmp_source.zig:6:16: error: enum 'Foo' has no tag matching integer value 0",
- ".tmp_source.zig:1:13: note: 'Foo' declared here");
+ ".tmp_source.zig:6:13: error: enum 'Foo' has no tag matching integer value 0",
+ ".tmp_source.zig:1:13: note: 'Foo' declared here",
+ );
- cases.add("comptime cast enum to union but field has payload",
+ cases.add(
+ "comptime cast enum to union but field has payload",
\\const Letter = enum { A, B, C };
\\const Value = union(Letter) {
\\ A: i32,
@@ -3129,9 +4750,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:8:26: error: cast to union 'Value' must initialize 'i32' field 'A'",
- ".tmp_source.zig:3:5: note: field 'A' declared here");
+ ".tmp_source.zig:3:5: note: field 'A' declared here",
+ );
- cases.add("runtime cast to union which has non-void fields",
+ cases.add(
+ "runtime cast to union which has non-void fields",
\\const Letter = enum { A, B, C };
\\const Value = union(Letter) {
\\ A: i32,
@@ -3146,27 +4769,52 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\}
,
".tmp_source.zig:11:20: error: runtime cast to union 'Value' which has non-void fields",
- ".tmp_source.zig:3:5: note: field 'A' has type 'i32'");
+ ".tmp_source.zig:3:5: note: field 'A' has type 'i32'",
+ );
- cases.add("self-referencing function pointer field",
- \\const S = struct {
- \\ f: fn(_: S) void,
+ cases.add(
+ "taking offset of void field in struct",
+ \\const Empty = struct {
+ \\ val: void,
\\};
- \\fn f(_: S) void {
- \\}
- \\export fn entry() void {
- \\ var _ = S { .f = f };
+ \\export fn foo() void {
+ \\ const fieldOffset = @offsetOf(Empty, "val",);
\\}
,
- ".tmp_source.zig:4:9: error: type 'S' is not copyable; cannot pass by value");
+ ".tmp_source.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset",
+ );
- cases.add("taking offset of void field in struct",
- \\const Empty = struct {
- \\ val: void,
+ cases.add(
+ "invalid union field access in comptime",
+ \\const Foo = union {
+ \\ Bar: u8,
+ \\ Baz: void,
\\};
- \\export fn foo() void {
- \\ const fieldOffset = @offsetOf(Empty, "val");
+ \\comptime {
+ \\ var foo = Foo {.Baz = {}};
+ \\ const bar_val = foo.Bar;
+ \\}
+ ,
+ ".tmp_source.zig:7:24: error: accessing union field 'Bar' while field 'Baz' is set",
+ );
+
+ cases.add(
+ "getting return type of generic function",
+ \\fn generic(a: var) void {}
+ \\comptime {
+ \\ _ = @typeOf(generic).ReturnType;
+ \\}
+ ,
+ ".tmp_source.zig:3:25: error: ReturnType has not been resolved because 'fn(var)var' is generic",
+ );
+
+ cases.add(
+ "getting @ArgType of generic function",
+ \\fn generic(a: var) void {}
+ \\comptime {
+ \\ _ = @ArgType(@typeOf(generic), 0);
\\}
,
- ".tmp_source.zig:5:42: error: zero-bit field 'val' in struct 'Empty' has no offset");
+ ".tmp_source.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var)var' is generic",
+ );
}
diff --git a/test/gen_h.zig b/test/gen_h.zig
index 30d168cf2c..b3aaa263d6 100644
--- a/test/gen_h.zig
+++ b/test/gen_h.zig
@@ -1,6 +1,6 @@
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.GenHContext) void {
+pub fn addCases(cases: *tests.GenHContext) void {
cases.add("declare enum",
\\const Foo = extern enum { A, B, C };
\\export fn entry(foo: Foo) void { }
@@ -54,7 +54,7 @@ pub fn addCases(cases: &tests.GenHContext) void {
cases.add("declare opaque type",
\\export const Foo = @OpaqueType();
\\
- \\export fn entry(foo: ?&Foo) void { }
+ \\export fn entry(foo: ?*Foo) void { }
,
\\struct Foo;
\\
@@ -64,7 +64,7 @@ pub fn addCases(cases: &tests.GenHContext) void {
cases.add("array field-type",
\\const Foo = extern struct {
\\ A: [2]i32,
- \\ B: [4]&u32,
+ \\ B: [4]*u32,
\\};
\\export fn entry(foo: Foo, bar: [3]u8) void { }
,
@@ -77,4 +77,50 @@ pub fn addCases(cases: &tests.GenHContext) void {
\\
);
+ cases.add("ptr to zig struct",
+ \\const S = struct {
+ \\ a: u8,
+ \\};
+ \\
+ \\export fn a(s: *S) u8 {
+ \\ return s.a;
+ \\}
+
+ ,
+ \\struct S;
+ \\TEST_EXPORT uint8_t a(struct S * s);
+ \\
+ );
+
+ cases.add("ptr to zig union",
+ \\const U = union(enum) {
+ \\ A: u8,
+ \\ B: u16,
+ \\};
+ \\
+ \\export fn a(s: *U) u8 {
+ \\ return s.A;
+ \\}
+
+ ,
+ \\union U;
+ \\TEST_EXPORT uint8_t a(union U * s);
+ \\
+ );
+
+ cases.add("ptr to zig enum",
+ \\const E = enum(u8) {
+ \\ A,
+ \\ B,
+ \\};
+ \\
+ \\export fn a(s: *E) u8 {
+ \\ return @enumToInt(s.*);
+ \\}
+
+ ,
+ \\enum E;
+ \\TEST_EXPORT uint8_t a(enum E * s);
+ \\
+ );
}
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 1fea6347ab..3d58dfe748 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -1,8 +1,65 @@
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.CompareOutputContext) void {
+pub fn addCases(cases: *tests.CompareOutputContext) void {
+ cases.addRuntimeSafety("@intToEnum - no matching tag value",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\const Foo = enum {
+ \\ A,
+ \\ B,
+ \\ C,
+ \\};
+ \\pub fn main() void {
+ \\ baz(bar(3));
+ \\}
+ \\fn bar(a: u2) Foo {
+ \\ return @intToEnum(Foo, a);
+ \\}
+ \\fn baz(a: Foo) void {}
+ );
+
+ cases.addRuntimeSafety("@floatToInt cannot fit - negative to unsigned",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ baz(bar(-1.1));
+ \\}
+ \\fn bar(a: f32) u8 {
+ \\ return @floatToInt(u8, a);
+ \\}
+ \\fn baz(a: u8) void { }
+ );
+
+ cases.addRuntimeSafety("@floatToInt cannot fit - negative out of range",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ baz(bar(-129.1));
+ \\}
+ \\fn bar(a: f32) i8 {
+ \\ return @floatToInt(i8, a);
+ \\}
+ \\fn baz(a: i8) void { }
+ );
+
+ cases.addRuntimeSafety("@floatToInt cannot fit - positive out of range",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
+ \\ @import("std").os.exit(126);
+ \\}
+ \\pub fn main() void {
+ \\ baz(bar(256.2));
+ \\}
+ \\fn bar(a: f32) u8 {
+ \\ return @floatToInt(u8, a);
+ \\}
+ \\fn baz(a: u8) void { }
+ );
+
cases.addRuntimeSafety("calling panic",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() void {
@@ -11,7 +68,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("out of bounds slice access",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() void {
@@ -25,7 +82,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("integer addition overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -38,7 +95,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("integer subtraction overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -51,7 +108,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("integer multiplication overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -64,7 +121,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("integer negation overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -77,7 +134,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("signed integer division overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -90,7 +147,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("signed shift left overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -103,7 +160,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("unsigned shift left overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -116,7 +173,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("signed shift right overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -129,7 +186,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("unsigned shift right overflow",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -142,7 +199,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("integer division by zero",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() void {
@@ -154,7 +211,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("exact division failure",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -167,7 +224,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -175,12 +232,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ if (x.len == 0) return error.Whatever;
\\}
\\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
- \\ return ([]align(1) const i32)(slice);
+ \\ return @bytesToSlice(i32, slice);
\\}
);
cases.addRuntimeSafety("value does not fit in shortening cast",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -188,12 +245,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ if (x == 0) return error.Whatever;
\\}
\\fn shorten_cast(x: i32) i8 {
- \\ return i8(x);
+ \\ return @intCast(i8, x);
\\}
);
cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
@@ -201,12 +258,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ if (x == 0) return error.Whatever;
\\}
\\fn unsigned_cast(x: i32) u32 {
- \\ return u32(x);
+ \\ return @intCast(u32, x);
\\}
);
cases.addRuntimeSafety("unwrap error",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
\\ @import("std").os.exit(126); // good
\\ }
@@ -221,19 +278,19 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
);
cases.addRuntimeSafety("cast integer to global error and no code matches",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() void {
\\ _ = bar(9999);
\\}
- \\fn bar(x: u32) error {
- \\ return error(x);
+ \\fn bar(x: u16) error {
+ \\ return @intToError(x);
\\}
);
- cases.addRuntimeSafety("cast integer to non-global error set and no match",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ cases.addRuntimeSafety("@errSetCast error not present in destination",
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\const Set1 = error{A, B};
@@ -242,28 +299,28 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ _ = foo(Set1.B);
\\}
\\fn foo(set1: Set1) Set2 {
- \\ return Set2(set1);
+ \\ return @errSetCast(Set2, set1);
\\}
);
cases.addRuntimeSafety("@alignCast misaligned",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() !void {
\\ var array align(4) = []u32{0x11111111, 0x11111111};
- \\ const bytes = ([]u8)(array[0..]);
+ \\ const bytes = @sliceToBytes(array[0..]);
\\ if (foo(bytes) != 0x11111111) return error.Wrong;
\\}
\\fn foo(bytes: []u8) u32 {
\\ const slice4 = bytes[1..5];
- \\ const int_slice = ([]u32)(@alignCast(4, slice4));
+ \\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));
\\ return int_slice[0];
\\}
);
cases.addRuntimeSafety("bad union field access",
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\
@@ -277,7 +334,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ bar(&f);
\\}
\\
- \\fn bar(f: &Foo) void {
+ \\fn bar(f: *Foo) void {
\\ f.float = 12.34;
\\}
);
@@ -287,7 +344,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.addRuntimeSafety("error return trace across suspend points",
\\const std = @import("std");
\\
- \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
+ \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {
\\ std.os.exit(126);
\\}
\\
diff --git a/test/stage2/compare_output.zig b/test/stage2/compare_output.zig
new file mode 100644
index 0000000000..fdc3d49145
--- /dev/null
+++ b/test/stage2/compare_output.zig
@@ -0,0 +1,25 @@
+const std = @import("std");
+const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
+
+pub fn addCases(ctx: *TestContext) !void {
+ // hello world
+ try ctx.testCompareOutputLibC(
+ \\extern fn puts([*]const u8) void;
+ \\export fn main() c_int {
+ \\ puts(c"Hello, world!");
+ \\ return 0;
+ \\}
+ , "Hello, world!" ++ std.cstr.line_sep);
+
+ // function calling another function
+ try ctx.testCompareOutputLibC(
+ \\extern fn puts(s: [*]const u8) void;
+ \\export fn main() c_int {
+ \\ return foo(c"OK");
+ \\}
+ \\fn foo(s: [*]const u8) c_int {
+ \\ puts(s);
+ \\ return 0;
+ \\}
+ , "OK" ++ std.cstr.line_sep);
+}
diff --git a/test/stage2/compile_errors.zig b/test/stage2/compile_errors.zig
new file mode 100644
index 0000000000..2cecd78653
--- /dev/null
+++ b/test/stage2/compile_errors.zig
@@ -0,0 +1,30 @@
+const TestContext = @import("../../src-self-hosted/test.zig").TestContext;
+
+pub fn addCases(ctx: *TestContext) !void {
+ try ctx.testCompileError(
+ \\export fn entry() void {}
+ \\export fn entry() void {}
+ , "1.zig", 2, 8, "exported symbol collision: 'entry'");
+
+ try ctx.testCompileError(
+ \\fn() void {}
+ , "1.zig", 1, 1, "missing function name");
+
+ try ctx.testCompileError(
+ \\comptime {
+ \\ return;
+ \\}
+ , "1.zig", 2, 5, "return expression outside function definition");
+
+ try ctx.testCompileError(
+ \\export fn entry() void {
+ \\ defer return;
+ \\}
+ , "1.zig", 2, 11, "cannot return from defer expression");
+
+ try ctx.testCompileError(
+ \\export fn entry() c_int {
+ \\ return 36893488147419103232;
+ \\}
+ , "1.zig", 2, 12, "integer value '36893488147419103232' cannot be stored in type 'c_int'");
+}
diff --git a/test/standalone/brace_expansion/build.zig b/test/standalone/brace_expansion/build.zig
index 7752f599df..64f3c08583 100644
--- a/test/standalone/brace_expansion/build.zig
+++ b/test/standalone/brace_expansion/build.zig
@@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) void {
+pub fn build(b: *Builder) void {
const main = b.addTest("main.zig");
main.setBuildMode(b.standardReleaseOptions());
diff --git a/test/standalone/brace_expansion/main.zig b/test/standalone/brace_expansion/main.zig
index d4d86ae12c..ccb4f6dd45 100644
--- a/test/standalone/brace_expansion/main.zig
+++ b/test/standalone/brace_expansion/main.zig
@@ -14,9 +14,9 @@ const Token = union(enum) {
Eof,
};
-var global_allocator: &mem.Allocator = undefined;
+var global_allocator: *mem.Allocator = undefined;
-fn tokenize(input:[] const u8) !ArrayList(Token) {
+fn tokenize(input: []const u8) !ArrayList(Token) {
const State = enum {
Start,
Word,
@@ -41,7 +41,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
State.Word => switch (b) {
'a'...'z', 'A'...'Z' => {},
'{', '}', ',' => {
- try token_list.append(Token { .Word = input[tok_begin..i] });
+ try token_list.append(Token{ .Word = input[tok_begin..i] });
switch (b) {
'{' => try token_list.append(Token.OpenBrace),
'}' => try token_list.append(Token.CloseBrace),
@@ -56,7 +56,7 @@ fn tokenize(input:[] const u8) !ArrayList(Token) {
}
switch (state) {
State.Start => {},
- State.Word => try token_list.append(Token {.Word = input[tok_begin..] }),
+ State.Word => try token_list.append(Token{ .Word = input[tok_begin..] }),
}
try token_list.append(Token.Eof);
return token_list;
@@ -68,24 +68,24 @@ const Node = union(enum) {
Combine: []Node,
};
-const ParseError = error {
+const ParseError = error{
InvalidInput,
OutOfMemory,
};
-fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
- const first_token = tokens.items[*token_index];
- *token_index += 1;
+fn parse(tokens: *const ArrayList(Token), token_index: *usize) ParseError!Node {
+ const first_token = tokens.items[token_index.*];
+ token_index.* += 1;
const result_node = switch (first_token) {
- Token.Word => |word| Node { .Scalar = word },
+ Token.Word => |word| Node{ .Scalar = word },
Token.OpenBrace => blk: {
var list = ArrayList(Node).init(global_allocator);
while (true) {
try list.append(try parse(tokens, token_index));
- const token = tokens.items[*token_index];
- *token_index += 1;
+ const token = tokens.items[token_index.*];
+ token_index.* += 1;
switch (token) {
Token.CloseBrace => break,
@@ -93,23 +93,23 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node {
else => return error.InvalidInput,
}
}
- break :blk Node { .List = list };
+ break :blk Node{ .List = list };
},
else => return error.InvalidInput,
};
- switch (tokens.items[*token_index]) {
+ switch (tokens.items[token_index.*]) {
Token.Word, Token.OpenBrace => {
const pair = try global_allocator.alloc(Node, 2);
pair[0] = result_node;
pair[1] = try parse(tokens, token_index);
- return Node { .Combine = pair };
+ return Node{ .Combine = pair };
},
else => return result_node,
}
}
-fn expandString(input: []const u8, output: &Buffer) !void {
+fn expandString(input: []const u8, output: *Buffer) !void {
const tokens = try tokenize(input);
if (tokens.len == 1) {
return output.resize(0);
@@ -137,13 +137,11 @@ fn expandString(input: []const u8, output: &Buffer) !void {
}
}
-const ExpandNodeError = error {
- OutOfMemory,
-};
+const ExpandNodeError = error{OutOfMemory};
-fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void {
+fn expandNode(node: *const Node, output: *ArrayList(Buffer)) ExpandNodeError!void {
assert(output.len == 0);
- switch (*node) {
+ switch (node.*) {
Node.Scalar => |scalar| {
try output.append(try Buffer.init(global_allocator, scalar));
},
diff --git a/test/standalone/issue_339/build.zig b/test/standalone/issue_339/build.zig
index f3ab327006..733b3729c1 100644
--- a/test/standalone/issue_339/build.zig
+++ b/test/standalone/issue_339/build.zig
@@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) void {
+pub fn build(b: *Builder) void {
const obj = b.addObject("test", "test.zig");
const test_step = b.step("test", "Test the program");
diff --git a/test/standalone/issue_339/test.zig b/test/standalone/issue_339/test.zig
index f65b9f734e..f4068dcfac 100644
--- a/test/standalone/issue_339/test.zig
+++ b/test/standalone/issue_339/test.zig
@@ -1,5 +1,8 @@
const StackTrace = @import("builtin").StackTrace;
-pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) noreturn { @breakpoint(); while (true) {} }
+pub fn panic(msg: []const u8, stack_trace: ?*StackTrace) noreturn {
+ @breakpoint();
+ while (true) {}
+}
fn bar() error!void {}
diff --git a/test/standalone/issue_794/build.zig b/test/standalone/issue_794/build.zig
index 4f5dcd7ff4..06c37a83a3 100644
--- a/test/standalone/issue_794/build.zig
+++ b/test/standalone/issue_794/build.zig
@@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) void {
+pub fn build(b: *Builder) void {
const test_artifact = b.addTest("main.zig");
test_artifact.addIncludeDir("a_directory");
diff --git a/test/standalone/load_dynamic_library/add.zig b/test/standalone/load_dynamic_library/add.zig
new file mode 100644
index 0000000000..a04ec1544d
--- /dev/null
+++ b/test/standalone/load_dynamic_library/add.zig
@@ -0,0 +1,3 @@
+export fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
diff --git a/test/standalone/load_dynamic_library/build.zig b/test/standalone/load_dynamic_library/build.zig
new file mode 100644
index 0000000000..2d47a893f2
--- /dev/null
+++ b/test/standalone/load_dynamic_library/build.zig
@@ -0,0 +1,21 @@
+const Builder = @import("std").build.Builder;
+
+pub fn build(b: *Builder) void {
+ const opts = b.standardReleaseOptions();
+
+ const lib = b.addSharedLibrary("add", "add.zig", b.version(1, 0, 0));
+ lib.setBuildMode(opts);
+
+ const main = b.addExecutable("main", "main.zig");
+ main.setBuildMode(opts);
+
+ const run = b.addCommand(".", b.env_map, [][]const u8{
+ main.getOutputPath(),
+ lib.getOutputPath(),
+ });
+ run.step.dependOn(&lib.step);
+ run.step.dependOn(&main.step);
+
+ const test_step = b.step("test", "Test the program");
+ test_step.dependOn(&run.step);
+}
diff --git a/test/standalone/load_dynamic_library/main.zig b/test/standalone/load_dynamic_library/main.zig
new file mode 100644
index 0000000000..4c45ad6fde
--- /dev/null
+++ b/test/standalone/load_dynamic_library/main.zig
@@ -0,0 +1,17 @@
+const std = @import("std");
+
+pub fn main() !void {
+ const args = try std.os.argsAlloc(std.debug.global_allocator);
+ defer std.os.argsFree(std.debug.global_allocator, args);
+
+ const dynlib_name = args[1];
+
+ var lib = try std.DynLib.open(std.debug.global_allocator, dynlib_name);
+ defer lib.close();
+
+ const addr = lib.lookup("add") orelse return error.SymbolNotFound;
+ const addFn = @intToPtr(extern fn (i32, i32) i32, addr);
+
+ const result = addFn(12, 34);
+ std.debug.assert(result == 46);
+}
diff --git a/test/standalone/pkg_import/build.zig b/test/standalone/pkg_import/build.zig
index bb9416d3c4..e0b3885dc3 100644
--- a/test/standalone/pkg_import/build.zig
+++ b/test/standalone/pkg_import/build.zig
@@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) void {
+pub fn build(b: *Builder) void {
const exe = b.addExecutable("test", "test.zig");
exe.addPackagePath("my_pkg", "pkg.zig");
diff --git a/test/standalone/pkg_import/pkg.zig b/test/standalone/pkg_import/pkg.zig
index abb977a2ef..19ab525b81 100644
--- a/test/standalone/pkg_import/pkg.zig
+++ b/test/standalone/pkg_import/pkg.zig
@@ -1 +1,3 @@
-pub fn add(a: i32, b: i32) i32 { return a + b; }
+pub fn add(a: i32, b: i32) i32 {
+ return a + b;
+}
diff --git a/test/standalone/use_alias/build.zig b/test/standalone/use_alias/build.zig
index ecbba297d8..c700d43db9 100644
--- a/test/standalone/use_alias/build.zig
+++ b/test/standalone/use_alias/build.zig
@@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) void {
+pub fn build(b: *Builder) void {
b.addCIncludePath(".");
const main = b.addTest("main.zig");
diff --git a/test/standalone/use_alias/main.zig b/test/standalone/use_alias/main.zig
index 40cab9ad8a..873393cef7 100644
--- a/test/standalone/use_alias/main.zig
+++ b/test/standalone/use_alias/main.zig
@@ -2,7 +2,7 @@ const c = @import("c.zig");
const assert = @import("std").debug.assert;
test "symbol exists" {
- var foo = c.Foo {
+ var foo = c.Foo{
.a = 1,
.b = 1,
};
diff --git a/test/tests.zig b/test/tests.zig
index 19a4f82b74..aa5eed17ee 100644
--- a/test/tests.zig
+++ b/test/tests.zig
@@ -27,18 +27,18 @@ const TestTarget = struct {
environ: builtin.Environ,
};
-const test_targets = []TestTarget {
- TestTarget {
+const test_targets = []TestTarget{
+ TestTarget{
.os = builtin.Os.linux,
.arch = builtin.Arch.x86_64,
.environ = builtin.Environ.gnu,
},
- TestTarget {
+ TestTarget{
.os = builtin.Os.macosx,
.arch = builtin.Arch.x86_64,
.environ = builtin.Environ.unknown,
},
- TestTarget {
+ TestTarget{
.os = builtin.Os.windows,
.arch = builtin.Arch.x86_64,
.environ = builtin.Environ.msvc,
@@ -47,120 +47,117 @@ const test_targets = []TestTarget {
const max_stdout_size = 1 * 1024 * 1024; // 1 MB
-pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(CompareOutputContext) catch unreachable;
- *cases = CompareOutputContext {
+pub fn addCompareOutputTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
+ const cases = b.allocator.create(CompareOutputContext{
.b = b,
.step = b.step("test-compare-output", "Run the compare output tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ .modes = modes,
+ }) catch unreachable;
compare_output.addCases(cases);
return cases.step;
}
-pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(CompareOutputContext) catch unreachable;
- *cases = CompareOutputContext {
+pub fn addRuntimeSafetyTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
+ const cases = b.allocator.create(CompareOutputContext{
.b = b,
.step = b.step("test-runtime-safety", "Run the runtime safety tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ .modes = modes,
+ }) catch unreachable;
runtime_safety.addCases(cases);
return cases.step;
}
-pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(CompileErrorContext) catch unreachable;
- *cases = CompileErrorContext {
+pub fn addCompileErrorTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
+ const cases = b.allocator.create(CompileErrorContext{
.b = b,
.step = b.step("test-compile-errors", "Run the compile error tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ .modes = modes,
+ }) catch unreachable;
compile_errors.addCases(cases);
return cases.step;
}
-pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
- *cases = BuildExamplesContext {
+pub fn addBuildExampleTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
+ const cases = b.allocator.create(BuildExamplesContext{
.b = b,
.step = b.step("test-build-examples", "Build the examples"),
.test_index = 0,
.test_filter = test_filter,
- };
+ .modes = modes,
+ }) catch unreachable;
build_examples.addCases(cases);
return cases.step;
}
-pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(CompareOutputContext) catch unreachable;
- *cases = CompareOutputContext {
+pub fn addAssembleAndLinkTests(b: *build.Builder, test_filter: ?[]const u8, modes: []const Mode) *build.Step {
+ const cases = b.allocator.create(CompareOutputContext{
.b = b,
.step = b.step("test-asm-link", "Run the assemble and link tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ .modes = modes,
+ }) catch unreachable;
assemble_and_link.addCases(cases);
return cases.step;
}
-pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(TranslateCContext) catch unreachable;
- *cases = TranslateCContext {
+pub fn addTranslateCTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
+ const cases = b.allocator.create(TranslateCContext{
.b = b,
.step = b.step("test-translate-c", "Run the C transation tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ }) catch unreachable;
translate_c.addCases(cases);
return cases.step;
}
-pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
- const cases = b.allocator.create(GenHContext) catch unreachable;
- *cases = GenHContext {
+pub fn addGenHTests(b: *build.Builder, test_filter: ?[]const u8) *build.Step {
+ const cases = b.allocator.create(GenHContext{
.b = b,
.step = b.step("test-gen-h", "Run the C header file generation tests"),
.test_index = 0,
.test_filter = test_filter,
- };
+ }) catch unreachable;
gen_h.addCases(cases);
return cases.step;
}
-
-pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,
- name:[] const u8, desc: []const u8, with_lldb: bool) &build.Step
-{
+pub fn addPkgTests(b: *build.Builder, test_filter: ?[]const u8, root_src: []const u8, name: []const u8, desc: []const u8, modes: []const Mode) *build.Step {
const step = b.step(b.fmt("test-{}", name), desc);
for (test_targets) |test_target| {
const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);
- for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
- for ([]bool{false, true}) |link_libc| {
+ for (modes) |mode| {
+ for ([]bool{
+ false,
+ true,
+ }) |link_libc| {
if (link_libc and !is_native) {
// don't assume we have a cross-compiling libc set up
continue;
}
const these_tests = b.addTest(root_src);
- these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os),
- @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
+ these_tests.setNamePrefix(b.fmt("{}-{}-{}-{}-{} ", name, @tagName(test_target.os), @tagName(test_target.arch), @tagName(mode), if (link_libc) "c" else "bare"));
these_tests.setFilter(test_filter);
these_tests.setBuildMode(mode);
if (!is_native) {
@@ -169,10 +166,6 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
if (link_libc) {
these_tests.linkSystemLibrary("c");
}
- if (with_lldb) {
- these_tests.setExecCmd([]?[]const u8{
- "lldb", null, "-o", "run", "-o", "bt", "-o", "exit"});
- }
step.dependOn(&these_tests.step);
}
}
@@ -181,10 +174,11 @@ pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []cons
}
pub const CompareOutputContext = struct {
- b: &build.Builder,
- step: &build.Step,
+ b: *build.Builder,
+ step: *build.Step,
test_index: usize,
test_filter: ?[]const u8,
+ modes: []const Mode,
const Special = enum {
None,
@@ -205,34 +199,30 @@ pub const CompareOutputContext = struct {
source: []const u8,
};
- pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
- self.sources.append(SourceFile {
+ pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
+ self.sources.append(SourceFile{
.filename = filename,
.source = source,
}) catch unreachable;
}
- pub fn setCommandLineArgs(self: &TestCase, args: []const []const u8) void {
+ pub fn setCommandLineArgs(self: *TestCase, args: []const []const u8) void {
self.cli_args = args;
}
};
const RunCompareOutputStep = struct {
step: build.Step,
- context: &CompareOutputContext,
+ context: *CompareOutputContext,
exe_path: []const u8,
name: []const u8,
expected_output: []const u8,
test_index: usize,
cli_args: []const []const u8,
- pub fn create(context: &CompareOutputContext, exe_path: []const u8,
- name: []const u8, expected_output: []const u8,
- cli_args: []const []const u8) &RunCompareOutputStep
- {
+ pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8, expected_output: []const u8, cli_args: []const []const u8) *RunCompareOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
- *ptr = RunCompareOutputStep {
+ const ptr = allocator.create(RunCompareOutputStep{
.context = context,
.exe_path = exe_path,
.name = name,
@@ -240,12 +230,12 @@ pub const CompareOutputContext = struct {
.test_index = context.test_index,
.step = build.Step.init("RunCompareOutput", allocator, make),
.cli_args = cli_args,
- };
+ }) catch unreachable;
context.test_index += 1;
return ptr;
}
- fn make(step: &build.Step) !void {
+ fn make(step: *build.Step) !void {
const self = @fieldParentPtr(RunCompareOutputStep, "step", step);
const b = self.context.b;
@@ -258,7 +248,7 @@ pub const CompareOutputContext = struct {
args.append(arg) catch unreachable;
}
- warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
+ warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
const child = os.ChildProcess.init(args.toSliceConst(), b.allocator) catch unreachable;
defer child.deinit();
@@ -273,8 +263,8 @@ pub const CompareOutputContext = struct {
var stdout = Buffer.initNull(b.allocator);
var stderr = Buffer.initNull(b.allocator);
- var stdout_file_in_stream = io.FileInStream.init(&??child.stdout);
- var stderr_file_in_stream = io.FileInStream.init(&??child.stderr);
+ var stdout_file_in_stream = io.FileInStream.init(&child.stdout.?);
+ var stderr_file_in_stream = io.FileInStream.init(&child.stderr.?);
stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size) catch unreachable;
stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size) catch unreachable;
@@ -295,7 +285,6 @@ pub const CompareOutputContext = struct {
},
}
-
if (!mem.eql(u8, self.expected_output, stdout.toSliceConst())) {
warn(
\\
@@ -313,34 +302,32 @@ pub const CompareOutputContext = struct {
const RuntimeSafetyRunStep = struct {
step: build.Step,
- context: &CompareOutputContext,
+ context: *CompareOutputContext,
exe_path: []const u8,
name: []const u8,
test_index: usize,
- pub fn create(context: &CompareOutputContext, exe_path: []const u8,
- name: []const u8) &RuntimeSafetyRunStep
- {
+ pub fn create(context: *CompareOutputContext, exe_path: []const u8, name: []const u8) *RuntimeSafetyRunStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
- *ptr = RuntimeSafetyRunStep {
+ const ptr = allocator.create(RuntimeSafetyRunStep{
.context = context,
.exe_path = exe_path,
.name = name,
.test_index = context.test_index,
.step = build.Step.init("RuntimeSafetyRun", allocator, make),
- };
+ }) catch unreachable;
+
context.test_index += 1;
return ptr;
}
- fn make(step: &build.Step) !void {
+ fn make(step: *build.Step) !void {
const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
const b = self.context.b;
const full_exe_path = b.pathFromRoot(self.exe_path);
- warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
+ warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
const child = os.ChildProcess.init([][]u8{full_exe_path}, b.allocator) catch unreachable;
defer child.deinit();
@@ -358,19 +345,16 @@ pub const CompareOutputContext = struct {
switch (term) {
Term.Exited => |code| {
if (code != expected_exit_code) {
- warn("\nProgram expected to exit with code {} " ++
- "but exited with code {}\n", expected_exit_code, code);
+ warn("\nProgram expected to exit with code {} " ++ "but exited with code {}\n", expected_exit_code, code);
return error.TestFailed;
}
},
Term.Signal => |sig| {
- warn("\nProgram expected to exit with code {} " ++
- "but instead signaled {}\n", expected_exit_code, sig);
+ warn("\nProgram expected to exit with code {} " ++ "but instead signaled {}\n", expected_exit_code, sig);
return error.TestFailed;
},
else => {
- warn("\nProgram expected to exit with code {}" ++
- " but exited in an unexpected way\n", expected_exit_code);
+ warn("\nProgram expected to exit with code {}" ++ " but exited in an unexpected way\n", expected_exit_code);
return error.TestFailed;
},
}
@@ -379,10 +363,8 @@ pub const CompareOutputContext = struct {
}
};
- pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8,
- expected_output: []const u8, special: Special) TestCase
- {
- var tc = TestCase {
+ pub fn createExtra(self: *CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8, special: Special) TestCase {
+ var tc = TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_output = expected_output,
@@ -395,34 +377,32 @@ pub const CompareOutputContext = struct {
return tc;
}
- pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8,
- expected_output: []const u8) TestCase
- {
+ pub fn create(self: *CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) TestCase {
return createExtra(self, name, source, expected_output, Special.None);
}
- pub fn addC(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
+ pub fn addC(self: *CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
var tc = self.create(name, source, expected_output);
tc.link_libc = true;
self.addCase(tc);
}
- pub fn add(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
+ pub fn add(self: *CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
const tc = self.create(name, source, expected_output);
self.addCase(tc);
}
- pub fn addAsm(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
+ pub fn addAsm(self: *CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
const tc = self.createExtra(name, source, expected_output, Special.Asm);
self.addCase(tc);
}
- pub fn addRuntimeSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) void {
+ pub fn addRuntimeSafety(self: *CompareOutputContext, name: []const u8, source: []const u8) void {
const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
self.addCase(tc);
}
- pub fn addCase(self: &CompareOutputContext, case: &const TestCase) void {
+ pub fn addCase(self: *CompareOutputContext, case: *const TestCase) void {
const b = self.b;
const root_src = os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename) catch unreachable;
@@ -431,8 +411,7 @@ pub const CompareOutputContext = struct {
Special.Asm => {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "assemble-and-link {}", case.name) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- return;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
const exe = b.addExecutable("test", null);
@@ -444,19 +423,16 @@ pub const CompareOutputContext = struct {
exe.step.dependOn(&write_src.step);
}
- const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name,
- case.expected_output, case.cli_args);
+ const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
run_and_cmp_output.step.dependOn(&exe.step);
self.step.dependOn(&run_and_cmp_output.step);
},
Special.None => {
- for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
- const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})",
- "compare-output", case.name, @tagName(mode)) catch unreachable;
+ for (self.modes) |mode| {
+ const annotated_case_name = fmt.allocPrint(self.b.allocator, "{} {} ({})", "compare-output", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- continue;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
}
const exe = b.addExecutable("test", root_src);
@@ -471,8 +447,7 @@ pub const CompareOutputContext = struct {
exe.step.dependOn(&write_src.step);
}
- const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(),
- annotated_case_name, case.expected_output, case.cli_args);
+ const run_and_cmp_output = RunCompareOutputStep.create(self, exe.getOutputPath(), annotated_case_name, case.expected_output, case.cli_args);
run_and_cmp_output.step.dependOn(&exe.step);
self.step.dependOn(&run_and_cmp_output.step);
@@ -481,8 +456,7 @@ pub const CompareOutputContext = struct {
Special.RuntimeSafety => {
const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- return;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
const exe = b.addExecutable("test", root_src);
@@ -506,10 +480,11 @@ pub const CompareOutputContext = struct {
};
pub const CompileErrorContext = struct {
- b: &build.Builder,
- step: &build.Step,
+ b: *build.Builder,
+ step: *build.Step,
test_index: usize,
test_filter: ?[]const u8,
+ modes: []const Mode,
const TestCase = struct {
name: []const u8,
@@ -523,44 +498,42 @@ pub const CompileErrorContext = struct {
source: []const u8,
};
- pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
- self.sources.append(SourceFile {
+ pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
+ self.sources.append(SourceFile{
.filename = filename,
.source = source,
}) catch unreachable;
}
- pub fn addExpectedError(self: &TestCase, text: []const u8) void {
+ pub fn addExpectedError(self: *TestCase, text: []const u8) void {
self.expected_errors.append(text) catch unreachable;
}
};
const CompileCmpOutputStep = struct {
step: build.Step,
- context: &CompileErrorContext,
+ context: *CompileErrorContext,
name: []const u8,
test_index: usize,
- case: &const TestCase,
+ case: *const TestCase,
build_mode: Mode,
- pub fn create(context: &CompileErrorContext, name: []const u8,
- case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep
- {
+ pub fn create(context: *CompileErrorContext, name: []const u8, case: *const TestCase, build_mode: Mode) *CompileCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
- *ptr = CompileCmpOutputStep {
+ const ptr = allocator.create(CompileCmpOutputStep{
.step = build.Step.init("CompileCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
.build_mode = build_mode,
- };
+ }) catch unreachable;
+
context.test_index += 1;
return ptr;
}
- fn make(step: &build.Step) !void {
+ fn make(step: *build.Step) !void {
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
const b = self.context.b;
@@ -583,9 +556,10 @@ pub const CompileErrorContext = struct {
Mode.Debug => {},
Mode.ReleaseSafe => zig_args.append("--release-safe") catch unreachable,
Mode.ReleaseFast => zig_args.append("--release-fast") catch unreachable,
+ Mode.ReleaseSmall => zig_args.append("--release-small") catch unreachable,
}
- warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
+ warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
if (b.verbose) {
printInvocation(zig_args.toSliceConst());
@@ -604,8 +578,8 @@ pub const CompileErrorContext = struct {
var stdout_buf = Buffer.initNull(b.allocator);
var stderr_buf = Buffer.initNull(b.allocator);
- var stdout_file_in_stream = io.FileInStream.init(&??child.stdout);
- var stderr_file_in_stream = io.FileInStream.init(&??child.stderr);
+ var stdout_file_in_stream = io.FileInStream.init(&child.stdout.?);
+ var stderr_file_in_stream = io.FileInStream.init(&child.stderr.?);
stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size) catch unreachable;
stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size) catch unreachable;
@@ -625,7 +599,6 @@ pub const CompileErrorContext = struct {
},
}
-
const stdout = stdout_buf.toSliceConst();
const stderr = stderr_buf.toSliceConst();
@@ -665,17 +638,15 @@ pub const CompileErrorContext = struct {
warn("\n");
}
- pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,
- expected_lines: ...) &TestCase
- {
- const tc = self.b.allocator.create(TestCase) catch unreachable;
- *tc = TestCase {
+ pub fn create(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
+ const tc = self.b.allocator.create(TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_errors = ArrayList([]const u8).init(self.b.allocator),
.link_libc = false,
.is_exe = false,
- };
+ }) catch unreachable;
+
tc.addSourceFile(".tmp_source.zig", source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
@@ -684,32 +655,30 @@ pub const CompileErrorContext = struct {
return tc;
}
- pub fn addC(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn addC(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
var tc = self.create(name, source, expected_lines);
tc.link_libc = true;
self.addCase(tc);
}
- pub fn addExe(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn addExe(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
var tc = self.create(name, source, expected_lines);
tc.is_exe = true;
self.addCase(tc);
}
- pub fn add(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn add(self: *CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
const tc = self.create(name, source, expected_lines);
self.addCase(tc);
}
- pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {
+ pub fn addCase(self: *CompileErrorContext, case: *const TestCase) void {
const b = self.b;
- for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
- const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})",
- case.name, @tagName(mode)) catch unreachable;
+ for (self.modes) |mode| {
+ const annotated_case_name = fmt.allocPrint(self.b.allocator, "compile-error {} ({})", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- continue;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
}
const compile_and_cmp_errors = CompileCmpOutputStep.create(self, annotated_case_name, case, mode);
@@ -725,26 +694,26 @@ pub const CompileErrorContext = struct {
};
pub const BuildExamplesContext = struct {
- b: &build.Builder,
- step: &build.Step,
+ b: *build.Builder,
+ step: *build.Step,
test_index: usize,
test_filter: ?[]const u8,
+ modes: []const Mode,
- pub fn addC(self: &BuildExamplesContext, root_src: []const u8) void {
+ pub fn addC(self: *BuildExamplesContext, root_src: []const u8) void {
self.addAllArgs(root_src, true);
}
- pub fn add(self: &BuildExamplesContext, root_src: []const u8) void {
+ pub fn add(self: *BuildExamplesContext, root_src: []const u8) void {
self.addAllArgs(root_src, false);
}
- pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) void {
+ pub fn addBuildFile(self: *BuildExamplesContext, build_file: []const u8) void {
const b = self.b;
const annotated_case_name = b.fmt("build {} (Debug)", build_file);
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- return;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
var zig_args = ArrayList([]const u8).init(b.allocator);
@@ -769,15 +738,13 @@ pub const BuildExamplesContext = struct {
self.step.dependOn(&log_step.step);
}
- pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void {
+ pub fn addAllArgs(self: *BuildExamplesContext, root_src: []const u8, link_libc: bool) void {
const b = self.b;
- for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
- const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})",
- root_src, @tagName(mode)) catch unreachable;
+ for (self.modes) |mode| {
+ const annotated_case_name = fmt.allocPrint(self.b.allocator, "build {} ({})", root_src, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- continue;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) continue;
}
const exe = b.addExecutable("test", root_src);
@@ -795,8 +762,8 @@ pub const BuildExamplesContext = struct {
};
pub const TranslateCContext = struct {
- b: &build.Builder,
- step: &build.Step,
+ b: *build.Builder,
+ step: *build.Step,
test_index: usize,
test_filter: ?[]const u8,
@@ -811,40 +778,40 @@ pub const TranslateCContext = struct {
source: []const u8,
};
- pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
- self.sources.append(SourceFile {
+ pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
+ self.sources.append(SourceFile{
.filename = filename,
.source = source,
}) catch unreachable;
}
- pub fn addExpectedLine(self: &TestCase, text: []const u8) void {
+ pub fn addExpectedLine(self: *TestCase, text: []const u8) void {
self.expected_lines.append(text) catch unreachable;
}
};
const TranslateCCmpOutputStep = struct {
step: build.Step,
- context: &TranslateCContext,
+ context: *TranslateCContext,
name: []const u8,
test_index: usize,
- case: &const TestCase,
+ case: *const TestCase,
- pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep {
+ pub fn create(context: *TranslateCContext, name: []const u8, case: *const TestCase) *TranslateCCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
- *ptr = TranslateCCmpOutputStep {
+ const ptr = allocator.create(TranslateCCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.name = name,
.test_index = context.test_index,
.case = case,
- };
+ }) catch unreachable;
+
context.test_index += 1;
return ptr;
}
- fn make(step: &build.Step) !void {
+ fn make(step: *build.Step) !void {
const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
const b = self.context.b;
@@ -856,7 +823,7 @@ pub const TranslateCContext = struct {
zig_args.append("translate-c") catch unreachable;
zig_args.append(b.pathFromRoot(root_src)) catch unreachable;
- warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
+ warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
if (b.verbose) {
printInvocation(zig_args.toSliceConst());
@@ -875,8 +842,8 @@ pub const TranslateCContext = struct {
var stdout_buf = Buffer.initNull(b.allocator);
var stderr_buf = Buffer.initNull(b.allocator);
- var stdout_file_in_stream = io.FileInStream.init(&??child.stdout);
- var stderr_file_in_stream = io.FileInStream.init(&??child.stderr);
+ var stdout_file_in_stream = io.FileInStream.init(&child.stdout.?);
+ var stderr_file_in_stream = io.FileInStream.init(&child.stderr.?);
stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size) catch unreachable;
stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size) catch unreachable;
@@ -938,16 +905,14 @@ pub const TranslateCContext = struct {
warn("\n");
}
- pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8,
- source: []const u8, expected_lines: ...) &TestCase
- {
- const tc = self.b.allocator.create(TestCase) catch unreachable;
- *tc = TestCase {
+ pub fn create(self: *TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
+ const tc = self.b.allocator.create(TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
.allow_warnings = allow_warnings,
- };
+ }) catch unreachable;
+
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
@@ -956,28 +921,27 @@ pub const TranslateCContext = struct {
return tc;
}
- pub fn add(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn add(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
const tc = self.create(false, "source.h", name, source, expected_lines);
self.addCase(tc);
}
- pub fn addC(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn addC(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
const tc = self.create(false, "source.c", name, source, expected_lines);
self.addCase(tc);
}
- pub fn addAllowWarnings(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn addAllowWarnings(self: *TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
const tc = self.create(true, "source.h", name, source, expected_lines);
self.addCase(tc);
}
- pub fn addCase(self: &TranslateCContext, case: &const TestCase) void {
+ pub fn addCase(self: *TranslateCContext, case: *const TestCase) void {
const b = self.b;
const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- return;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
const translate_c_and_cmp = TranslateCCmpOutputStep.create(self, annotated_case_name, case);
@@ -992,8 +956,8 @@ pub const TranslateCContext = struct {
};
pub const GenHContext = struct {
- b: &build.Builder,
- step: &build.Step,
+ b: *build.Builder,
+ step: *build.Step,
test_index: usize,
test_filter: ?[]const u8,
@@ -1007,46 +971,46 @@ pub const GenHContext = struct {
source: []const u8,
};
- pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
- self.sources.append(SourceFile {
+ pub fn addSourceFile(self: *TestCase, filename: []const u8, source: []const u8) void {
+ self.sources.append(SourceFile{
.filename = filename,
.source = source,
}) catch unreachable;
}
- pub fn addExpectedLine(self: &TestCase, text: []const u8) void {
+ pub fn addExpectedLine(self: *TestCase, text: []const u8) void {
self.expected_lines.append(text) catch unreachable;
}
};
const GenHCmpOutputStep = struct {
step: build.Step,
- context: &GenHContext,
+ context: *GenHContext,
h_path: []const u8,
name: []const u8,
test_index: usize,
- case: &const TestCase,
+ case: *const TestCase,
- pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep {
+ pub fn create(context: *GenHContext, h_path: []const u8, name: []const u8, case: *const TestCase) *GenHCmpOutputStep {
const allocator = context.b.allocator;
- const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
- *ptr = GenHCmpOutputStep {
+ const ptr = allocator.create(GenHCmpOutputStep{
.step = build.Step.init("ParseCCmpOutput", allocator, make),
.context = context,
.h_path = h_path,
.name = name,
.test_index = context.test_index,
.case = case,
- };
+ }) catch unreachable;
+
context.test_index += 1;
return ptr;
}
- fn make(step: &build.Step) !void {
+ fn make(step: *build.Step) !void {
const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
const b = self.context.b;
- warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
+ warn("Test {}/{} {}...", self.test_index + 1, self.context.test_index, self.name);
const full_h_path = b.pathFromRoot(self.h_path);
const actual_h = try io.readFileAlloc(b.allocator, full_h_path);
@@ -1075,15 +1039,13 @@ pub const GenHContext = struct {
warn("\n");
}
- pub fn create(self: &GenHContext, filename: []const u8, name: []const u8,
- source: []const u8, expected_lines: ...) &TestCase
- {
- const tc = self.b.allocator.create(TestCase) catch unreachable;
- *tc = TestCase {
+ pub fn create(self: *GenHContext, filename: []const u8, name: []const u8, source: []const u8, expected_lines: ...) *TestCase {
+ const tc = self.b.allocator.create(TestCase{
.name = name,
.sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
.expected_lines = ArrayList([]const u8).init(self.b.allocator),
- };
+ }) catch unreachable;
+
tc.addSourceFile(filename, source);
comptime var arg_i = 0;
inline while (arg_i < expected_lines.len) : (arg_i += 1) {
@@ -1092,20 +1054,19 @@ pub const GenHContext = struct {
return tc;
}
- pub fn add(self: &GenHContext, name: []const u8, source: []const u8, expected_lines: ...) void {
+ pub fn add(self: *GenHContext, name: []const u8, source: []const u8, expected_lines: ...) void {
const tc = self.create("test.zig", name, source, expected_lines);
self.addCase(tc);
}
- pub fn addCase(self: &GenHContext, case: &const TestCase) void {
+ pub fn addCase(self: *GenHContext, case: *const TestCase) void {
const b = self.b;
const root_src = os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename) catch unreachable;
const mode = builtin.Mode.Debug;
const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;
if (self.test_filter) |filter| {
- if (mem.indexOf(u8, annotated_case_name, filter) == null)
- return;
+ if (mem.indexOf(u8, annotated_case_name, filter) == null) return;
}
const obj = b.addObject("test", root_src);
diff --git a/test/translate_c.zig b/test/translate_c.zig
index 9a69c2b03e..b31e515aa2 100644
--- a/test/translate_c.zig
+++ b/test/translate_c.zig
@@ -1,6 +1,72 @@
const tests = @import("tests.zig");
-pub fn addCases(cases: &tests.TranslateCContext) void {
+pub fn addCases(cases: *tests.TranslateCContext) void {
+ cases.add("for loop with var init but empty body",
+ \\void foo(void) {
+ \\ for (int x = 0; x < 10; x++);
+ \\}
+ ,
+ \\pub fn foo() void {
+ \\ {
+ \\ var x: c_int = 0;
+ \\ while (x < 10) : (x += 1) {}
+ \\ }
+ \\}
+ );
+
+ cases.add("do while with empty body",
+ \\void foo(void) {
+ \\ do ; while (1);
+ \\}
+ , // TODO this should be if (1 != 0) break
+ \\pub fn foo() void {
+ \\ while (true) {
+ \\ if (!1) break;
+ \\ }
+ \\}
+ );
+
+ cases.add("for with empty body",
+ \\void foo(void) {
+ \\ for (;;);
+ \\}
+ ,
+ \\pub fn foo() void {
+ \\ while (true) {}
+ \\}
+ );
+
+ cases.add("while with empty body",
+ \\void foo(void) {
+ \\ while (1);
+ \\}
+ ,
+ \\pub fn foo() void {
+ \\ while (1 != 0) {}
+ \\}
+ );
+
+ cases.add("double define struct",
+ \\typedef struct Bar Bar;
+ \\typedef struct Foo Foo;
+ \\
+ \\struct Foo {
+ \\ Foo *a;
+ \\};
+ \\
+ \\struct Bar {
+ \\ Foo *a;
+ \\};
+ ,
+ \\pub const struct_Foo = extern struct {
+ \\ a: ?[*]Foo,
+ \\};
+ \\pub const Foo = struct_Foo;
+ \\pub const struct_Bar = extern struct {
+ \\ a: ?[*]Foo,
+ \\};
+ );
+
cases.addAllowWarnings("simple data types",
\\#include <stdint.h>
\\int foo(char a, unsigned char b, signed char c);
@@ -53,10 +119,32 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub const Foo = enum_Foo;
);
+ cases.add("enums",
+ \\enum Foo {
+ \\ FooA = 2,
+ \\ FooB = 5,
+ \\ Foo1,
+ \\};
+ ,
+ \\pub const enum_Foo = extern enum {
+ \\ A = 2,
+ \\ B = 5,
+ \\ @"1" = 6,
+ \\};
+ ,
+ \\pub const FooA = enum_Foo.A;
+ ,
+ \\pub const FooB = enum_Foo.B;
+ ,
+ \\pub const Foo1 = enum_Foo.@"1";
+ ,
+ \\pub const Foo = enum_Foo;
+ );
+
cases.add("restrict -> noalias",
\\void foo(void *restrict bar, void *restrict);
,
- \\pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void) void;
+ \\pub extern fn foo(noalias bar: ?*c_void, noalias arg1: ?*c_void) void;
);
cases.add("simple struct",
@@ -67,7 +155,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
,
\\const struct_Foo = extern struct {
\\ x: c_int,
- \\ y: ?&u8,
+ \\ y: ?[*]u8,
\\};
,
\\pub const Foo = struct_Foo;
@@ -98,7 +186,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
,
\\pub const BarB = enum_Bar.B;
,
- \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar)) void;
+ \\pub extern fn func(a: ?[*]struct_Foo, b: ?[*](?[*]enum_Bar)) void;
,
\\pub const Foo = struct_Foo;
,
@@ -108,7 +196,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
cases.add("constant size array",
\\void func(int array[20]);
,
- \\pub extern fn func(array: ?&c_int) void;
+ \\pub extern fn func(array: ?[*]c_int) void;
);
cases.add("self referential struct with function pointer",
@@ -117,7 +205,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\};
,
\\pub const struct_Foo = extern struct {
- \\ derp: ?extern fn(?&struct_Foo) void,
+ \\ derp: ?extern fn(?[*]struct_Foo) void,
\\};
,
\\pub const Foo = struct_Foo;
@@ -129,7 +217,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
,
\\pub const struct_Foo = @OpaqueType();
,
- \\pub extern fn some_func(foo: ?&struct_Foo, x: c_int) ?&struct_Foo;
+ \\pub extern fn some_func(foo: ?*struct_Foo, x: c_int) ?*struct_Foo;
,
\\pub const Foo = struct_Foo;
);
@@ -176,11 +264,11 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\};
,
\\pub const struct_Bar = extern struct {
- \\ next: ?&struct_Foo,
+ \\ next: ?[*]struct_Foo,
\\};
,
\\pub const struct_Foo = extern struct {
- \\ next: ?&struct_Bar,
+ \\ next: ?[*]struct_Bar,
\\};
);
@@ -190,7 +278,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
,
\\pub const Foo = c_void;
,
- \\pub extern fn fun(a: ?&Foo) Foo;
+ \\pub extern fn fun(a: ?*Foo) Foo;
);
cases.add("generate inline func for #define global extern fn",
@@ -203,13 +291,13 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub extern var fn_ptr: ?extern fn() void;
,
\\pub inline fn foo() void {
- \\ return (??fn_ptr)();
+ \\ return fn_ptr.?();
\\}
,
\\pub extern var fn_ptr2: ?extern fn(c_int, f32) u8;
,
\\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
- \\ return (??fn_ptr2)(arg0, arg1);
+ \\ return fn_ptr2.?(arg0, arg1);
\\}
);
@@ -462,7 +550,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return 6;
\\}
,
- \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
+ \\pub export fn and_or_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ if ((a != 0) and (b != 0)) return 0;
\\ if ((b != 0) and (c != null)) return 1;
\\ if ((a != 0) and (c != null)) return 2;
@@ -564,8 +652,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub const struct_Foo = extern struct {
\\ field: c_int,
\\};
- \\pub export fn read_field(foo: ?&struct_Foo) c_int {
- \\ return (??foo).field;
+ \\pub export fn read_field(foo: ?[*]struct_Foo) c_int {
+ \\ return foo.?.field;
\\}
);
@@ -595,7 +683,6 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\}
);
-
cases.addC("c style cast",
\\int float_to_int(float a) {
\\ return (int)a;
@@ -611,8 +698,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return x;
\\}
,
- \\pub export fn foo(x: ?&c_ushort) ?&c_void {
- \\ return @ptrCast(?&c_void, x);
+ \\pub export fn foo(x: ?[*]c_ushort) ?*c_void {
+ \\ return @ptrCast(?*c_void, x);
\\}
);
@@ -632,7 +719,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return 0;
\\}
,
- \\pub export fn foo() ?&c_int {
+ \\pub export fn foo() ?[*]c_int {
\\ return null;
\\}
);
@@ -677,43 +764,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ var a: c_int = 0;
\\ a += x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) + 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* + 1);
+ \\ break :x _ref.*;
\\ };
\\ a -= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) - 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* - 1);
+ \\ break :x _ref.*;
\\ };
\\ a *= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) * 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* * 1);
+ \\ break :x _ref.*;
\\ };
\\ a &= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) & 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* & 1);
+ \\ break :x _ref.*;
\\ };
\\ a |= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) | 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* | 1);
+ \\ break :x _ref.*;
\\ };
\\ a ^= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) ^ 1);
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* ^ 1);
+ \\ break :x _ref.*;
\\ };
\\ a >>= @import("std").math.Log2Int(c_int)(x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_int)(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_int)(1));
+ \\ break :x _ref.*;
\\ });
\\ a <<= @import("std").math.Log2Int(c_int)(x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_int)(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_int)(1));
+ \\ break :x _ref.*;
\\ });
\\}
);
@@ -735,43 +822,43 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ var a: c_uint = c_uint(0);
\\ a +%= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) +% c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* +% c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a -%= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) -% c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* -% c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a *%= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) *% c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* *% c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a &= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) & c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* & c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a |= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) | c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* | c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a ^= x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) ^ c_uint(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* ^ c_uint(1));
+ \\ break :x _ref.*;
\\ };
\\ a >>= @import("std").math.Log2Int(c_uint)(x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) >> @import("std").math.Log2Int(c_uint)(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* >> @import("std").math.Log2Int(c_uint)(1));
+ \\ break :x _ref.*;
\\ });
\\ a <<= @import("std").math.Log2Int(c_uint)(x: {
\\ const _ref = &a;
- \\ (*_ref) = ((*_ref) << @import("std").math.Log2Int(c_uint)(1));
- \\ break :x *_ref;
+ \\ _ref.* = (_ref.* << @import("std").math.Log2Int(c_uint)(1));
+ \\ break :x _ref.*;
\\ });
\\}
);
@@ -810,26 +897,26 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ u -%= 1;
\\ i = x: {
\\ const _ref = &i;
- \\ const _tmp = *_ref;
- \\ (*_ref) += 1;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* += 1;
\\ break :x _tmp;
\\ };
\\ i = x: {
\\ const _ref = &i;
- \\ const _tmp = *_ref;
- \\ (*_ref) -= 1;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* -= 1;
\\ break :x _tmp;
\\ };
\\ u = x: {
\\ const _ref = &u;
- \\ const _tmp = *_ref;
- \\ (*_ref) +%= 1;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* +%= 1;
\\ break :x _tmp;
\\ };
\\ u = x: {
\\ const _ref = &u;
- \\ const _tmp = *_ref;
- \\ (*_ref) -%= 1;
+ \\ const _tmp = _ref.*;
+ \\ _ref.* -%= 1;
\\ break :x _tmp;
\\ };
\\}
@@ -858,23 +945,23 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ u -%= 1;
\\ i = x: {
\\ const _ref = &i;
- \\ (*_ref) += 1;
- \\ break :x *_ref;
+ \\ _ref.* += 1;
+ \\ break :x _ref.*;
\\ };
\\ i = x: {
\\ const _ref = &i;
- \\ (*_ref) -= 1;
- \\ break :x *_ref;
+ \\ _ref.* -= 1;
+ \\ break :x _ref.*;
\\ };
\\ u = x: {
\\ const _ref = &u;
- \\ (*_ref) +%= 1;
- \\ break :x *_ref;
+ \\ _ref.* +%= 1;
+ \\ break :x _ref.*;
\\ };
\\ u = x: {
\\ const _ref = &u;
- \\ (*_ref) -%= 1;
- \\ break :x *_ref;
+ \\ _ref.* -%= 1;
+ \\ break :x _ref.*;
\\ };
\\}
);
@@ -927,11 +1014,11 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub export fn bar() void {
\\ var f: ?extern fn() void = foo;
\\ var b: ?extern fn() c_int = baz;
- \\ (??f)();
- \\ (??f)();
+ \\ f.?();
+ \\ f.?();
\\ foo();
- \\ _ = (??b)();
- \\ _ = (??b)();
+ \\ _ = b.?();
+ \\ _ = b.?();
\\ _ = baz();
\\}
);
@@ -941,8 +1028,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ *x = 1;
\\}
,
- \\pub export fn foo(x: ?&c_int) void {
- \\ (*??x) = 1;
+ \\pub export fn foo(x: ?[*]c_int) void {
+ \\ x.?.* = 1;
\\}
);
@@ -969,8 +1056,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
,
\\pub fn foo() c_int {
\\ var x: c_int = 1234;
- \\ var ptr: ?&c_int = &x;
- \\ return *??ptr;
+ \\ var ptr: ?[*]c_int = &x;
+ \\ return ptr.?.*;
\\}
);
@@ -979,7 +1066,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return "bar";
\\}
,
- \\pub fn foo() ?&const u8 {
+ \\pub fn foo() ?[*]const u8 {
\\ return c"bar";
\\}
);
@@ -1077,7 +1164,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\pub const glClearPFN = PFNGLCLEARPROC;
,
\\pub inline fn glClearUnion(arg0: GLbitfield) void {
- \\ return (??glProcs.gl.Clear)(arg0);
+ \\ return glProcs.gl.Clear.?(arg0);
\\}
,
\\pub const OpenGLProcs = union_OpenGLProcs;
@@ -1108,8 +1195,8 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return (float *)a;
\\}
,
- \\fn ptrcast(a: ?&c_int) ?&f32 {
- \\ return @ptrCast(?&f32, a);
+ \\fn ptrcast(a: ?[*]c_int) ?[*]f32 {
+ \\ return @ptrCast(?[*]f32, a);
\\}
);
@@ -1131,7 +1218,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return !c;
\\}
,
- \\pub fn foo(a: c_int, b: f32, c: ?&c_void) c_int {
+ \\pub fn foo(a: c_int, b: f32, c: ?*c_void) c_int {
\\ return !(a == 0);
\\ return !(a != 0);
\\ return !(b != 0);
@@ -1152,7 +1239,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
cases.add("const ptr initializer",
\\static const char *v0 = "0.0.0";
,
- \\pub var v0: ?&const u8 = c"0.0.0";
+ \\pub var v0: ?[*]const u8 = c"0.0.0";
);
cases.add("static incomplete array inside function",
@@ -1161,14 +1248,14 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\}
,
\\pub fn foo() void {
- \\ const v2: &const u8 = c"2.2.2";
+ \\ const v2: [*]const u8 = c"2.2.2";
\\}
);
cases.add("macro pointer cast",
\\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
,
- \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast(&NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr(&NRF_GPIO_Type, NRF_GPIO_BASE) else (&NRF_GPIO_Type)(NRF_GPIO_BASE);
+ \\pub const NRF_GPIO = if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Pointer) @ptrCast([*]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@typeOf(NRF_GPIO_BASE)) == @import("builtin").TypeId.Int) @intToPtr([*]NRF_GPIO_Type, NRF_GPIO_BASE) else ([*]NRF_GPIO_Type)(NRF_GPIO_BASE);
);
cases.add("if on none bool",
@@ -1189,7 +1276,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ B,
\\ C,
\\};
- \\pub fn if_none_bool(a: c_int, b: f32, c: ?&c_void, d: enum_SomeEnum) c_int {
+ \\pub fn if_none_bool(a: c_int, b: f32, c: ?*c_void, d: enum_SomeEnum) c_int {
\\ if (a != 0) return 0;
\\ if (b != 0) return 1;
\\ if (c != null) return 2;
@@ -1206,7 +1293,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn while_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
+ \\pub fn while_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
@@ -1222,7 +1309,7 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ return 3;
\\}
,
- \\pub fn for_none_bool(a: c_int, b: f32, c: ?&c_void) c_int {
+ \\pub fn for_none_bool(a: c_int, b: f32, c: ?*c_void) c_int {
\\ while (a != 0) return 0;
\\ while (b != 0) return 1;
\\ while (c != null) return 2;
@@ -1246,29 +1333,29 @@ pub fn addCases(cases: &tests.TranslateCContext) void {
\\ }
\\}
,
- \\pub fn switch_fn(i: c_int) c_int {
- \\ var res: c_int = 0;
- \\ __switch: {
- \\ __case_2: {
- \\ __default: {
- \\ __case_1: {
- \\ __case_0: {
- \\ switch (i) {
- \\ 0 => break :__case_0,
- \\ 1 => break :__case_1,
- \\ else => break :__default,
- \\ 2 => break :__case_2,
- \\ }
- \\ }
- \\ res = 1;
- \\ }
- \\ res = 2;
- \\ }
- \\ res = (3 * i);
- \\ break :__switch;
- \\ }
- \\ res = 5;
- \\ }
- \\}
+ \\pub fn switch_fn(i: c_int) c_int {
+ \\ var res: c_int = 0;
+ \\ __switch: {
+ \\ __case_2: {
+ \\ __default: {
+ \\ __case_1: {
+ \\ __case_0: {
+ \\ switch (i) {
+ \\ 0 => break :__case_0,
+ \\ 1 => break :__case_1,
+ \\ else => break :__default,
+ \\ 2 => break :__case_2,
+ \\ }
+ \\ }
+ \\ res = 1;
+ \\ }
+ \\ res = 2;
+ \\ }
+ \\ res = (3 * i);
+ \\ break :__switch;
+ \\ }
+ \\ res = 5;
+ \\ }
+ \\}
);
}