diff --git a/src/type.zig b/src/type.zig index 28b87a8afe..41f392c04a 100644 --- a/src/type.zig +++ b/src/type.zig @@ -534,15 +534,24 @@ pub const Type = extern union { return a_data.error_set.eql(b_data.error_set) and a_data.payload.eql(b_data.payload); }, .ErrorSet => { - const a_is_anyerror = a.tag() == .anyerror; - const b_is_anyerror = b.tag() == .anyerror; + if (a.tag() == .anyerror and b.tag() == .anyerror) { + return true; + } - if (a_is_anyerror and b_is_anyerror) return true; - if (a_is_anyerror or b_is_anyerror) return false; + if (a.tag() == .error_set and b.tag() == .error_set) { + return a.castTag(.error_set).?.data.owner_decl == b.castTag(.error_set).?.data.owner_decl; + } - std.debug.panic("TODO implement Type equality comparison of {} and {}", .{ - a.tag(), b.tag(), - }); + if (a.tag() == .error_set_inferred and b.tag() == .error_set_inferred) { + return a.castTag(.error_set_inferred).?.data.func == b.castTag(.error_set_inferred).?.data.func; + } + + if (a.tag() == .error_set_single and b.tag() == .error_set_single) { + const a_data = a.castTag(.error_set_single).?.data; + const b_data = b.castTag(.error_set_single).?.data; + return std.mem.eql(u8, a_data, b_data); + } + return false; }, .Opaque, .Float, diff --git a/test/cases.zig b/test/cases.zig index ffff88f7d8..302246065f 100644 --- a/test/cases.zig +++ b/test/cases.zig @@ -1567,6 +1567,24 @@ pub fn addCases(ctx: *TestContext) !void { ":2:20: note: '||' merges error sets; 'or' performs boolean OR", }); } + { + var case = ctx.exe("error set equality", linux_x64); + + case.addCompareOutput( + \\pub fn main() void { + \\ assert(@TypeOf(error.Foo) == @TypeOf(error.Foo)); + \\ assert(@TypeOf(error.Bar) != @TypeOf(error.Foo)); + \\ assert(anyerror == anyerror); + \\ assert(error{Foo} != error{Foo}); + \\ // TODO put inferred error sets here when @typeInfo works + \\} + \\fn assert(b: bool) void { + \\ if (!b) unreachable; + \\} + , + "", + ); + } { var case = ctx.exe("inline assembly", linux_x64);