diff options
| author | Robin Voetter <robin@voetter.nl> | 2021-11-22 03:32:28 +0100 |
|---|---|---|
| committer | Robin Voetter <robin@voetter.nl> | 2021-11-22 04:36:57 +0100 |
| commit | 2b589d71fbcacb2e8bc8746dd4b675e57b3a53df (patch) | |
| tree | 83fda2aa57b2f48c958a522a9393c4ba900943ef /test | |
| parent | cb248898ab41378c2e9bcf94d05c7c42577a7bab (diff) | |
| download | zig-2b589d71fbcacb2e8bc8746dd4b675e57b3a53df.tar.gz zig-2b589d71fbcacb2e8bc8746dd4b675e57b3a53df.zip | |
stage2: move some tests which are now passing
Diffstat (limited to 'test')
| -rw-r--r-- | test/behavior.zig | 2 | ||||
| -rw-r--r-- | test/behavior/cast.zig | 29 | ||||
| -rw-r--r-- | test/behavior/cast_llvm.zig | 132 | ||||
| -rw-r--r-- | test/behavior/cast_stage1.zig | 159 | ||||
| -rw-r--r-- | test/behavior/fn.zig | 42 | ||||
| -rw-r--r-- | test/behavior/fn_stage1.zig | 42 | ||||
| -rw-r--r-- | test/behavior/generics.zig | 29 | ||||
| -rw-r--r-- | test/behavior/generics_llvm.zig | 42 | ||||
| -rw-r--r-- | test/behavior/generics_stage1.zig | 73 |
9 files changed, 275 insertions, 275 deletions
diff --git a/test/behavior.zig b/test/behavior.zig index bb155a7de4..21398cfddb 100644 --- a/test/behavior.zig +++ b/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"); diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 607df6a8e8..c4ebbc7643 100644 --- a/test/behavior/cast.zig +++ b/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); +} diff --git a/test/behavior/cast_llvm.zig b/test/behavior/cast_llvm.zig index 6c41152fe9..df8d0ba515 100644 --- a/test/behavior/cast_llvm.zig +++ b/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); +} diff --git a/test/behavior/cast_stage1.zig b/test/behavior/cast_stage1.zig index 157a830f3c..7f1fe41a50 100644 --- a/test/behavior/cast_stage1.zig +++ b/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); -} diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 80f1f4d919..db1059a427 100644 --- a/test/behavior/fn.zig +++ b/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); +} diff --git a/test/behavior/fn_stage1.zig b/test/behavior/fn_stage1.zig index 9368b39a46..66eb40296e 100644 --- a/test/behavior/fn_stage1.zig +++ b/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); -} diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index 76ad5cede7..6cb1a82e3e 100644 --- a/test/behavior/generics.zig +++ b/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); +} diff --git a/test/behavior/generics_llvm.zig b/test/behavior/generics_llvm.zig new file mode 100644 index 0000000000..bb4c1b2ef4 --- /dev/null +++ b/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; + } + }; +} diff --git a/test/behavior/generics_stage1.zig b/test/behavior/generics_stage1.zig deleted file mode 100644 index c4b9687aa6..0000000000 --- a/test/behavior/generics_stage1.zig +++ /dev/null @@ -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); -} |
