aboutsummaryrefslogtreecommitdiff
path: root/test/behavior/while.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-12-27 15:26:56 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-12-27 15:30:31 -0700
commit70894d5c2f6032b0d0be1fa00a30554b7e6db2d6 (patch)
treef54e4c5757e41dd1add4aa61ff60a6e6923087d6 /test/behavior/while.zig
parent2c23699594348d5707d6cc9cd591cc8c28fa4605 (diff)
downloadzig-70894d5c2f6032b0d0be1fa00a30554b7e6db2d6.tar.gz
zig-70894d5c2f6032b0d0be1fa00a30554b7e6db2d6.zip
AstGen: fix loop result locations
The main problem was that the loop body was treated as an expression that was one of the peer result values of a loop, when in reality the loop body is noreturn and only the `break` operands are the result values of loops. This was solved by introducing an override that prevents rvalue() from emitting a store to result location instruction for loop bodies. An orthogonal change also included in this commit is switching `elem_val` index expressions to using `coerced_ty` and doing the coercion to `usize` inside `Sema`, resulting in smaller ZIR (since the cast becomes implied). I also changed the break operand expression to use `reachableExpr`, introducing a new compile error for double break. This makes a few more behavior tests pass for `while` and `for` loops.
Diffstat (limited to 'test/behavior/while.zig')
-rw-r--r--test/behavior/while.zig30
1 files changed, 30 insertions, 0 deletions
diff --git a/test/behavior/while.zig b/test/behavior/while.zig
index f2f0bc0bbe..d86e061d17 100644
--- a/test/behavior/while.zig
+++ b/test/behavior/while.zig
@@ -236,3 +236,33 @@ test "while on error union with else result follow break prong" {
} else |_| @as(i32, 2);
try expect(result == 10);
}
+
+test "while bool 2 break statements and an else" {
+ const S = struct {
+ fn entry(t: bool, f: bool) !void {
+ var ok = false;
+ ok = while (t) {
+ if (f) break false;
+ if (t) break true;
+ } else false;
+ try expect(ok);
+ }
+ };
+ try S.entry(true, false);
+ comptime try S.entry(true, false);
+}
+
+test "while optional 2 break statements and an else" {
+ const S = struct {
+ fn entry(opt_t: ?bool, f: bool) !void {
+ var ok = false;
+ ok = while (opt_t) |t| {
+ if (f) break false;
+ if (t) break true;
+ } else false;
+ try expect(ok);
+ }
+ };
+ try S.entry(true, false);
+ comptime try S.entry(true, false);
+}