Commit 25012ab3d1

Robin Voetter <robin@voetter.nl>
2021-10-26 17:33:35
astgen: generate correct switch prong indices
Switch prong values are fetched by index in semantic analysis by prong offset, but these were computed as capture offset. This means that a switch where the first prong does not capture and the second does, the switch_capture zir instruction would be assigned switch_prong 0 instead of 1.
1 parent 17e46a3
Changed files (2)
src
test
behavior
src/AstGen.zig
@@ -6070,6 +6070,13 @@ fn switchExpr(
 
         var capture_val_scope: Scope.LocalVal = undefined;
         const sub_scope = blk: {
+            const capture_index = if (is_multi_case) ci: {
+                multi_case_index += 1;
+                break :ci multi_case_index - 1;
+            } else ci: {
+                scalar_case_index += 1;
+                break :ci scalar_case_index - 1;
+            };
             const payload_token = case.payload_token orelse break :blk &case_scope.base;
             const ident = if (token_tags[payload_token] == .asterisk)
                 payload_token + 1
@@ -6103,13 +6110,6 @@ fn switchExpr(
                     0b10 => .switch_capture_multi,
                     0b11 => .switch_capture_multi_ref,
                 };
-                const capture_index = if (is_multi_case) ci: {
-                    multi_case_index += 1;
-                    break :ci multi_case_index - 1;
-                } else ci: {
-                    scalar_case_index += 1;
-                    break :ci scalar_case_index - 1;
-                };
                 break :capture try case_scope.add(.{
                     .tag = capture_tag,
                     .data = .{ .switch_capture = .{
test/behavior/switch.zig
@@ -299,3 +299,17 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {
         204...255 => 3,
     };
 }
+
+test "switch on union with some prongs capturing" {
+    const X = union(enum) {
+        a,
+        b: i32,
+    };
+
+    var x: X = X{ .b = 10 };
+    var y: i32 = switch (x) {
+        .a => unreachable,
+        .b => |b| b + 1,
+    };
+    try expect(y == 11);
+}