| author | |
| committer | |
| log | 0249344a479a8eb51637c04fdecd947445ece0d5 |
| tree | ab6f40562728736a469fa9e2bbd09f9694aa442c |
| parent | f33af8f071a1782d222067e48b68eaed5d1a05a8 |
4 files changed, 299 insertions(+), 299 deletions(-)
test/behavior.zig+2-2| ... | @@ -19,7 +19,7 @@ test { | ... | @@ -19,7 +19,7 @@ test { |
| 19 | _ = @import("behavior/bugs/4769_b.zig"); | 19 | _ = @import("behavior/bugs/4769_b.zig"); |
| 20 | _ = @import("behavior/bugs/6850.zig"); | 20 | _ = @import("behavior/bugs/6850.zig"); |
| 21 | _ = @import("behavior/call.zig"); | 21 | _ = @import("behavior/call.zig"); |
| 22 | _ = @import("behavior/cast_c.zig"); | 22 | _ = @import("behavior/cast.zig"); |
| 23 | _ = @import("behavior/defer.zig"); | 23 | _ = @import("behavior/defer.zig"); |
| 24 | _ = @import("behavior/enum.zig"); | 24 | _ = @import("behavior/enum.zig"); |
| 25 | _ = @import("behavior/hasdecl.zig"); | 25 | _ = @import("behavior/hasdecl.zig"); |
| ... | @@ -52,7 +52,7 @@ test { | ... | @@ -52,7 +52,7 @@ test { |
| 52 | _ = @import("behavior/bugs/1741.zig"); | 52 | _ = @import("behavior/bugs/1741.zig"); |
| 53 | _ = @import("behavior/bugs/2006.zig"); | 53 | _ = @import("behavior/bugs/2006.zig"); |
| 54 | _ = @import("behavior/bugs/3112.zig"); | 54 | _ = @import("behavior/bugs/3112.zig"); |
| 55 | _ = @import("behavior/cast.zig"); | 55 | _ = @import("behavior/cast_llvm.zig"); |
| 56 | _ = @import("behavior/error.zig"); | 56 | _ = @import("behavior/error.zig"); |
| 57 | _ = @import("behavior/eval.zig"); | 57 | _ = @import("behavior/eval.zig"); |
| 58 | _ = @import("behavior/floatop.zig"); | 58 | _ = @import("behavior/floatop.zig"); |
test/behavior/cast.zig+230-37| ... | @@ -2,18 +2,95 @@ const std = @import("std"); | ... | @@ -2,18 +2,95 @@ const std = @import("std"); |
| 2 | const expect = std.testing.expect; | 2 | const expect = std.testing.expect; |
| 3 | const mem = std.mem; | 3 | const mem = std.mem; |
| 4 | const maxInt = std.math.maxInt; | 4 | const maxInt = std.math.maxInt; |
| 5 | const native_endian = @import("builtin").target.cpu.arch.endian(); | ||
| 6 | 5 | ||
| 7 | test "pointer reinterpret const float to int" { | 6 | test "int to ptr cast" { |
| 8 | // The hex representation is 0x3fe3333333333303. | 7 | const x = @as(usize, 13); |
| 9 | const float: f64 = 5.99999999999994648725e-01; | 8 | const y = @intToPtr(*u8, x); |
| 10 | const float_ptr = &float; | 9 | const z = @ptrToInt(y); |
| 11 | const int_ptr = @ptrCast(*const i32, float_ptr); | 10 | try expect(z == 13); |
| 12 | const int_val = int_ptr.*; | 11 | } |
| 13 | if (native_endian == .Little) | 12 | |
| 14 | try expect(int_val == 0x33333303) | 13 | test "integer literal to pointer cast" { |
| 15 | else | 14 | const vga_mem = @intToPtr(*u16, 0xB8000); |
| 16 | try expect(int_val == 0x3fe33333); | 15 | try expect(@ptrToInt(vga_mem) == 0xB8000); |
| 16 | } | ||
| 17 | |||
| 18 | test "peer type resolution: ?T and T" { | ||
| 19 | try expect(peerTypeTAndOptionalT(true, false).? == 0); | ||
| 20 | try expect(peerTypeTAndOptionalT(false, false).? == 3); | ||
| 21 | comptime { | ||
| 22 | try expect(peerTypeTAndOptionalT(true, false).? == 0); | ||
| 23 | try expect(peerTypeTAndOptionalT(false, false).? == 3); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { | ||
| 27 | if (c) { | ||
| 28 | return if (b) null else @as(usize, 0); | ||
| 29 | } | ||
| 30 | |||
| 31 | return @as(usize, 3); | ||
| 32 | } | ||
| 33 | |||
| 34 | test "resolve undefined with integer" { | ||
| 35 | try testResolveUndefWithInt(true, 1234); | ||
| 36 | comptime try testResolveUndefWithInt(true, 1234); | ||
| 37 | } | ||
| 38 | fn testResolveUndefWithInt(b: bool, x: i32) !void { | ||
| 39 | const value = if (b) x else undefined; | ||
| 40 | if (b) { | ||
| 41 | try expect(value == x); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | test "@intCast i32 to u7" { | ||
| 46 | var x: u128 = maxInt(u128); | ||
| 47 | var y: i32 = 120; | ||
| 48 | var z = x >> @intCast(u7, y); | ||
| 49 | try expect(z == 0xff); | ||
| 50 | } | ||
| 51 | |||
| 52 | test "@intCast to comptime_int" { | ||
| 53 | try expect(@intCast(comptime_int, 0) == 0); | ||
| 54 | } | ||
| 55 | |||
| 56 | test "implicit cast comptime numbers to any type when the value fits" { | ||
| 57 | const a: u64 = 255; | ||
| 58 | var b: u8 = a; | ||
| 59 | try expect(b == 255); | ||
| 60 | } | ||
| 61 | |||
| 62 | test "implicit cast comptime_int to comptime_float" { | ||
| 63 | comptime try expect(@as(comptime_float, 10) == @as(f32, 10)); | ||
| 64 | try expect(2 == 2.0); | ||
| 65 | } | ||
| 66 | |||
| 67 | test "comptime_int @intToFloat" { | ||
| 68 | { | ||
| 69 | const result = @intToFloat(f16, 1234); | ||
| 70 | try expect(@TypeOf(result) == f16); | ||
| 71 | try expect(result == 1234.0); | ||
| 72 | } | ||
| 73 | { | ||
| 74 | const result = @intToFloat(f32, 1234); | ||
| 75 | try expect(@TypeOf(result) == f32); | ||
| 76 | try expect(result == 1234.0); | ||
| 77 | } | ||
| 78 | { | ||
| 79 | const result = @intToFloat(f64, 1234); | ||
| 80 | try expect(@TypeOf(result) == f64); | ||
| 81 | try expect(result == 1234.0); | ||
| 82 | } | ||
| 83 | { | ||
| 84 | const result = @intToFloat(f128, 1234); | ||
| 85 | try expect(@TypeOf(result) == f128); | ||
| 86 | try expect(result == 1234.0); | ||
| 87 | } | ||
| 88 | // big comptime_int (> 64 bits) to f128 conversion | ||
| 89 | { | ||
| 90 | const result = @intToFloat(f128, 0x1_0000_0000_0000_0000); | ||
| 91 | try expect(@TypeOf(result) == f128); | ||
| 92 | try expect(result == 0x1_0000_0000_0000_0000.0); | ||
| 93 | } | ||
| 17 | } | 94 | } |
| 18 | 95 | ||
| 19 | test "@floatToInt" { | 96 | test "@floatToInt" { |
| ... | @@ -22,46 +99,162 @@ test "@floatToInt" { | ... | @@ -22,46 +99,162 @@ test "@floatToInt" { |
| 22 | } | 99 | } |
| 23 | 100 | ||
| 24 | fn testFloatToInts() !void { | 101 | fn testFloatToInts() !void { |
| 25 | try expectFloatToInt(f16, 255.1, u8, 255); | 102 | const x = @as(i32, 1e4); |
| 26 | try expectFloatToInt(f16, 127.2, i8, 127); | 103 | try expect(x == 10000); |
| 27 | try expectFloatToInt(f16, -128.2, i8, -128); | 104 | const y = @floatToInt(i32, @as(f32, 1e4)); |
| 105 | try expect(y == 10000); | ||
| 106 | try expectFloatToInt(f32, 255.1, u8, 255); | ||
| 107 | try expectFloatToInt(f32, 127.2, i8, 127); | ||
| 108 | try expectFloatToInt(f32, -128.2, i8, -128); | ||
| 28 | } | 109 | } |
| 29 | 110 | ||
| 30 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | 111 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { |
| 31 | try expect(@floatToInt(I, f) == i); | 112 | try expect(@floatToInt(I, f) == i); |
| 32 | } | 113 | } |
| 33 | 114 | ||
| 34 | test "implicit cast from [*]T to ?*c_void" { | 115 | test "implicitly cast indirect pointer to maybe-indirect pointer" { |
| 35 | var a = [_]u8{ 3, 2, 1 }; | 116 | const S = struct { |
| 36 | var runtime_zero: usize = 0; | 117 | const Self = @This(); |
| 37 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); | 118 | x: u8, |
| 38 | try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); | 119 | fn constConst(p: *const *const Self) u8 { |
| 120 | return p.*.x; | ||
| 121 | } | ||
| 122 | fn maybeConstConst(p: ?*const *const Self) u8 { | ||
| 123 | return p.?.*.x; | ||
| 124 | } | ||
| 125 | fn constConstConst(p: *const *const *const Self) u8 { | ||
| 126 | return p.*.*.x; | ||
| 127 | } | ||
| 128 | fn maybeConstConstConst(p: ?*const *const *const Self) u8 { | ||
| 129 | return p.?.*.*.x; | ||
| 130 | } | ||
| 131 | }; | ||
| 132 | const s = S{ .x = 42 }; | ||
| 133 | const p = &s; | ||
| 134 | const q = &p; | ||
| 135 | const r = &q; | ||
| 136 | try expect(42 == S.constConst(q)); | ||
| 137 | try expect(42 == S.maybeConstConst(q)); | ||
| 138 | try expect(42 == S.constConstConst(r)); | ||
| 139 | try expect(42 == S.maybeConstConstConst(r)); | ||
| 39 | } | 140 | } |
| 40 | 141 | ||
| 41 | fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { | 142 | test "@intCast comptime_int" { |
| 42 | var n: usize = 0; | 143 | const result = @intCast(i32, 1234); |
| 43 | while (n < len) : (n += 1) { | 144 | try expect(@TypeOf(result) == i32); |
| 44 | @ptrCast([*]u8, array.?)[n] += 1; | 145 | try expect(result == 1234); |
| 146 | } | ||
| 147 | |||
| 148 | test "@floatCast comptime_int and comptime_float" { | ||
| 149 | { | ||
| 150 | const result = @floatCast(f16, 1234); | ||
| 151 | try expect(@TypeOf(result) == f16); | ||
| 152 | try expect(result == 1234.0); | ||
| 153 | } | ||
| 154 | { | ||
| 155 | const result = @floatCast(f16, 1234.0); | ||
| 156 | try expect(@TypeOf(result) == f16); | ||
| 157 | try expect(result == 1234.0); | ||
| 45 | } | 158 | } |
| 159 | { | ||
| 160 | const result = @floatCast(f32, 1234); | ||
| 161 | try expect(@TypeOf(result) == f32); | ||
| 162 | try expect(result == 1234.0); | ||
| 163 | } | ||
| 164 | { | ||
| 165 | const result = @floatCast(f32, 1234.0); | ||
| 166 | try expect(@TypeOf(result) == f32); | ||
| 167 | try expect(result == 1234.0); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | test "coerce undefined to optional" { | ||
| 172 | try expect(MakeType(void).getNull() == null); | ||
| 173 | try expect(MakeType(void).getNonNull() != null); | ||
| 174 | } | ||
| 175 | |||
| 176 | fn MakeType(comptime T: type) type { | ||
| 177 | return struct { | ||
| 178 | fn getNull() ?T { | ||
| 179 | return null; | ||
| 180 | } | ||
| 181 | |||
| 182 | fn getNonNull() ?T { | ||
| 183 | return @as(T, undefined); | ||
| 184 | } | ||
| 185 | }; | ||
| 186 | } | ||
| 187 | |||
| 188 | test "implicit cast from *[N]T to [*c]T" { | ||
| 189 | var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | ||
| 190 | var y: [*c]u16 = &x; | ||
| 191 | |||
| 192 | try expect(std.mem.eql(u16, x[0..4], y[0..4])); | ||
| 193 | x[0] = 8; | ||
| 194 | y[3] = 6; | ||
| 195 | try expect(std.mem.eql(u16, x[0..4], y[0..4])); | ||
| 196 | } | ||
| 197 | |||
| 198 | test "*usize to *void" { | ||
| 199 | var i = @as(usize, 0); | ||
| 200 | var v = @ptrCast(*void, &i); | ||
| 201 | v.* = {}; | ||
| 46 | } | 202 | } |
| 47 | 203 | ||
| 48 | test "compile time int to ptr of function" { | 204 | test "@intToEnum passed a comptime_int to an enum with one item" { |
| 49 | try foobar(FUNCTION_CONSTANT); | 205 | const E = enum { A }; |
| 206 | const x = @intToEnum(E, 0); | ||
| 207 | try expect(x == E.A); | ||
| 50 | } | 208 | } |
| 51 | 209 | ||
| 52 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | 210 | test "@intCast to u0 and use the result" { |
| 53 | pub const PFN_void = fn (*c_void) callconv(.C) void; | 211 | const S = struct { |
| 212 | fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { | ||
| 213 | try expect((one << @intCast(u0, bigzero)) == 1); | ||
| 214 | try expect((zero << @intCast(u0, bigzero)) == 0); | ||
| 215 | } | ||
| 216 | }; | ||
| 217 | try S.doTheTest(0, 1, 0); | ||
| 218 | comptime try S.doTheTest(0, 1, 0); | ||
| 219 | } | ||
| 220 | |||
| 221 | test "peer result null and comptime_int" { | ||
| 222 | const S = struct { | ||
| 223 | fn blah(n: i32) ?i32 { | ||
| 224 | if (n == 0) { | ||
| 225 | return null; | ||
| 226 | } else if (n < 0) { | ||
| 227 | return -1; | ||
| 228 | } else { | ||
| 229 | return 1; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | }; | ||
| 233 | |||
| 234 | try expect(S.blah(0) == null); | ||
| 235 | comptime try expect(S.blah(0) == null); | ||
| 236 | try expect(S.blah(10).? == 1); | ||
| 237 | comptime try expect(S.blah(10).? == 1); | ||
| 238 | try expect(S.blah(-10).? == -1); | ||
| 239 | comptime try expect(S.blah(-10).? == -1); | ||
| 240 | } | ||
| 54 | 241 | ||
| 55 | fn foobar(func: PFN_void) !void { | 242 | test "*const ?[*]const T to [*c]const [*c]const T" { |
| 56 | try std.testing.expect(@ptrToInt(func) == maxInt(usize)); | 243 | var array = [_]u8{ 'o', 'k' }; |
| 244 | const opt_array_ptr: ?[*]const u8 = &array; | ||
| 245 | const a: *const ?[*]const u8 = &opt_array_ptr; | ||
| 246 | const b: [*c]const [*c]const u8 = a; | ||
| 247 | try expect(b.*[0] == 'o'); | ||
| 248 | try expect(b[0][1] == 'k'); | ||
| 57 | } | 249 | } |
| 58 | 250 | ||
| 59 | test "implicit ptr to *c_void" { | 251 | test "array coersion to undefined at runtime" { |
| 60 | var a: u32 = 1; | 252 | @setRuntimeSafety(true); |
| 61 | var ptr: *align(@alignOf(u32)) c_void = &a; | 253 | |
| 62 | var b: *u32 = @ptrCast(*u32, ptr); | 254 | var array = [4]u8{ 3, 4, 5, 6 }; |
| 63 | try expect(b.* == 1); | 255 | var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA }; |
| 64 | var ptr2: ?*align(@alignOf(u32)) c_void = &a; | 256 | |
| 65 | var c: *u32 = @ptrCast(*u32, ptr2.?); | 257 | try expect(std.mem.eql(u8, &array, &array)); |
| 66 | try expect(c.* == 1); | 258 | array = undefined; |
| 259 | try expect(std.mem.eql(u8, &array, &undefined_val)); | ||
| 67 | } | 260 | } |
test/behavior/cast_c.zig deleted-260| ... | @@ -1,260 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | const mem = std.mem; | ||
| 4 | const maxInt = std.math.maxInt; | ||
| 5 | |||
| 6 | test "int to ptr cast" { | ||
| 7 | const x = @as(usize, 13); | ||
| 8 | const y = @intToPtr(*u8, x); | ||
| 9 | const z = @ptrToInt(y); | ||
| 10 | try expect(z == 13); | ||
| 11 | } | ||
| 12 | |||
| 13 | test "integer literal to pointer cast" { | ||
| 14 | const vga_mem = @intToPtr(*u16, 0xB8000); | ||
| 15 | try expect(@ptrToInt(vga_mem) == 0xB8000); | ||
| 16 | } | ||
| 17 | |||
| 18 | test "peer type resolution: ?T and T" { | ||
| 19 | try expect(peerTypeTAndOptionalT(true, false).? == 0); | ||
| 20 | try expect(peerTypeTAndOptionalT(false, false).? == 3); | ||
| 21 | comptime { | ||
| 22 | try expect(peerTypeTAndOptionalT(true, false).? == 0); | ||
| 23 | try expect(peerTypeTAndOptionalT(false, false).? == 3); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { | ||
| 27 | if (c) { | ||
| 28 | return if (b) null else @as(usize, 0); | ||
| 29 | } | ||
| 30 | |||
| 31 | return @as(usize, 3); | ||
| 32 | } | ||
| 33 | |||
| 34 | test "resolve undefined with integer" { | ||
| 35 | try testResolveUndefWithInt(true, 1234); | ||
| 36 | comptime try testResolveUndefWithInt(true, 1234); | ||
| 37 | } | ||
| 38 | fn testResolveUndefWithInt(b: bool, x: i32) !void { | ||
| 39 | const value = if (b) x else undefined; | ||
| 40 | if (b) { | ||
| 41 | try expect(value == x); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 45 | test "@intCast i32 to u7" { | ||
| 46 | var x: u128 = maxInt(u128); | ||
| 47 | var y: i32 = 120; | ||
| 48 | var z = x >> @intCast(u7, y); | ||
| 49 | try expect(z == 0xff); | ||
| 50 | } | ||
| 51 | |||
| 52 | test "@intCast to comptime_int" { | ||
| 53 | try expect(@intCast(comptime_int, 0) == 0); | ||
| 54 | } | ||
| 55 | |||
| 56 | test "implicit cast comptime numbers to any type when the value fits" { | ||
| 57 | const a: u64 = 255; | ||
| 58 | var b: u8 = a; | ||
| 59 | try expect(b == 255); | ||
| 60 | } | ||
| 61 | |||
| 62 | test "implicit cast comptime_int to comptime_float" { | ||
| 63 | comptime try expect(@as(comptime_float, 10) == @as(f32, 10)); | ||
| 64 | try expect(2 == 2.0); | ||
| 65 | } | ||
| 66 | |||
| 67 | test "comptime_int @intToFloat" { | ||
| 68 | { | ||
| 69 | const result = @intToFloat(f16, 1234); | ||
| 70 | try expect(@TypeOf(result) == f16); | ||
| 71 | try expect(result == 1234.0); | ||
| 72 | } | ||
| 73 | { | ||
| 74 | const result = @intToFloat(f32, 1234); | ||
| 75 | try expect(@TypeOf(result) == f32); | ||
| 76 | try expect(result == 1234.0); | ||
| 77 | } | ||
| 78 | { | ||
| 79 | const result = @intToFloat(f64, 1234); | ||
| 80 | try expect(@TypeOf(result) == f64); | ||
| 81 | try expect(result == 1234.0); | ||
| 82 | } | ||
| 83 | { | ||
| 84 | const result = @intToFloat(f128, 1234); | ||
| 85 | try expect(@TypeOf(result) == f128); | ||
| 86 | try expect(result == 1234.0); | ||
| 87 | } | ||
| 88 | // big comptime_int (> 64 bits) to f128 conversion | ||
| 89 | { | ||
| 90 | const result = @intToFloat(f128, 0x1_0000_0000_0000_0000); | ||
| 91 | try expect(@TypeOf(result) == f128); | ||
| 92 | try expect(result == 0x1_0000_0000_0000_0000.0); | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | test "@floatToInt" { | ||
| 97 | try testFloatToInts(); | ||
| 98 | comptime try testFloatToInts(); | ||
| 99 | } | ||
| 100 | |||
| 101 | fn testFloatToInts() !void { | ||
| 102 | const x = @as(i32, 1e4); | ||
| 103 | try expect(x == 10000); | ||
| 104 | const y = @floatToInt(i32, @as(f32, 1e4)); | ||
| 105 | try expect(y == 10000); | ||
| 106 | try expectFloatToInt(f32, 255.1, u8, 255); | ||
| 107 | try expectFloatToInt(f32, 127.2, i8, 127); | ||
| 108 | try expectFloatToInt(f32, -128.2, i8, -128); | ||
| 109 | } | ||
| 110 | |||
| 111 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | ||
| 112 | try expect(@floatToInt(I, f) == i); | ||
| 113 | } | ||
| 114 | |||
| 115 | test "implicitly cast indirect pointer to maybe-indirect pointer" { | ||
| 116 | const S = struct { | ||
| 117 | const Self = @This(); | ||
| 118 | x: u8, | ||
| 119 | fn constConst(p: *const *const Self) u8 { | ||
| 120 | return p.*.x; | ||
| 121 | } | ||
| 122 | fn maybeConstConst(p: ?*const *const Self) u8 { | ||
| 123 | return p.?.*.x; | ||
| 124 | } | ||
| 125 | fn constConstConst(p: *const *const *const Self) u8 { | ||
| 126 | return p.*.*.x; | ||
| 127 | } | ||
| 128 | fn maybeConstConstConst(p: ?*const *const *const Self) u8 { | ||
| 129 | return p.?.*.*.x; | ||
| 130 | } | ||
| 131 | }; | ||
| 132 | const s = S{ .x = 42 }; | ||
| 133 | const p = &s; | ||
| 134 | const q = &p; | ||
| 135 | const r = &q; | ||
| 136 | try expect(42 == S.constConst(q)); | ||
| 137 | try expect(42 == S.maybeConstConst(q)); | ||
| 138 | try expect(42 == S.constConstConst(r)); | ||
| 139 | try expect(42 == S.maybeConstConstConst(r)); | ||
| 140 | } | ||
| 141 | |||
| 142 | test "@intCast comptime_int" { | ||
| 143 | const result = @intCast(i32, 1234); | ||
| 144 | try expect(@TypeOf(result) == i32); | ||
| 145 | try expect(result == 1234); | ||
| 146 | } | ||
| 147 | |||
| 148 | test "@floatCast comptime_int and comptime_float" { | ||
| 149 | { | ||
| 150 | const result = @floatCast(f16, 1234); | ||
| 151 | try expect(@TypeOf(result) == f16); | ||
| 152 | try expect(result == 1234.0); | ||
| 153 | } | ||
| 154 | { | ||
| 155 | const result = @floatCast(f16, 1234.0); | ||
| 156 | try expect(@TypeOf(result) == f16); | ||
| 157 | try expect(result == 1234.0); | ||
| 158 | } | ||
| 159 | { | ||
| 160 | const result = @floatCast(f32, 1234); | ||
| 161 | try expect(@TypeOf(result) == f32); | ||
| 162 | try expect(result == 1234.0); | ||
| 163 | } | ||
| 164 | { | ||
| 165 | const result = @floatCast(f32, 1234.0); | ||
| 166 | try expect(@TypeOf(result) == f32); | ||
| 167 | try expect(result == 1234.0); | ||
| 168 | } | ||
| 169 | } | ||
| 170 | |||
| 171 | test "coerce undefined to optional" { | ||
| 172 | try expect(MakeType(void).getNull() == null); | ||
| 173 | try expect(MakeType(void).getNonNull() != null); | ||
| 174 | } | ||
| 175 | |||
| 176 | fn MakeType(comptime T: type) type { | ||
| 177 | return struct { | ||
| 178 | fn getNull() ?T { | ||
| 179 | return null; | ||
| 180 | } | ||
| 181 | |||
| 182 | fn getNonNull() ?T { | ||
| 183 | return @as(T, undefined); | ||
| 184 | } | ||
| 185 | }; | ||
| 186 | } | ||
| 187 | |||
| 188 | test "implicit cast from *[N]T to [*c]T" { | ||
| 189 | var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; | ||
| 190 | var y: [*c]u16 = &x; | ||
| 191 | |||
| 192 | try expect(std.mem.eql(u16, x[0..4], y[0..4])); | ||
| 193 | x[0] = 8; | ||
| 194 | y[3] = 6; | ||
| 195 | try expect(std.mem.eql(u16, x[0..4], y[0..4])); | ||
| 196 | } | ||
| 197 | |||
| 198 | test "*usize to *void" { | ||
| 199 | var i = @as(usize, 0); | ||
| 200 | var v = @ptrCast(*void, &i); | ||
| 201 | v.* = {}; | ||
| 202 | } | ||
| 203 | |||
| 204 | test "@intToEnum passed a comptime_int to an enum with one item" { | ||
| 205 | const E = enum { A }; | ||
| 206 | const x = @intToEnum(E, 0); | ||
| 207 | try expect(x == E.A); | ||
| 208 | } | ||
| 209 | |||
| 210 | test "@intCast to u0 and use the result" { | ||
| 211 | const S = struct { | ||
| 212 | fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { | ||
| 213 | try expect((one << @intCast(u0, bigzero)) == 1); | ||
| 214 | try expect((zero << @intCast(u0, bigzero)) == 0); | ||
| 215 | } | ||
| 216 | }; | ||
| 217 | try S.doTheTest(0, 1, 0); | ||
| 218 | comptime try S.doTheTest(0, 1, 0); | ||
| 219 | } | ||
| 220 | |||
| 221 | test "peer result null and comptime_int" { | ||
| 222 | const S = struct { | ||
| 223 | fn blah(n: i32) ?i32 { | ||
| 224 | if (n == 0) { | ||
| 225 | return null; | ||
| 226 | } else if (n < 0) { | ||
| 227 | return -1; | ||
| 228 | } else { | ||
| 229 | return 1; | ||
| 230 | } | ||
| 231 | } | ||
| 232 | }; | ||
| 233 | |||
| 234 | try expect(S.blah(0) == null); | ||
| 235 | comptime try expect(S.blah(0) == null); | ||
| 236 | try expect(S.blah(10).? == 1); | ||
| 237 | comptime try expect(S.blah(10).? == 1); | ||
| 238 | try expect(S.blah(-10).? == -1); | ||
| 239 | comptime try expect(S.blah(-10).? == -1); | ||
| 240 | } | ||
| 241 | |||
| 242 | test "*const ?[*]const T to [*c]const [*c]const T" { | ||
| 243 | var array = [_]u8{ 'o', 'k' }; | ||
| 244 | const opt_array_ptr: ?[*]const u8 = &array; | ||
| 245 | const a: *const ?[*]const u8 = &opt_array_ptr; | ||
| 246 | const b: [*c]const [*c]const u8 = a; | ||
| 247 | try expect(b.*[0] == 'o'); | ||
| 248 | try expect(b[0][1] == 'k'); | ||
| 249 | } | ||
| 250 | |||
| 251 | test "array coersion to undefined at runtime" { | ||
| 252 | @setRuntimeSafety(true); | ||
| 253 | |||
| 254 | var array = [4]u8{ 3, 4, 5, 6 }; | ||
| 255 | var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA }; | ||
| 256 | |||
| 257 | try expect(std.mem.eql(u8, &array, &array)); | ||
| 258 | array = undefined; | ||
| 259 | try expect(std.mem.eql(u8, &array, &undefined_val)); | ||
| 260 | } | ||
test/behavior/cast_llvm.zig created+67| ... | @@ -0,0 +1,67 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | const mem = std.mem; | ||
| 4 | const maxInt = std.math.maxInt; | ||
| 5 | const native_endian = @import("builtin").target.cpu.arch.endian(); | ||
| 6 | |||
| 7 | test "pointer reinterpret const float to int" { | ||
| 8 | // The hex representation is 0x3fe3333333333303. | ||
| 9 | const float: f64 = 5.99999999999994648725e-01; | ||
| 10 | const float_ptr = &float; | ||
| 11 | const int_ptr = @ptrCast(*const i32, float_ptr); | ||
| 12 | const int_val = int_ptr.*; | ||
| 13 | if (native_endian == .Little) | ||
| 14 | try expect(int_val == 0x33333303) | ||
| 15 | else | ||
| 16 | try expect(int_val == 0x3fe33333); | ||
| 17 | } | ||
| 18 | |||
| 19 | test "@floatToInt" { | ||
| 20 | try testFloatToInts(); | ||
| 21 | comptime try testFloatToInts(); | ||
| 22 | } | ||
| 23 | |||
| 24 | fn testFloatToInts() !void { | ||
| 25 | try expectFloatToInt(f16, 255.1, u8, 255); | ||
| 26 | try expectFloatToInt(f16, 127.2, i8, 127); | ||
| 27 | try expectFloatToInt(f16, -128.2, i8, -128); | ||
| 28 | } | ||
| 29 | |||
| 30 | fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { | ||
| 31 | try expect(@floatToInt(I, f) == i); | ||
| 32 | } | ||
| 33 | |||
| 34 | test "implicit cast from [*]T to ?*c_void" { | ||
| 35 | var a = [_]u8{ 3, 2, 1 }; | ||
| 36 | var runtime_zero: usize = 0; | ||
| 37 | incrementVoidPtrArray(a[runtime_zero..].ptr, 3); | ||
| 38 | try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); | ||
| 39 | } | ||
| 40 | |||
| 41 | fn incrementVoidPtrArray(array: ?*c_void, len: usize) void { | ||
| 42 | var n: usize = 0; | ||
| 43 | while (n < len) : (n += 1) { | ||
| 44 | @ptrCast([*]u8, array.?)[n] += 1; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | test "compile time int to ptr of function" { | ||
| 49 | try foobar(FUNCTION_CONSTANT); | ||
| 50 | } | ||
| 51 | |||
| 52 | pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize)); | ||
| 53 | pub const PFN_void = fn (*c_void) callconv(.C) void; | ||
| 54 | |||
| 55 | fn foobar(func: PFN_void) !void { | ||
| 56 | try std.testing.expect(@ptrToInt(func) == maxInt(usize)); | ||
| 57 | } | ||
| 58 | |||
| 59 | test "implicit ptr to *c_void" { | ||
| 60 | var a: u32 = 1; | ||
| 61 | var ptr: *align(@alignOf(u32)) c_void = &a; | ||
| 62 | var b: *u32 = @ptrCast(*u32, ptr); | ||
| 63 | try expect(b.* == 1); | ||
| 64 | var ptr2: ?*align(@alignOf(u32)) c_void = &a; | ||
| 65 | var c: *u32 = @ptrCast(*u32, ptr2.?); | ||
| 66 | try expect(c.* == 1); | ||
| 67 | } | ||