Commit bf4a3df9a9

Veikka Tuominen <git@vexu.eu>
2022-09-09 15:56:59
Sema: allow runtime break from inline loop
Closes #12787
1 parent 002260c
Changed files (2)
src
test
behavior
src/Sema.zig
@@ -1353,6 +1353,8 @@ fn analyzeBodyInner(
                 const else_body = sema.code.extra[extra.end + then_body.len ..][0..extra.data.else_body_len];
                 const cond = try sema.resolveInstConst(block, cond_src, extra.data.condition, "condition in comptime branch must be comptime known");
                 const inline_body = if (cond.val.toBool()) then_body else else_body;
+                const old_runtime_index = block.runtime_index;
+                defer block.runtime_index = old_runtime_index;
                 const break_data = (try sema.analyzeBodyBreak(block, inline_body)) orelse
                     break always_noreturn;
                 if (inst == break_data.block_inst) {
test/behavior/eval.zig
@@ -1337,3 +1337,37 @@ test "lazy value is resolved as slice operand" {
     try expect(@ptrToInt(ptr1) == @ptrToInt(ptr2));
     try expect(ptr1.len == ptr2.len);
 }
+
+test "break from inline loop depends on runtime condition" {
+    const S = struct {
+        fn foo(a: u8) bool {
+            return a == 4;
+        }
+    };
+    const arr = [_]u8{ 1, 2, 3, 4 };
+    {
+        const blk = blk: {
+            inline for (arr) |val| {
+                if (S.foo(val)) {
+                    break :blk val;
+                }
+            }
+            return error.TestFailed;
+        };
+        try expect(blk == 4);
+    }
+
+    {
+        comptime var i = 0;
+        const blk = blk: {
+            inline while (i < arr.len) : (i += 1) {
+                const val = arr[i];
+                if (S.foo(val)) {
+                    break :blk val;
+                }
+            }
+            return error.TestFailed;
+        };
+        try expect(blk == 4);
+    }
+}