From e1c47d6fe88bb1d79a4484e07d21f126ca9f1003 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 20 Mar 2017 15:32:13 -0400 Subject: [PATCH] fix test regression regarding shadowing names closes #271 --- src/analyze.cpp | 11 ++++++----- src/analyze.hpp | 2 +- src/ir.cpp | 8 ++++---- src/parseh.cpp | 3 ++- test/run_tests.cpp | 18 ++++++++++++++++++ 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/analyze.cpp b/src/analyze.cpp index 8e3c82822f..e6c95c58f6 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -2138,7 +2138,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt // Set name to nullptr to make the variable anonymous (not visible to programmer). // TODO merge with definition of add_local_var in ir.cpp VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, - bool is_const, ConstExprValue *value) + bool is_const, ConstExprValue *value, Tld *src_tld) { assert(value); @@ -2167,9 +2167,9 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent add_node_error(g, source_node, buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); variable_entry->value->type = g->builtin_types.entry_invalid; - } else { + } else if (src_tld == nullptr) { Tld *tld = find_decl(g, parent_scope, name); - if (tld && tld->id != TldIdVar) { + if (tld) { ErrorMsg *msg = add_node_error(g, source_node, buf_sprintf("redefinition of '%s'", buf_ptr(name))); add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition is here")); @@ -2263,7 +2263,8 @@ static void resolve_decl_var(CodeGen *g, TldVar *tld_var) { ConstExprValue *init_val = init_value ? &init_value->value : create_const_runtime(type); - tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, is_const, init_val); + tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, + is_const, init_val, &tld_var->base); tld_var->var->linkage = linkage; g->global_vars.append(tld_var); @@ -2653,7 +2654,7 @@ void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, Vari } VariableTableEntry *var = add_variable(g, param_decl_node, fn_table_entry->child_scope, - param_name, true, create_const_runtime(param_type)); + param_name, true, create_const_runtime(param_type), nullptr); var->src_arg_index = i; fn_table_entry->child_scope = var->child_scope; var->shadowable = var->shadowable || is_var_args; diff --git a/src/analyze.hpp b/src/analyze.hpp index 4a2e62e432..67e36cce0c 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -69,7 +69,7 @@ FnTableEntry *scope_fn_entry(Scope *scope); ImportTableEntry *get_scope_import(Scope *scope); void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, Scope *parent_scope); VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, - bool is_const, ConstExprValue *init_value); + bool is_const, ConstExprValue *init_value, Tld *src_tld); TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); FnTableEntry *create_fn(AstNode *proto_node); FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); diff --git a/src/ir.cpp b/src/ir.cpp index 0abf051ad3..e9d0b2f311 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3171,7 +3171,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco variable_entry->value->type = codegen->builtin_types.entry_invalid; } else { Tld *tld = find_decl(codegen, parent_scope, name); - if (tld && tld->id != TldIdVar) { + if (tld != nullptr) { ErrorMsg *msg = add_node_error(codegen, node, buf_sprintf("redefinition of '%s'", buf_ptr(name))); add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); @@ -7897,7 +7897,7 @@ static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node Buf *param_name = param_decl_node->data.param_decl.name; VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, - *exec_scope, param_name, true, arg_val); + *exec_scope, param_name, true, arg_val, nullptr); *exec_scope = var->child_scope; *next_proto_i += 1; @@ -7954,7 +7954,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod Buf *param_name = param_decl_node->data.param_decl.name; if (!is_var_args) { VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, - *child_scope, param_name, true, arg_val); + *child_scope, param_name, true, arg_val, nullptr); *child_scope = var->child_scope; var->shadowable = !comptime_arg; @@ -8245,7 +8245,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, first_var_arg, inst_fn_type_id.param_count); VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, - impl_fn->child_scope, param_name, true, var_args_val); + impl_fn->child_scope, param_name, true, var_args_val, nullptr); impl_fn->child_scope = var->child_scope; } { diff --git a/src/parseh.cpp b/src/parseh.cpp index 810acf07bf..b4582e26b4 100644 --- a/src/parseh.cpp +++ b/src/parseh.cpp @@ -151,7 +151,8 @@ static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_valu } TldVar *tld_var = allocate(1); parseh_init_tld(c, &tld_var->base, TldIdVar, name); - tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, name, is_const, var_value); + tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, + name, is_const, var_value, &tld_var->base); c->codegen->global_vars.append(tld_var); return tld_var; } diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 823d04af94..0029699d74 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -991,6 +991,24 @@ export fn entry() -> foo { } )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant"); + + add_compile_fail_case("variables shadowing types", R"SOURCE( +const Foo = struct {}; +const Bar = struct {}; + +fn f(Foo: i32) { + var Bar : i32 = undefined; +} + +export fn entry() { + f(1234); +} + )SOURCE", 4, + ".tmp_source.zig:5:6: error: redefinition of 'Foo'", + ".tmp_source.zig:2:1: note: previous definition is here", + ".tmp_source.zig:6:5: error: redefinition of 'Bar'", + ".tmp_source.zig:3:1: note: previous definition is here"); + add_compile_fail_case("multiple else prongs in a switch", R"SOURCE( fn f(x: u32) { const value: bool = switch (x) {