aboutsummaryrefslogtreecommitdiff
path: root/test/cases
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/cases
parent06614b3fa09954464c2e2f32756cacedc178a282 (diff)
parent63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff)
downloadzig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz
zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'test/cases')
-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
62 files changed, 2979 insertions, 896 deletions
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);
+}