authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-25 19:43:01-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-02 13:26:50-07:00
logcffa22a658d23bdedbdd7e23853b80d856e43627
treef528655756630f403bba344d76a9ae634424d7d6
parent527c55aa5671381a7e6652fba237279453e0bb6e

AstGen: implement compile error for useless locals

When a local variable has an initialization expression of type 'noreturn', emit a compile error. This brings this branch closer to parity with master branch.

2 files changed, 32 insertions(+), 2 deletions(-)

src/AstGen.zig+30-1
...@@ -2332,6 +2332,8 @@ fn varDecl(...@@ -2332,6 +2332,8 @@ fn varDecl(
2332 .ty = try typeExpr(gz, scope, var_decl.ast.type_node),2332 .ty = try typeExpr(gz, scope, var_decl.ast.type_node),
2333 } else .none;2333 } else .none;
2334 const init_inst = try expr(gz, scope, result_loc, var_decl.ast.init_node);2334 const init_inst = try expr(gz, scope, result_loc, var_decl.ast.init_node);
2335 try astgen.checkVarInitExpr(gz.*, node, var_decl.ast.init_node, init_inst, "local constant");
2336
2335 const sub_scope = try block_arena.create(Scope.LocalVal);2337 const sub_scope = try block_arena.create(Scope.LocalVal);
2336 sub_scope.* = .{2338 sub_scope.* = .{
2337 .parent = scope,2339 .parent = scope,
...@@ -2382,6 +2384,8 @@ fn varDecl(...@@ -2382,6 +2384,8 @@ fn varDecl(
2382 }2384 }
2383 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };2385 const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };
2384 const init_inst = try expr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node);2386 const init_inst = try expr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node);
2387 try astgen.checkVarInitExpr(init_scope, node, var_decl.ast.init_node, init_inst, "local constant");
2388
2385 const zir_tags = astgen.instructions.items(.tag);2389 const zir_tags = astgen.instructions.items(.tag);
2386 const zir_datas = astgen.instructions.items(.data);2390 const zir_datas = astgen.instructions.items(.data);
23872391
...@@ -2482,7 +2486,8 @@ fn varDecl(...@@ -2482,7 +2486,8 @@ fn varDecl(
2482 resolve_inferred_alloc = alloc;2486 resolve_inferred_alloc = alloc;
2483 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };2487 break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } };
2484 };2488 };
2485 _ = try expr(gz, scope, var_data.result_loc, var_decl.ast.init_node);2489 const init_inst = try expr(gz, scope, var_data.result_loc, var_decl.ast.init_node);
2490 try astgen.checkVarInitExpr(gz.*, node, var_decl.ast.init_node, init_inst, "local variable");
2486 if (resolve_inferred_alloc != .none) {2491 if (resolve_inferred_alloc != .none) {
2487 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);2492 _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node);
2488 }2493 }
...@@ -9602,3 +9607,27 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {...@@ -9602,3 +9607,27 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void {
9602 astgen.source_line = line;9607 astgen.source_line = line;
9603 astgen.source_column = column;9608 astgen.source_column = column;
9604}9609}
9610
9611fn checkVarInitExpr(
9612 astgen: *AstGen,
9613 gz: GenZir,
9614 var_node: ast.Node.Index,
9615 init_node: ast.Node.Index,
9616 init_inst: Zir.Inst.Ref,
9617 var_name_text: []const u8,
9618) !void {
9619 if (gz.refIsNoReturn(init_inst)) {
9620 return astgen.failNodeNotes(
9621 var_node,
9622 "useless {s}",
9623 .{var_name_text},
9624 &[_]u32{
9625 try astgen.errNoteNode(
9626 init_node,
9627 "control flow is diverted here",
9628 .{},
9629 ),
9630 },
9631 );
9632 }
9633}
test/compile_errors.zig+2-1
...@@ -4831,7 +4831,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4831,7 +4831,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4831 \\ const a = return;4831 \\ const a = return;
4832 \\}4832 \\}
4833 , &[_][]const u8{4833 , &[_][]const u8{
4834 "tmp.zig:2:5: error: unreachable code",4834 "tmp.zig:2:5: error: useless local constant",
4835 "tmp.zig:2:15: note: control flow is diverted here",
4835 });4836 });
48364837
4837 cases.add("unreachable variable",4838 cases.add("unreachable variable",