1const std = @import("std"); 2const expect = std.testing.expect; 3const mem = std.mem; 4const maxInt = std.math.maxInt; 5 6test "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 13test "integer literal to pointer cast" { 14 const vga_mem = @intToPtr(*u16, 0xB8000); 15 try expect(@ptrToInt(vga_mem) == 0xB8000); 16} 17 18test "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} 26fn 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 34test "resolve undefined with integer" { 35 try testResolveUndefWithInt(true, 1234); 36 comptime try testResolveUndefWithInt(true, 1234); 37} 38fn 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 45test "@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 52test "@intCast to comptime_int" { 53 try expect(@intCast(comptime_int, 0) == 0); 54} 55 56test "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 62test "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 67test "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 96test "@floatToInt" { 97 try testFloatToInts(); 98 comptime try testFloatToInts(); 99} 100 101fn 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 111fn expectFloatToInt(comptime F: type, f: F, comptime I: type, i: I) !void { 112 try expect(@floatToInt(I, f) == i); 113} 114 115test "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 142test "@intCast comptime_int" { 143 const result = @intCast(i32, 1234); 144 try expect(@TypeOf(result) == i32); 145 try expect(result == 1234); 146} 147 148test "@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 171test "coerce undefined to optional" { 172 try expect(MakeType(void).getNull() == null); 173 try expect(MakeType(void).getNonNull() != null); 174} 175 176fn 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 188test "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 198test "*usize to *void" { 199 var i = @as(usize, 0); 200 var v = @ptrCast(*void, &i); 201 v.* = {}; 202} 203 204test "@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 210test "@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 221test "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 242test "*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 251test "array coersion to undefined at runtime" { 252 @setRuntimeSafety(true); 253 254 // TODO implement @setRuntimeSafety in stage2 255 if (@import("builtin").zig_is_stage2 and 256 @import("builtin").mode != .Debug and 257 @import("builtin").mode != .ReleaseSafe) 258 { 259 return error.SkipZigTest; 260 } 261 262 var array = [4]u8{ 3, 4, 5, 6 }; 263 var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA }; 264 265 try expect(std.mem.eql(u8, &array, &array)); 266 array = undefined; 267 try expect(std.mem.eql(u8, &array, &undefined_val)); 268} 269 270test "implicitly cast from int to anyerror!?T" { 271 implicitIntLitToOptional(); 272 comptime implicitIntLitToOptional(); 273} 274fn implicitIntLitToOptional() void { 275 const f: ?i32 = 1; 276 _ = f; 277 const g: anyerror!?i32 = 1; 278 _ = g catch {}; 279} 280 281test "return u8 coercing into ?u32 return type" { 282 const S = struct { 283 fn doTheTest() !void { 284 try expect(foo(123).? == 123); 285 } 286 fn foo(arg: u8) ?u32 { 287 return arg; 288 } 289 }; 290 try S.doTheTest(); 291 comptime try S.doTheTest(); 292} 293 294test "cast from ?[*]T to ??[*]T" { 295 const a: ??[*]u8 = @as(?[*]u8, null); 296 try expect(a != null and a.? == null); 297} 298