Commit 2b589d71fb

Robin Voetter <robin@voetter.nl>
2021-11-22 03:32:28
stage2: move some tests which are now passing
1 parent cb24889
test/behavior/cast.zig
@@ -266,3 +266,32 @@ test "array coersion to undefined at runtime" {
     array = undefined;
     try expect(std.mem.eql(u8, &array, &undefined_val));
 }
+
+test "implicitly cast from int to anyerror!?T" {
+    implicitIntLitToOptional();
+    comptime implicitIntLitToOptional();
+}
+fn implicitIntLitToOptional() void {
+    const f: ?i32 = 1;
+    _ = f;
+    const g: anyerror!?i32 = 1;
+    _ = g catch {};
+}
+
+test "return u8 coercing into ?u32 return type" {
+    const S = struct {
+        fn doTheTest() !void {
+            try expect(foo(123).? == 123);
+        }
+        fn foo(arg: u8) ?u32 {
+            return arg;
+        }
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "cast from ?[*]T to ??[*]T" {
+    const a: ??[*]u8 = @as(?[*]u8, null);
+    try expect(a != null and a.? == null);
+}
test/behavior/cast_llvm.zig
@@ -65,3 +65,135 @@ test "implicit ptr to *c_void" {
     var c: *u32 = @ptrCast(*u32, ptr2.?);
     try expect(c.* == 1);
 }
+
+const A = struct {
+    a: i32,
+};
+test "return null from fn() anyerror!?&T" {
+    const a = returnNullFromOptionalTypeErrorRef();
+    const b = returnNullLitFromOptionalTypeErrorRef();
+    try expect((try a) == null and (try b) == null);
+}
+fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
+    const a: ?*A = null;
+    return a;
+}
+fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
+    return null;
+}
+
+test "peer type resolution: [0]u8 and []const u8" {
+    try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+    try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+    comptime {
+        try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
+        try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
+    }
+}
+fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
+    if (a) {
+        return &[_]u8{};
+    }
+
+    return slice[0..1];
+}
+
+test "implicitly cast from [N]T to ?[]const T" {
+    try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
+    comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
+}
+
+fn castToOptionalSlice() ?[]const u8 {
+    return "hi";
+}
+
+test "cast u128 to f128 and back" {
+    comptime try testCast128();
+    try testCast128();
+}
+
+fn testCast128() !void {
+    try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
+}
+
+fn cast128Int(x: f128) u128 {
+    return @bitCast(u128, x);
+}
+
+fn cast128Float(x: u128) f128 {
+    return @bitCast(f128, x);
+}
+
+test "implicit cast from *[N]T to ?[*]T" {
+    var x: ?[*]u16 = null;
+    var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
+
+    x = &y;
+    try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
+    x.?[0] = 8;
+    y[3] = 6;
+    try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
+}
+
+test "implicit cast from *T to ?*c_void" {
+    var a: u8 = 1;
+    incrementVoidPtrValue(&a);
+    try std.testing.expect(a == 2);
+}
+
+fn incrementVoidPtrValue(value: ?*c_void) void {
+    @ptrCast(*u8, value.?).* += 1;
+}
+
+test "implicit cast *[0]T to E![]const u8" {
+    var x = @as(anyerror![]const u8, &[0]u8{});
+    try expect((x catch unreachable).len == 0);
+}
+
+var global_array: [4]u8 = undefined;
+test "cast from array reference to fn" {
+    const f = @ptrCast(fn () callconv(.C) void, &global_array);
+    try expect(@ptrToInt(f) == @ptrToInt(&global_array));
+}
+
+test "*const [N]null u8 to ?[]const u8" {
+    const S = struct {
+        fn doTheTest() !void {
+            var a = "Hello";
+            var b: ?[]const u8 = a;
+            try expect(mem.eql(u8, b.?, "Hello"));
+        }
+    };
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "cast between [*c]T and ?[*:0]T on fn parameter" {
+    const S = struct {
+        const Handler = ?fn ([*c]const u8) callconv(.C) void;
+        fn addCallback(handler: Handler) void {
+            _ = handler;
+        }
+
+        fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {
+            _ = cstr;
+        }
+
+        fn doTheTest() void {
+            addCallback(myCallback);
+        }
+    };
+    S.doTheTest();
+}
+
+var global_struct: struct { f0: usize } = undefined;
+test "assignment to optional pointer result loc" {
+    var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct };
+    try expect(foo.ptr.? == @ptrCast(*c_void, &global_struct));
+}
+
+test "cast between *[N]void and []void" {
+    var a: [4]void = undefined;
+    var b: []void = &a;
+    try expect(b.len == 4);
+}
test/behavior/cast_stage1.zig
@@ -58,55 +58,6 @@ fn castToOptionalTypeError(z: i32) !void {
     try expect((b catch unreachable).?.a == 1);
 }
 
