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