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(...@@ -6333,8 +6333,10 @@ fn ifExpr(
6333 const token_name_index = payload_token + @intFromBool(payload_is_ref);6333 const token_name_index = payload_token + @intFromBool(payload_is_ref);
6334 const ident_name = try astgen.identAsString(token_name_index);6334 const ident_name = try astgen.identAsString(token_name_index);
6335 const token_name_str = tree.tokenSlice(token_name_index);6335 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", .{});
6337 break :s &then_scope.base;6338 break :s &then_scope.base;
6339 }
6338 try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .capture);6340 try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str, .capture);
6339 payload_val_scope = .{6341 payload_val_scope = .{
6340 .parent = &then_scope.base,6342 .parent = &then_scope.base,
...@@ -6357,8 +6359,10 @@ fn ifExpr(...@@ -6357,8 +6359,10 @@ fn ifExpr(
6357 else6359 else
6358 .optional_payload_unsafe;6360 .optional_payload_unsafe;
6359 const ident_bytes = tree.tokenSlice(ident_token);6361 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", .{});
6361 break :s &then_scope.base;6364 break :s &then_scope.base;
6365 }
6362 const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);6366 const payload_inst = try then_scope.addUnNode(tag, cond.inst, then_node);
6363 const ident_name = try astgen.identAsString(ident_token);6367 const ident_name = try astgen.identAsString(ident_token);
6364 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);6368 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
...@@ -6581,8 +6585,10 @@ fn whileExpr(...@@ -6581,8 +6585,10 @@ fn whileExpr(
6581 opt_payload_inst = payload_inst.toOptional();6585 opt_payload_inst = payload_inst.toOptional();
6582 const ident_token = payload_token + @intFromBool(payload_is_ref);6586 const ident_token = payload_token + @intFromBool(payload_is_ref);
6583 const ident_bytes = tree.tokenSlice(ident_token);6587 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", .{});
6585 break :s &then_scope.base;6590 break :s &then_scope.base;
6591 }
6586 const ident_name = try astgen.identAsString(ident_token);6592 const ident_name = try astgen.identAsString(ident_token);
6587 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);6593 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
6588 payload_val_scope = .{6594 payload_val_scope = .{
...@@ -6611,8 +6617,10 @@ fn whileExpr(...@@ -6611,8 +6617,10 @@ fn whileExpr(
6611 opt_payload_inst = payload_inst.toOptional();6617 opt_payload_inst = payload_inst.toOptional();
6612 const ident_name = try astgen.identAsString(ident_token);6618 const ident_name = try astgen.identAsString(ident_token);
6613 const ident_bytes = tree.tokenSlice(ident_token);6619 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", .{});
6615 break :s &then_scope.base;6622 break :s &then_scope.base;
6623 }
6616 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);6624 try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes, .capture);
6617 payload_val_scope = .{6625 payload_val_scope = .{
6618 .parent = &then_scope.base,6626 .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