-test "implicitly cast from int to anyerror!?T" {
-    implicitIntLitToOptional();
-    comptime implicitIntLitToOptional();
-}
-fn implicitIntLitToOptional() void {
-    const f: ?i32 = 1;
-    _ = f;
-    const g: anyerror!?i32 = 1;
-    _ = g catch {};
-}
-
-test "return null from fn() anyerror!?&T" {
-    const a = returnNullFromOptionalTypeErrorRef();
-    const b = returnNullLitFromOptionalTypeErrorRef();
-    try expect((try a) == null and (try b) == null);
-}
-fn returnNullFromOptionalTypeErrorRef() anyerror!?*A {
-    const a: ?*A = null;
-    return a;
-}
-fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A {
-    return null;
-}
-
-test "peer type resolution: [0]u8 and []const u8" {
-    try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
-    try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
-    comptime {
-        try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
-        try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
-    }
-}
-fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
-    if (a) {
-        return &[_]u8{};
-    }
-
-    return slice[0..1];
-}
-
-test "implicitly cast from [N]T to ?[]const T" {
-    try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
-    comptime try expect(mem.eql(u8, castToOptionalSlice().?, "hi"));
-}
-
-fn castToOptionalSlice() ?[]const u8 {
-    return "hi";
-}
-
 test "implicitly cast from [0]T to anyerror![]T" {
     try testCastZeroArrayToErrSliceMut();
     comptime try testCastZeroArrayToErrSliceMut();
@@ -191,23 +142,6 @@ fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
     };
 }
 
-test "cast u128 to f128 and back" {
-    comptime try testCast128();
-    try testCast128();
-}
-
-fn testCast128() !void {
-    try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
-}
-
-fn cast128Int(x: f128) u128 {
-    return @bitCast(u128, x);
-}
-
-fn cast128Float(x: u128) f128 {
-    return @bitCast(f128, x);
-}
-
 test "single-item pointer of array to slice to unknown length pointer" {
     try testCastPtrOfArrayToSliceAndPtr();
     comptime try testCastPtrOfArrayToSliceAndPtr();
@@ -316,27 +250,6 @@ test "@floatCast cast down" {
     }
 }
 
