| author | |
| committer | |
| log | e1c47d6fe88bb1d79a4484e07d21f126ca9f1003 |
| tree | 9fe0d27ddce80b0c37800961e394f36fe0127ac8 |
| parent | fa7c64ccd511703fef9971c4d07c447c9aeda49c |
closes #2715 files changed, 31 insertions(+), 11 deletions(-)
src/analyze.cpp+6-5| ... | ... | @@ -2138,7 +2138,7 @@ TypeTableEntry *validate_var_type(CodeGen *g, AstNode *source_node, TypeTableEnt |
| 2138 | 2138 | // Set name to nullptr to make the variable anonymous (not visible to programmer). |
| 2139 | 2139 | // TODO merge with definition of add_local_var in ir.cpp |
| 2140 | 2140 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, |
| 2141 | bool is_const, ConstExprValue *value) | |
| 2141 | bool is_const, ConstExprValue *value, Tld *src_tld) | |
| 2142 | 2142 | { |
| 2143 | 2143 | assert(value); |
| 2144 | 2144 | |
| ... | ... | @@ -2167,9 +2167,9 @@ VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent |
| 2167 | 2167 | add_node_error(g, source_node, |
| 2168 | 2168 | buf_sprintf("variable shadows type '%s'", buf_ptr(&type->name))); |
| 2169 | 2169 | variable_entry->value->type = g->builtin_types.entry_invalid; |
| 2170 | } else { | |
| 2170 | } else if (src_tld == nullptr) { | |
| 2171 | 2171 | Tld *tld = find_decl(g, parent_scope, name); |
| 2172 | if (tld && tld->id != TldIdVar) { | |
| 2172 | if (tld) { | |
| 2173 | 2173 | ErrorMsg *msg = add_node_error(g, source_node, |
| 2174 | 2174 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 2175 | 2175 | 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) { |
| 2263 | 2263 | |
| 2264 | 2264 | ConstExprValue *init_val = init_value ? &init_value->value : create_const_runtime(type); |
| 2265 | 2265 | |
| 2266 | tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, is_const, init_val); | |
| 2266 | tld_var->var = add_variable(g, source_node, tld_var->base.parent_scope, var_decl->symbol, | |
| 2267 | is_const, init_val, &tld_var->base); | |
| 2267 | 2268 | tld_var->var->linkage = linkage; |
| 2268 | 2269 | |
| 2269 | 2270 | g->global_vars.append(tld_var); |
| ... | ... | @@ -2653,7 +2654,7 @@ void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, Vari |
| 2653 | 2654 | } |
| 2654 | 2655 | |
| 2655 | 2656 | VariableTableEntry *var = add_variable(g, param_decl_node, fn_table_entry->child_scope, |
| 2656 | param_name, true, create_const_runtime(param_type)); | |
| 2657 | param_name, true, create_const_runtime(param_type), nullptr); | |
| 2657 | 2658 | var->src_arg_index = i; |
| 2658 | 2659 | fn_table_entry->child_scope = var->child_scope; |
| 2659 | 2660 | var->shadowable = var->shadowable || is_var_args; |
src/analyze.hpp+1-1| ... | ... | @@ -69,7 +69,7 @@ FnTableEntry *scope_fn_entry(Scope *scope); |
| 69 | 69 | ImportTableEntry *get_scope_import(Scope *scope); |
| 70 | 70 | void init_tld(Tld *tld, TldId id, Buf *name, VisibMod visib_mod, AstNode *source_node, Scope *parent_scope); |
| 71 | 71 | VariableTableEntry *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf *name, |
| 72 | bool is_const, ConstExprValue *init_value); | |
| 72 | bool is_const, ConstExprValue *init_value, Tld *src_tld); | |
| 73 | 73 | TypeTableEntry *analyze_type_expr(CodeGen *g, Scope *scope, AstNode *node); |
| 74 | 74 | FnTableEntry *create_fn(AstNode *proto_node); |
| 75 | 75 | FnTableEntry *create_fn_raw(FnInline inline_value, bool internal_linkage); |
src/ir.cpp+4-4| ... | ... | @@ -3171,7 +3171,7 @@ static VariableTableEntry *create_local_var(CodeGen *codegen, AstNode *node, Sco |
| 3171 | 3171 | variable_entry->value->type = codegen->builtin_types.entry_invalid; |
| 3172 | 3172 | } else { |
| 3173 | 3173 | Tld *tld = find_decl(codegen, parent_scope, name); |
| 3174 | if (tld && tld->id != TldIdVar) { | |
| 3174 | if (tld != nullptr) { | |
| 3175 | 3175 | ErrorMsg *msg = add_node_error(codegen, node, |
| 3176 | 3176 | buf_sprintf("redefinition of '%s'", buf_ptr(name))); |
| 3177 | 3177 | 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 |
| 7897 | 7897 | |
| 7898 | 7898 | Buf *param_name = param_decl_node->data.param_decl.name; |
| 7899 | 7899 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| 7900 | *exec_scope, param_name, true, arg_val); | |
| 7900 | *exec_scope, param_name, true, arg_val, nullptr); | |
| 7901 | 7901 | *exec_scope = var->child_scope; |
| 7902 | 7902 | *next_proto_i += 1; |
| 7903 | 7903 | |
| ... | ... | @@ -7954,7 +7954,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod |
| 7954 | 7954 | Buf *param_name = param_decl_node->data.param_decl.name; |
| 7955 | 7955 | if (!is_var_args) { |
| 7956 | 7956 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| 7957 | *child_scope, param_name, true, arg_val); | |
| 7957 | *child_scope, param_name, true, arg_val, nullptr); | |
| 7958 | 7958 | *child_scope = var->child_scope; |
| 7959 | 7959 | var->shadowable = !comptime_arg; |
| 7960 | 7960 | |
| ... | ... | @@ -8245,7 +8245,7 @@ static TypeTableEntry *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *cal |
| 8245 | 8245 | ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, |
| 8246 | 8246 | first_var_arg, inst_fn_type_id.param_count); |
| 8247 | 8247 | VariableTableEntry *var = add_variable(ira->codegen, param_decl_node, |
| 8248 | impl_fn->child_scope, param_name, true, var_args_val); | |
| 8248 | impl_fn->child_scope, param_name, true, var_args_val, nullptr); | |
| 8249 | 8249 | impl_fn->child_scope = var->child_scope; |
| 8250 | 8250 | } |
| 8251 | 8251 | { |
src/parseh.cpp+2-1| ... | ... | @@ -151,7 +151,8 @@ static TldVar *create_global_var(Context *c, Buf *name, ConstExprValue *var_valu |
| 151 | 151 | } |
| 152 | 152 | TldVar *tld_var = allocate<TldVar>(1); |
| 153 | 153 | parseh_init_tld(c, &tld_var->base, TldIdVar, name); |
| 154 | tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, name, is_const, var_value); | |
| 154 | tld_var->var = add_variable(c->codegen, c->source_node, &c->import->decls_scope->base, | |
| 155 | name, is_const, var_value, &tld_var->base); | |
| 155 | 156 | c->codegen->global_vars.append(tld_var); |
| 156 | 157 | return tld_var; |
| 157 | 158 | } |
test/run_tests.cpp+18| ... | ... | @@ -991,6 +991,24 @@ export fn entry() -> foo { |
| 991 | 991 | } |
| 992 | 992 | )SOURCE", 1, ".tmp_source.zig:2:1: error: variable of type 'type' must be constant"); |
| 993 | 993 | |
| 994 | ||
| 995 | add_compile_fail_case("variables shadowing types", R"SOURCE( | |
| 996 | const Foo = struct {}; | |
| 997 | const Bar = struct {}; | |
| 998 | ||
| 999 | fn f(Foo: i32) { | |
| 1000 | var Bar : i32 = undefined; | |
| 1001 | } | |
| 1002 | ||
| 1003 | export fn entry() { | |
| 1004 | f(1234); | |
| 1005 | } | |
| 1006 | )SOURCE", 4, | |
| 1007 | ".tmp_source.zig:5:6: error: redefinition of 'Foo'", | |
| 1008 | ".tmp_source.zig:2:1: note: previous definition is here", | |
| 1009 | ".tmp_source.zig:6:5: error: redefinition of 'Bar'", | |
| 1010 | ".tmp_source.zig:3:1: note: previous definition is here"); | |
| 1011 | ||
| 994 | 1012 | add_compile_fail_case("multiple else prongs in a switch", R"SOURCE( |
| 995 | 1013 | fn f(x: u32) { |
| 996 | 1014 | const value: bool = switch (x) { |