diff --git a/src/Sema.zig b/src/Sema.zig index 5ee2d914d032cd120cbc65bc9369afbc139cda23..cd5cc98f0670c86b0cd38fe6d291b2eafc888cc9 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -9843,7 +9843,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp const maybe_switch_ref: ?Air.Inst.Ref = ref: { // make err capture (i.e. switch operand) available to switch prong bodies - sema.inst_map.putAssumeCapacityNoClobber(inst, raw_switch_operand); + sema.inst_map.putAssumeCapacity(inst, raw_switch_operand); defer assert(sema.inst_map.remove(inst)); break :ref try sema.analyzeSwitchBlock(block, &switch_block, raw_switch_operand, false, merges, inst, &zir_switch, &validated_switch); }; diff --git a/test/behavior/switch.zig b/test/behavior/switch.zig index 9683639c50edca4a3a05c98e13b39ed02bd617f7..d9e581521b9a66851a0d4966c2df3e1f8975a6a2 100644 --- a/test/behavior/switch.zig +++ b/test/behavior/switch.zig @@ -1542,3 +1542,40 @@ test "error captures narrow error sets" { try comptime S.doTheTest(error.B); try comptime S.doTheTest(error.C); } + +test "repeated switch analysis overrides previous analysis results" { + // This tests an implementation detail where semantic analysis of switch + // statements uses the switch inst itself to store capture values and result + // type information while analyzing (parts of) that switch inst. + // If that inst has already been assigned a result by a previous analysis + // that result needs to be overwritten. + + comptime { + const x: u32 = 123; + for (0..2) |_| _ = switch (x) { + 123 => |capture| capture, + else => unreachable, + }; + } + comptime { + const x: union(enum) { a, b, c } = .a; + for (0..2) |_| _ = switch (x) { + .a => |_, tag| tag, + else => unreachable, + }; + } + comptime { + const x: enum { a, b, c } = .a; + for (0..2) |_| _ = label: switch (x) { + .a => continue :label .b, + else => 123, + }; + } + comptime { + const x: anyerror!void = error.MyError; + for (0..2) |_| _ = x catch |err| switch (err) { + error.MyError => {}, + else => unreachable, + }; + } +}