Commit d6d09f4ea7

xdBronch <51252236+xdBronch@users.noreply.github.com>
2024-09-09 06:49:03
add error for discarding if/while pointer capture
1 parent 6b1f509
Changed files (2)
lib
std
test
cases
lib/std/zig/AstGen.zig
@@ -6333,8 +6333,10 @@ fn ifExpr(
                 const token_name_index = payload_token + @intFromBool(payload_is_ref);
                 const ident_name = try astgen.identAsString(token_name_index);
                 const token_name_str = tree.tokenSlice(token_name_index);
-                if (mem.eql(u8, "_", token_name_str))
+                if (mem.eql(u8, "_", token_name_str)) {
+                    if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
                     break :s &then_scope.base;
+                }
                 try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .capture);
                 payload_val_scope = .{
                     .parent = &then_scope.base,
@@ -6357,8 +6359,10 @@ fn ifExpr(
             else
                 .optional_payload_unsafe;
             const ident_bytes = tree.tokenSlice(ident_token);
-            if (mem.eql(u8, "_", ident_bytes))
+            if (mem.eql(u8, "_", ident_bytes)) {
+                if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
                 break :s &then_scope.base;
+            }
             const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
             const ident_name = try astgen.identAsString(ident_token);
             try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
@@ -6581,8 +6585,10 @@ fn whileExpr(
                 opt_payload_inst = payload_inst.toOptional();
                 const ident_token = payload_token + @intFromBool(payload_is_ref);
                 const ident_bytes = tree.tokenSlice(ident_token);
-                if (mem.eql(u8, "_", ident_bytes))
+                if (mem.eql(u8, "_", ident_bytes)) {
+                    if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
                     break :s &then_scope.base;
+                }
                 const ident_name = try astgen.identAsString(ident_token);
                 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
                 payload_val_scope = .{
@@ -6611,8 +6617,10 @@ fn whileExpr(
             opt_payload_inst = payload_inst.toOptional();
             const ident_name = try astgen.identAsString(ident_token);
             const ident_bytes = tree.tokenSlice(ident_token);
-            if (mem.eql(u8, "_", ident_bytes))
+            if (mem.eql(u8, "_", ident_bytes)) {
+                if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
                 break :s &then_scope.base;
+            }
             try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
             payload_val_scope = .{
                 .parent = &then_scope.base,
test/cases/compile_errors/capture_by_ref_discard.zig
@@ -0,0 +1,26 @@
+export fn a() void {
+    for (.{}) |*_| {}
+}
+
+export fn b() void {
+    switch (0) {
+        else => |*_| {},
+    }
+}
+
+export fn c() void {
+    if (null) |*_| {}
+}
+
+export fn d() void {
+    while (null) |*_| {}
+}
+
+// error
+// backend=stage2
+// target=native
+//
+// :2:16: error: pointer modifier invalid on discard
+// :7:18: error: pointer modifier invalid on discard
+// :12:16: error: pointer modifier invalid on discard
+// :16:19: error: pointer modifier invalid on discard