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 {
339339 fn_arg,
340340 /// The expression is the right-hand side of an initializer for a `const` variable
341341 const_init,
342 /// The expression is the right-hand side of an assignment expression.
343 assignment,
342344 /// No specific operator in particular.
343345 none,
344346 };
......@@ -3216,7 +3218,7 @@ fn assign(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerError!voi
32163218 // This intentionally does not support `@"_"` syntax.
32173219 const ident_name = tree.tokenSlice(main_tokens[lhs]);
32183220 if (mem.eql(u8, ident_name, "_")) {
3219 _ = try expr(gz, scope, .{ .rl = .discard }, rhs);
3221 _ = try expr(gz, scope, .{ .rl = .discard, .ctx = .assignment }, rhs);
32203222 return;
32213223 }
32223224 }
......@@ -7088,7 +7090,7 @@ fn localVarRef(
70887090 if (local_val.name == name_str_index) {
70897091 // Locals cannot shadow anything, so we do not need to look for ambiguous
70907092 // references in this case.
7091 if (ri.rl == .discard) {
7093 if (ri.rl == .discard and ri.ctx == .assignment) {
70927094 local_val.discarded = ident_token;
70937095 } else {
70947096 local_val.used = ident_token;
......@@ -7111,7 +7113,7 @@ fn localVarRef(
71117113 .local_ptr => {
71127114 const local_ptr = s.cast(Scope.LocalPtr).?;
71137115 if (local_ptr.name == name_str_index) {
7114 if (ri.rl == .discard) {
7116 if (ri.rl == .discard and ri.ctx == .assignment) {
71157117 local_ptr.discarded = ident_token;
71167118 } else {
71177119 local_ptr.used = ident_token;
......@@ -10672,14 +10674,19 @@ const GenZir = struct {
1067210674 gz.break_result_info = parent_ri;
1067310675 },
1067410676
10675 .discard, .none, .ref => {
10677 .none, .ref => {
1067610678 gz.rl_ty_inst = .none;
1067710679 gz.break_result_info = parent_ri;
1067810680 },
1067910681
10682 .discard => {
10683 gz.rl_ty_inst = .none;
10684 gz.break_result_info = .{ .rl = .discard };
10685 },
10686
1068010687 .ptr => |ptr_res| {
1068110688 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 };
1068310690 },
1068410691
1068510692 .inferred_ptr => |ptr| {
test/cases/compile_errors/pointless discard.zig +8
......@@ -3,6 +3,14 @@ export fn foo() void {
33 x += 1;
44 _ = x;
55}
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
715// error
816// backend=stage2