zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cffa22a658d23bdedbdd7e23853b80d856e43627 (tree)
parent 527c55aa5671381a7e6652fba237279453e0bb6e
Author: Andrew Kelley <andrew@ziglang.org>
Date:   Fri, 25 Jun 2021 19:43:01 -0700

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.

Diffstat:
Msrc/AstGen.zig | 31++++++++++++++++++++++++++++++-
Mtest/compile_errors.zig | 3++-
2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/AstGen.zig b/src/AstGen.zig @@ -2332,6 +2332,8 @@ fn varDecl( .ty = try typeExpr(gz, scope, var_decl.ast.type_node), } else .none; const init_inst = try expr(gz, scope, result_loc, var_decl.ast.init_node); + try astgen.checkVarInitExpr(gz.*, node, var_decl.ast.init_node, init_inst, "local constant"); + const sub_scope = try block_arena.create(Scope.LocalVal); sub_scope.* = .{ .parent = scope, @@ -2382,6 +2384,8 @@ fn varDecl( } const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope }; const init_inst = try expr(&init_scope, &init_scope.base, init_result_loc, var_decl.ast.init_node); + try astgen.checkVarInitExpr(init_scope, node, var_decl.ast.init_node, init_inst, "local constant"); + const zir_tags = astgen.instructions.items(.tag); const zir_datas = astgen.instructions.items(.data); @@ -2482,7 +2486,8 @@ fn varDecl( resolve_inferred_alloc = alloc; break :a .{ .alloc = alloc, .result_loc = .{ .inferred_ptr = alloc } }; }; - _ = try expr(gz, scope, var_data.result_loc, var_decl.ast.init_node); + const init_inst = try expr(gz, scope, var_data.result_loc, var_decl.ast.init_node); + try astgen.checkVarInitExpr(gz.*, node, var_decl.ast.init_node, init_inst, "local variable"); if (resolve_inferred_alloc != .none) { _ = try gz.addUnNode(.resolve_inferred_alloc, resolve_inferred_alloc, node); } @@ -9602,3 +9607,27 @@ fn advanceSourceCursor(astgen: *AstGen, source: []const u8, end: usize) void { astgen.source_line = line; astgen.source_column = column; } + +fn checkVarInitExpr( + astgen: *AstGen, + gz: GenZir, + var_node: ast.Node.Index, + init_node: ast.Node.Index, + init_inst: Zir.Inst.Ref, + var_name_text: []const u8, +) !void { + if (gz.refIsNoReturn(init_inst)) { + return astgen.failNodeNotes( + var_node, + "useless {s}", + .{var_name_text}, + &[_]u32{ + try astgen.errNoteNode( + init_node, + "control flow is diverted here", + .{}, + ), + }, + ); + } +} diff --git a/test/compile_errors.zig b/test/compile_errors.zig @@ -4831,7 +4831,8 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ const a = return; \\} , &[_][]const u8{ - "tmp.zig:2:5: error: unreachable code", + "tmp.zig:2:5: error: useless local constant", + "tmp.zig:2:15: note: control flow is diverted here", }); cases.add("unreachable variable",