Commit cb248898ab

Robin Voetter <robin@voetter.nl>
2021-11-22 02:52:26
sema: error union in-memory coercion
1 parent 83a0329
Changed files (3)
src/Sema.zig
@@ -12415,6 +12415,15 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target:
         return coerceInMemoryAllowedFns(dest_ty, src_ty, target);
     }
 
+    // Error Unions
+    if (dest_ty.zigTypeTag() == .ErrorUnion and src_ty.zigTypeTag() == .ErrorUnion) {
+        const child = coerceInMemoryAllowed(dest_ty.errorUnionPayload(), src_ty.errorUnionPayload(), dest_is_mut, target);
+        if (child == .no_match) {
+            return child;
+        }
+        return coerceInMemoryAllowed(dest_ty.errorUnionSet(), src_ty.errorUnionSet(), dest_is_mut, target);
+    }
+
     // Error Sets
     if (dest_ty.zigTypeTag() == .ErrorSet and src_ty.zigTypeTag() == .ErrorSet) {
         return coerceInMemoryAllowedErrorSets(dest_ty, src_ty);
@@ -12422,7 +12431,6 @@ fn coerceInMemoryAllowed(dest_ty: Type, src_ty: Type, dest_is_mut: bool, target:
 
     // TODO: arrays
     // TODO: non-pointer-like optionals
-    // TODO: error unions
     // TODO: vectors
 
     return .no_match;
test/behavior/error.zig
@@ -115,3 +115,19 @@ test "implicit cast to optional to error union to return result loc" {
     try S.entry();
     //comptime S.entry(); TODO
 }
+
+test "error: fn returning empty error set can be passed as fn returning any error" {
+    entry();
+    comptime entry();
+}
+
+fn entry() void {
+    foo2(bar2);
+}
+
+fn foo2(f: fn () anyerror!void) void {
+    const x = f();
+    x catch {};
+}
+
+fn bar2() (error{}!void) {}
test/behavior/error_stage1.zig
@@ -120,22 +120,6 @@ fn quux_1() !i32 {
     return error.C;
 }
 
-test "error: fn returning empty error set can be passed as fn returning any error" {
-    entry();
-    comptime entry();
-}
-
-fn entry() void {
-    foo2(bar2);
-}
-
-fn foo2(f: fn () anyerror!void) void {
-    const x = f();
-    x catch {};
-}
-
-fn bar2() (error{}!void) {}
-
 test "error: Zero sized error set returned with value payload crash" {
     _ = foo3(0) catch {};
     _ = comptime foo3(0) catch {};