aboutsummaryrefslogtreecommitdiff
path: root/src/AstGen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-06-25 19:43:01 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-07-02 13:26:50 -0700
commitcffa22a658d23bdedbdd7e23853b80d856e43627 (patch)
treef528655756630f403bba344d76a9ae634424d7d6 /src/AstGen.zig
parent527c55aa5671381a7e6652fba237279453e0bb6e (diff)
downloadzig-cffa22a658d23bdedbdd7e23853b80d856e43627.tar.gz
zig-cffa22a658d23bdedbdd7e23853b80d856e43627.zip
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 (limited to 'src/AstGen.zig')
-rw-r--r--src/AstGen.zig31
1 files changed, 30 insertions, 1 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 6c5f2b5dae..c74106ef44 100644
--- 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",
+ .{},
+ ),
+ },
+ );
+ }
+}