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 mem = std.mem;
   7
   8/// A more basic implementation of std.testing.expectError which
   9/// does not require formatter/printing support
  10fn expectError(expected_err: anyerror, observed_err_union: anytype) !void {
  11    if (observed_err_union) |_| {
  12        return error.TestExpectedError;
  13    } else |err| if (err == expected_err) {
  14        return; // Success
  15    }
  16    return error.TestExpectedError;
  17}
  18
  19test "error values" {
  20    const a = @intFromError(error.err1);
  21    const b = @intFromError(error.err2);
  22    try expect(a != b);
  23}
  24
  25test "redefinition of error values allowed" {
  26    shouldBeNotEqual(error.AnError, error.SecondError);
  27}
  28fn shouldBeNotEqual(a: anyerror, b: anyerror) void {
  29    if (a == b) unreachable;
  30}
  31
  32test "error binary operator" {
  33    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  34
  35    const a = errBinaryOperatorG(true) catch 3;
  36    const b = errBinaryOperatorG(false) catch 3;
  37    try expect(a == 3);
  38    try expect(b == 10);
  39}
  40fn errBinaryOperatorG(x: bool) anyerror!isize {
  41    return if (x) error.ItBroke else @as(isize, 10);
  42}
  43
  44test "empty error union" {
  45    const x = error{} || error{};
  46    _ = x;
  47}
  48
  49pub fn foo() anyerror!i32 {
  50    const x = try bar();
  51    return x + 1;
  52}
  53
  54pub fn bar() anyerror!i32 {
  55    return 13;
  56}
  57
  58pub fn baz() anyerror!i32 {
  59    const y = foo() catch 1234;
  60    return y + 1;
  61}
  62
  63test "error wrapping" {
  64    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  65
  66    try expect((baz() catch unreachable) == 15);
  67}
  68
  69test "unwrap simple value from error" {
  70    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  71
  72    const i = unwrapSimpleValueFromErrorDo() catch unreachable;
  73    try expect(i == 13);
  74}
  75fn unwrapSimpleValueFromErrorDo() anyerror!isize {
  76    return 13;
  77}
  78
  79test "error return in assignment" {
  80    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  81
  82    doErrReturnInAssignment() catch unreachable;
  83}
  84
  85fn doErrReturnInAssignment() anyerror!void {
  86    var x: i32 = undefined;
  87    x = try makeANonErr();
  88}
  89
  90fn makeANonErr() anyerror!i32 {
  91    return 1;
  92}
  93
  94test "syntax: optional operator in front of error union operator" {
  95    comptime {
  96        try expect(?(anyerror!i32) == ?(anyerror!i32));
  97    }
  98}
  99
 100test "widen cast integer payload of error union function call" {
 101    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 102    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 103
 104    const S = struct {
 105        fn errorable() !u64 {
 106            return @as(u64, try number());
 107        }
 108
 109        fn number() anyerror!u32 {
 110            return 1234;
 111        }
 112    };
 113    try expect((try S.errorable()) == 1234);
 114}
 115
 116test "debug info for optional error set" {
 117    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 118    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 119
 120    const SomeError = error{ Hello, Hello2 };
 121    var a_local_variable: ?SomeError = null;
 122    _ = &a_local_variable;
 123}
 124
 125test "implicit cast to optional to error union to return result loc" {
 126    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 127    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 128
 129    const S = struct {
 130        fn entry() !void {
 131            var x: Foo = undefined;
 132            if (func(&x)) |opt| {
 133                try expect(opt != null);
 134            } else |_| @panic("expected non error");
 135        }
 136        fn func(f: *Foo) anyerror!?*Foo {
 137            return f;
 138        }
 139        const Foo = struct {
 140            field: i32,
 141        };
 142    };
 143    try S.entry();
 144    //comptime S.entry(); TODO
 145}
 146
 147test "fn returning empty error set can be passed as fn returning any error" {
 148    entry();
 149    comptime entry();
 150}
 151
 152test "fn returning empty error set can be passed as fn returning any error - pointer" {
 153    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 154
 155    entryPtr();
 156    comptime entryPtr();
 157}
 158
 159fn entry() void {
 160    foo2(bar2);
 161}
 162
 163fn entryPtr() void {
 164    var ptr = &bar2;
 165    _ = &ptr;
 166    fooPtr(ptr);
 167}
 168
 169fn foo2(comptime f: fn () anyerror!void) void {
 170    const x = f();
 171    x catch {
 172        @panic("fail");
 173    };
 174}
 175
 176fn fooPtr(f: *const fn () anyerror!void) void {
 177    const x = f();
 178    x catch {
 179        @panic("fail");
 180    };
 181}
 182
 183fn bar2() (error{}!void) {}
 184
 185test "error union type " {
 186    try testErrorUnionType();
 187    try comptime testErrorUnionType();
 188}
 189
 190fn testErrorUnionType() !void {
 191    const x: anyerror!i32 = 1234;
 192    if (x) |value| try expect(value == 1234) else |_| unreachable;
 193    try expect(@typeInfo(@TypeOf(x)) == .error_union);
 194    try expect(@typeInfo(@typeInfo(@TypeOf(x)).error_union.error_set) == .error_set);
 195    try expect(@typeInfo(@TypeOf(x)).error_union.error_set == anyerror);
 196}
 197
 198test "error set type" {
 199    try testErrorSetType();
 200    try comptime testErrorSetType();
 201}
 202
 203const MyErrSet = error{
 204    OutOfMemory,
 205    FileNotFound,
 206};
 207
 208fn testErrorSetType() !void {
 209    try expect(@typeInfo(MyErrSet).error_set.?.len == 2);
 210
 211    const a: MyErrSet!i32 = 5678;
 212    const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
 213    try expect(b catch error.OutOfMemory == error.OutOfMemory);
 214
 215    if (a) |value| try expect(value == 5678) else |err| switch (err) {
 216        error.OutOfMemory => unreachable,
 217        error.FileNotFound => unreachable,
 218    }
 219}
 220
 221test "explicit error set cast" {
 222    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 223
 224    try testExplicitErrorSetCast(Set1.A);
 225    try comptime testExplicitErrorSetCast(Set1.A);
 226}
 227
 228const Set1 = error{ A, B };
 229const Set2 = error{ A, C };
 230
 231fn testExplicitErrorSetCast(set1: Set1) !void {
 232    const x: Set2 = @errorCast(set1);
 233    try expect(@TypeOf(x) == Set2);
 234    const y: Set1 = @errorCast(x);
 235    try expect(@TypeOf(y) == Set1);
 236    try expect(y == error.A);
 237}
 238
 239test "@errorCast on error unions" {
 240    const S = struct {
 241        fn doTheTest() !void {
 242            {
 243                const casted: error{Bad}!i32 = @errorCast(retErrUnion());
 244                try expect((try casted) == 1234);
 245            }
 246            {
 247                const casted: error{Bad}!i32 = @errorCast(retInferredErrUnion());
 248                try expect((try casted) == 5678);
 249            }
 250        }
 251
 252        fn retErrUnion() anyerror!i32 {
 253            return 1234;
 254        }
 255
 256        fn retInferredErrUnion() !i32 {
 257            return 5678;
 258        }
 259    };
 260
 261    try S.doTheTest();
 262    try comptime S.doTheTest();
 263}
 264
 265test "comptime test error for empty error set" {
 266    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 267
 268    try testComptimeTestErrorEmptySet(1234);
 269    try comptime testComptimeTestErrorEmptySet(1234);
 270}
 271
 272const EmptyErrorSet = error{};
 273
 274fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) !void {
 275    if (x) |v| try expect(v == 1234) else |err| {
 276        _ = err;
 277        @compileError("bad");
 278    }
 279}
 280
 281test "comptime err to int of error set with only 1 possible value" {
 282    testErrToIntWithOnePossibleValue(error.A, @intFromError(error.A));
 283    comptime testErrToIntWithOnePossibleValue(error.A, @intFromError(error.A));
 284}
 285fn testErrToIntWithOnePossibleValue(
 286    x: error{A},
 287    comptime value: u32,
 288) void {
 289    if (@intFromError(x) != value) {
 290        @compileError("bad");
 291    }
 292}
 293
 294test "inferred empty error set comptime catch" {
 295    const S = struct {
 296        fn foo() !void {}
 297    };
 298    S.foo() catch @compileError("fail");
 299}
 300
 301test "error inference with an empty set" {
 302    const S = struct {
 303        const Struct = struct {
 304            pub fn func() (error{})!usize {
 305                return 0;
 306            }
 307        };
 308
 309        fn AnotherStruct(comptime SubStruct: type) type {
 310            return struct {
 311                fn anotherFunc() !void {
 312                    try expect(0 == (try SubStruct.func()));
 313                }
 314            };
 315        }
 316    };
 317
 318    const GeneratedStruct = S.AnotherStruct(S.Struct);
 319    try GeneratedStruct.anotherFunc();
 320}
 321
 322test "error union peer type resolution" {
 323    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 324
 325    try testErrorUnionPeerTypeResolution(1);
 326}
 327
 328fn testErrorUnionPeerTypeResolution(x: i32) !void {
 329    const y = switch (x) {
 330        1 => bar_1(),
 331        2 => baz_1(),
 332        else => quux_1(),
 333    };
 334    if (y) |_| {
 335        @panic("expected error");
 336    } else |e| {
 337        try expect(e == error.A);
 338    }
 339}
 340
 341fn bar_1() anyerror {
 342    return error.A;
 343}
 344
 345fn baz_1() !i32 {
 346    return error.B;
 347}
 348
 349fn quux_1() !i32 {
 350    return error.C;
 351}
 352
 353test "error: Zero sized error set returned with value payload crash" {
 354    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 355
 356    _ = try foo3(0);
 357    _ = try comptime foo3(0);
 358}
 359
 360const Error = error{};
 361fn foo3(b: usize) Error!usize {
 362    return b;
 363}
 364
 365test "error: Infer error set from literals" {
 366    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 367    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 368
 369    _ = nullLiteral("n") catch |err| handleErrors(err);
 370    _ = floatLiteral("n") catch |err| handleErrors(err);
 371    _ = intLiteral("n") catch |err| handleErrors(err);
 372    _ = comptime nullLiteral("n") catch |err| handleErrors(err);
 373    _ = comptime floatLiteral("n") catch |err| handleErrors(err);
 374    _ = comptime intLiteral("n") catch |err| handleErrors(err);
 375}
 376
 377fn handleErrors(err: anytype) noreturn {
 378    switch (err) {
 379        error.T => {},
 380    }
 381
 382    unreachable;
 383}
 384
 385fn nullLiteral(str: []const u8) !?i64 {
 386    if (str[0] == 'n') return null;
 387
 388    return error.T;
 389}
 390
 391fn floatLiteral(str: []const u8) !?f64 {
 392    if (str[0] == 'n') return 1.0;
 393
 394    return error.T;
 395}
 396
 397fn intLiteral(str: []const u8) !?i64 {
 398    if (str[0] == 'n') return 1;
 399
 400    return error.T;
 401}
 402
 403test "nested error union function call in optional unwrap" {
 404    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 405    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 406
 407    const S = struct {
 408        const Foo = struct {
 409            a: i32,
 410        };
 411
 412        fn errorable() !i32 {
 413            const x: Foo = (try getFoo()) orelse return error.Other;
 414            return x.a;
 415        }
 416
 417        fn errorable2() !i32 {
 418            const x: Foo = (try getFoo2()) orelse return error.Other;
 419            return x.a;
 420        }
 421
 422        fn errorable3() !i32 {
 423            const x: Foo = (try getFoo3()) orelse return error.Other;
 424            return x.a;
 425        }
 426
 427        fn getFoo() anyerror!?Foo {
 428            return Foo{ .a = 1234 };
 429        }
 430
 431        fn getFoo2() anyerror!?Foo {
 432            return error.Failure;
 433        }
 434
 435        fn getFoo3() anyerror!?Foo {
 436            return null;
 437        }
 438    };
 439    try expect((try S.errorable()) == 1234);
 440    try expectError(error.Failure, S.errorable2());
 441    try expectError(error.Other, S.errorable3());
 442    comptime {
 443        try expect((try S.errorable()) == 1234);
 444        try expectError(error.Failure, S.errorable2());
 445        try expectError(error.Other, S.errorable3());
 446    }
 447}
 448
 449test "return function call to error set from error union function" {
 450    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 451
 452    const S = struct {
 453        fn errorable() anyerror!i32 {
 454            return fail();
 455        }
 456
 457        fn fail() anyerror {
 458            return error.Failure;
 459        }
 460    };
 461    try expectError(error.Failure, S.errorable());
 462    comptime assert(error.Failure == S.errorable());
 463}
 464
 465test "optional error set is the same size as error set" {
 466    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 467    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 468
 469    comptime assert(@sizeOf(?anyerror) == @sizeOf(anyerror));
 470    comptime assert(@alignOf(?anyerror) == @alignOf(anyerror));
 471    const S = struct {
 472        fn returnsOptErrSet() ?anyerror {
 473            return null;
 474        }
 475    };
 476    try expect(S.returnsOptErrSet() == null);
 477    comptime assert(S.returnsOptErrSet() == null);
 478}
 479
 480test "nested catch" {
 481    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 482
 483    const S = struct {
 484        fn entry() !void {
 485            try expectError(error.Bad, func());
 486        }
 487        fn fail() anyerror!Foo {
 488            return error.Wrong;
 489        }
 490        fn func() anyerror!Foo {
 491            _ = fail() catch
 492                fail() catch
 493                return error.Bad;
 494            unreachable;
 495        }
 496        const Foo = struct {
 497            field: i32,
 498        };
 499    };
 500    try S.entry();
 501    try comptime S.entry();
 502}
 503
 504test "function pointer with return type that is error union with payload which is pointer of parent struct" {
 505    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 506    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 507
 508    const S = struct {
 509        const Foo = struct {
 510            fun: *const fn (a: i32) (anyerror!*Foo),
 511        };
 512
 513        const Err = error{UnspecifiedErr};
 514
 515        fn bar(a: i32) anyerror!*Foo {
 516            _ = a;
 517            return Err.UnspecifiedErr;
 518        }
 519
 520        fn doTheTest() !void {
 521            var x = Foo{ .fun = @This().bar };
 522            try expectError(error.UnspecifiedErr, x.fun(1));
 523        }
 524    };
 525    try S.doTheTest();
 526}
 527
 528test "return result loc as peer result loc in inferred error set function" {
 529    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 530    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 531    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 532
 533    const S = struct {
 534        fn doTheTest() !void {
 535            if (quux(2)) |x| {
 536                try expect(x.Two);
 537            } else |e| switch (e) {
 538                error.Whatever => @panic("fail"),
 539            }
 540            try expectError(error.Whatever, quux(99));
 541        }
 542        const FormValue = union(enum) {
 543            One: void,
 544            Two: bool,
 545        };
 546
 547        fn quux(id: u64) !FormValue {
 548            return switch (id) {
 549                2 => FormValue{ .Two = true },
 550                1 => FormValue{ .One = {} },
 551                else => return error.Whatever,
 552            };
 553        }
 554    };
 555    try S.doTheTest();
 556    try comptime S.doTheTest();
 557}
 558
 559test "error payload type is correctly resolved" {
 560    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 561    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 562
 563    const MyIntWrapper = struct {
 564        const Self = @This();
 565
 566        x: i32,
 567
 568        pub fn create() anyerror!Self {
 569            return Self{ .x = 42 };
 570        }
 571    };
 572
 573    try expect(std.meta.eql(MyIntWrapper{ .x = 42 }, try MyIntWrapper.create()));
 574}
 575
 576test "error union comptime caching" {
 577    const S = struct {
 578        fn quux(comptime arg: anytype) void {
 579            arg catch {};
 580        }
 581    };
 582
 583    S.quux(@as(anyerror!void, {}));
 584    S.quux(@as(anyerror!void, {}));
 585}
 586
 587test "@errorName" {
 588    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 589    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 590    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 591    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 592
 593    try expect(mem.eql(u8, @errorName(error.AnError), "AnError"));
 594    try expect(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
 595    try expect(mem.eql(u8, @errorName(gimmeItBroke()), "ItBroke"));
 596}
 597fn gimmeItBroke() anyerror {
 598    return error.ItBroke;
 599}
 600
 601test "@errorName sentinel length matches slice length" {
 602    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 603    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 604    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 605    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 606
 607    const name = testBuiltinErrorName(error.FooBar);
 608    const length: usize = 6;
 609    try expect(length == std.mem.indexOfSentinel(u8, 0, name.ptr));
 610    try expect(length == name.len);
 611}
 612
 613pub fn testBuiltinErrorName(err: anyerror) [:0]const u8 {
 614    return @errorName(err);
 615}
 616
 617test "error set equality" {
 618    const a = error{One};
 619    const b = error{One};
 620
 621    try expect(a == a);
 622    try expect(a == b);
 623    try expect(a == error{One});
 624
 625    // should treat as a set
 626    const c = error{ One, Two };
 627    const d = error{ Two, One };
 628
 629    try expect(c == d);
 630}
 631
 632test "inferred error set equality" {
 633    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 634
 635    const S = struct {
 636        fn foo() !void {
 637            return @This().bar();
 638        }
 639
 640        fn bar() !void {
 641            return error.Bad;
 642        }
 643
 644        fn baz() !void {
 645            return quux();
 646        }
 647
 648        fn quux() anyerror!void {}
 649    };
 650
 651    const FooError = @typeInfo(@typeInfo(@TypeOf(S.foo)).@"fn".return_type.?).error_union.error_set;
 652    const BarError = @typeInfo(@typeInfo(@TypeOf(S.bar)).@"fn".return_type.?).error_union.error_set;
 653    const BazError = @typeInfo(@typeInfo(@TypeOf(S.baz)).@"fn".return_type.?).error_union.error_set;
 654
 655    try expect(BarError != error{Bad});
 656
 657    try expect(FooError != anyerror);
 658    try expect(BarError != anyerror);
 659    try expect(BazError != anyerror);
 660
 661    try expect(FooError != BarError);
 662    try expect(FooError != BazError);
 663    try expect(BarError != BazError);
 664
 665    try expect(FooError == FooError);
 666    try expect(BarError == BarError);
 667    try expect(BazError == BazError);
 668}
 669
 670test "peer type resolution of two different error unions" {
 671    const a: error{B}!void = {};
 672    const b: error{A}!void = {};
 673    var cond = true;
 674    _ = &cond;
 675    const err = if (cond) a else b;
 676    try err;
 677}
 678
 679test "coerce error set to the current inferred error set" {
 680    const S = struct {
 681        fn foo() !void {
 682            var a = false;
 683            _ = &a;
 684            if (a) {
 685                const b: error{A}!void = error.A;
 686                return b;
 687            }
 688            const b = error.A;
 689            return b;
 690        }
 691    };
 692    S.foo() catch {};
 693}
 694
 695test "error union payload is properly aligned" {
 696    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 697    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 698    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 699    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 700
 701    const S = struct {
 702        a: u128,
 703        b: u128,
 704        c: u128,
 705        fn foo() error{}!@This() {
 706            return @This(){ .a = 1, .b = 2, .c = 3 };
 707        }
 708    };
 709    const blk = S.foo() catch unreachable;
 710    if (blk.a != 1) unreachable;
 711}
 712
 713test "ret_ptr doesn't cause own inferred error set to be resolved" {
 714    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 715
 716    const S = struct {
 717        fn foo() !void {}
 718
 719        fn doTheTest() !void {
 720            errdefer @compileError("bad");
 721
 722            return try @This().foo();
 723        }
 724    };
 725    try S.doTheTest();
 726}
 727
 728test "simple else prong allowed even when all errors handled" {
 729    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 730
 731    const S = struct {
 732        fn foo() !u8 {
 733            return error.Foo;
 734        }
 735    };
 736    var value = S.foo() catch |err| switch (err) {
 737        error.Foo => @as(u8, 255),
 738        else => |e| return e,
 739    };
 740    try expect(value == 255);
 741    value = S.foo() catch |err| switch (err) {
 742        error.Foo => 255,
 743        else => unreachable,
 744    };
 745    try expect(value == 255);
 746    value = S.foo() catch |err| switch (err) {
 747        error.Foo => 255,
 748        else => return,
 749    };
 750    try expect(value == 255);
 751}
 752
 753test "pointer to error union payload" {
 754    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 755    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 756    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 757    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 758
 759    var err_union: anyerror!u8 = 15;
 760
 761    const payload_ptr = &(err_union catch unreachable);
 762    try expect(payload_ptr.* == 15);
 763}
 764
 765const NoReturn = struct {
 766    var a: u32 = undefined;
 767    fn someData() bool {
 768        a -= 1;
 769        return a == 0;
 770    }
 771    fn loop() !noreturn {
 772        while (true) {
 773            if (someData())
 774                return error.GenericFailure;
 775        }
 776    }
 777    fn testTry() anyerror {
 778        try loop();
 779    }
 780    fn testCatch() anyerror {
 781        loop() catch return error.OtherFailure;
 782        @compileError("bad");
 783    }
 784};
 785
 786test "error union of noreturn used with if" {
 787    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 788    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 789    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 790    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 791
 792    NoReturn.a = 64;
 793    if (NoReturn.loop()) {
 794        @compileError("bad");
 795    } else |err| {
 796        try expect(err == error.GenericFailure);
 797    }
 798}
 799
 800test "error union of noreturn used with try" {
 801    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 802    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 803    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 804    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 805
 806    NoReturn.a = 64;
 807    const err = NoReturn.testTry();
 808    try expect(err == error.GenericFailure);
 809}
 810
 811test "error union of noreturn used with catch" {
 812    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 813    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 814    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 815    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 816
 817    NoReturn.a = 64;
 818    const err = NoReturn.testCatch();
 819    try expect(err == error.OtherFailure);
 820}
 821
 822test "alignment of wrapping an error union payload" {
 823    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 824    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 825    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 826    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 827
 828    const S = struct {
 829        const I = extern struct { x: i128 };
 830
 831        fn foo() anyerror!I {
 832            var i: I = .{ .x = 1234 };
 833            _ = &i;
 834            return i;
 835        }
 836    };
 837    try expect((S.foo() catch unreachable).x == 1234);
 838}
 839
 840test "compare error union and error set" {
 841    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 842
 843    var a: anyerror = error.Foo;
 844    var b: anyerror!u32 = error.Bar;
 845    _ = &a;
 846
 847    try expect(a != b);
 848    try expect(b != a);
 849
 850    b = error.Foo;
 851
 852    try expect(a == b);
 853    try expect(b == a);
 854
 855    b = 2;
 856
 857    try expect(a != b);
 858    try expect(b != a);
 859}
 860
 861fn non_errorable() void {
 862    // Make sure catch works even in a function that does not call any errorable functions.
 863    //
 864    // This test is needed because stage 2's fix for #1923 means that catch blocks interact
 865    // with the error return trace index.
 866    var x: error{Foo}!void = {};
 867    _ = &x;
 868    return x catch {};
 869}
 870
 871test "catch within a function that calls no errorable functions" {
 872    non_errorable();
 873}
 874
 875test "error from comptime string" {
 876    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 877    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 878    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 879    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 880
 881    const name = "Weird error name!";
 882    const S = struct {
 883        fn foo() !void {
 884            return @field(anyerror, name);
 885        }
 886    };
 887    if (S.foo()) unreachable else |err| {
 888        try expect(mem.eql(u8, name, @errorName(err)));
 889    }
 890}
 891
 892test "field access of anyerror results in smaller error set" {
 893    const E1 = @TypeOf(error.Foo);
 894    try expect(@TypeOf(E1.Foo) == E1);
 895    const E2 = error{ A, B, C };
 896    try expect(@TypeOf(E2.A) == E2);
 897    try expect(@TypeOf(@field(anyerror, "NotFound")) == error{NotFound});
 898}
 899
 900test "optional error union return type" {
 901    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 902
 903    const S = struct {
 904        fn foo() ?anyerror!u32 {
 905            var x: u32 = 1234;
 906            _ = &x;
 907            return @as(anyerror!u32, x);
 908        }
 909    };
 910    try expect(1234 == try S.foo().?);
 911}
 912
 913test "optional error set return type" {
 914    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 915
 916    const E = error{ A, B };
 917    const S = struct {
 918        fn foo(return_null: bool) ?E {
 919            return if (return_null) null else E.A;
 920        }
 921    };
 922
 923    try expect(null == S.foo(true));
 924    try expect(E.A == S.foo(false).?);
 925}
 926
 927test "optional error set function parameter" {
 928    const S = struct {
 929        fn doTheTest(a: ?anyerror) !void {
 930            try std.testing.expect(a.? == error.OutOfMemory);
 931        }
 932    };
 933    try S.doTheTest(error.OutOfMemory);
 934    try comptime S.doTheTest(error.OutOfMemory);
 935}
 936
 937test "returning an error union containing a type with no runtime bits" {
 938    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 939    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 940
 941    const ZeroByteType = struct {
 942        foo: void,
 943
 944        pub fn init() !@This() {
 945            return .{ .foo = {} };
 946        }
 947    };
 948
 949    var zero_byte: ZeroByteType = undefined;
 950    (&zero_byte).* = try ZeroByteType.init();
 951}
 952
 953test "try used in recursive function with inferred error set" {
 954    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 955    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 956
 957    const Value = union(enum) {
 958        values: []const @This(),
 959        b,
 960
 961        fn x(value: @This()) !void {
 962            switch (value.values[0]) {
 963                .values => return try x(value.values[0]),
 964                .b => return error.a,
 965            }
 966        }
 967    };
 968    const a = Value{
 969        .values = &[1]Value{
 970            .{
 971                .values = &[1]Value{.{ .b = {} }},
 972            },
 973        },
 974    };
 975    try expectError(error.a, Value.x(a));
 976}
 977
 978test "generic inline function returns inferred error set" {
 979    const S = struct {
 980        inline fn retErr(comptime T: type) !T {
 981            return error.AnError;
 982        }
 983
 984        fn main0() !void {
 985            _ = try retErr(u8);
 986        }
 987    };
 988    S.main0() catch |e| {
 989        try std.testing.expect(e == error.AnError);
 990    };
 991}
 992
 993test "function called at runtime is properly analyzed for inferred error set" {
 994    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 995    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 996
 997    const S = struct {
 998        fn foo() !void {
 999            var a = true;
1000            _ = &a;
1001            if (a) return error.Foo;
1002            return error.Bar;
1003        }
1004        fn bar() !void {
1005            try @This().foo();
1006        }
1007    };
1008
1009    S.bar() catch |err| switch (err) {
1010        error.Foo => {},
1011        error.Bar => {},
1012    };
1013}
1014
1015test "errorCast to adhoc inferred error set" {
1016    const S = struct {
1017        inline fn baz() !i32 {
1018            return @errorCast(err());
1019        }
1020        fn err() anyerror!i32 {
1021            return 1234;
1022        }
1023    };
1024    try std.testing.expect((try S.baz()) == 1234);
1025}
1026
1027test "@errorCast from error set to error union" {
1028    const S = struct {
1029        fn doTheTest(set: error{ A, B }) error{A}!i32 {
1030            return @errorCast(set);
1031        }
1032    };
1033    try expectError(error.A, S.doTheTest(error.A));
1034    try expectError(error.A, comptime S.doTheTest(error.A));
1035}
1036
1037test "@errorCast from error union to error union" {
1038    const S = struct {
1039        fn doTheTest(set: error{ A, B }!i32) error{A}!i32 {
1040            return @errorCast(set);
1041        }
1042    };
1043    try expectError(error.A, S.doTheTest(error.A));
1044    try expectError(error.A, comptime S.doTheTest(error.A));
1045}
1046
1047test "result location initialization of error union with OPV payload" {
1048    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1049    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1050    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1051    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1052    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1053
1054    const S = struct {
1055        x: u0,
1056    };
1057
1058    const a: anyerror!S = .{ .x = 0 };
1059    comptime assert((a catch unreachable).x == 0);
1060
1061    comptime {
1062        var b: anyerror!S = .{ .x = 0 };
1063        _ = &b;
1064        assert((b catch unreachable).x == 0);
1065    }
1066
1067    var c: anyerror!S = .{ .x = 0 };
1068    _ = &c;
1069    try expectEqual(0, (c catch return error.TestFailed).x);
1070}
1071
1072test "return error union with i65" {
1073    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1074    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1075
1076    try expect(try add(1000, 234) == 1234);
1077}
1078
1079fn add(x: i65, y: i65) anyerror!i65 {
1080    return x + y;
1081}
1082
1083test "compare error union to error set" {
1084    const S = struct {
1085        fn doTheTest(val: error{Foo}!i32) !void {
1086            if (error.Foo == val) return error.Unexpected;
1087            if (val == error.Foo) return error.Unexpected;
1088        }
1089    };
1090    try S.doTheTest(0);
1091    try comptime S.doTheTest(0);
1092}