Commit e41bc640c6

John Schmidt <john.schmidt.h@gmail.com>
2023-02-28 11:27:56
astgen: do not discard result location in for/while loops
If we use the discard result location any break with a value will be ignored and not checked for usage. Closes https://github.com/ziglang/zig/issues/14684.
1 parent 98508a1
src/AstGen.zig
@@ -2342,10 +2342,10 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
 
             .while_simple,
             .while_cont,
-            .@"while", => _ = try whileExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.fullWhile(inner_node).?, true),
+            .@"while", => _ = try whileExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullWhile(inner_node).?, true),
 
             .for_simple,
-            .@"for", => _ = try forExpr(gz, scope, .{ .rl = .discard }, inner_node, tree.fullFor(inner_node).?, true),
+            .@"for", => _ = try forExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullFor(inner_node).?, true),
 
             else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node),
             // zig fmt: on
test/cases/compile_errors/for_loop_break_value_ignored.zig
@@ -0,0 +1,15 @@
+fn returns() usize {
+    return 2;
+}
+
+export fn f1() void {
+    for ("hello") |_| {
+        break returns();
+    }
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :6:5: error: incompatible types: 'usize' and 'void'
test/cases/compile_errors/while_loop_break_value_ignored.zig
@@ -0,0 +1,26 @@
+fn returns() usize {
+    return 2;
+}
+
+export fn f1() void {
+    var a: bool = true;
+    while (a) {
+        break returns();
+    }
+}
+
+export fn f2() void {
+    var x: bool = true;
+    outer: while (x) {
+        while (x) {
+            break :outer returns();
+        }
+    }
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :7:5: error: incompatible types: 'usize' and 'void'
+// :14:12: error: incompatible types: 'usize' and 'void'