authorgravatar for 51252236+xdBronch@users.noreply.github.comxdBronch <51252236+xdBronch@users.noreply.github.com> 2024-09-09 00:49:03-04:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-09-10 01:45:48+03:00
logd6d09f4ea7cc590035bf8af6617f93767423c691
tree165cad4410f9f3e9c85431d9d4c20c38177ea4fa
parent6b1f50942212def19b094016a00dbba5387c2d58

add error for discarding if/while pointer capture


2 files changed, 38 insertions(+), 4 deletions(-)

lib/std/zig/AstGen.zig+12-4
......@@ -6333,8 +6333,10 @@ fn ifExpr(
63336333 const token_name_index = payload_token + @intFromBool(payload_is_ref);
63346334 const ident_name = try astgen.identAsString(token_name_index);
63356335 const token_name_str = tree.tokenSlice(token_name_index);
6336 if (mem.eql(u8, "_", token_name_str))
6336 if (mem.eql(u8, "_", token_name_str)) {
6337 if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
63376338 break :s &then_scope.base;
6339 }
63386340 try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .capture);
63396341 payload_val_scope = .{
63406342 .parent = &then_scope.base,
......@@ -6357,8 +6359,10 @@ fn ifExpr(
63576359 else
63586360 .optional_payload_unsafe;
63596361 const ident_bytes = tree.tokenSlice(ident_token);
6360 if (mem.eql(u8, "_", ident_bytes))
6362 if (mem.eql(u8, "_", ident_bytes)) {
6363 if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
63616364 break :s &then_scope.base;
6365 }
63626366 const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
63636367 const ident_name = try astgen.identAsString(ident_token);
63646368 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
......@@ -6581,8 +6585,10 @@ fn whileExpr(
65816585 opt_payload_inst = payload_inst.toOptional();
65826586 const ident_token = payload_token + @intFromBool(payload_is_ref);
65836587 const ident_bytes = tree.tokenSlice(ident_token);
6584 if (mem.eql(u8, "_", ident_bytes))
6588 if (mem.eql(u8, "_", ident_bytes)) {
6589 if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
65856590 break :s &then_scope.base;
6591 }
65866592 const ident_name = try astgen.identAsString(ident_token);
65876593 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
65886594 payload_val_scope = .{
......@@ -6611,8 +6617,10 @@ fn whileExpr(
66116617 opt_payload_inst = payload_inst.toOptional();
66126618 const ident_name = try astgen.identAsString(ident_token);
66136619 const ident_bytes = tree.tokenSlice(ident_token);
6614 if (mem.eql(u8, "_", ident_bytes))
6620 if (mem.eql(u8, "_", ident_bytes)) {
6621 if (payload_is_ref) return astgen.failTok(payload_token, "pointer modifier invalid on discard", .{});
66156622 break :s &then_scope.base;
6623 }
66166624 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
66176625 payload_val_scope = .{
66186626 .parent = &then_scope.base,
test/cases/compile_errors/capture_by_ref_discard.zig created+26
......@@ -0,0 +1,26 @@
1export fn a() void {
2 for (.{}) |*_| {}
3}
4
5export fn b() void {
6 switch (0) {
7 else => |*_| {},
8 }
9}
10
11export fn c() void {
12 if (null) |*_| {}
13}
14
15export fn d() void {
16 while (null) |*_| {}
17}
18
19// error
20// backend=stage2
21// target=native
22//
23// :2:16: error: pointer modifier invalid on discard
24// :7:18: error: pointer modifier invalid on discard
25// :12:16: error: pointer modifier invalid on discard
26// :16:19: error: pointer modifier invalid on discard