blob 8ea564ad (94887B) - Raw
1 const builtin = @import("builtin"); 2 const std = @import("std"); 3 const assert = std.debug.assert; 4 const expect = std.testing.expect; 5 const expectEqual = std.testing.expectEqual; 6 const expectEqualSlices = std.testing.expectEqualSlices; 7 const mem = std.mem; 8 const maxInt = std.math.maxInt; 9 const native_endian = builtin.target.cpu.arch.endian(); 10 11 test "int to ptr cast" { 12 const x = @as(usize, 13); 13 const y = @as(*u8, @ptrFromInt(x)); 14 const z = @intFromPtr(y); 15 try expect(z == 13); 16 } 17 18 test "integer literal to pointer cast" { 19 const vga_mem = @as(*u16, @ptrFromInt(0xB8000)); 20 try expect(@intFromPtr(vga_mem) == 0xB8000); 21 } 22 23 test "peer type resolution: ?T and T" { 24 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 25 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 26 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 27 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 28 29 try expect(peerTypeTAndOptionalT(true, false).? == 0); 30 try expect(peerTypeTAndOptionalT(false, false).? == 3); 31 comptime { 32 try expect(peerTypeTAndOptionalT(true, false).? == 0); 33 try expect(peerTypeTAndOptionalT(false, false).? == 3); 34 } 35 } 36 fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize { 37 if (c) { 38 return if (b) null else @as(usize, 0); 39 } 40 41 return @as(usize, 3); 42 } 43 44 test "resolve undefined with integer" { 45 try testResolveUndefWithInt(true, 1234); 46 try comptime testResolveUndefWithInt(true, 1234); 47 } 48 fn testResolveUndefWithInt(b: bool, x: i32) !void { 49 const value = if (b) x else undefined; 50 if (b) { 51 try expect(value == x); 52 } 53 } 54 55 test "@intCast to comptime_int" { 56 try expect(@as(comptime_int, @intCast(0)) == 0); 57 } 58 59 test "implicit cast comptime numbers to any type when the value fits" { 60 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 61 62 const a: u64 = 255; 63 var b: u8 = a; 64 _ = &b; 65 try expect(b == 255); 66 } 67 68 test "implicit cast comptime_int to comptime_float" { 69 comptime assert(@as(comptime_float, 10) == @as(f32, 10)); 70 try expect(2 == 2.0); 71 } 72 73 test "comptime_int @floatFromInt" { 74 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 75 76 { 77 const result = @as(f16, @floatFromInt(1234)); 78 try expect(@TypeOf(result) == f16); 79 try expect(result == 1234.0); 80 } 81 { 82 const result = @as(f32, @floatFromInt(1234)); 83 try expect(@TypeOf(result) == f32); 84 try expect(result == 1234.0); 85 } 86 { 87 const result = @as(f64, @floatFromInt(1234)); 88 try expect(@TypeOf(result) == f64); 89 try expect(result == 1234.0); 90 } 91 92 { 93 const result = @as(f128, @floatFromInt(1234)); 94 try expect(@TypeOf(result) == f128); 95 try expect(result == 1234.0); 96 } 97 // big comptime_int (> 64 bits) to f128 conversion 98 { 99 const result = @as(f128, @floatFromInt(0x1_0000_0000_0000_0000)); 100 try expect(@TypeOf(result) == f128); 101 try expect(result == 0x1_0000_0000_0000_0000.0); 102 } 103 } 104 105 test "@floatFromInt" { 106 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 107 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 108 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 109 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 110 111 const S = struct { 112 fn doTheTest() !void { 113 try testIntToFloat(-2); 114 } 115 116 fn testIntToFloat(k: i32) !void { 117 const f = @as(f32, @floatFromInt(k)); 118 const i = @as(i32, @intFromFloat(f)); 119 try expect(i == k); 120 } 121 }; 122 try S.doTheTest(); 123 try comptime S.doTheTest(); 124 } 125 126 test "@floatFromInt(f80)" { 127 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 128 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 130 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 131 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; 132 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 133 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 134 135 const S = struct { 136 fn doTheTest(comptime Int: type) !void { 137 try testIntToFloat(Int, -2); 138 } 139 140 fn testIntToFloat(comptime Int: type, k: Int) !void { 141 @setRuntimeSafety(false); // TODO 142 const f = @as(f80, @floatFromInt(k)); 143 const i = @as(Int, @intFromFloat(f)); 144 try expect(i == k); 145 } 146 }; 147 try S.doTheTest(i31); 148 try S.doTheTest(i32); 149 try S.doTheTest(i45); 150 try S.doTheTest(i64); 151 try S.doTheTest(i80); 152 try S.doTheTest(i128); 153 // try S.doTheTest(i256); // TODO missing compiler_rt symbols 154 try comptime S.doTheTest(i31); 155 try comptime S.doTheTest(i32); 156 try comptime S.doTheTest(i45); 157 try comptime S.doTheTest(i64); 158 try comptime S.doTheTest(i80); 159 try comptime S.doTheTest(i128); 160 try comptime S.doTheTest(i256); 161 } 162 163 test "@intFromFloat" { 164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 165 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 166 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 168 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 169 170 try testIntFromFloats(); 171 try comptime testIntFromFloats(); 172 } 173 174 fn testIntFromFloats() !void { 175 const x = @as(i32, 1e4); 176 try expect(x == 10000); 177 const y = @as(i32, @intFromFloat(@as(f32, 1e4))); 178 try expect(y == 10000); 179 try expectIntFromFloat(f32, 255.1, u8, 255); 180 try expectIntFromFloat(f32, 127.2, i8, 127); 181 try expectIntFromFloat(f32, -128.2, i8, -128); 182 } 183 184 fn expectIntFromFloat(comptime F: type, f: F, comptime I: type, i: I) !void { 185 try expect(@as(I, @intFromFloat(f)) == i); 186 } 187 188 test "implicitly cast indirect pointer to maybe-indirect pointer" { 189 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 190 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 191 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 192 193 const S = struct { 194 const Self = @This(); 195 x: u8, 196 fn constConst(p: *const *const Self) u8 { 197 return p.*.x; 198 } 199 fn maybeConstConst(p: ?*const *const Self) u8 { 200 return p.?.*.x; 201 } 202 fn constConstConst(p: *const *const *const Self) u8 { 203 return p.*.*.x; 204 } 205 fn maybeConstConstConst(p: ?*const *const *const Self) u8 { 206 return p.?.*.*.x; 207 } 208 }; 209 const s = S{ .x = 42 }; 210 const p = &s; 211 const q = &p; 212 const r = &q; 213 try expect(42 == S.constConst(q)); 214 try expect(42 == S.maybeConstConst(q)); 215 try expect(42 == S.constConstConst(r)); 216 try expect(42 == S.maybeConstConstConst(r)); 217 } 218 219 test "@intCast comptime_int" { 220 const result = @as(i32, @intCast(1234)); 221 try expect(@TypeOf(result) == i32); 222 try expect(result == 1234); 223 } 224 225 test "@floatCast comptime_int and comptime_float" { 226 { 227 const result = @as(f16, @floatCast(1234)); 228 try expect(@TypeOf(result) == f16); 229 try expect(result == 1234.0); 230 } 231 { 232 const result = @as(f16, @floatCast(1234.0)); 233 try expect(@TypeOf(result) == f16); 234 try expect(result == 1234.0); 235 } 236 { 237 const result = @as(f32, @floatCast(1234)); 238 try expect(@TypeOf(result) == f32); 239 try expect(result == 1234.0); 240 } 241 { 242 const result = @as(f32, @floatCast(1234.0)); 243 try expect(@TypeOf(result) == f32); 244 try expect(result == 1234.0); 245 } 246 } 247 248 test "coerce undefined to optional" { 249 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 250 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 251 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 252 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 253 254 try expect(MakeType(void).getNull() == null); 255 try expect(MakeType(void).getNonNull() != null); 256 } 257 258 fn MakeType(comptime T: type) type { 259 return struct { 260 fn getNull() ?T { 261 return null; 262 } 263 264 fn getNonNull() ?T { 265 return @as(T, undefined); 266 } 267 }; 268 } 269 270 test "implicit cast from *[N]T to [*c]T" { 271 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 272 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 273 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 274 275 var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; 276 var y: [*c]u16 = &x; 277 278 try expect(std.mem.eql(u16, x[0..4], y[0..4])); 279 x[0] = 8; 280 y[3] = 6; 281 try expect(std.mem.eql(u16, x[0..4], y[0..4])); 282 } 283 284 test "*usize to *void" { 285 var i = @as(usize, 0); 286 const v: *void = @ptrCast(&i); 287 v.* = {}; 288 } 289 290 test "@enumFromInt passed a comptime_int to an enum with one item" { 291 const E = enum { A }; 292 const x = @as(E, @enumFromInt(0)); 293 try expect(x == E.A); 294 } 295 296 test "@intCast to u0 and use the result" { 297 const S = struct { 298 fn doTheTest(zero: u1, one: u1, bigzero: i32) !void { 299 try expect((one << @as(u0, @intCast(bigzero))) == 1); 300 try expect((zero << @as(u0, @intCast(bigzero))) == 0); 301 } 302 }; 303 try S.doTheTest(0, 1, 0); 304 try comptime S.doTheTest(0, 1, 0); 305 } 306 307 test "peer result null and comptime_int" { 308 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 309 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 310 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 311 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 312 313 const S = struct { 314 fn blah(n: i32) ?i32 { 315 if (n == 0) { 316 return null; 317 } else if (n < 0) { 318 return -1; 319 } else { 320 return 1; 321 } 322 } 323 }; 324 325 try expect(S.blah(0) == null); 326 comptime assert(S.blah(0) == null); 327 try expect(S.blah(10).? == 1); 328 comptime assert(S.blah(10).? == 1); 329 try expect(S.blah(-10).? == -1); 330 comptime assert(S.blah(-10).? == -1); 331 } 332 333 test "*const ?[*]const T to [*c]const [*c]const T" { 334 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 335 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 336 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 337 338 var array = [_]u8{ 'o', 'k' }; 339 const opt_array_ptr: ?[*]const u8 = &array; 340 const a: *const ?[*]const u8 = &opt_array_ptr; 341 const b: [*c]const [*c]const u8 = a; 342 try expect(b.*[0] == 'o'); 343 try expect(b[0][1] == 'k'); 344 } 345 346 test "array coercion to undefined at runtime" { 347 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 348 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 349 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 350 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 351 352 @setRuntimeSafety(true); 353 354 if (builtin.mode != .Debug and builtin.mode != .ReleaseSafe) { 355 return error.SkipZigTest; 356 } 357 358 var array = [4]u8{ 3, 4, 5, 6 }; 359 var undefined_val = [4]u8{ 0xAA, 0xAA, 0xAA, 0xAA }; 360 361 try expect(std.mem.eql(u8, &array, &array)); 362 array = undefined; 363 try expect(std.mem.eql(u8, &array, &undefined_val)); 364 } 365 366 test "implicitly cast from int to anyerror!?T" { 367 implicitIntLitToOptional(); 368 comptime implicitIntLitToOptional(); 369 } 370 fn implicitIntLitToOptional() void { 371 const f: ?i32 = 1; 372 _ = f; 373 const g: anyerror!?i32 = 1; 374 _ = g catch {}; 375 } 376 377 test "return u8 coercing into ?u32 return type" { 378 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 379 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 380 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 381 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 382 383 const S = struct { 384 fn doTheTest() !void { 385 try expect(foo(123).? == 123); 386 } 387 fn foo(arg: u8) ?u32 { 388 return arg; 389 } 390 }; 391 try S.doTheTest(); 392 try comptime S.doTheTest(); 393 } 394 395 test "cast from ?[*]T to ??[*]T" { 396 const a: ??[*]u8 = @as(?[*]u8, null); 397 try expect(a != null and a.? == null); 398 } 399 400 test "peer type unsigned int to signed" { 401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 402 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 403 404 var w: u31 = 5; 405 var x: u8 = 7; 406 var y: i32 = -5; 407 _ = .{ &w, &x, &y }; 408 const a = w + y + x; 409 comptime assert(@TypeOf(a) == i32); 410 try expect(a == 7); 411 } 412 413 test "expected [*c]const u8, found [*:0]const u8" { 414 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 415 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 416 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 417 418 var a: [*:0]const u8 = "hello"; 419 _ = &a; 420 const b: [*c]const u8 = a; 421 const c: [*:0]const u8 = b; 422 try expect(std.mem.eql(u8, c[0..5], "hello")); 423 } 424 425 test "explicit cast from integer to error type" { 426 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 427 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 428 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 429 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 430 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 431 432 try testCastIntToErr(error.ItBroke); 433 try comptime testCastIntToErr(error.ItBroke); 434 } 435 fn testCastIntToErr(err: anyerror) !void { 436 const x = @intFromError(err); 437 const y = @errorFromInt(x); 438 try expect(error.ItBroke == y); 439 } 440 441 test "peer resolve array and const slice" { 442 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 443 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 444 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 445 446 try testPeerResolveArrayConstSlice(true); 447 try comptime testPeerResolveArrayConstSlice(true); 448 } 449 fn testPeerResolveArrayConstSlice(b: bool) !void { 450 const value1 = if (b) "aoeu" else @as([]const u8, "zz"); 451 const value2 = if (b) @as([]const u8, "zz") else "aoeu"; 452 try expect(mem.eql(u8, value1, "aoeu")); 453 try expect(mem.eql(u8, value2, "zz")); 454 } 455 456 test "implicitly cast from T to anyerror!?T" { 457 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 458 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 459 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 460 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 461 462 try castToOptionalTypeError(1); 463 try comptime castToOptionalTypeError(1); 464 } 465 466 const A = struct { 467 a: i32, 468 }; 469 fn castToOptionalTypeError(z: i32) !void { 470 const x = @as(i32, 1); 471 const y: anyerror!?i32 = x; 472 try expect((try y).? == 1); 473 474 const f = z; 475 const g: anyerror!?i32 = f; 476 _ = try g; 477 478 const a = A{ .a = z }; 479 const b: anyerror!?A = a; 480 try expect((b catch unreachable).?.a == 1); 481 } 482 483 test "implicitly cast from [0]T to anyerror![]T" { 484 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 485 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 486 487 try testCastZeroArrayToErrSliceMut(); 488 try comptime testCastZeroArrayToErrSliceMut(); 489 } 490 491 fn testCastZeroArrayToErrSliceMut() !void { 492 try expect((gimmeErrOrSlice() catch unreachable).len == 0); 493 } 494 495 fn gimmeErrOrSlice() anyerror![]u8 { 496 return &[_]u8{}; 497 } 498 499 test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" { 500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 501 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 502 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 503 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 504 505 const S = struct { 506 fn doTheTest() anyerror!void { 507 { 508 var data = "hi".*; 509 const slice = data[0..]; 510 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); 511 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); 512 } 513 { 514 var data: [2]u8 = "hi".*; 515 const slice = data[0..]; 516 try expect((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0); 517 try expect((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1); 518 } 519 } 520 }; 521 try S.doTheTest(); 522 try comptime S.doTheTest(); 523 } 524 fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 { 525 if (a) { 526 return &[_]u8{}; 527 } 528 529 return slice[0..1]; 530 } 531 532 test "implicit cast from *const [N]T to []const T" { 533 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 534 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 535 536 try testCastConstArrayRefToConstSlice(); 537 try comptime testCastConstArrayRefToConstSlice(); 538 } 539 540 fn testCastConstArrayRefToConstSlice() !void { 541 { 542 const blah = "aoeu".*; 543 const const_array_ref = &blah; 544 try expect(@TypeOf(const_array_ref) == *const [4:0]u8); 545 const slice: []const u8 = const_array_ref; 546 try expect(mem.eql(u8, slice, "aoeu")); 547 } 548 { 549 const blah: [4]u8 = "aoeu".*; 550 const const_array_ref = &blah; 551 try expect(@TypeOf(const_array_ref) == *const [4]u8); 552 const slice: []const u8 = const_array_ref; 553 try expect(mem.eql(u8, slice, "aoeu")); 554 } 555 } 556 557 test "peer type resolution: error and [N]T" { 558 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 559 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 560 561 try expect(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); 562 comptime assert(mem.eql(u8, try testPeerErrorAndArray(0), "OK")); 563 try expect(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); 564 comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK")); 565 } 566 567 fn testPeerErrorAndArray(x: u8) anyerror![]const u8 { 568 return switch (x) { 569 0x00 => "OK", 570 else => error.BadValue, 571 }; 572 } 573 fn testPeerErrorAndArray2(x: u8) anyerror![]const u8 { 574 return switch (x) { 575 0x00 => "OK", 576 0x01 => "OKK", 577 else => error.BadValue, 578 }; 579 } 580 581 test "single-item pointer of array to slice to unknown length pointer" { 582 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 583 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 584 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 585 586 try testCastPtrOfArrayToSliceAndPtr(); 587 try comptime testCastPtrOfArrayToSliceAndPtr(); 588 } 589 590 fn testCastPtrOfArrayToSliceAndPtr() !void { 591 { 592 var array = "aoeu".*; 593 const x: [*]u8 = &array; 594 x[0] += 1; 595 try expect(mem.eql(u8, array[0..], "boeu")); 596 const y: []u8 = &array; 597 y[0] += 1; 598 try expect(mem.eql(u8, array[0..], "coeu")); 599 } 600 { 601 var array: [4]u8 = "aoeu".*; 602 const x: [*]u8 = &array; 603 x[0] += 1; 604 try expect(mem.eql(u8, array[0..], "boeu")); 605 const y: []u8 = &array; 606 y[0] += 1; 607 try expect(mem.eql(u8, array[0..], "coeu")); 608 } 609 } 610 611 test "cast *[1][*]const u8 to [*]const ?[*]const u8" { 612 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 613 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 614 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 615 616 const window_name = [1][*]const u8{"window name"}; 617 const x: [*]const ?[*]const u8 = &window_name; 618 try expect(mem.eql(u8, std.mem.sliceTo(@as([*:0]const u8, @ptrCast(x[0].?)), 0), "window name")); 619 } 620 621 test "@intCast on vector" { 622 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 623 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 624 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 625 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 626 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; 627 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 628 629 const S = struct { 630 fn doTheTest() !void { 631 // Upcast (implicit, equivalent to @intCast) 632 var up0: @Vector(2, u8) = [_]u8{ 0x55, 0xaa }; 633 _ = &up0; 634 const up1: @Vector(2, u16) = up0; 635 const up2: @Vector(2, u32) = up0; 636 const up3: @Vector(2, u64) = up0; 637 // Downcast (safety-checked) 638 var down0 = up3; 639 _ = &down0; 640 const down1: @Vector(2, u32) = @intCast(down0); 641 const down2: @Vector(2, u16) = @intCast(down0); 642 const down3: @Vector(2, u8) = @intCast(down0); 643 644 try expect(mem.eql(u16, &@as([2]u16, up1), &[2]u16{ 0x55, 0xaa })); 645 try expect(mem.eql(u32, &@as([2]u32, up2), &[2]u32{ 0x55, 0xaa })); 646 try expect(mem.eql(u64, &@as([2]u64, up3), &[2]u64{ 0x55, 0xaa })); 647 648 try expect(mem.eql(u32, &@as([2]u32, down1), &[2]u32{ 0x55, 0xaa })); 649 try expect(mem.eql(u16, &@as([2]u16, down2), &[2]u16{ 0x55, 0xaa })); 650 try expect(mem.eql(u8, &@as([2]u8, down3), &[2]u8{ 0x55, 0xaa })); 651 } 652 }; 653 654 try S.doTheTest(); 655 try comptime S.doTheTest(); 656 } 657 658 test "@floatCast cast down" { 659 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 660 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 661 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 662 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 663 664 { 665 var double: f64 = 0.001534; 666 _ = &double; 667 const single = @as(f32, @floatCast(double)); 668 try expect(single == 0.001534); 669 } 670 { 671 const double: f64 = 0.001534; 672 const single = @as(f32, @floatCast(double)); 673 try expect(single == 0.001534); 674 } 675 } 676 677 test "peer type resolution: unreachable, error set, unreachable" { 678 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 679 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 680 681 const Error = error{ 682 FileDescriptorAlreadyPresentInSet, 683 OperationCausesCircularLoop, 684 FileDescriptorNotRegistered, 685 SystemResources, 686 UserResourceLimitReached, 687 FileDescriptorIncompatibleWithEpoll, 688 Unexpected, 689 }; 690 var err = Error.SystemResources; 691 _ = &err; 692 const transformed_err = switch (err) { 693 error.FileDescriptorAlreadyPresentInSet => unreachable, 694 error.OperationCausesCircularLoop => unreachable, 695 error.FileDescriptorNotRegistered => unreachable, 696 error.SystemResources => error.SystemResources, 697 error.UserResourceLimitReached => error.UserResourceLimitReached, 698 error.FileDescriptorIncompatibleWithEpoll => unreachable, 699 error.Unexpected => unreachable, 700 }; 701 try expect(transformed_err == error.SystemResources); 702 } 703 704 test "peer cast: error set any anyerror" { 705 const a: error{ One, Two } = undefined; 706 const b: anyerror = undefined; 707 try expect(@TypeOf(a, b) == anyerror); 708 try expect(@TypeOf(b, a) == anyerror); 709 } 710 711 test "peer type resolution: error set supersets" { 712 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 713 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 714 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 715 716 const a: error{ One, Two } = undefined; 717 const b: error{One} = undefined; 718 719 // A superset of B 720 { 721 const ty = @TypeOf(a, b); 722 const error_set_info = @typeInfo(ty); 723 try expect(error_set_info == .ErrorSet); 724 try expect(error_set_info.ErrorSet.?.len == 2); 725 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 726 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 727 } 728 729 // B superset of A 730 { 731 const ty = @TypeOf(b, a); 732 const error_set_info = @typeInfo(ty); 733 try expect(error_set_info == .ErrorSet); 734 try expect(error_set_info.ErrorSet.?.len == 2); 735 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 736 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 737 } 738 } 739 740 test "peer type resolution: disjoint error sets" { 741 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 742 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 743 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 744 745 const a: error{ One, Two } = undefined; 746 const b: error{Three} = undefined; 747 748 { 749 const ty = @TypeOf(a, b); 750 const error_set_info = @typeInfo(ty); 751 try expect(error_set_info == .ErrorSet); 752 try expect(error_set_info.ErrorSet.?.len == 3); 753 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 754 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 755 try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three")); 756 } 757 758 { 759 const ty = @TypeOf(b, a); 760 const error_set_info = @typeInfo(ty); 761 try expect(error_set_info == .ErrorSet); 762 try expect(error_set_info.ErrorSet.?.len == 3); 763 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 764 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 765 try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three")); 766 } 767 } 768 769 test "peer type resolution: error union and error set" { 770 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 771 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 772 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 773 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 774 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 775 776 const a: error{Three} = undefined; 777 const b: error{ One, Two }!u32 = undefined; 778 779 { 780 const ty = @TypeOf(a, b); 781 const info = @typeInfo(ty); 782 try expect(info == .ErrorUnion); 783 784 const error_set_info = @typeInfo(info.ErrorUnion.error_set); 785 try expect(error_set_info.ErrorSet.?.len == 3); 786 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 787 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 788 try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three")); 789 } 790 791 { 792 const ty = @TypeOf(b, a); 793 const info = @typeInfo(ty); 794 try expect(info == .ErrorUnion); 795 796 const error_set_info = @typeInfo(info.ErrorUnion.error_set); 797 try expect(error_set_info.ErrorSet.?.len == 3); 798 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 799 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 800 try expect(mem.eql(u8, error_set_info.ErrorSet.?[2].name, "Three")); 801 } 802 } 803 804 test "peer type resolution: error union after non-error" { 805 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 806 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 807 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 808 809 const a: u32 = undefined; 810 const b: error{ One, Two }!u32 = undefined; 811 812 { 813 const ty = @TypeOf(a, b); 814 const info = @typeInfo(ty); 815 try expect(info == .ErrorUnion); 816 try expect(info.ErrorUnion.payload == u32); 817 818 const error_set_info = @typeInfo(info.ErrorUnion.error_set); 819 try expect(error_set_info.ErrorSet.?.len == 2); 820 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 821 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 822 } 823 824 { 825 const ty = @TypeOf(b, a); 826 const info = @typeInfo(ty); 827 try expect(info == .ErrorUnion); 828 try expect(info.ErrorUnion.payload == u32); 829 830 const error_set_info = @typeInfo(info.ErrorUnion.error_set); 831 try expect(error_set_info.ErrorSet.?.len == 2); 832 try expect(mem.eql(u8, error_set_info.ErrorSet.?[0].name, "One")); 833 try expect(mem.eql(u8, error_set_info.ErrorSet.?[1].name, "Two")); 834 } 835 } 836 837 test "peer cast *[0]T to E![]const T" { 838 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 839 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 840 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 841 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 842 843 var buffer: [5]u8 = "abcde".*; 844 const buf: anyerror![]const u8 = buffer[0..]; 845 var b = false; 846 _ = &b; 847 const y = if (b) &[0]u8{} else buf; 848 const z = if (!b) buf else &[0]u8{}; 849 try expect(mem.eql(u8, "abcde", y catch unreachable)); 850 try expect(mem.eql(u8, "abcde", z catch unreachable)); 851 } 852 853 test "peer cast *[0]T to []const T" { 854 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; 855 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 856 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 857 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 858 859 var buffer: [5]u8 = "abcde".*; 860 const buf: []const u8 = buffer[0..]; 861 var b = false; 862 _ = &b; 863 const y = if (b) &[0]u8{} else buf; 864 try expect(mem.eql(u8, "abcde", y)); 865 } 866 867 test "peer cast *[N]T to [*]T" { 868 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 869 870 var array = [4:99]i32{ 1, 2, 3, 4 }; 871 var dest: [*]i32 = undefined; 872 _ = &dest; 873 try expect(@TypeOf(&array, dest) == [*]i32); 874 try expect(@TypeOf(dest, &array) == [*]i32); 875 } 876 877 test "peer resolution of string literals" { 878 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 879 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 880 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 881 882 const S = struct { 883 const E = enum { a, b, c, d }; 884 885 fn doTheTest(e: E) !void { 886 const cmd = switch (e) { 887 .a => "one", 888 .b => "two", 889 .c => "three", 890 .d => "four", 891 }; 892 try expect(mem.eql(u8, cmd, "two")); 893 } 894 }; 895 try S.doTheTest(.b); 896 try comptime S.doTheTest(.b); 897 } 898 899 test "peer cast [:x]T to []T" { 900 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 901 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 902 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 903 904 const S = struct { 905 fn doTheTest() !void { 906 var array = [4:0]i32{ 1, 2, 3, 4 }; 907 const slice: [:0]i32 = &array; 908 const dest: []i32 = slice; 909 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); 910 } 911 }; 912 try S.doTheTest(); 913 try comptime S.doTheTest(); 914 } 915 916 test "peer cast [N:x]T to [N]T" { 917 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 918 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 919 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 920 921 const S = struct { 922 fn doTheTest() !void { 923 var array = [4:0]i32{ 1, 2, 3, 4 }; 924 _ = &array; 925 const dest: [4]i32 = array; 926 try expect(mem.eql(i32, &dest, &[_]i32{ 1, 2, 3, 4 })); 927 } 928 }; 929 try S.doTheTest(); 930 try comptime S.doTheTest(); 931 } 932 933 test "peer cast *[N:x]T to *[N]T" { 934 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 935 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 936 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 937 938 const S = struct { 939 fn doTheTest() !void { 940 var array = [4:0]i32{ 1, 2, 3, 4 }; 941 const dest: *[4]i32 = &array; 942 try expect(mem.eql(i32, dest, &[_]i32{ 1, 2, 3, 4 })); 943 } 944 }; 945 try S.doTheTest(); 946 try comptime S.doTheTest(); 947 } 948 949 test "peer cast [*:x]T to [*]T" { 950 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 951 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 952 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 953 954 const S = struct { 955 fn doTheTest() !void { 956 var array = [4:99]i32{ 1, 2, 3, 4 }; 957 const dest: [*]i32 = &array; 958 try expect(dest[0] == 1); 959 try expect(dest[1] == 2); 960 try expect(dest[2] == 3); 961 try expect(dest[3] == 4); 962 try expect(dest[4] == 99); 963 } 964 }; 965 try S.doTheTest(); 966 try comptime S.doTheTest(); 967 } 968 969 test "peer cast [:x]T to [*:x]T" { 970 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 971 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 972 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 973 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 974 975 const S = struct { 976 fn doTheTest() !void { 977 var array = [4:0]i32{ 1, 2, 3, 4 }; 978 const slice: [:0]i32 = &array; 979 const dest: [*:0]i32 = slice; 980 try expect(dest[0] == 1); 981 try expect(dest[1] == 2); 982 try expect(dest[2] == 3); 983 try expect(dest[3] == 4); 984 try expect(dest[4] == 0); 985 } 986 }; 987 try S.doTheTest(); 988 try comptime S.doTheTest(); 989 } 990 991 test "peer type resolution implicit cast to return type" { 992 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 993 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 994 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 995 996 const S = struct { 997 fn doTheTest() !void { 998 for ("hello") |c| _ = f(c); 999 } 1000 fn f(c: u8) []const u8 { 1001 return switch (c) { 1002 'h', 'e' => &[_]u8{c}, // should cast to slice 1003 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice 1004 else => ([_]u8{c})[0..], // is a slice 1005 }; 1006 } 1007 }; 1008 try S.doTheTest(); 1009 try comptime S.doTheTest(); 1010 } 1011 1012 test "peer type resolution implicit cast to variable type" { 1013 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1014 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1015 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1016 1017 const S = struct { 1018 fn doTheTest() !void { 1019 var x: []const u8 = undefined; 1020 for ("hello") |c| x = switch (c) { 1021 'h', 'e' => &[_]u8{c}, // should cast to slice 1022 'l', ' ' => &[_]u8{ c, '.' }, // should cast to slice 1023 else => ([_]u8{c})[0..], // is a slice 1024 }; 1025 } 1026 }; 1027 try S.doTheTest(); 1028 try comptime S.doTheTest(); 1029 } 1030 1031 test "variable initialization uses result locations properly with regards to the type" { 1032 var b = true; 1033 _ = &b; 1034 const x: i32 = if (b) 1 else 2; 1035 try expect(x == 1); 1036 } 1037 1038 test "cast between C pointer with different but compatible types" { 1039 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1040 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1041 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1042 1043 const S = struct { 1044 fn foo(arg: [*]c_ushort) u16 { 1045 return arg[0]; 1046 } 1047 fn doTheTest() !void { 1048 var x = [_]u16{ 4, 2, 1, 3 }; 1049 try expect(foo(@as([*]u16, @ptrCast(&x))) == 4); 1050 } 1051 }; 1052 try S.doTheTest(); 1053 try comptime S.doTheTest(); 1054 } 1055 1056 test "peer type resolve string lit with sentinel-terminated mutable slice" { 1057 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1058 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1059 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1060 1061 var array: [4:0]u8 = undefined; 1062 array[4] = 0; // TODO remove this when #4372 is solved 1063 const slice: [:0]u8 = array[0..4 :0]; 1064 comptime assert(@TypeOf(slice, "hi") == [:0]const u8); 1065 comptime assert(@TypeOf("hi", slice) == [:0]const u8); 1066 } 1067 1068 test "peer type resolve array pointers, one of them const" { 1069 var array1: [4]u8 = undefined; 1070 const array2: [5]u8 = undefined; 1071 comptime assert(@TypeOf(&array1, &array2) == []const u8); 1072 comptime assert(@TypeOf(&array2, &array1) == []const u8); 1073 } 1074 1075 test "peer type resolve array pointer and unknown pointer" { 1076 const const_array: [4]u8 = undefined; 1077 var array: [4]u8 = undefined; 1078 var const_ptr: [*]const u8 = undefined; 1079 var ptr: [*]u8 = undefined; 1080 _ = .{ &const_ptr, &ptr }; 1081 1082 comptime assert(@TypeOf(&array, ptr) == [*]u8); 1083 comptime assert(@TypeOf(ptr, &array) == [*]u8); 1084 1085 comptime assert(@TypeOf(&const_array, ptr) == [*]const u8); 1086 comptime assert(@TypeOf(ptr, &const_array) == [*]const u8); 1087 1088 comptime assert(@TypeOf(&array, const_ptr) == [*]const u8); 1089 comptime assert(@TypeOf(const_ptr, &array) == [*]const u8); 1090 1091 comptime assert(@TypeOf(&const_array, const_ptr) == [*]const u8); 1092 comptime assert(@TypeOf(const_ptr, &const_array) == [*]const u8); 1093 } 1094 1095 test "comptime float casts" { 1096 const a = @as(comptime_float, @floatFromInt(1)); 1097 try expect(a == 1); 1098 try expect(@TypeOf(a) == comptime_float); 1099 const b = @as(comptime_int, @intFromFloat(2)); 1100 try expect(b == 2); 1101 try expect(@TypeOf(b) == comptime_int); 1102 1103 try expectIntFromFloat(comptime_int, 1234, i16, 1234); 1104 try expectIntFromFloat(comptime_float, 12.3, comptime_int, 12); 1105 } 1106 1107 test "pointer reinterpret const float to int" { 1108 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1109 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1110 1111 // The hex representation is 0x3fe3333333333303. 1112 const float: f64 = 5.99999999999994648725e-01; 1113 const float_ptr = &float; 1114 const int_ptr = @as(*const i32, @ptrCast(float_ptr)); 1115 const int_val = int_ptr.*; 1116 if (native_endian == .little) 1117 try expect(int_val == 0x33333303) 1118 else 1119 try expect(int_val == 0x3fe33333); 1120 } 1121 1122 test "implicit cast from [*]T to ?*anyopaque" { 1123 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1124 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1125 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1126 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1127 1128 var a = [_]u8{ 3, 2, 1 }; 1129 var runtime_zero: usize = 0; 1130 _ = &runtime_zero; 1131 incrementVoidPtrArray(a[runtime_zero..].ptr, 3); 1132 try expect(std.mem.eql(u8, &a, &[_]u8{ 4, 3, 2 })); 1133 } 1134 1135 fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void { 1136 var n: usize = 0; 1137 while (n < len) : (n += 1) { 1138 @as([*]u8, @ptrCast(array.?))[n] += 1; 1139 } 1140 } 1141 1142 test "compile time int to ptr of function" { 1143 try foobar(FUNCTION_CONSTANT); 1144 } 1145 1146 // On some architectures function pointers must be aligned. 1147 const hardcoded_fn_addr = maxInt(usize) & ~@as(usize, 0xf); 1148 pub const FUNCTION_CONSTANT = @as(PFN_void, @ptrFromInt(hardcoded_fn_addr)); 1149 pub const PFN_void = *const fn (*anyopaque) callconv(.C) void; 1150 1151 fn foobar(func: PFN_void) !void { 1152 try std.testing.expect(@intFromPtr(func) == hardcoded_fn_addr); 1153 } 1154 1155 test "cast function with an opaque parameter" { 1156 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1157 1158 if (builtin.zig_backend == .stage2_c) { 1159 // https://github.com/ziglang/zig/issues/16845 1160 return error.SkipZigTest; 1161 } 1162 1163 const Container = struct { 1164 const Ctx = opaque {}; 1165 ctx: *Ctx, 1166 func: *const fn (*Ctx) void, 1167 }; 1168 const Foo = struct { 1169 x: i32, 1170 y: i32, 1171 fn funcImpl(self: *@This()) void { 1172 self.x += 1; 1173 self.y += 1; 1174 } 1175 }; 1176 var foo = Foo{ .x = 100, .y = 200 }; 1177 var c = Container{ 1178 .ctx = @ptrCast(&foo), 1179 .func = @ptrCast(&Foo.funcImpl), 1180 }; 1181 c.func(c.ctx); 1182 try std.testing.expectEqual(Foo{ .x = 101, .y = 201 }, foo); 1183 } 1184 1185 test "implicit ptr to *anyopaque" { 1186 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1187 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1188 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1189 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1190 1191 var a: u32 = 1; 1192 const ptr: *align(@alignOf(u32)) anyopaque = &a; 1193 const b: *u32 = @as(*u32, @ptrCast(ptr)); 1194 try expect(b.* == 1); 1195 const ptr2: ?*align(@alignOf(u32)) anyopaque = &a; 1196 const c: *u32 = @as(*u32, @ptrCast(ptr2.?)); 1197 try expect(c.* == 1); 1198 } 1199 1200 test "return null from fn () anyerror!?&T" { 1201 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1202 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1203 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1204 1205 const a = returnNullFromOptionalTypeErrorRef(); 1206 const b = returnNullLitFromOptionalTypeErrorRef(); 1207 try expect((try a) == null and (try b) == null); 1208 } 1209 fn returnNullFromOptionalTypeErrorRef() anyerror!?*A { 1210 const a: ?*A = null; 1211 return a; 1212 } 1213 fn returnNullLitFromOptionalTypeErrorRef() anyerror!?*A { 1214 return null; 1215 } 1216 1217 test "peer type resolution: [0]u8 and []const u8" { 1218 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1219 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1220 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1221 1222 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); 1223 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); 1224 comptime { 1225 try expect(peerTypeEmptyArrayAndSlice(true, "hi").len == 0); 1226 try expect(peerTypeEmptyArrayAndSlice(false, "hi").len == 1); 1227 } 1228 } 1229 fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 { 1230 if (a) { 1231 return &[_]u8{}; 1232 } 1233 1234 return slice[0..1]; 1235 } 1236 1237 test "implicitly cast from [N]T to ?[]const T" { 1238 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1239 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1240 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1241 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1242 1243 try expect(mem.eql(u8, castToOptionalSlice().?, "hi")); 1244 comptime assert(mem.eql(u8, castToOptionalSlice().?, "hi")); 1245 } 1246 1247 fn castToOptionalSlice() ?[]const u8 { 1248 return "hi"; 1249 } 1250 1251 test "cast u128 to f128 and back" { 1252 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1253 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1254 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1255 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1256 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1257 1258 try comptime testCast128(); 1259 try testCast128(); 1260 } 1261 1262 fn testCast128() !void { 1263 try expect(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000); 1264 } 1265 1266 fn cast128Int(x: f128) u128 { 1267 return @as(u128, @bitCast(x)); 1268 } 1269 1270 fn cast128Float(x: u128) f128 { 1271 return @as(f128, @bitCast(x)); 1272 } 1273 1274 test "implicit cast from *[N]T to ?[*]T" { 1275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1277 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1278 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1279 1280 var x: ?[*]u16 = null; 1281 var y: [4]u16 = [4]u16{ 0, 1, 2, 3 }; 1282 1283 x = &y; 1284 try expect(std.mem.eql(u16, x.?[0..4], y[0..4])); 1285 x.?[0] = 8; 1286 y[3] = 6; 1287 try expect(std.mem.eql(u16, x.?[0..4], y[0..4])); 1288 } 1289 1290 test "implicit cast from *T to ?*anyopaque" { 1291 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1292 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1293 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1294 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1295 1296 var a: u8 = 1; 1297 incrementVoidPtrValue(&a); 1298 try std.testing.expect(a == 2); 1299 } 1300 1301 fn incrementVoidPtrValue(value: ?*anyopaque) void { 1302 @as(*u8, @ptrCast(value.?)).* += 1; 1303 } 1304 1305 test "implicit cast *[0]T to E![]const u8" { 1306 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1307 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1308 1309 var x = @as(anyerror![]const u8, &[0]u8{}); 1310 _ = &x; 1311 try expect((x catch unreachable).len == 0); 1312 } 1313 1314 var global_array: [4]u8 = undefined; 1315 test "cast from array reference to fn: comptime fn ptr" { 1316 const f = @as(*align(1) const fn () callconv(.C) void, @ptrCast(&global_array)); 1317 try expect(@intFromPtr(f) == @intFromPtr(&global_array)); 1318 } 1319 test "cast from array reference to fn: runtime fn ptr" { 1320 var f = @as(*align(1) const fn () callconv(.C) void, @ptrCast(&global_array)); 1321 _ = &f; 1322 try expect(@intFromPtr(f) == @intFromPtr(&global_array)); 1323 } 1324 1325 test "*const [N]null u8 to ?[]const u8" { 1326 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1327 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1328 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1329 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1330 1331 const S = struct { 1332 fn doTheTest() !void { 1333 var a = "Hello"; 1334 _ = &a; 1335 const b: ?[]const u8 = a; 1336 try expect(mem.eql(u8, b.?, "Hello")); 1337 } 1338 }; 1339 try S.doTheTest(); 1340 try comptime S.doTheTest(); 1341 } 1342 1343 test "cast between [*c]T and ?[*:0]T on fn parameter" { 1344 const S = struct { 1345 const Handler = ?fn ([*c]const u8) callconv(.C) void; 1346 fn addCallback(comptime handler: Handler) void { 1347 _ = handler; 1348 } 1349 1350 fn myCallback(cstr: ?[*:0]const u8) callconv(.C) void { 1351 _ = cstr; 1352 } 1353 1354 fn doTheTest() void { 1355 addCallback(myCallback); 1356 } 1357 }; 1358 S.doTheTest(); 1359 } 1360 1361 var global_struct: struct { f0: usize } = undefined; 1362 test "assignment to optional pointer result loc" { 1363 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1364 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1365 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1366 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1367 1368 var foo: struct { ptr: ?*anyopaque } = .{ .ptr = &global_struct }; 1369 _ = &foo; 1370 try expect(foo.ptr.? == @as(*anyopaque, @ptrCast(&global_struct))); 1371 } 1372 1373 test "cast between *[N]void and []void" { 1374 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1375 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1376 1377 var a: [4]void = undefined; 1378 const b: []void = &a; 1379 try expect(b.len == 4); 1380 } 1381 1382 test "peer resolve arrays of different size to const slice" { 1383 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1384 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1385 1386 try expect(mem.eql(u8, boolToStr(true), "true")); 1387 try expect(mem.eql(u8, boolToStr(false), "false")); 1388 comptime assert(mem.eql(u8, boolToStr(true), "true")); 1389 comptime assert(mem.eql(u8, boolToStr(false), "false")); 1390 } 1391 fn boolToStr(b: bool) []const u8 { 1392 return if (b) "true" else "false"; 1393 } 1394 1395 test "cast f16 to wider types" { 1396 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1397 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1398 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1399 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1400 if (builtin.zig_backend == .stage2_c and comptime builtin.cpu.arch.isArmOrThumb()) return error.SkipZigTest; 1401 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 1402 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1403 1404 const S = struct { 1405 fn doTheTest() !void { 1406 var x: f16 = 1234.0; 1407 _ = &x; 1408 try expect(@as(f32, 1234.0) == x); 1409 try expect(@as(f64, 1234.0) == x); 1410 try expect(@as(f128, 1234.0) == x); 1411 } 1412 }; 1413 try S.doTheTest(); 1414 try comptime S.doTheTest(); 1415 } 1416 1417 test "cast f128 to narrower types" { 1418 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1419 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1420 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1421 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1422 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 1423 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1424 1425 const S = struct { 1426 fn doTheTest() !void { 1427 var x: f128 = 1234.0; 1428 _ = &x; 1429 try expect(@as(f16, 1234.0) == @as(f16, @floatCast(x))); 1430 try expect(@as(f32, 1234.0) == @as(f32, @floatCast(x))); 1431 try expect(@as(f64, 1234.0) == @as(f64, @floatCast(x))); 1432 } 1433 }; 1434 try S.doTheTest(); 1435 try comptime S.doTheTest(); 1436 } 1437 1438 test "peer type resolution: unreachable, null, slice" { 1439 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1440 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1441 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1442 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1443 1444 const S = struct { 1445 fn doTheTest(num: usize, word: []const u8) !void { 1446 const result = switch (num) { 1447 0 => null, 1448 1 => word, 1449 else => unreachable, 1450 }; 1451 try expect(mem.eql(u8, result.?, "hi")); 1452 } 1453 }; 1454 try S.doTheTest(1, "hi"); 1455 } 1456 1457 test "cast i8 fn call peers to i32 result" { 1458 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; 1459 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1460 1461 const S = struct { 1462 fn doTheTest() !void { 1463 var cond = true; 1464 _ = &cond; 1465 const value: i32 = if (cond) smallBoi() else bigBoi(); 1466 try expect(value == 123); 1467 } 1468 fn smallBoi() i8 { 1469 return 123; 1470 } 1471 fn bigBoi() i16 { 1472 return 1234; 1473 } 1474 }; 1475 try S.doTheTest(); 1476 try comptime S.doTheTest(); 1477 } 1478 1479 test "cast compatible optional types" { 1480 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1481 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1482 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1483 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1484 1485 var a: ?[:0]const u8 = null; 1486 _ = &a; 1487 const b: ?[]const u8 = a; 1488 try expect(b == null); 1489 } 1490 1491 test "coerce undefined single-item pointer of array to error union of slice" { 1492 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1493 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1494 1495 const a = @as([*]u8, undefined)[0..0]; 1496 var b: error{a}![]const u8 = a; 1497 _ = &b; 1498 const s = try b; 1499 try expect(s.len == 0); 1500 } 1501 1502 test "pointer to empty struct literal to mutable slice" { 1503 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1504 1505 var x: []i32 = &.{}; 1506 _ = &x; 1507 try expect(x.len == 0); 1508 } 1509 1510 test "coerce between pointers of compatible differently-named floats" { 1511 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1512 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1513 if (builtin.zig_backend == .stage2_c and builtin.os.tag == .windows and !builtin.link_libc) return error.SkipZigTest; 1514 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1515 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1516 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 1517 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1518 1519 if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) { 1520 // https://github.com/ziglang/zig/issues/12396 1521 return error.SkipZigTest; 1522 } 1523 1524 const F = switch (@typeInfo(c_longdouble).Float.bits) { 1525 16 => f16, 1526 32 => f32, 1527 64 => f64, 1528 80 => f80, 1529 128 => f128, 1530 else => @compileError("unreachable"), 1531 }; 1532 var f1: F = 12.34; 1533 const f2: *c_longdouble = &f1; 1534 f2.* += 1; 1535 try expect(f1 == @as(F, 12.34) + 1); 1536 } 1537 1538 test "peer type resolution of const and non-const pointer to array" { 1539 const a = @as(*[1024]u8, @ptrFromInt(42)); 1540 const b = @as(*const [1024]u8, @ptrFromInt(42)); 1541 try std.testing.expect(@TypeOf(a, b) == *const [1024]u8); 1542 try std.testing.expect(a == b); 1543 } 1544 1545 test "intFromFloat to zero-bit int" { 1546 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1547 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1548 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1549 1550 const a: f32 = 0.0; 1551 try comptime std.testing.expect(@as(u0, @intFromFloat(a)) == 0); 1552 } 1553 1554 test "peer type resolution of function pointer and function body" { 1555 const T = fn () u32; 1556 const a: T = undefined; 1557 const b: *const T = undefined; 1558 try expect(@TypeOf(a, b) == *const fn () u32); 1559 try expect(@TypeOf(b, a) == *const fn () u32); 1560 } 1561 1562 test "cast typed undefined to int" { 1563 comptime { 1564 const a: u16 = undefined; 1565 const b: u8 = a; 1566 _ = b; 1567 } 1568 } 1569 1570 test "implicit cast from [:0]T to [*c]T" { 1571 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1572 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1573 1574 var a: [:0]const u8 = "foo"; 1575 _ = &a; 1576 const b: [*c]const u8 = a; 1577 const c = std.mem.span(b); 1578 try expect(c.len == a.len); 1579 try expect(c.ptr == a.ptr); 1580 } 1581 1582 test "bitcast packed struct with u0" { 1583 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1584 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; 1585 1586 const S = packed struct(u2) { a: u0, b: u2 }; 1587 const s = @as(S, @bitCast(@as(u2, 2))); 1588 try expect(s.a == 0); 1589 try expect(s.b == 2); 1590 const i = @as(u2, @bitCast(s)); 1591 try expect(i == 2); 1592 } 1593 1594 test "optional pointer coerced to optional allowzero pointer" { 1595 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1596 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1597 1598 var p: ?*u32 = undefined; 1599 var q: ?*allowzero u32 = undefined; 1600 p = @as(*u32, @ptrFromInt(4)); 1601 q = p; 1602 try expect(@intFromPtr(q.?) == 4); 1603 } 1604 1605 test "optional slice coerced to allowzero many pointer" { 1606 const a: ?[]const u32 = null; 1607 const b: [*]allowzero const u8 = @ptrCast(a); 1608 const c = @intFromPtr(b); 1609 try std.testing.expect(c == 0); 1610 } 1611 1612 test "optional slice passed as parameter coerced to allowzero many pointer" { 1613 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1614 1615 const ns = struct { 1616 const Color = struct { 1617 r: u8, 1618 g: u8, 1619 b: u8, 1620 a: u8, 1621 }; 1622 1623 fn foo(pixels: ?[]const Color) !void { 1624 const data: [*]allowzero const u8 = @ptrCast(pixels); 1625 const int = @intFromPtr(data); 1626 try std.testing.expect(int == 0); 1627 } 1628 }; 1629 1630 try ns.foo(null); 1631 } 1632 1633 test "single item pointer to pointer to array to slice" { 1634 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1635 1636 var x: i32 = 1234; 1637 try expect(@as([]const i32, @as(*[1]i32, &x))[0] == 1234); 1638 const z1 = @as([]const i32, @as(*[1]i32, &x)); 1639 try expect(z1[0] == 1234); 1640 } 1641 1642 test "peer type resolution forms error union" { 1643 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1644 1645 var foo: i32 = 123; 1646 _ = &foo; 1647 const result = if (foo < 0) switch (-foo) { 1648 0 => unreachable, 1649 42 => error.AccessDenied, 1650 else => unreachable, 1651 } else @as(u32, @intCast(foo)); 1652 try expect(try result == 123); 1653 } 1654 1655 test "@constCast without a result location" { 1656 const x: i32 = 1234; 1657 const y = @constCast(&x); 1658 try expect(@TypeOf(y) == *i32); 1659 try expect(y.* == 1234); 1660 } 1661 1662 test "@constCast optional" { 1663 const x: u8 = 10; 1664 const m: ?*const u8 = &x; 1665 const p = @constCast(m); 1666 try expect(@TypeOf(p) == ?*u8); 1667 } 1668 1669 test "@volatileCast without a result location" { 1670 var x: i32 = 1234; 1671 const y: *volatile i32 = &x; 1672 const z = @volatileCast(y); 1673 try expect(@TypeOf(z) == *i32); 1674 try expect(z.* == 1234); 1675 } 1676 1677 test "coercion from single-item pointer to @as to slice" { 1678 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1679 1680 var x: u32 = 1; 1681 1682 // Why the following line gets a compile error? 1683 const t: []u32 = @as(*[1]u32, &x); 1684 1685 try expect(t[0] == 1); 1686 } 1687 1688 test "peer type resolution: const sentinel slice and mutable non-sentinel slice" { 1689 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1690 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1691 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1692 1693 const S = struct { 1694 fn doTheTest(comptime T: type, comptime s: T) !void { 1695 var a: [:s]const T = @as(*const [2:s]T, @ptrFromInt(0x1000)); 1696 var b: []T = @as(*[3]T, @ptrFromInt(0x2000)); 1697 _ = .{ &a, &b }; 1698 comptime assert(@TypeOf(a, b) == []const T); 1699 comptime assert(@TypeOf(b, a) == []const T); 1700 1701 var t = true; 1702 _ = &t; 1703 const r1 = if (t) a else b; 1704 const r2 = if (t) b else a; 1705 1706 const R = @TypeOf(r1); 1707 1708 try expectEqual(@as(R, @as(*const [2:s]T, @ptrFromInt(0x1000))), r1); 1709 try expectEqual(@as(R, @as(*const [3]T, @ptrFromInt(0x2000))), r2); 1710 } 1711 }; 1712 1713 try S.doTheTest(u8, 0); 1714 try S.doTheTest(?*anyopaque, null); 1715 } 1716 1717 test "peer type resolution: float and comptime-known fixed-width integer" { 1718 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1719 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1720 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1721 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 1722 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1723 1724 const i: u8 = 100; 1725 var f: f32 = 1.234; 1726 _ = &f; 1727 comptime assert(@TypeOf(i, f) == f32); 1728 comptime assert(@TypeOf(f, i) == f32); 1729 1730 var t = true; 1731 _ = &t; 1732 const r1 = if (t) i else f; 1733 const r2 = if (t) f else i; 1734 1735 const T = @TypeOf(r1); 1736 1737 try expectEqual(@as(T, 100.0), r1); 1738 try expectEqual(@as(T, 1.234), r2); 1739 } 1740 1741 test "peer type resolution: same array type with sentinel" { 1742 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1743 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1744 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1745 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1746 1747 var a: [2:0]u32 = .{ 0, 1 }; 1748 var b: [2:0]u32 = .{ 2, 3 }; 1749 _ = .{ &a, &b }; 1750 comptime assert(@TypeOf(a, b) == [2:0]u32); 1751 comptime assert(@TypeOf(b, a) == [2:0]u32); 1752 1753 var t = true; 1754 _ = &t; 1755 const r1 = if (t) a else b; 1756 const r2 = if (t) b else a; 1757 1758 const T = @TypeOf(r1); 1759 1760 try expectEqual(T{ 0, 1 }, r1); 1761 try expectEqual(T{ 2, 3 }, r2); 1762 } 1763 1764 test "peer type resolution: array with sentinel and array without sentinel" { 1765 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1766 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1767 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1768 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1769 1770 var a: [2:0]u32 = .{ 0, 1 }; 1771 var b: [2]u32 = .{ 2, 3 }; 1772 _ = .{ &a, &b }; 1773 comptime assert(@TypeOf(a, b) == [2]u32); 1774 comptime assert(@TypeOf(b, a) == [2]u32); 1775 1776 var t = true; 1777 _ = &t; 1778 const r1 = if (t) a else b; 1779 const r2 = if (t) b else a; 1780 1781 const T = @TypeOf(r1); 1782 1783 try expectEqual(T{ 0, 1 }, r1); 1784 try expectEqual(T{ 2, 3 }, r2); 1785 } 1786 1787 test "peer type resolution: array and vector with same child type" { 1788 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1789 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1790 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1791 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1792 1793 var arr: [2]u32 = .{ 0, 1 }; 1794 var vec: @Vector(2, u32) = .{ 2, 3 }; 1795 _ = .{ &arr, &vec }; 1796 comptime assert(@TypeOf(arr, vec) == @Vector(2, u32)); 1797 comptime assert(@TypeOf(vec, arr) == @Vector(2, u32)); 1798 1799 var t = true; 1800 _ = &t; 1801 const r1 = if (t) arr else vec; 1802 const r2 = if (t) vec else arr; 1803 1804 const T = @TypeOf(r1); 1805 1806 try expectEqual(T{ 0, 1 }, r1); 1807 try expectEqual(T{ 2, 3 }, r2); 1808 } 1809 1810 test "peer type resolution: array with smaller child type and vector with larger child type" { 1811 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1812 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1813 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 1814 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1815 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1816 1817 var arr: [2]u8 = .{ 0, 1 }; 1818 var vec: @Vector(2, u64) = .{ 2, 3 }; 1819 _ = .{ &arr, &vec }; 1820 comptime assert(@TypeOf(arr, vec) == @Vector(2, u64)); 1821 comptime assert(@TypeOf(vec, arr) == @Vector(2, u64)); 1822 1823 var t = true; 1824 _ = &t; 1825 const r1 = if (t) arr else vec; 1826 const r2 = if (t) vec else arr; 1827 1828 const T = @TypeOf(r1); 1829 1830 try expectEqual(T{ 0, 1 }, r1); 1831 try expectEqual(T{ 2, 3 }, r2); 1832 } 1833 1834 test "peer type resolution: error union and optional of same type" { 1835 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1836 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1837 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1838 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1839 1840 const E = error{Foo}; 1841 var a: E!*u8 = error.Foo; 1842 var b: ?*u8 = null; 1843 _ = .{ &a, &b }; 1844 comptime assert(@TypeOf(a, b) == E!?*u8); 1845 comptime assert(@TypeOf(b, a) == E!?*u8); 1846 1847 var t = true; 1848 _ = &t; 1849 const r1 = if (t) a else b; 1850 const r2 = if (t) b else a; 1851 1852 const T = @TypeOf(r1); 1853 1854 try expectEqual(@as(T, error.Foo), r1); 1855 try expectEqual(@as(T, null), r2); 1856 } 1857 1858 test "peer type resolution: C pointer and @TypeOf(null)" { 1859 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1860 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1861 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1862 1863 var a: [*c]c_int = 0x1000; 1864 _ = &a; 1865 const b = null; 1866 comptime assert(@TypeOf(a, b) == [*c]c_int); 1867 comptime assert(@TypeOf(b, a) == [*c]c_int); 1868 1869 var t = true; 1870 _ = &t; 1871 const r1 = if (t) a else b; 1872 const r2 = if (t) b else a; 1873 1874 const T = @TypeOf(r1); 1875 1876 try expectEqual(@as(T, 0x1000), r1); 1877 try expectEqual(@as(T, null), r2); 1878 } 1879 1880 test "peer type resolution: three-way resolution combines error set and optional" { 1881 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1882 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1883 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1884 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1885 1886 const E = error{Foo}; 1887 var a: E = error.Foo; 1888 var b: *const [5:0]u8 = @ptrFromInt(0x1000); 1889 var c: ?[*:0]u8 = null; 1890 _ = .{ &a, &b, &c }; 1891 comptime assert(@TypeOf(a, b, c) == E!?[*:0]const u8); 1892 comptime assert(@TypeOf(a, c, b) == E!?[*:0]const u8); 1893 comptime assert(@TypeOf(b, a, c) == E!?[*:0]const u8); 1894 comptime assert(@TypeOf(b, c, a) == E!?[*:0]const u8); 1895 comptime assert(@TypeOf(c, a, b) == E!?[*:0]const u8); 1896 comptime assert(@TypeOf(c, b, a) == E!?[*:0]const u8); 1897 1898 var x: u8 = 0; 1899 _ = &x; 1900 const r1 = switch (x) { 1901 0 => a, 1902 1 => b, 1903 else => c, 1904 }; 1905 const r2 = switch (x) { 1906 0 => b, 1907 1 => a, 1908 else => c, 1909 }; 1910 const r3 = switch (x) { 1911 0 => c, 1912 1 => a, 1913 else => b, 1914 }; 1915 1916 const T = @TypeOf(r1); 1917 1918 try expectEqual(@as(T, error.Foo), r1); 1919 try expectEqual(@as(T, @as([*:0]u8, @ptrFromInt(0x1000))), r2); 1920 try expectEqual(@as(T, null), r3); 1921 } 1922 1923 test "peer type resolution: vector and optional vector" { 1924 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1925 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1926 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 1927 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1928 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO 1929 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1930 1931 var a: ?@Vector(3, u32) = .{ 0, 1, 2 }; 1932 var b: @Vector(3, u32) = .{ 3, 4, 5 }; 1933 _ = .{ &a, &b }; 1934 comptime assert(@TypeOf(a, b) == ?@Vector(3, u32)); 1935 comptime assert(@TypeOf(b, a) == ?@Vector(3, u32)); 1936 1937 var t = true; 1938 _ = &t; 1939 const r1 = if (t) a else b; 1940 const r2 = if (t) b else a; 1941 1942 const T = @TypeOf(r1); 1943 1944 try expectEqual(@as(T, .{ 0, 1, 2 }), r1); 1945 try expectEqual(@as(T, .{ 3, 4, 5 }), r2); 1946 } 1947 1948 test "peer type resolution: optional fixed-width int and comptime_int" { 1949 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1950 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1951 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1952 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1953 1954 var a: ?i32 = 42; 1955 _ = &a; 1956 const b: comptime_int = 50; 1957 comptime assert(@TypeOf(a, b) == ?i32); 1958 comptime assert(@TypeOf(b, a) == ?i32); 1959 1960 var t = true; 1961 _ = &t; 1962 const r1 = if (t) a else b; 1963 const r2 = if (t) b else a; 1964 1965 const T = @TypeOf(r1); 1966 1967 try expectEqual(@as(T, 42), r1); 1968 try expectEqual(@as(T, 50), r2); 1969 } 1970 1971 test "peer type resolution: array and tuple" { 1972 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1973 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1974 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 1975 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 1976 1977 var arr: [3]i32 = .{ 1, 2, 3 }; 1978 _ = &arr; 1979 const tup = .{ 4, 5, 6 }; 1980 1981 comptime assert(@TypeOf(arr, tup) == [3]i32); 1982 comptime assert(@TypeOf(tup, arr) == [3]i32); 1983 1984 var t = true; 1985 _ = &t; 1986 const r1 = if (t) arr else tup; 1987 const r2 = if (t) tup else arr; 1988 1989 const T = @TypeOf(r1); 1990 1991 try expectEqual(T{ 1, 2, 3 }, r1); 1992 try expectEqual(T{ 4, 5, 6 }, r2); 1993 } 1994 1995 test "peer type resolution: vector and tuple" { 1996 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 1997 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 1998 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 1999 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2000 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2001 2002 var vec: @Vector(3, i32) = .{ 1, 2, 3 }; 2003 _ = &vec; 2004 const tup = .{ 4, 5, 6 }; 2005 2006 comptime assert(@TypeOf(vec, tup) == @Vector(3, i32)); 2007 comptime assert(@TypeOf(tup, vec) == @Vector(3, i32)); 2008 2009 var t = true; 2010 _ = &t; 2011 const r1 = if (t) vec else tup; 2012 const r2 = if (t) tup else vec; 2013 2014 const T = @TypeOf(r1); 2015 2016 try expectEqual(T{ 1, 2, 3 }, r1); 2017 try expectEqual(T{ 4, 5, 6 }, r2); 2018 } 2019 2020 test "peer type resolution: vector and array and tuple" { 2021 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2022 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2023 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2024 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2025 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2026 2027 var vec: @Vector(2, i8) = .{ 10, 20 }; 2028 var arr: [2]i8 = .{ 30, 40 }; 2029 _ = .{ &vec, &arr }; 2030 const tup = .{ 50, 60 }; 2031 2032 comptime assert(@TypeOf(vec, arr, tup) == @Vector(2, i8)); 2033 comptime assert(@TypeOf(vec, tup, arr) == @Vector(2, i8)); 2034 comptime assert(@TypeOf(arr, vec, tup) == @Vector(2, i8)); 2035 comptime assert(@TypeOf(arr, tup, vec) == @Vector(2, i8)); 2036 comptime assert(@TypeOf(tup, vec, arr) == @Vector(2, i8)); 2037 comptime assert(@TypeOf(tup, arr, vec) == @Vector(2, i8)); 2038 2039 var x: u8 = 0; 2040 _ = &x; 2041 const r1 = switch (x) { 2042 0 => vec, 2043 1 => arr, 2044 else => tup, 2045 }; 2046 const r2 = switch (x) { 2047 0 => arr, 2048 1 => vec, 2049 else => tup, 2050 }; 2051 const r3 = switch (x) { 2052 0 => tup, 2053 1 => vec, 2054 else => arr, 2055 }; 2056 2057 const T = @TypeOf(r1); 2058 2059 try expectEqual(T{ 10, 20 }, r1); 2060 try expectEqual(T{ 30, 40 }, r2); 2061 try expectEqual(T{ 50, 60 }, r3); 2062 } 2063 2064 test "peer type resolution: empty tuple pointer and slice" { 2065 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2066 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2067 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2068 2069 var a: [:0]const u8 = "Hello"; 2070 var b = &.{}; 2071 _ = .{ &a, &b }; 2072 2073 comptime assert(@TypeOf(a, b) == []const u8); 2074 comptime assert(@TypeOf(b, a) == []const u8); 2075 2076 var t = true; 2077 _ = &t; 2078 const r1 = if (t) a else b; 2079 const r2 = if (t) b else a; 2080 2081 try expectEqualSlices(u8, "Hello", r1); 2082 try expectEqualSlices(u8, "", r2); 2083 } 2084 2085 test "peer type resolution: tuple pointer and slice" { 2086 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2087 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2088 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2089 2090 var a: [:0]const u8 = "Hello"; 2091 var b = &.{ @as(u8, 'x'), @as(u8, 'y'), @as(u8, 'z') }; 2092 _ = .{ &a, &b }; 2093 2094 comptime assert(@TypeOf(a, b) == []const u8); 2095 comptime assert(@TypeOf(b, a) == []const u8); 2096 2097 var t = true; 2098 _ = &t; 2099 const r1 = if (t) a else b; 2100 const r2 = if (t) b else a; 2101 2102 try expectEqualSlices(u8, "Hello", r1); 2103 try expectEqualSlices(u8, "xyz", r2); 2104 } 2105 2106 test "peer type resolution: tuple pointer and optional slice" { 2107 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2108 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2109 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2110 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2111 // Miscompilation on Intel's OpenCL CPU runtime. 2112 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // flaky 2113 2114 var a: ?[:0]const u8 = null; 2115 var b = &.{ @as(u8, 'x'), @as(u8, 'y'), @as(u8, 'z') }; 2116 _ = .{ &a, &b }; 2117 2118 comptime assert(@TypeOf(a, b) == ?[]const u8); 2119 comptime assert(@TypeOf(b, a) == ?[]const u8); 2120 2121 var t = true; 2122 _ = &t; 2123 const r1 = if (t) a else b; 2124 const r2 = if (t) b else a; 2125 2126 try expectEqual(@as(?[]const u8, null), r1); 2127 try expectEqualSlices(u8, "xyz", r2 orelse ""); 2128 } 2129 2130 test "peer type resolution: many compatible pointers" { 2131 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2132 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2133 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2134 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO 2135 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2136 2137 var buf = "foo-3".*; 2138 2139 var vals = .{ 2140 @as([*]const u8, "foo-0"), 2141 @as([*:0]const u8, "foo-1"), 2142 @as([*:0]const u8, "foo-2"), 2143 @as([*]u8, &buf), 2144 @as(*const [5]u8, "foo-4"), 2145 }; 2146 _ = &vals; 2147 2148 // Check every possible permutation of types in @TypeOf 2149 @setEvalBranchQuota(5000); 2150 comptime var perms = 0; // check the loop is hitting every permutation 2151 inline for (0..5) |i_0| { 2152 inline for (0..5) |i_1| { 2153 if (i_1 == i_0) continue; 2154 inline for (0..5) |i_2| { 2155 if (i_2 == i_0 or i_2 == i_1) continue; 2156 inline for (0..5) |i_3| { 2157 if (i_3 == i_0 or i_3 == i_1 or i_3 == i_2) continue; 2158 inline for (0..5) |i_4| { 2159 if (i_4 == i_0 or i_4 == i_1 or i_4 == i_2 or i_4 == i_3) continue; 2160 perms += 1; 2161 comptime assert(@TypeOf( 2162 vals[i_0], 2163 vals[i_1], 2164 vals[i_2], 2165 vals[i_3], 2166 vals[i_4], 2167 ) == [*]const u8); 2168 } 2169 } 2170 } 2171 } 2172 } 2173 comptime assert(perms == 5 * 4 * 3 * 2 * 1); 2174 2175 var x: u8 = 0; 2176 _ = &x; 2177 inline for (0..5) |i| { 2178 const r = switch (x) { 2179 0 => vals[i], 2180 1 => vals[0], 2181 2 => vals[1], 2182 3 => vals[2], 2183 4 => vals[3], 2184 else => vals[4], 2185 }; 2186 const expected = switch (i) { 2187 0 => "foo-0", 2188 1 => "foo-1", 2189 2 => "foo-2", 2190 3 => "foo-3", 2191 4 => "foo-4", 2192 else => unreachable, 2193 }; 2194 try expectEqualSlices(u8, expected, std.mem.span(@as([*:0]const u8, @ptrCast(r)))); 2195 } 2196 } 2197 2198 test "peer type resolution: tuples with comptime fields" { 2199 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2200 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2201 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2202 if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO 2203 2204 const a = .{ 1, 2 }; 2205 const b = .{ @as(u32, 3), @as(i16, 4) }; 2206 2207 // TODO: tuple type equality doesn't work properly yet 2208 const ti1 = @typeInfo(@TypeOf(a, b)); 2209 const ti2 = @typeInfo(@TypeOf(b, a)); 2210 inline for (.{ ti1, ti2 }) |ti| { 2211 const s = ti.Struct; 2212 comptime assert(s.is_tuple); 2213 comptime assert(s.fields.len == 2); 2214 comptime assert(s.fields[0].type == u32); 2215 comptime assert(s.fields[1].type == i16); 2216 } 2217 2218 var t = true; 2219 _ = &t; 2220 const r1 = if (t) a else b; 2221 const r2 = if (t) b else a; 2222 2223 try expectEqual(@as(u32, 1), r1[0]); 2224 try expectEqual(@as(i16, 2), r1[1]); 2225 2226 try expectEqual(@as(u32, 3), r2[0]); 2227 try expectEqual(@as(i16, 4), r2[1]); 2228 } 2229 2230 test "peer type resolution: C pointer and many pointer" { 2231 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2232 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2233 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2234 2235 var buf = "hello".*; 2236 2237 const a: [*c]u8 = &buf; 2238 var b: [*:0]const u8 = "world"; 2239 _ = &b; 2240 2241 comptime assert(@TypeOf(a, b) == [*c]const u8); 2242 comptime assert(@TypeOf(b, a) == [*c]const u8); 2243 2244 var t = true; 2245 _ = &t; 2246 const r1 = if (t) a else b; 2247 const r2 = if (t) b else a; 2248 2249 try expectEqual(r1, a); 2250 try expectEqual(r2, b); 2251 } 2252 2253 test "peer type resolution: pointer attributes are combined correctly" { 2254 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2255 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2256 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2257 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2258 2259 var buf_a align(4) = "foo".*; 2260 var buf_b align(4) = "bar".*; 2261 var buf_c align(4) = "baz".*; 2262 2263 const a: [*:0]align(4) const u8 = &buf_a; 2264 const b: *align(2) volatile [3:0]u8 = &buf_b; 2265 const c: [*:0]align(4) u8 = &buf_c; 2266 2267 comptime assert(@TypeOf(a, b, c) == [*:0]align(2) const volatile u8); 2268 comptime assert(@TypeOf(a, c, b) == [*:0]align(2) const volatile u8); 2269 comptime assert(@TypeOf(b, a, c) == [*:0]align(2) const volatile u8); 2270 comptime assert(@TypeOf(b, c, a) == [*:0]align(2) const volatile u8); 2271 comptime assert(@TypeOf(c, a, b) == [*:0]align(2) const volatile u8); 2272 comptime assert(@TypeOf(c, b, a) == [*:0]align(2) const volatile u8); 2273 2274 var x: u8 = 0; 2275 _ = &x; 2276 const r1 = switch (x) { 2277 0 => a, 2278 1 => b, 2279 else => c, 2280 }; 2281 const r2 = switch (x) { 2282 0 => b, 2283 1 => a, 2284 else => c, 2285 }; 2286 const r3 = switch (x) { 2287 0 => c, 2288 1 => a, 2289 else => b, 2290 }; 2291 2292 try expectEqualSlices(u8, std.mem.span(@volatileCast(r1)), "foo"); 2293 try expectEqualSlices(u8, std.mem.span(@volatileCast(r2)), "bar"); 2294 try expectEqualSlices(u8, std.mem.span(@volatileCast(r3)), "baz"); 2295 } 2296 2297 test "peer type resolution: arrays of compatible types" { 2298 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2299 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2300 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2301 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2302 2303 var e0: u8 = 3; 2304 var e1: u8 = 2; 2305 var e2: u8 = 1; 2306 const a = [3]*u8{ &e0, &e1, &e2 }; 2307 const b = [3]*const u8{ &e0, &e1, &e2 }; 2308 2309 comptime assert(@TypeOf(a, b) == [3]*const u8); 2310 comptime assert(@TypeOf(b, a) == [3]*const u8); 2311 2312 try expectEqual(@as(@TypeOf(a, b), a), b); 2313 } 2314 2315 test "cast builtins can wrap result in optional" { 2316 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2317 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2318 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2319 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2320 2321 const S = struct { 2322 const MyEnum = enum(u32) { _ }; 2323 fn a() ?MyEnum { 2324 return @enumFromInt(123); 2325 } 2326 fn b() ?u32 { 2327 return @intFromFloat(42.50); 2328 } 2329 fn c() ?*const f32 { 2330 const x: u32 = 1; 2331 return @ptrCast(&x); 2332 } 2333 2334 fn doTheTest() !void { 2335 const ra = a() orelse return error.ImpossibleError; 2336 const rb = b() orelse return error.ImpossibleError; 2337 const rc = c() orelse return error.ImpossibleError; 2338 2339 comptime assert(@TypeOf(ra) == MyEnum); 2340 comptime assert(@TypeOf(rb) == u32); 2341 comptime assert(@TypeOf(rc) == *const f32); 2342 2343 try expect(@intFromEnum(ra) == 123); 2344 try expect(rb == 42); 2345 try expect(@as(*const u32, @ptrCast(rc)).* == 1); 2346 } 2347 }; 2348 2349 try S.doTheTest(); 2350 try comptime S.doTheTest(); 2351 } 2352 2353 test "cast builtins can wrap result in error union" { 2354 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2355 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2356 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2357 2358 const S = struct { 2359 const MyEnum = enum(u32) { _ }; 2360 const E = error{ImpossibleError}; 2361 fn a() E!MyEnum { 2362 return @enumFromInt(123); 2363 } 2364 fn b() E!u32 { 2365 return @intFromFloat(42.50); 2366 } 2367 fn c() E!*const f32 { 2368 const x: u32 = 1; 2369 return @ptrCast(&x); 2370 } 2371 2372 fn doTheTest() !void { 2373 const ra = try a(); 2374 const rb = try b(); 2375 const rc = try c(); 2376 2377 comptime assert(@TypeOf(ra) == MyEnum); 2378 comptime assert(@TypeOf(rb) == u32); 2379 comptime assert(@TypeOf(rc) == *const f32); 2380 2381 try expect(@intFromEnum(ra) == 123); 2382 try expect(rb == 42); 2383 try expect(@as(*const u32, @ptrCast(rc)).* == 1); 2384 } 2385 }; 2386 2387 try S.doTheTest(); 2388 try comptime S.doTheTest(); 2389 } 2390 2391 test "cast builtins can wrap result in error union and optional" { 2392 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2393 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2394 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2395 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2396 2397 const S = struct { 2398 const MyEnum = enum(u32) { _ }; 2399 const E = error{ImpossibleError}; 2400 fn a() E!?MyEnum { 2401 return @enumFromInt(123); 2402 } 2403 fn b() E!?u32 { 2404 return @intFromFloat(42.50); 2405 } 2406 fn c() E!?*const f32 { 2407 const x: u32 = 1; 2408 return @ptrCast(&x); 2409 } 2410 2411 fn doTheTest() !void { 2412 const ra = try a() orelse return error.ImpossibleError; 2413 const rb = try b() orelse return error.ImpossibleError; 2414 const rc = try c() orelse return error.ImpossibleError; 2415 2416 comptime assert(@TypeOf(ra) == MyEnum); 2417 comptime assert(@TypeOf(rb) == u32); 2418 comptime assert(@TypeOf(rc) == *const f32); 2419 2420 try expect(@intFromEnum(ra) == 123); 2421 try expect(rb == 42); 2422 try expect(@as(*const u32, @ptrCast(rc)).* == 1); 2423 } 2424 }; 2425 2426 try S.doTheTest(); 2427 try comptime S.doTheTest(); 2428 } 2429 2430 test "@floatCast on vector" { 2431 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2432 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2433 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2434 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2435 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 2436 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2437 2438 const S = struct { 2439 fn doTheTest() !void { 2440 { 2441 var a: @Vector(2, f64) = .{ 1.5, 2.5 }; 2442 _ = &a; 2443 const b: @Vector(2, f32) = @floatCast(a); 2444 try expectEqual(@Vector(2, f32){ 1.5, 2.5 }, b); 2445 } 2446 { 2447 var a: @Vector(2, f32) = .{ 3.25, 4.25 }; 2448 _ = &a; 2449 const b: @Vector(2, f64) = @floatCast(a); 2450 try expectEqual(@Vector(2, f64){ 3.25, 4.25 }, b); 2451 } 2452 { 2453 var a: @Vector(2, f32) = .{ 5.75, 6.75 }; 2454 _ = &a; 2455 const b: @Vector(2, f64) = a; 2456 try expectEqual(@Vector(2, f64){ 5.75, 6.75 }, b); 2457 } 2458 { 2459 var vec: @Vector(2, f32) = @splat(1234.0); 2460 _ = &vec; 2461 const wider: @Vector(2, f64) = vec; 2462 try expect(wider[0] == 1234.0); 2463 try expect(wider[1] == 1234.0); 2464 } 2465 } 2466 }; 2467 2468 try S.doTheTest(); 2469 try comptime S.doTheTest(); 2470 } 2471 2472 test "@ptrFromInt on vector" { 2473 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2474 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2475 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2476 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2477 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2478 2479 const S = struct { 2480 fn doTheTest() !void { 2481 var a: @Vector(3, usize) = .{ 0x1000, 0x2000, 0x3000 }; 2482 _ = &a; 2483 const b: @Vector(3, *anyopaque) = @ptrFromInt(a); 2484 try expectEqual(@Vector(3, *anyopaque){ 2485 @ptrFromInt(0x1000), 2486 @ptrFromInt(0x2000), 2487 @ptrFromInt(0x3000), 2488 }, b); 2489 } 2490 }; 2491 2492 try S.doTheTest(); 2493 try comptime S.doTheTest(); 2494 } 2495 2496 test "@intFromPtr on vector" { 2497 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2498 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2499 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2500 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2501 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2502 2503 const S = struct { 2504 fn doTheTest() !void { 2505 var a: @Vector(3, *anyopaque) = .{ 2506 @ptrFromInt(0x1000), 2507 @ptrFromInt(0x2000), 2508 @ptrFromInt(0x3000), 2509 }; 2510 _ = &a; 2511 const b: @Vector(3, usize) = @intFromPtr(a); 2512 try expectEqual(@Vector(3, usize){ 0x1000, 0x2000, 0x3000 }, b); 2513 } 2514 }; 2515 2516 try S.doTheTest(); 2517 try comptime S.doTheTest(); 2518 } 2519 2520 test "@floatFromInt on vector" { 2521 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2522 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2523 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2524 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2525 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 2526 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2527 2528 const S = struct { 2529 fn doTheTest() !void { 2530 var a: @Vector(3, u32) = .{ 10, 20, 30 }; 2531 _ = &a; 2532 const b: @Vector(3, f32) = @floatFromInt(a); 2533 try expectEqual(@Vector(3, f32){ 10.0, 20.0, 30.0 }, b); 2534 } 2535 }; 2536 2537 try S.doTheTest(); 2538 try comptime S.doTheTest(); 2539 } 2540 2541 test "@intFromFloat on vector" { 2542 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2543 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2544 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2545 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2546 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2547 2548 const S = struct { 2549 fn doTheTest() !void { 2550 var a: @Vector(3, f32) = .{ 10.3, 20.5, 30.7 }; 2551 _ = &a; 2552 const b: @Vector(3, u32) = @intFromFloat(a); 2553 try expectEqual(@Vector(3, u32){ 10, 20, 30 }, b); 2554 } 2555 }; 2556 2557 try S.doTheTest(); 2558 try comptime S.doTheTest(); 2559 } 2560 2561 test "@intFromBool on vector" { 2562 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2563 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2564 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2565 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2566 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; 2567 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2568 2569 if (builtin.zig_backend == .stage2_llvm and 2570 builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) 2571 { 2572 // https://github.com/ziglang/zig/issues/19825 2573 return error.SkipZigTest; 2574 } 2575 2576 const S = struct { 2577 fn doTheTest() !void { 2578 var a: @Vector(3, bool) = .{ false, true, false }; 2579 _ = &a; 2580 const b: @Vector(3, u1) = @intFromBool(a); 2581 try expectEqual(@Vector(3, u1){ 0, 1, 0 }, b); 2582 } 2583 }; 2584 2585 try S.doTheTest(); 2586 try comptime S.doTheTest(); 2587 } 2588 2589 test "numeric coercions with undefined" { 2590 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 2591 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2592 2593 const from: i32 = undefined; 2594 var to: f32 = from; 2595 to = @floatFromInt(from); 2596 to = 42.0; 2597 try expectEqual(@as(f32, 42.0), to); 2598 } 2599 2600 test "15-bit int to float" { 2601 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; 2602 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2603 2604 var a: u15 = 42; 2605 _ = &a; 2606 const b: f32 = @floatFromInt(a); 2607 try expect(b == 42.0); 2608 } 2609 2610 test "@as does not corrupt values with incompatible representations" { 2611 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2612 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2613 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2614 if (builtin.zig_backend == .stage2_x86_64 and builtin.target.ofmt != .elf and builtin.target.ofmt != .macho) return error.SkipZigTest; 2615 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2616 2617 const x: f32 = @as(f16, blk: { 2618 if (false) { 2619 // Trick the compiler into trying to use a result pointer if it can! 2620 break :blk .{undefined}; 2621 } 2622 break :blk 1.23; 2623 }); 2624 try std.testing.expectApproxEqAbs(@as(f32, 1.23), x, 0.001); 2625 } 2626 2627 test "result information is preserved through many nested structures" { 2628 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2629 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2630 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2631 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2632 2633 const S = struct { 2634 fn doTheTest() !void { 2635 const E = error{Foo}; 2636 const T = *const ?E!struct { x: ?*const E!?u8 }; 2637 2638 var val: T = &.{ .x = &@truncate(0x1234) }; 2639 _ = &val; 2640 2641 const struct_val = val.*.? catch unreachable; 2642 const int_val = (struct_val.x.?.* catch unreachable).?; 2643 2644 try expect(int_val == 0x34); 2645 } 2646 }; 2647 2648 try S.doTheTest(); 2649 try comptime S.doTheTest(); 2650 } 2651 2652 test "@intCast vector of signed integer" { 2653 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2654 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2655 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO 2656 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO 2657 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO 2658 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2659 2660 var x: @Vector(4, i32) = .{ 1, 2, 3, 4 }; 2661 _ = &x; 2662 const y: @Vector(4, i8) = @intCast(x); 2663 2664 try expect(y[0] == 1); 2665 try expect(y[1] == 2); 2666 try expect(y[2] == 3); 2667 try expect(y[3] == 4); 2668 } 2669 2670 test "result type is preserved into comptime block" { 2671 const x: u32 = comptime @intCast(123); 2672 try expect(x == 123); 2673 } 2674 2675 test "implicit cast from ptr to tuple to ptr to struct" { 2676 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO 2677 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2678 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2679 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; 2680 2681 const ComptimeReason = union(enum) { 2682 c_import: struct { 2683 a: u32, 2684 }, 2685 }; 2686 2687 const Block = struct { 2688 reason: ?*const ComptimeReason, 2689 }; 2690 2691 var a: u32 = 16; 2692 _ = &a; 2693 var reason = .{ .c_import = .{ .a = a } }; 2694 var block = Block{ 2695 .reason = &reason, 2696 }; 2697 _ = █ 2698 try expect(block.reason.?.c_import.a == 16); 2699 } 2700 2701 test "bitcast vector" { 2702 if (builtin.zig_backend == .stage2_x86) return error.SkipZigTest; // TODO 2703 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO 2704 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO 2705 2706 const u8x32 = @Vector(32, u8); 2707 const u32x8 = @Vector(8, u32); 2708 2709 const zerox32: u8x32 = [_]u8{0} ** 32; 2710 const bigsum: u32x8 = @bitCast(zerox32); 2711 try std.testing.expectEqual(0, @reduce(.Add, bigsum)); 2712 }