authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2026-10-21 16:33:39+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-23 02:16:33+02:00
log5382c84ed22519a600642f5cf3b1d8c2769050d6
tree2d11defb265047506e0c8a941d81a982809941fa
parent1bb9a9dafa1f7961e6bf7cf66bcf1a425eedc07e
signature Signed by SSH key SHA256:7B/LJ7bpR1eX8aCXSr4mtd5M45VMPKcx9zY8e95b5QM

AstGen: error on tag capture in `else` prong of `switch`

Resolves: https://codeberg.org/ziglang/zig/issues/37325

4 files changed, 23 insertions(+), 4 deletions(-)

lib/std/zig/AstGen.zig+6
......@@ -7731,6 +7731,12 @@ fn switchExpr(
77317731 const tag_name = try astgen.identAsString(tag_token);
77327732 try astgen.detectLocalShadowing(payload_sub_scope, tag_name, tag_token, tag_slice, .@"switch tag capture");
77337733
7734 if (case_node.toOptional() == else_case_node and case.inline_token == null) {
7735 return astgen.failTokNotes(tag_token, "cannot capture tag of 'else' prong", .{}, &.{
7736 try astgen.errNoteTok(ident, "first capture in 'else' prong always captures 'switch' operand", .{}),
7737 });
7738 }
7739
77347740 assert(any_has_tag_capture);
77357741 has_tag_capture = true;
77367742
test/behavior/switch.zig+1-2
......@@ -1186,8 +1186,7 @@ test "switch with tag capture" {
11861186 _ = &tag;
11871187 comptime unreachable;
11881188 },
1189 else => |un, tag| {
1190 try expect(tag == .c);
1189 else => |un| {
11911190 try expect(un == .c);
11921191 try expect(un.c == 0xFF);
11931192 },
test/behavior/switch_loop.zig+1-2
......@@ -416,8 +416,7 @@ test "switch loop with tag capture" {
416416 _ = &tag;
417417 return error.AnalyzedNoreturnProng;
418418 },
419 else => |un, tag| {
420 try expect(tag == .c);
419 else => |un| {
421420 try expect(un == .c);
422421 if (un.c == 0xFF) continue :label .a;
423422 if (un.c == 0x00) break :label false;
test/cases/compile_errors/tag_capture_in_else_prong.zig created+15
......@@ -0,0 +1,15 @@
1const Foo = union(enum) { a: u32, b: u32 };
2export fn entry() void {
3 const foo: Foo = .{ .a = 123 };
4 switch (foo) {
5 else => |payload, tag| {
6 _ = payload;
7 _ = tag;
8 },
9 }
10}
11
12// error
13//
14// :5:27: error: cannot capture tag of 'else' prong
15// :5:18: note: first capture in 'else' prong always captures 'switch' operand