Commit d6e3988fe8

Veikka Tuominen <git@vexu.eu>
2022-07-26 14:39:47
Sema: better error when coercing error sets
1 parent 7862ab9
src/Sema.zig
@@ -5496,7 +5496,7 @@ fn analyzeCall(
         // TODO add error note: declared here
         return sema.fail(
             block,
-            func_src,
+            call_src,
             "expected {d} argument(s), found {d}",
             .{ fn_params_len, uncasted_args.len },
         );
@@ -21275,7 +21275,7 @@ fn coerceExtra(
             else => {},
         },
         .ErrorUnion => switch (inst_ty.zigTypeTag()) {
-            .ErrorUnion => {
+            .ErrorUnion => eu: {
                 if (maybe_inst_val) |inst_val| {
                     switch (inst_val.tag()) {
                         .undef => return sema.addConstUndef(dest_ty),
@@ -21284,7 +21284,10 @@ fn coerceExtra(
                                 inst_ty.errorUnionPayload(),
                                 inst_val.castTag(.eu_payload).?.data,
                             );
-                            return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src);
+                            return sema.wrapErrorUnionPayload(block, dest_ty, payload, inst_src) catch |err| switch (err) {
+                                error.NotCoercible => break :eu,
+                                else => |e| return e,
+                            };
                         },
                         else => {
                             const error_set = try sema.addConstant(
@@ -21303,9 +21306,12 @@ fn coerceExtra(
             .Undefined => {
                 return sema.addConstUndef(dest_ty);
             },
-            else => {
+            else => eu: {
                 // T to E!T
-                return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src);
+                return sema.wrapErrorUnionPayload(block, dest_ty, inst, inst_src) catch |err| switch (err) {
+                    error.NotCoercible => break :eu,
+                    else => |e| return e,
+                };
             },
         },
         .Union => switch (inst_ty.zigTypeTag()) {
@@ -24795,7 +24801,7 @@ fn wrapErrorUnionPayload(
     inst_src: LazySrcLoc,
 ) !Air.Inst.Ref {
     const dest_payload_ty = dest_ty.errorUnionPayload();
-    const coerced = try sema.coerce(block, dest_payload_ty, inst, inst_src);
+    const coerced = try sema.coerceExtra(block, dest_payload_ty, inst, inst_src, false, false);
     if (try sema.resolveMaybeUndefVal(block, inst_src, coerced)) |val| {
         return sema.addConstant(dest_ty, try Value.Tag.eu_payload.create(sema.arena, val));
     }
test/cases/compile_errors/stage1/obj/issue_2032_compile_diagnostic_string_for_top_level_decl_type.zig
@@ -1,10 +0,0 @@
-export fn entry() void {
-    var foo: u32 = @This(){};
-    _ = foo;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:2:27: error: type 'u32' does not support array initialization
test/cases/compile_errors/stage1/obj/nested_error_set_mismatch.zig
@@ -1,20 +0,0 @@
-const NextError = error{NextError};
-const OtherError = error{OutOfMemory};
-
-export fn entry() void {
-    const a: ?NextError!i32 = foo();
-    _ = a;
-}
-
-fn foo() ?OtherError!i32 {
-    return null;
-}
-
-// error
-// backend=stage1
-// target=native
-//
-// tmp.zig:5:34: error: expected type '?NextError!i32', found '?OtherError!i32'
-// tmp.zig:5:34: note: optional type child 'OtherError!i32' cannot cast into optional type child 'NextError!i32'
-// tmp.zig:5:34: note: error set 'OtherError' cannot cast into error set 'NextError'
-// tmp.zig:2:26: note: 'error.OutOfMemory' not a member of destination error set
test/cases/compile_errors/issue_2032_compile_diagnostic_string_for_top_level_decl_type.zig
@@ -0,0 +1,11 @@
+export fn entry() void {
+    var foo: u32 = @This(){};
+    _ = foo;
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:27: error: expected type 'u32', found 'tmp.tmp'
+// :1:1: note: struct declared here
test/cases/compile_errors/nested_error_set_mismatch.zig
@@ -0,0 +1,19 @@
+const NextError = error{NextError};
+const OtherError = error{OutOfMemory};
+
+export fn entry() void {
+    const a: ?NextError!i32 = foo();
+    _ = a;
+}
+
+fn foo() ?OtherError!i32 {
+    return null;
+}
+
+// error
+// backend=llvm
+// target=native
+//
+// :4:1: error: expected type '?error{NextError}!i32', found '?error{OutOfMemory}!i32'
+// :4:1: note: optional type child 'error{OutOfMemory}!i32' cannot cast into optional type child 'error{NextError}!i32'
+// :4:1: note: 'error.OutOfMemory' not a member of destination error set
test/cases/compile_errors/return_invalid_type_from_test.zig
@@ -5,4 +5,4 @@ test "example" { return 1; }
 // target=native
 // is_test=1
 //
-// :1:25: error: expected type 'void', found 'comptime_int'
+// :1:25: error: expected type '@typeInfo(@typeInfo(@TypeOf(tmp.test.example)).Fn.return_type.?).ErrorUnion.error_set!void', found 'comptime_int'
\ No newline at end of file
test/cases/compile_errors/stage1/obj/std.fmt_error_for_unused_arguments.zig → test/cases/compile_errors/std.fmt_error_for_unused_arguments.zig
@@ -3,7 +3,7 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=llvm
 // target=native
 //
-// ?:?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
+// :?:?: error: 10 unused arguments in '{d} {d} {d} {d} {d}'
test/cases/compile_errors/stage1/obj/wrong_number_of_arguments.zig → test/cases/compile_errors/wrong_number_of_arguments.zig
@@ -4,7 +4,7 @@ export fn a() void {
 fn c(d: i32, e: i32, f: i32) void { _ = d; _ = e; _ = f; }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:2:6: error: expected 3 argument(s), found 1
+// :2:6: error: expected 3 argument(s), found 1
test/cases/compile_errors/stage1/obj/wrong_types_given_to_atomic_order_args_in_cmpxchg.zig → test/cases/compile_errors/wrong_types_given_to_atomic_order_args_in_cmpxchg.zig
@@ -4,7 +4,8 @@ export fn entry() void {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:3:47: error: expected type 'std.builtin.AtomicOrder', found 'u32'
+// :3:47: error: expected type 'builtin.AtomicOrder', found 'u32'
+// :?:?: note: enum declared here
test/cases/compile_errors/stage1/obj/wrong_types_given_to_export.zig → test/cases/compile_errors/wrong_types_given_to_export.zig
@@ -4,7 +4,8 @@ comptime {
 }
 
 // error
-// backend=stage1
+// backend=stage2
 // target=native
 //
-// tmp.zig:3:59: error: expected type 'std.builtin.GlobalLinkage', found 'comptime_int'
+// :3:50: error: expected type 'builtin.GlobalLinkage', found 'u32'
+// :?:?: note: enum declared here