Commit 0249344a47

drew <reserveblue@protonmail.com>
2021-11-16 02:57:48
cast -> cast_llvm, cast_c -> cast (doesn't work on LLVM backend)
1 parent f33af8f
Changed files (4)
test/behavior/cast.zig
@@ -2,18 +2,95 @@ const std = @import("std");
 const expect = std.testing.expect;
 const mem = std.mem;
 const maxInt = std.math.maxInt;
-const native_endian = @import("builtin").target.cpu.arch.endian();
 
-test "pointer reinterpret const float to int" {
-    // The hex representation is 0x3fe3333333333303.
-    const float: f64 = 5.99999999999994648725e-01;
-    const float_ptr = &float;
-    const int_ptr = @ptrCast(*const i32, float_ptr);
-    const int_val = int_ptr.*;
-    if (native_endian == .Little)
-        try expect(int_val == 0x33333303)
-    else
-        try expect(int_val == 0x3fe33333);
+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" {
+    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" {
+    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 i32 to u7" {
+    var x: u128 = maxInt(u128);
+    var y: i32 = 120;
+    var z = x >> @intCast(u7, y);
+    try expect(z == 0xff);
+}
+
+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" {
@@ -22,46 +99,162 @@ test "@floatToInt" {
 }
 
 fn testFloatToInts() !void {
-    try expectFloatToInt(f16, 255.1, u8, 255);
-    try expectFloatToInt(f16, 127.2, i8, 127);
-    try expectFloatToInt(f16, -128.2, i8, -128);
+    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 "implicit cast from [*]T to ?*c_void" {
-    var a = [_]u8{ 3, 2, 1 };
-    var runtime_zero: usize = 0;
-    incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
-    try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
+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 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));
 }
 
-fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
-    var n: usize = 0;
-    while (n < len) : (n += 1) {
-        @ptrCast([*]u8, array.?)[n] += 1;
+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" {
+    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" {
+    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" {
+    var i = @as(usize, 0);
+    var v = @ptrCast(*void, &i);
+    v.* = {};
 }
 
-test "compile time int to ptr of function" {
-    try foobar(FUNCTION_CONSTANT);
+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);
 }
 
-pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
-pub const PFN_void = fn (*c_void) callconv(.C) void;
+test "@intCast to u0 and use the result" {
+    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" {
+    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);
+}
 
-fn foobar(func: PFN_void) !void {
-    try std.testing.expect(@ptrToInt(func) == maxInt(usize));
+test "*const ?[*]const T to [*c]const [*c]const T" {
+    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 "implicit ptr to *c_void" {
-    var a: u32 = 1;
-    var ptr: *align(@alignOf(u32)) c_void = &a;
-    var b: *u32 = @ptrCast(*u32, ptr);
-    try expect(b.* == 1);
-    var ptr2: ?*align(@alignOf(u32)) c_void = &a;
-    var c: *u32 = @ptrCast(*u32, ptr2.?);
-    try expect(c.* == 1);
+test "array coersion to undefined at runtime" {
+    @setRuntimeSafety(true);
+
+    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/behavior/cast_c.zig
@@ -1,260 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const mem = std.mem;
-const maxInt = std.math.maxInt;
-
-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" {
-    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" {
-    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 i32 to u7" {
-    var x: u128 = maxInt(u128);
-    var y: i32 = 120;
-    var z = x >> @intCast(u7, y);
-    try expect(z == 0xff);
-}
-
-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" {
-    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" {
-    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" {
-    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" {
-    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" {
-    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" {
-    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" {
-    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" {
-    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" {
-    @setRuntimeSafety(true);
-
-    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/behavior/cast_llvm.zig
@@ -0,0 +1,67 @@
+const std = @import("std");
+const expect = std.testing.expect;
+const mem = std.mem;
+const maxInt = std.math.maxInt;
+const native_endian = @import("builtin").target.cpu.arch.endian();
+
+test "pointer reinterpret const float to int" {
+    // The hex representation is 0x3fe3333333333303.
+    const float: f64 = 5.99999999999994648725e-01;
+    const float_ptr = &float;
+    const int_ptr = @ptrCast(*const i32, float_ptr);
+    const int_val = int_ptr.*;
+    if (native_endian == .Little)
+        try expect(int_val == 0x33333303)
+    else
+        try expect(int_val == 0x3fe33333);
+}
+
+test "@floatToInt" {
+    try testFloatToInts();
+    comptime try testFloatToInts();
+}
+
+fn testFloatToInts() !void {
+    try expectFloatToInt(f16, 255.1, u8, 255);
+    try expectFloatToInt(f16, 127.2, i8, 127);
+    try expectFloatToInt(f16, -128.2, i8, -128);
+}
+
+fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void {
+    try expect(@floatToInt(I, f) == i);
+}
+
+test "implicit cast from [*]T to ?*c_void" {
+    var a = [_]u8{ 3, 2, 1 };
+    var runtime_zero: usize = 0;
+    incrementVoidPtrArray(a[runtime_zero..].ptr, 3);
+    try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 }));
+}
+
+fn incrementVoidPtrArray(array: ?*c_void, len: usize) void {
+    var n: usize = 0;
+    while (n < len) : (n += 1) {
+        @ptrCast([*]u8, array.?)[n] += 1;
+    }
+}
+
+test "compile time int to ptr of function" {
+    try foobar(FUNCTION_CONSTANT);
+}
+
+pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
+pub const PFN_void = fn (*c_void) callconv(.C) void;
+
+fn foobar(func: PFN_void) !void {
+    try std.testing.expect(@ptrToInt(func) == maxInt(usize));
+}
+
+test "implicit ptr to *c_void" {
+    var a: u32 = 1;
+    var ptr: *align(@alignOf(u32)) c_void = &a;
+    var b: *u32 = @ptrCast(*u32, ptr);
+    try expect(b.* == 1);
+    var ptr2: ?*align(@alignOf(u32)) c_void = &a;
+    var c: *u32 = @ptrCast(*u32, ptr2.?);
+    try expect(c.* == 1);
+}
test/behavior.zig
@@ -19,7 +19,7 @@ test {
     _ = @import("behavior/bugs/4769_b.zig");
     _ = @import("behavior/bugs/6850.zig");
     _ = @import("behavior/call.zig");
-    _ = @import("behavior/cast_c.zig");
+    _ = @import("behavior/cast.zig");
     _ = @import("behavior/defer.zig");
     _ = @import("behavior/enum.zig");
     _ = @import("behavior/hasdecl.zig");
@@ -52,7 +52,7 @@ test {
         _ = @import("behavior/bugs/1741.zig");
         _ = @import("behavior/bugs/2006.zig");
         _ = @import("behavior/bugs/3112.zig");
-        _ = @import("behavior/cast.zig");
+        _ = @import("behavior/cast_llvm.zig");
         _ = @import("behavior/error.zig");
         _ = @import("behavior/eval.zig");
         _ = @import("behavior/floatop.zig");