-test "implicit cast from *[N]T to ?[*]T" {
-    var x: ?[*]u16 = null;
-    var y: [4]u16 = [4]u16{ 0, 1, 2, 3 };
-
-    x = &y;
-    try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
-    x.?[0] = 8;
-    y[3] = 6;
-    try expect(std.mem.eql(u16, x.?[0..4], y[0..4]));
-}
-
-test "implicit cast from *T to ?*c_void" {
-    var a: u8 = 1;
-    incrementVoidPtrValue(&a);
-    try std.testing.expect(a == 2);
-}
-
-fn incrementVoidPtrValue(value: ?*c_void) void {
-    @ptrCast(*u8, value.?).* += 1;
-}
-
 test "peer type resolution: unreachable, null, slice" {
     const S = struct {
         fn doTheTest(num: usize, word: []const u8) !void {
@@ -374,11 +287,6 @@ test "peer type resolution: unreachable, error set, unreachable" {
     try expect(transformed_err == error.SystemResources);
 }
 
-test "implicit cast *[0]T to E![]const u8" {
-    var x = @as(anyerror![]const u8, &[0]u8{});
-    try expect((x catch unreachable).len == 0);
-}
-
 test "peer cast *[0]T to E![]const T" {
     var buffer: [5]u8 = "abcde".*;
     var buf: anyerror![]const u8 = buffer[0..];
@@ -395,24 +303,6 @@ test "peer cast *[0]T to []const T" {
     try expect(mem.eql(u8, "abcde", y));
 }
 
-var global_array: [4]u8 = undefined;
-test "cast from array reference to fn" {
-    const f = @ptrCast(fn () callconv(.C) void, &global_array);
-    try expect(@ptrToInt(f) == @ptrToInt(&global_array));
-}
-
-test "*const [N]null u8 to ?[]const u8" {
-    const S = struct {
-        fn doTheTest() !void {
-            var a = "Hello";
-            var b: ?[]const u8 = a;
-            try expect(mem.eql(u8, b.?, "Hello"));
-        }
-    };
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
 test "peer resolution of string literals" {
     const S = struct {
         const E = enum { a, b, c, d };
@@ -502,19 +392,6 @@ test "cast i8 fn call peers to i32 result" {
     comptime try S.doTheTest();
 }
 
-test "return u8 coercing into ?u32 return type" {
-    const S = struct {
-        fn doTheTest() !void {
-            try expect(foo(123).? == 123);
-        }
-        fn foo(arg: u8) ?u32 {
-            return arg;
-        }
-    };
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
 test "peer type resolution implicit cast to return type" {
     const S = struct {
         fn doTheTest() !void {
@@ -553,24 +430,6 @@ test "variable initialization uses result locations properly with regards to the
     try expect(x == 1);
 }
 
-test "cast between [*c]T and ?[*:0]T on fn parameter" {
-    const S = struct {
-        const Handler = ?fn ([*c]const u8) callconv(.C) void;
-        fn addCallback(handler: Handler) void {
-            _ = handler;
-        }
-
-        fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void {
-            _ = cstr;
-        }
-
-        fn doTheTest() void {
-            addCallback(myCallback);
-        }
-    };
-    S.doTheTest();
-}
-
 test "cast between C pointer with different but compatible types" {
     const S = struct {
         fn foo(arg: [*]c_ushort) u16 {
@@ -584,13 +443,6 @@ test "cast between C pointer with different but compatible types" {
     try S.doTheTest();
 }
 
-var global_struct: struct { f0: usize } = undefined;
-
-test "assignment to optional pointer result loc" {
-    var foo: struct { ptr: ?*c_void } = .{ .ptr = &global_struct };
-    try expect(foo.ptr.? == @ptrCast(*c_void, &global_struct));
-}
-
 test "peer type resolve string lit with sentinel-terminated mutable slice" {
     var array: [4:0]u8 = undefined;
     array[4] = 0; // TODO remove this when #4372 is solved
@@ -649,14 +501,3 @@ test "comptime float casts" {
 fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
     try expect(@floatToInt(I, f) == i);
 }
-
-test "cast from ?[*]T to ??[*]T" {
-    const a: ??[*]u8 = @as(?[*]u8, null);
-    try expect(a != null and a.? == null);
-}
-
-test "cast between *[N]void and []void" {
-    var a: [4]void = undefined;
-    var b: []void = &a;
-    try expect(b.len == 4);
-}
test/behavior/fn.zig
@@ -121,3 +121,45 @@ test "inline function call that calls optional function pointer, return pointer
     };
     try S.doTheTest();
 }
+
+test "implicit cast function unreachable return" {
+    wantsFnWithVoid(fnWithUnreachable);
+}
+
+fn wantsFnWithVoid(f: fn () void) void {
+    _ = f;
+}
+
+fn fnWithUnreachable() noreturn {
+    unreachable;
+}
+
+test "extern struct with stdcallcc fn pointer" {
+    const S = extern struct {
+        ptr: fn () callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32,
+
+        fn foo() callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32 {
+            return 1234;
+        }
+    };
+
+    var s: S = undefined;
+    s.ptr = S.foo;
+    try expect(s.ptr() == 1234);
+}
+
+const nComplexCallconv = 100;
+fn fComplexCallconvRet(x: u32) callconv(blk: {
+    const s: struct { n: u32 } = .{ .n = nComplexCallconv };
+    break :blk switch (s.n) {
+        0 => .C,
+        1 => .Inline,
+        else => .Unspecified,
+    };
+}) struct { x: u32 } {
+    return .{ .x = x * x };
+}
+
+test "function with complex callconv and return type expressions" {
+    try expect(fComplexCallconvRet(3).x == 9);
+}
test/behavior/fn_stage1.zig
@@ -23,18 +23,6 @@ fn acceptsString(foo: []u8) void {
     _ = foo;
 }
 
-test "implicit cast function unreachable return" {
-    wantsFnWithVoid(fnWithUnreachable);
-}
-
-fn wantsFnWithVoid(f: fn () void) void {
-    _ = f;
-}
-
-fn fnWithUnreachable() noreturn {
-    unreachable;
-}
-
 test "function pointers" {
     const fns = [_]@TypeOf(fn1){
         fn1,
@@ -126,20 +114,6 @@ test "pass by non-copying value as method, at comptime" {
     }
 }
 
-test "extern struct with stdcallcc fn pointer" {
-    const S = extern struct {
-        ptr: fn () callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32,
-
-        fn foo() callconv(if (builtin.target.cpu.arch == .i386) .Stdcall else .C) i32 {
-            return 1234;
-        }
-    };
-
-    var s: S = undefined;
-    s.ptr = S.foo;
-    try expect(s.ptr() == 1234);
-}
-
 test "implicit cast fn call result to optional in field result" {
     const S = struct {
         fn entry() !void {
@@ -204,19 +178,3 @@ test "function with inferred error set but returning no error" {
     const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
     try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
 }
-
-const nComplexCallconv = 100;
-fn fComplexCallconvRet(x: u32) callconv(blk: {
-    const s: struct { n: u32 } = .{ .n = nComplexCallconv };
-    break :blk switch (s.n) {
-        0 => .C,
-        1 => .Inline,
-        else => .Unspecified,
-    };
-}) struct { x: u32 } {
-    return .{ .x = x * x };
-}
-
-test "function with complex callconv and return type expressions" {
-    try expect(fComplexCallconvRet(3).x == 9);
-}
test/behavior/generics.zig
@@ -134,3 +134,32 @@ test "use generic param in generic param" {
 fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
     return a + b;
 }
+
+test "generic fn with implicit cast" {
+    try expect(getFirstByte(u8, &[_]u8{13}) == 13);
+    try expect(getFirstByte(u16, &[_]u16{
+        0,
+        13,
+    }) == 0);
+}
+fn getByte(ptr: ?*const u8) u8 {
+    return ptr.?.*;
+}
+fn getFirstByte(comptime T: type, mem: []const T) u8 {
+    return getByte(@ptrCast(*const u8, &mem[0]));
+}
+
+test "generic fn keeps non-generic parameter types" {
+    const A = 128;
+
+    const S = struct {
+        fn f(comptime T: type, s: []T) !void {
+            try expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment);
+        }
+    };
+
+    // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that
+    // `x` type not affect `s` parameter type.
+    var x: [16]u8 align(A) = undefined;
+    try S.f(u8, &x);
+}
test/behavior/generics_llvm.zig
@@ -0,0 +1,42 @@
+const std = @import("std");
+const expect = std.testing.expect;
+
+const foos = [_]fn (anytype) bool{
+    foo1,
+    foo2,
+};
+
+fn foo1(arg: anytype) bool {
+    return arg;
+}
+fn foo2(arg: anytype) bool {
+    return !arg;
+}
+
+test "array of generic fns" {
+    try expect(foos[0](true));
+    try expect(!foos[1](true));
+}
+
+test "generic struct" {
+    var a1 = GenNode(i32){
+        .value = 13,
+        .next = null,
+    };
+    var b1 = GenNode(bool){
+        .value = true,
+        .next = null,
+    };
+    try expect(a1.value == 13);
+    try expect(a1.value == a1.getVal());
+    try expect(b1.getVal());
+}
+fn GenNode(comptime T: type) type {
+    return struct {
+        value: T,
+        next: ?*GenNode(T),
+        fn getVal(n: *const GenNode(T)) T {
+            return n.value;
+        }
+    };
+}
test/behavior/generics_stage1.zig
@@ -1,73 +0,0 @@
-const std = @import("std");
-const testing = std.testing;
-const expect = testing.expect;
-const expectEqual = testing.expectEqual;
-
-test "generic struct" {
-    var a1 = GenNode(i32){
-        .value = 13,
-        .next = null,
-    };
-    var b1 = GenNode(bool){
-        .value = true,
-        .next = null,
-    };
-    try expect(a1.value == 13);
-    try expect(a1.value == a1.getVal());
-    try expect(b1.getVal());
-}
-fn GenNode(comptime T: type) type {
-    return struct {
-        value: T,
-        next: ?*GenNode(T),
-        fn getVal(n: *const GenNode(T)) T {
-            return n.value;
-        }
-    };
-}
-
-test "generic fn with implicit cast" {
-    try expect(getFirstByte(u8, &[_]u8{13}) == 13);
-    try expect(getFirstByte(u16, &[_]u16{
-        0,
-        13,
-    }) == 0);
-}
-fn getByte(ptr: ?*const u8) u8 {
-    return ptr.?.*;
-}
-fn getFirstByte(comptime T: type, mem: []const T) u8 {
-    return getByte(@ptrCast(*const u8, &mem[0]));
-}
-
-const foos = [_]fn (anytype) bool{
-    foo1,
-    foo2,
-};
-
-fn foo1(arg: anytype) bool {
-    return arg;
-}
-fn foo2(arg: anytype) bool {
-    return !arg;
-}
-
-test "array of generic fns" {
-    try expect(foos[0](true));
-    try expect(!foos[1](true));
-}
-
-test "generic fn keeps non-generic parameter types" {
-    const A = 128;
-
-    const S = struct {
-        fn f(comptime T: type, s: []T) !void {
-            try expect(A != @typeInfo(@TypeOf(s)).Pointer.alignment);
-        }
-    };
-
-    // The compiler monomorphizes `S.f` for `T=u8` on its first use, check that
-    // `x` type not affect `s` parameter type.
-    var x: [16]u8 align(A) = undefined;
-    try S.f(u8, &x);
-}
test/behavior.zig
@@ -58,6 +58,7 @@ test {
         _ = @import("behavior/floatop.zig");
         _ = @import("behavior/fn.zig");
         _ = @import("behavior/for.zig");
+        _ = @import("behavior/generics_llvm.zig");
         _ = @import("behavior/math.zig");
         _ = @import("behavior/maximum_minimum.zig");
         _ = @import("behavior/null_llvm.zig");
@@ -145,7 +146,6 @@ test {
             _ = @import("behavior/fn_delegation.zig");
             _ = @import("behavior/fn_in_struct_in_comptime.zig");
             _ = @import("behavior/for_stage1.zig");
-            _ = @import("behavior/generics_stage1.zig");
             _ = @import("behavior/if_stage1.zig");
             _ = @import("behavior/import.zig");
             _ = @import("behavior/incomplete_struct_param_tld.zig");