authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-08 19:48:21+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-11-11 17:59:53+02:00
log0a188190b3b2b42906d0cc38f101b010bc07b414
tree60f1914391ff3467f5eb97d389a18dbe73e1684f
parentd2cc55109a64aaf004384b942e08e95829b9341f

AstGen: make pointless discard error more strict

The error should only happen as a result of `_ = <expr>` not for an operand of a break expression that is discarded. Closes #13212

2 files changed, 20 insertions(+), 5 deletions(-)

src/AstGen.zig+12-5
...@@ -339,6 +339,8 @@ pub const ResultInfo = struct {...@@ -339,6 +339,8 @@ pub const ResultInfo = struct {
339 fn_arg,339 fn_arg,
340 /// The expression is the right-hand side of an initializer for a `const` variable340 /// The expression is the right-hand side of an initializer for a `const` variable
341 const_init,341 const_init,
342 /// The expression is the right-hand side of an assignment expression.
343 assignment,
342 /// No specific operator in particular.344 /// No specific operator in particular.
343 none,345 none,
344 };346 };
...@@ -3216,7 +3218,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi...@@ -3216,7 +3218,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi
3216 // This intentionally does not support `@"_"` syntax.3218 // This intentionally does not support `@"_"` syntax.
3217 const ident_name = tree.tokenSlice(main_tokens[lhs]);3219 const ident_name = tree.tokenSlice(main_tokens[lhs]);
3218 if (mem.eql(u8, ident_name, "_")) {3220 if (mem.eql(u8, ident_name, "_")) {
3219 _ = try expr(gz, scope, .{ .rl = .discard }, rhs);3221 _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs);
3220 return;3222 return;
3221 }3223 }
3222 }3224 }
...@@ -7088,7 +7090,7 @@ fn localVarRef(...@@ -7088,7 +7090,7 @@ fn localVarRef(
7088 if (local_val.name == name_str_index) {7090 if (local_val.name == name_str_index) {
7089 // Locals cannot shadow anything, so we do not need to look for ambiguous7091 // Locals cannot shadow anything, so we do not need to look for ambiguous
7090 // references in this case.7092 // references in this case.
7091 if (ri.rl == .discard) {7093 if (ri.rl == .discard and ri.ctx == .assignment) {
7092 local_val.discarded = ident_token;7094 local_val.discarded = ident_token;
7093 } else {7095 } else {
7094 local_val.used = ident_token;7096 local_val.used = ident_token;
...@@ -7111,7 +7113,7 @@ fn localVarRef(...@@ -7111,7 +7113,7 @@ fn localVarRef(
7111 .local_ptr => {7113 .local_ptr => {
7112 const local_ptr = s.cast(Scope.LocalPtr).?;7114 const local_ptr = s.cast(Scope.LocalPtr).?;
7113 if (local_ptr.name == name_str_index) {7115 if (local_ptr.name == name_str_index) {
7114 if (ri.rl == .discard) {7116 if (ri.rl == .discard and ri.ctx == .assignment) {
7115 local_ptr.discarded = ident_token;7117 local_ptr.discarded = ident_token;
7116 } else {7118 } else {
7117 local_ptr.used = ident_token;7119 local_ptr.used = ident_token;
...@@ -10672,14 +10674,19 @@ const GenZir = struct {...@@ -10672,14 +10674,19 @@ const GenZir = struct {
10672 gz.break_result_info = parent_ri;10674 gz.break_result_info = parent_ri;
10673 },10675 },
1067410676
10675 .discard, .none, .ref => {10677 .none, .ref => {
10676 gz.rl_ty_inst = .none;10678 gz.rl_ty_inst = .none;
10677 gz.break_result_info = parent_ri;10679 gz.break_result_info = parent_ri;
10678 },10680 },
1067910681
10682 .discard => {
10683 gz.rl_ty_inst = .none;
10684 gz.break_result_info = .{ .rl = .discard };
10685 },
10686
10680 .ptr => |ptr_res| {10687 .ptr => |ptr_res| {
10681 gz.rl_ty_inst = .none;10688 gz.rl_ty_inst = .none;
10682 gz.break_result_info = .{ .rl = .{ .ptr = .{ .inst = ptr_res.inst } } };10689 gz.break_result_info = .{ .rl = .{ .ptr = .{ .inst = ptr_res.inst } }, .ctx = parent_ri.ctx };
10683 },10690 },
1068410691
10685 .inferred_ptr => |ptr| {10692 .inferred_ptr => |ptr| {
test/cases/compile_errors/pointless discard.zig +8
...@@ -3,6 +3,14 @@ export fn foo() void {...@@ -3,6 +3,14 @@ export fn foo() void {
3 x += 1;3 x += 1;
4 _ = x;4 _ = x;
5}5}
6export fn bar() void {
7 var b: u32 = 1;
8 _ = blk: {
9 const a = 1;
10 b = a;
11 break :blk a;
12 };
13}
614
7// error15// error
8// backend=stage216// backend=stage2