Commit 3f7b3daaa0

Techatrix <techatrix@mailbox.org>
2024-12-11 19:07:09
AstGen: fix analysis when encountering discard of error capture
1 parent 4a3800d
lib/std/zig/AstGen.zig
@@ -3172,7 +3172,8 @@ fn deferStmt(
     const sub_scope = if (!have_err_code) &defer_gen.base else blk: {
         const ident_name = try gz.astgen.identAsString(payload_token);
         if (std.mem.eql(u8, tree.tokenSlice(payload_token), "_")) {
-            return gz.astgen.failTok(payload_token, "discard of error capture; omit it instead", .{});
+            try gz.astgen.appendErrorTok(payload_token, "discard of error capture; omit it instead", .{});
+            break :blk &defer_gen.base;
         }
         const remapped_err_code: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len);
         opt_remapped_err_code = remapped_err_code.toOptional();
@@ -6219,6 +6220,7 @@ fn orelseCatchExpr(
         const err_str = tree.tokenSlice(payload);
         if (mem.eql(u8, err_str, "_")) {
             try astgen.appendErrorTok(payload, "discard of error capture; omit it instead", .{});
+            break :blk &else_scope.base;
         }
         const err_name = try astgen.identAsString(payload);
 
test/cases/compile_errors/invalid_error_capture_discard.zig
@@ -0,0 +1,30 @@
+export fn a() void {
+    errdefer |_| {
+        @"_";
+    }
+}
+export fn b() void {
+    const x: error{}!void = {};
+    x catch |_| {
+        @"_";
+    };
+}
+export fn c() void {
+    const x: error{}!void = {};
+    x catch |_| switch (_) {};
+}
+export fn d() void {
+    const x: error{}!u32 = 0;
+    if (x) |v| v else |_| switch (_) {}
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:15: error: discard of error capture; omit it instead
+// :3:9: error: use of undeclared identifier '_'
+// :8:14: error: discard of error capture; omit it instead
+// :9:9: error: use of undeclared identifier '_'
+// :14:14: error: discard of error capture; omit it instead
+// :18:24: error: discard of error capture; omit it instead
test/cases/compile_errors/switch_on_error_union_discard.zig
@@ -1,10 +0,0 @@
-export fn entry() void {
-    const x: error{}!u32 = 0;
-    if (x) |v| v else |_| switch (_) {}
-}
-
-// error
-// backend=stage2
-// target=native
-//
-// :3:24: error: discard of error capture; omit it instead
test/cases/errdefer_discard.zig
@@ -1,7 +0,0 @@
-pub fn main() !void {
-    errdefer |_| _ = @"_";
-}
-
-// error
-//
-// :2:15: error: discard of error capture; omit it instead