authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-20 08:04:46-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-20 08:04:46-05:00
log079728752eca4cffbb4f7e8dc06d5e23b81d7627
tree552dcf5837bf1b3f4cab297bed4a9e0e0bea4c0f
parent067968c57f2c7ed4f0606913aa608f6c2be418d2
signaturelock-open Commit is signed but in an unrecognized format.

deduplicate compile errors for undeclared identifiers

closes #111

3 files changed, 38 insertions(+), 8 deletions(-)

src/ir.cpp+18-1
...@@ -3674,6 +3674,22 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode...@@ -3674,6 +3674,22 @@ static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode
3674 return ir_build_const_null(irb, scope, node);3674 return ir_build_const_null(irb, scope, node);
3675}3675}
36763676
3677static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode *node, Buf *var_name) {
3678 ScopeDecls *scope_decls = nullptr;
3679 while (scope != nullptr) {
3680 if (scope->id == ScopeIdDecls) {
3681 scope_decls = reinterpret_cast<ScopeDecls *>(scope);
3682 }
3683 scope = scope->parent;
3684 }
3685 TldVar *tld_var = allocate<TldVar>(1);
3686 init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base);
3687 tld_var->base.resolution = TldResolutionInvalid;
3688 tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false,
3689 &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid);
3690 scope_decls->decl_table.put(var_name, &tld_var->base);
3691}
3692
3677static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {3693static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) {
3678 Error err;3694 Error err;
3679 assert(node->type == NodeTypeSymbol);3695 assert(node->type == NodeTypeSymbol);
...@@ -3727,8 +3743,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3727,8 +3743,9 @@ static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node,
3727 return irb->codegen->invalid_instruction;3743 return irb->codegen->invalid_instruction;
3728 }3744 }
37293745
3730 // TODO put a variable of same name with invalid type in global scope3746 // put a variable of same name with invalid type in global scope
3731 // so that future references to this same name will find a variable with an invalid type3747 // so that future references to this same name will find a variable with an invalid type
3748 populate_invalid_variable_in_scope(irb->codegen, scope, node, variable_name);
3732 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));3749 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
3733 return irb->codegen->invalid_instruction;3750 return irb->codegen->invalid_instruction;
3734}3751}
test/compile_errors.zig+18-6
...@@ -1,6 +1,22 @@...@@ -1,6 +1,22 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: *tests.CompileErrorContext) void {3pub fn addCases(cases: *tests.CompileErrorContext) void {
4 cases.addCase(x: {
5 var tc = cases.create(
6 "deduplicate undeclared identifier",
7 \\export fn a() void {
8 \\ x += 1;
9 \\}
10 \\export fn b() void {
11 \\ x += 1;
12 \\}
13 ,
14 ".tmp_source.zig:2:5: error: use of undeclared identifier 'x'",
15 );
16 tc.expect_exact = true;
17 break :x tc;
18 });
19
4 cases.addTest(20 cases.addTest(
5 "export generic function",21 "export generic function",
6 \\export fn foo(num: var) i32 {22 \\export fn foo(num: var) i32 {
...@@ -2280,7 +2296,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2280,7 +2296,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2280 \\}2296 \\}
2281 ,2297 ,
2282 ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",2298 ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
2283 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'",
2284 );2299 );
22852300
2286 cases.add(2301 cases.add(
...@@ -5618,8 +5633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5618,8 +5633,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5618 ".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid",5633 ".tmp_source.zig:2:26: error: vector element type must be integer, float, or pointer; '@Vector(4, u8)' is invalid",
5619 );5634 );
56205635
5621 cases.add(5636 cases.add("compileLog of tagged enum doesn't crash the compiler",
5622 "compileLog of tagged enum doesn't crash the compiler",
5623 \\const Bar = union(enum(u32)) {5637 \\const Bar = union(enum(u32)) {
5624 \\ X: i32 = 15638 \\ X: i32 = 1
5625 \\};5639 \\};
...@@ -5631,7 +5645,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5631,7 +5645,5 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5631 \\pub fn main () void {5645 \\pub fn main () void {
5632 \\ comptime testCompileLog(Bar{.X = 123});5646 \\ comptime testCompileLog(Bar{.X = 123});
5633 \\}5647 \\}
5634 ,5648 , ".tmp_source.zig:6:5: error: found compile log statement");
5635 ".tmp_source.zig:6:5: error: found compile log statement"
5636 );
5637}5649}
test/tests.zig+2-1
...@@ -716,7 +716,8 @@ pub const CompileErrorContext = struct {...@@ -716,7 +716,8 @@ pub const CompileErrorContext = struct {
716 for (self.case.expected_errors.toSliceConst()) |expected| {716 for (self.case.expected_errors.toSliceConst()) |expected| {
717 if (mem.indexOf(u8, stderr, expected) == null) {717 if (mem.indexOf(u8, stderr, expected) == null) {
718 warn(718 warn(
719 \\\n=========== Expected compile error: ============719 \\
720 \\=========== Expected compile error: ============
720 \\{}721 \\{}
721 \\722 \\
722 , expected);723 , expected);