Commit d785dc49aa

Jacob G-W <jacoblevgw@gmail.com>
2021-08-17 16:49:17
stage2: add error set type equality
1 parent 2129cc5
Changed files (2)
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,
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);