diff --git a/src/type.zig b/src/type.zig index 9126f1213b..e35006d930 100644 --- a/src/type.zig +++ b/src/type.zig @@ -556,37 +556,36 @@ pub const Type = extern union { return info_a.signedness == info_b.signedness and info_a.bits == info_b.bits; }, + .error_set_inferred => { + // Inferred error sets are only equal if both are inferred + // and they originate from the exact same function. + const a_set = a.castTag(.error_set_inferred).?.data; + const b_set = (b.castTag(.error_set_inferred) orelse return false).data; + return a_set.func == b_set.func; + }, + + .anyerror => { + return b.tag() == .anyerror; + }, + .error_set, .error_set_single, - .anyerror, - .error_set_inferred, .error_set_merged, => { - if (b.zigTypeTag() != .ErrorSet) return false; - - // inferred error sets are only equal if both are inferred - // and they originate from the exact same function. - if (a.castTag(.error_set_inferred)) |a_pl| { - if (b.castTag(.error_set_inferred)) |b_pl| { - return a_pl.data.func == b_pl.data.func; - } - return false; + switch (b.tag()) { + .error_set, .error_set_single, .error_set_merged => {}, + else => return false, } - if (b.tag() == .error_set_inferred) return false; - // anyerror matches exactly. - const a_is_any = a.isAnyError(); - const b_is_any = b.isAnyError(); - if (a_is_any or b_is_any) return a_is_any and b_is_any; - - // two resolved sets match if their error set names match. + // Two resolved sets match if their error set names match. + // Since they are pre-sorted we compare them element-wise. const a_set = a.errorSetNames(); const b_set = b.errorSetNames(); if (a_set.len != b_set.len) return false; - for (b_set) |b_val| { - if (!a.errorSetHasField(b_val)) return false; + for (a_set) |a_item, i| { + const b_item = b_set[i]; + if (!std.mem.eql(u8, a_item, b_item)) return false; } - return true; }, @@ -984,10 +983,10 @@ pub const Type = extern union { .error_set_inferred => { // inferred error sets are compared using their data pointer - const data = ty.castTag(.error_set_inferred).?.data.func; + const set = ty.castTag(.error_set_inferred).?.data; std.hash.autoHash(hasher, std.builtin.TypeId.ErrorSet); std.hash.autoHash(hasher, Tag.error_set_inferred); - std.hash.autoHash(hasher, data); + std.hash.autoHash(hasher, set.func); }, .@"opaque" => { diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 8541c7defd..73e03b1c3e 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -330,11 +330,11 @@ fn intLiteral(str: []const u8) !?i64 { } test "nested error union function call in optional unwrap" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { const Foo = struct { @@ -381,9 +381,9 @@ test "nested error union function call in optional unwrap" { test "return function call to error set from error union function" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn errorable() anyerror!i32 { @@ -414,9 +414,9 @@ test "optional error set is the same size as error set" { test "nested catch" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn entry() !void { @@ -440,14 +440,16 @@ test "nested catch" { } test "function pointer with return type that is error union with payload which is pointer of parent struct" { - // This test uses the stage2 const fn pointer - if (builtin.zig_backend == .stage1) return error.SkipZigTest; + if (builtin.zig_backend == .stage1) { + // stage1 has wrong function pointer semantics + return error.SkipZigTest; + } if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { const Foo = struct { @@ -501,9 +503,9 @@ test "return result loc as peer result loc in inferred error set function" { test "error payload type is correctly resolved" { if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const MyIntWrapper = struct { const Self = @This(); @@ -519,12 +521,6 @@ test "error payload type is correctly resolved" { } test "error union comptime caching" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const S = struct { fn quux(comptime arg: anytype) void { arg catch {}; @@ -571,12 +567,6 @@ test "error set equality" { // This tests using stage2 logic (#11022) if (builtin.zig_backend == .stage1) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - const a = error{One}; const b = error{One}; @@ -592,11 +582,7 @@ test "error set equality" { } test "inferred error set equality" { - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO const S = struct { fn foo() !void { diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index 8b917ad5e1..b2ea6ecbe0 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -209,10 +209,8 @@ test "type info: error set merged" { if (builtin.zig_backend == .stage1) return error.SkipZigTest; if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO const TestSet = error{ One, Two } || error{Three};