mirror of
https://github.com/ziglang/zig.git
synced 2025-12-26 16:13:07 +00:00
806 lines
25 KiB
Zig
806 lines
25 KiB
Zig
const std = @import("std");
|
|
const expect = std.testing.expect;
|
|
const mem = std.mem;
|
|
const maxInt = std.math.maxInt;
|
|
const builtin = @import("builtin");
|
|
|
|
test "int to ptr cast" {
|
|
const x = @as(usize, 13);
|
|
const y = @intToPtr(*u8, x);
|
|
const z = @ptrToInt(y);
|
|
try expect(z == 13);
|
|
}
|
|
|
|
test "integer literal to pointer cast" {
|
|
const vga_mem = @intToPtr(*u16, 0xB8000);
|
|
try expect(@ptrToInt(vga_mem) == 0xB8000);
|
|
}
|
|
|
|
test "peer type resolution: ?T and T" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(peerTypeTAndOptionalT(true, false).? == 0);
|
|
try expect(peerTypeTAndOptionalT(false, false).? == 3);
|
|
comptime {
|
|
try expect(peerTypeTAndOptionalT(true, false).? == 0);
|
|
try expect(peerTypeTAndOptionalT(false, false).? == 3);
|
|
}
|
|
}
|
|
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
|
|
if (c) {
|
|
return if (b) null else @as(usize, 0);
|
|
}
|
|
|
|
return @as(usize, 3);
|
|
}
|
|
|
|
test "resolve undefined with integer" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try testResolveUndefWithInt(true, 1234);
|
|
comptime try testResolveUndefWithInt(true, 1234);
|
|
}
|
|
fn testResolveUndefWithInt(b: bool, x: i32) !void {
|
|
const value = if (b) x else undefined;
|
|
if (b) {
|
|
try expect(value == x);
|
|
}
|
|
}
|
|
|
|
test "@intCast to comptime_int" {
|
|
try expect(@intCast(comptime_int, 0) == 0);
|
|
}
|
|
|
|
test "implicit cast comptime numbers to any type when the value fits" {
|
|
const a: u64 = 255;
|
|
var b: u8 = a;
|
|
try expect(b == 255);
|
|
}
|
|
|
|
test "implicit cast comptime_int to comptime_float" {
|
|
comptime try expect(@as(comptime_float, 10) == @as(f32, 10));
|
|
try expect(2 == 2.0);
|
|
}
|
|
|
|
test "comptime_int @intToFloat" {
|
|
{
|
|
const result = @intToFloat(f16, 1234);
|
|
try expect(@TypeOf(result) == f16);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @intToFloat(f32, 1234);
|
|
try expect(@TypeOf(result) == f32);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @intToFloat(f64, 1234);
|
|
try expect(@TypeOf(result) == f64);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @intToFloat(f128, 1234);
|
|
try expect(@TypeOf(result) == f128);
|
|
try expect(result == 1234.0);
|
|
}
|
|
// big comptime_int (> 64 bits) to f128 conversion
|
|
{
|
|
const result = @intToFloat(f128, 0x1_0000_0000_0000_0000);
|
|
try expect(@TypeOf(result) == f128);
|
|
try expect(result == 0x1_0000_0000_0000_0000.0);
|
|
}
|
|
}
|
|
|
|
test "@floatToInt" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try testFloatToInts();
|
|
comptime try testFloatToInts();
|
|
}
|
|
|
|
fn testFloatToInts() !void {
|
|
const x = @as(i32, 1e4);
|
|
try expect(x == 10000);
|
|
const y = @floatToInt(i32, @as(f32, 1e4));
|
|
try expect(y == 10000);
|
|
try expectFloatToInt(f32, 255.1, u8, 255);
|
|
try expectFloatToInt(f32, 127.2, i8, 127);
|
|
try expectFloatToInt(f32, -128.2, i8, -128);
|
|
}
|
|
|
|
fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
|
|
try expect(@floatToInt(I, f) == i);
|
|
}
|
|
|
|
test "implicitly cast indirect pointer to maybe-indirect pointer" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
const S = struct {
|
|
const Self = @This();
|
|
x: u8,
|
|
fn constConst(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 maybeConstConstConst(p: ?*const *const *const Self) u8 {
|
|
return p.?.*.*.x;
|
|
}
|
|
};
|
|
const s = S{ .x = 42 };
|
|
const p = &s;
|
|
const q = &p;
|
|
const r = &q;
|
|
try expect(42 == S.constConst(q));
|
|
try expect(42 == S.maybeConstConst(q));
|
|
try expect(42 == S.constConstConst(r));
|
|
try expect(42 == S.maybeConstConstConst(r));
|
|
}
|
|
|
|
test "@intCast comptime_int" {
|
|
const result = @intCast(i32, 1234);
|
|
try expect(@TypeOf(result) == i32);
|
|
try expect(result == 1234);
|
|
}
|
|
|
|
test "@floatCast comptime_int and comptime_float" {
|
|
{
|
|
const result = @floatCast(f16, 1234);
|
|
try expect(@TypeOf(result) == f16);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @floatCast(f16, 1234.0);
|
|
try expect(@TypeOf(result) == f16);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @floatCast(f32, 1234);
|
|
try expect(@TypeOf(result) == f32);
|
|
try expect(result == 1234.0);
|
|
}
|
|
{
|
|
const result = @floatCast(f32, 1234.0);
|
|
try expect(@TypeOf(result) == f32);
|
|
try expect(result == 1234.0);
|
|
}
|
|
}
|
|
|
|
test "coerce undefined to optional" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
try expect(MakeType(void).getNull() == null);
|
|
try expect(MakeType(void).getNonNull() != null);
|
|
}
|
|
|
|
fn MakeType(comptime T: type) type {
|
|
return struct {
|
|
fn getNull() ?T {
|
|
return null;
|
|
}
|
|
|
|
fn getNonNull() ?T {
|
|
return @as(T, undefined);
|
|
}
|
|
};
|
|
}
|
|
|
|
test "implicit cast from *[N]T to [*c]T" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var x: [4]u16 = [4]u16{ 0, 1, 2, 3 };
|
|
var y: [*c]u16 = &x;
|
|
|
|
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 "*usize to *void" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var i = @as(usize, 0);
|
|
var v = @ptrCast(*void, &i);
|
|
v.* = {};
|
|
}
|
|
|
|
test "@intToEnum passed a comptime_int to an enum with one item" {
|
|
const E = enum { A };
|
|
const x = @intToEnum(E, 0);
|
|
try expect(x == E.A);
|
|
}
|
|
|
|
test "@intCast to u0 and use the result" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
const S = struct {
|
|
fn doTheTest(zero: u1, one: u1, bigzero: i32) !void {
|
|
try expect((one << @intCast(u0, bigzero)) == 1);
|
|
try expect((zero << @intCast(u0, bigzero)) == 0);
|
|
}
|
|
};
|
|
try S.doTheTest(0, 1, 0);
|
|
comptime try S.doTheTest(0, 1, 0);
|
|
}
|
|
|
|
test "peer result null and comptime_int" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
const S = struct {
|
|
fn blah(n: i32) ?i32 {
|
|
if (n == 0) {
|
|
return null;
|
|
} else if (n < 0) {
|
|
return -1;
|
|
} else {
|
|
return 1;
|
|
}
|
|
}
|
|
};
|
|
|
|
try expect(S.blah(0) == null);
|
|
comptime try expect(S.blah(0) == null);
|
|
try expect(S.blah(10).? == 1);
|
|
comptime try expect(S.blah(10).? == 1);
|
|
try expect(S.blah(-10).? == -1);
|
|
comptime try expect(S.blah(-10).? == -1);
|
|
}
|
|
|
|
test "*const ?[*]const T to [*c]const [*c]const T" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
var array = [_]u8{ 'o', 'k' };
|
|
const opt_array_ptr: ?[*]const u8 = &array;
|
|
const a: *const ?[*]const u8 = &opt_array_ptr;
|
|
const b: [*c]const [*c]const u8 = a;
|
|
try expect(b.*[0] == 'o');
|
|
try expect(b[0][1] == 'k');
|
|
}
|
|
|
|
test "array coersion to undefined at runtime" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
@setRuntimeSafety(true);
|
|
|
|
// TODO implement @setRuntimeSafety in stage2
|
|
if (builtin.zig_backend != .stage1 and builtin.mode != .Debug and builtin.mode != .ReleaseSafe) {
|
|
return error.SkipZigTest;
|
|
}
|
|
|
|
var array = [4]u8{ 3, 4, 5, 6 };
|
|
var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA };
|
|
|
|
try expect(std.mem.eql(u8, &array, &array));
|
|
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" {
|
|
if (builtin.zig_backend == .stage2_x86_64 or builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
|
|
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 "peer type unsigned int to signed" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
|
|
|
var w: u31 = 5;
|
|
var x: u8 = 7;
|
|
var y: i32 = -5;
|
|
var a = w + y + x;
|
|
comptime try expect(@TypeOf(a) == i32);
|
|
try expect(a == 7);
|
|
}
|
|
|
|
test "expected [*c]const u8, found [*:0]const u8" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
|
|
|
var a: [*:0]const u8 = "hello";
|
|
var b: [*c]const u8 = a;
|
|
var c: [*:0]const u8 = b;
|
|
try expect(std.mem.eql(u8, c[0..5], "hello"));
|
|
}
|
|
|
|
test "explicit cast from integer to error type" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
try testCastIntToErr(error.ItBroke);
|
|
comptime try testCastIntToErr(error.ItBroke);
|
|
}
|
|
fn testCastIntToErr(err: anyerror) !void {
|
|
const x = @errorToInt(err);
|
|
const y = @intToError(x);
|
|
try expect(error.ItBroke == y);
|
|
}
|
|
|
|
test "peer resolve array and const slice" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
try testPeerResolveArrayConstSlice(true);
|
|
comptime try testPeerResolveArrayConstSlice(true);
|
|
}
|
|
fn testPeerResolveArrayConstSlice(b: bool) !void {
|
|
const value1 = if (b) "aoeu" else @as([]const u8, "zz");
|
|
const value2 = if (b) @as([]const u8, "zz") else "aoeu";
|
|
try expect(mem.eql(u8, value1, "aoeu"));
|
|
try expect(mem.eql(u8, value2, "zz"));
|
|
}
|
|
|
|
test "implicitly cast from T to anyerror!?T" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
try castToOptionalTypeError(1);
|
|
comptime try castToOptionalTypeError(1);
|
|
}
|
|
|
|
const A = struct {
|
|
a: i32,
|
|
};
|
|
fn castToOptionalTypeError(z: i32) !void {
|
|
const x = @as(i32, 1);
|
|
const y: anyerror!?i32 = x;
|
|
try expect((try y).? == 1);
|
|
|
|
const f = z;
|
|
const g: anyerror!?i32 = f;
|
|
_ = g catch {};
|
|
|
|
const a = A{ .a = z };
|
|
const b: anyerror!?A = a;
|
|
try expect((b catch unreachable).?.a == 1);
|
|
}
|
|
|
|
test "implicitly cast from [0]T to anyerror![]T" {
|
|
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
|
|
try testCastZeroArrayToErrSliceMut();
|
|
comptime try testCastZeroArrayToErrSliceMut();
|
|
}
|
|
|
|
fn testCastZeroArrayToErrSliceMut() !void {
|
|
try expect((gimmeErrOrSlice() catch unreachable).len == 0);
|
|
}
|
|
|
|
fn gimmeErrOrSlice() anyerror![]u8 {
|
|
return &[_]u8{};
|
|
}
|
|
|
|
test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn doTheTest() anyerror!void {
|
|
{
|
|
var data = "hi".*;
|
|
const slice = data[0..];
|
|
try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
|
|
try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
|
|
}
|
|
{
|
|
var data: [2]u8 = "hi".*;
|
|
const slice = data[0..];
|
|
try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
|
|
try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
|
|
}
|
|
}
|
|
};
|
|
try S.doTheTest();
|
|
comptime try S.doTheTest();
|
|
}
|
|
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
|
|
if (a) {
|
|
return &[_]u8{};
|
|
}
|
|
|
|
return slice[0..1];
|
|
}
|
|
|
|
test "implicit cast from *const [N]T to []const T" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
try testCastConstArrayRefToConstSlice();
|
|
comptime try testCastConstArrayRefToConstSlice();
|
|
}
|
|
|
|
fn testCastConstArrayRefToConstSlice() !void {
|
|
{
|
|
const blah = "aoeu".*;
|
|
const const_array_ref = &blah;
|
|
try expect(@TypeOf(const_array_ref) == *const [4:0]u8);
|
|
const slice: []const u8 = const_array_ref;
|
|
try expect(mem.eql(u8, slice, "aoeu"));
|
|
}
|
|
{
|
|
const blah: [4]u8 = "aoeu".*;
|
|
const const_array_ref = &blah;
|
|
try expect(@TypeOf(const_array_ref) == *const [4]u8);
|
|
const slice: []const u8 = const_array_ref;
|
|
try expect(mem.eql(u8, slice, "aoeu"));
|
|
}
|
|
}
|
|
|
|
test "peer type resolution: error and [N]T" {
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
|
|
try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
|
|
comptime try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK"));
|
|
try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
|
|
comptime try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
|
|
}
|
|
|
|
fn testPeerErrorAndArray(x: u8) anyerror![]const u8 {
|
|
return switch (x) {
|
|
0x00 => "OK",
|
|
else => error.BadValue,
|
|
};
|
|
}
|
|
fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 {
|
|
return switch (x) {
|
|
0x00 => "OK",
|
|
0x01 => "OKK",
|
|
else => error.BadValue,
|
|
};
|
|
}
|
|
|
|
test "single-item pointer of array to slice to unknown length pointer" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
try testCastPtrOfArrayToSliceAndPtr();
|
|
comptime try testCastPtrOfArrayToSliceAndPtr();
|
|
}
|
|
|
|
fn testCastPtrOfArrayToSliceAndPtr() !void {
|
|
{
|
|
var array = "aoeu".*;
|
|
const x: [*]u8 = &array;
|
|
x[0] += 1;
|
|
try expect(mem.eql(u8, array[0..], "boeu"));
|
|
const y: []u8 = &array;
|
|
y[0] += 1;
|
|
try expect(mem.eql(u8, array[0..], "coeu"));
|
|
}
|
|
{
|
|
var array: [4]u8 = "aoeu".*;
|
|
const x: [*]u8 = &array;
|
|
x[0] += 1;
|
|
try expect(mem.eql(u8, array[0..], "boeu"));
|
|
const y: []u8 = &array;
|
|
y[0] += 1;
|
|
try expect(mem.eql(u8, array[0..], "coeu"));
|
|
}
|
|
}
|
|
|
|
test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const window_name = [1][*]const u8{"window name"};
|
|
const x: [*]const ?[*]const u8 = &window_name;
|
|
try expect(mem.eql(u8, std.mem.sliceTo(@ptrCast([*:0]const u8, x[0].?), 0), "window name"));
|
|
}
|
|
|
|
test "vector casts" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn doTheTest() !void {
|
|
// Upcast (implicit, equivalent to @intCast)
|
|
var up0: @Vector(2, u8) = [_]u8{ 0x55, 0xaa };
|
|
var up1 = @as(@Vector(2, u16), up0);
|
|
var up2 = @as(@Vector(2, u32), up0);
|
|
var up3 = @as(@Vector(2, u64), up0);
|
|
// Downcast (safety-checked)
|
|
var down0 = up3;
|
|
var down1 = @intCast(@Vector(2, u32), down0);
|
|
var down2 = @intCast(@Vector(2, u16), down0);
|
|
var down3 = @intCast(@Vector(2, u8), down0);
|
|
|
|
try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa }));
|
|
try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa }));
|
|
try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa }));
|
|
|
|
try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa }));
|
|
try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa }));
|
|
try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa }));
|
|
}
|
|
|
|
fn doTheTestFloat() !void {
|
|
var vec = @splat(2, @as(f32, 1234.0));
|
|
var wider: @Vector(2, f64) = vec;
|
|
try expect(wider[0] == 1234.0);
|
|
try expect(wider[1] == 1234.0);
|
|
}
|
|
};
|
|
|
|
try S.doTheTest();
|
|
comptime try S.doTheTest();
|
|
try S.doTheTestFloat();
|
|
comptime try S.doTheTestFloat();
|
|
}
|
|
|
|
test "@floatCast cast down" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
{
|
|
var double: f64 = 0.001534;
|
|
var single = @floatCast(f32, double);
|
|
try expect(single == 0.001534);
|
|
}
|
|
{
|
|
const double: f64 = 0.001534;
|
|
const single = @floatCast(f32, double);
|
|
try expect(single == 0.001534);
|
|
}
|
|
}
|
|
|
|
test "peer type resolution: unreachable, error set, unreachable" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const Error = error{
|
|
FileDescriptorAlreadyPresentInSet,
|
|
OperationCausesCircularLoop,
|
|
FileDescriptorNotRegistered,
|
|
SystemResources,
|
|
UserResourceLimitReached,
|
|
FileDescriptorIncompatibleWithEpoll,
|
|
Unexpected,
|
|
};
|
|
var err = Error.SystemResources;
|
|
const transformed_err = switch (err) {
|
|
error.FileDescriptorAlreadyPresentInSet => unreachable,
|
|
error.OperationCausesCircularLoop => unreachable,
|
|
error.FileDescriptorNotRegistered => unreachable,
|
|
error.SystemResources => error.SystemResources,
|
|
error.UserResourceLimitReached => error.UserResourceLimitReached,
|
|
error.FileDescriptorIncompatibleWithEpoll => unreachable,
|
|
error.Unexpected => unreachable,
|
|
};
|
|
try expect(transformed_err == error.SystemResources);
|
|
}
|
|
|
|
test "peer cast *[0]T to E![]const T" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
var buffer: [5]u8 = "abcde".*;
|
|
var buf: anyerror![]const u8 = buffer[0..];
|
|
var b = false;
|
|
var y = if (b) &[0]u8{} else buf;
|
|
try expect(mem.eql(u8, "abcde", y catch unreachable));
|
|
}
|
|
|
|
test "peer cast *[0]T to []const T" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
var buffer: [5]u8 = "abcde".*;
|
|
var buf: []const u8 = buffer[0..];
|
|
var b = false;
|
|
var y = if (b) &[0]u8{} else buf;
|
|
try expect(mem.eql(u8, "abcde", y));
|
|
}
|
|
|
|
test "peer resolution of string literals" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
const E = enum { a, b, c, d };
|
|
|
|
fn doTheTest(e: E) !void {
|
|
const cmd = switch (e) {
|
|
.a => "one",
|
|
.b => "two",
|
|
.c => "three",
|
|
.d => "four",
|
|
};
|
|
try expect(mem.eql(u8, cmd, "two"));
|
|
}
|
|
};
|
|
try S.doTheTest(.b);
|
|
comptime try S.doTheTest(.b);
|
|
}
|
|
|
|
test "type coercion related to sentinel-termination" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn doTheTest() !void {
|
|
// [:x]T to []T
|
|
{
|
|
var array = [4:0]i32{ 1, 2, 3, 4 };
|
|
var slice: [:0]i32 = &array;
|
|
var dest: []i32 = slice;
|
|
try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
|
|
}
|
|
|
|
// [*:x]T to [*]T
|
|
{
|
|
var array = [4:99]i32{ 1, 2, 3, 4 };
|
|
var dest: [*]i32 = &array;
|
|
try expect(dest[0] == 1);
|
|
try expect(dest[1] == 2);
|
|
try expect(dest[2] == 3);
|
|
try expect(dest[3] == 4);
|
|
try expect(dest[4] == 99);
|
|
}
|
|
|
|
// [N:x]T to [N]T
|
|
{
|
|
var array = [4:0]i32{ 1, 2, 3, 4 };
|
|
var dest: [4]i32 = array;
|
|
try expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 }));
|
|
}
|
|
|
|
// *[N:x]T to *[N]T
|
|
{
|
|
var array = [4:0]i32{ 1, 2, 3, 4 };
|
|
var dest: *[4]i32 = &array;
|
|
try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 }));
|
|
}
|
|
|
|
// [:x]T to [*:x]T
|
|
{
|
|
var array = [4:0]i32{ 1, 2, 3, 4 };
|
|
var slice: [:0]i32 = &array;
|
|
var dest: [*:0]i32 = slice;
|
|
try expect(dest[0] == 1);
|
|
try expect(dest[1] == 2);
|
|
try expect(dest[2] == 3);
|
|
try expect(dest[3] == 4);
|
|
try expect(dest[4] == 0);
|
|
}
|
|
}
|
|
};
|
|
try S.doTheTest();
|
|
comptime try S.doTheTest();
|
|
}
|
|
|
|
test "peer type resolution implicit cast to return type" {
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn doTheTest() !void {
|
|
for ("hello") |c| _ = f(c);
|
|
}
|
|
fn f(c: u8) []const u8 {
|
|
return switch (c) {
|
|
'h', 'e' => &[_]u8{c}, // should cast to slice
|
|
'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
|
|
else => ([_]u8{c})[0..], // is a slice
|
|
};
|
|
}
|
|
};
|
|
try S.doTheTest();
|
|
comptime try S.doTheTest();
|
|
}
|
|
|
|
test "peer type resolution implicit cast to variable type" {
|
|
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
|
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn doTheTest() !void {
|
|
var x: []const u8 = undefined;
|
|
for ("hello") |c| x = switch (c) {
|
|
'h', 'e' => &[_]u8{c}, // should cast to slice
|
|
'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice
|
|
else => ([_]u8{c})[0..], // is a slice
|
|
};
|
|
}
|
|
};
|
|
try S.doTheTest();
|
|
comptime try S.doTheTest();
|
|
}
|
|
|
|
test "variable initialization uses result locations properly with regards to the type" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
var b = true;
|
|
const x: i32 = if (b) 1 else 2;
|
|
try expect(x == 1);
|
|
}
|
|
|
|
test "cast between C pointer with different but compatible types" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const S = struct {
|
|
fn foo(arg: [*]c_ushort) u16 {
|
|
return arg[0];
|
|
}
|
|
fn doTheTest() !void {
|
|
var x = [_]u16{ 4, 2, 1, 3 };
|
|
try expect(foo(@ptrCast([*]u16, &x)) == 4);
|
|
}
|
|
};
|
|
try S.doTheTest();
|
|
}
|
|
|
|
test "peer type resolve string lit with sentinel-terminated mutable slice" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
var array: [4:0]u8 = undefined;
|
|
array[4] = 0; // TODO remove this when #4372 is solved
|
|
var slice: [:0]u8 = array[0..4 :0];
|
|
comptime try expect(@TypeOf(slice, "hi") == [:0]const u8);
|
|
comptime try expect(@TypeOf("hi", slice) == [:0]const u8);
|
|
}
|
|
|
|
test "peer type resolve array pointers, one of them const" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
var array1: [4]u8 = undefined;
|
|
const array2: [5]u8 = undefined;
|
|
comptime try expect(@TypeOf(&array1, &array2) == []const u8);
|
|
comptime try expect(@TypeOf(&array2, &array1) == []const u8);
|
|
}
|
|
|
|
test "peer type resolve array pointer and unknown pointer" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const const_array: [4]u8 = undefined;
|
|
var array: [4]u8 = undefined;
|
|
var const_ptr: [*]const u8 = undefined;
|
|
var ptr: [*]u8 = undefined;
|
|
|
|
comptime try expect(@TypeOf(&array, ptr) == [*]u8);
|
|
comptime try expect(@TypeOf(ptr, &array) == [*]u8);
|
|
|
|
comptime try expect(@TypeOf(&const_array, ptr) == [*]const u8);
|
|
comptime try expect(@TypeOf(ptr, &const_array) == [*]const u8);
|
|
|
|
comptime try expect(@TypeOf(&array, const_ptr) == [*]const u8);
|
|
comptime try expect(@TypeOf(const_ptr, &array) == [*]const u8);
|
|
|
|
comptime try expect(@TypeOf(&const_array, const_ptr) == [*]const u8);
|
|
comptime try expect(@TypeOf(const_ptr, &const_array) == [*]const u8);
|
|
}
|
|
|
|
test "comptime float casts" {
|
|
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
|
|
|
const a = @intToFloat(comptime_float, 1);
|
|
try expect(a == 1);
|
|
try expect(@TypeOf(a) == comptime_float);
|
|
const b = @floatToInt(comptime_int, 2);
|
|
try expect(b == 2);
|
|
try expect(@TypeOf(b) == comptime_int);
|
|
|
|
try expectFloatToInt(comptime_int, 1234, i16, 1234);
|
|
try expectFloatToInt(comptime_float, 12.3, comptime_int, 12);
|
|
}
|