authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-24 18:56:16-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-24 22:35:37-07:00
log9c95f38a7c1defc7f63a4815bfc2d76a5f9f83f6
tree3182a24f22da9da86b56d8894b4bd603e89e10e3
parentf1f28af1880a79bb2d7210d3a704c78698f0b45b

stage1: remove incorrect compile error for var redeclaration

Locals are not allowed to shadow declarations, but declarations are allowed to shadow each other, as long as there are no ambiguous references. closes #678

6 files changed, 67 insertions(+), 83 deletions(-)

src/stage1/analyze.cpp+4-39
......@@ -4171,46 +4171,11 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
41714171 } else {
41724172 variable_entry->align_bytes = get_abi_alignment(g, var_type);
41734173
4174 ZigVar *existing_var = find_variable(g, parent_scope, name, nullptr);
4175 if (existing_var && !existing_var->shadowable) {
4176 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
4177 ErrorMsg *msg = add_node_error(g, source_node,
4178 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
4179 add_error_note(g, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));
4180 }
4174 ZigType *type;
4175 if (get_primitive_type(g, name, &type) != ErrorPrimitiveTypeNotFound) {
4176 add_node_error(g, source_node,
4177 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
41814178 variable_entry->var_type = g->builtin_types.entry_invalid;
4182 } else {
4183 ZigType *type;
4184 if (get_primitive_type(g, name, &type) != ErrorPrimitiveTypeNotFound) {
4185 add_node_error(g, source_node,
4186 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
4187 variable_entry->var_type = g->builtin_types.entry_invalid;
4188 } else {
4189 Scope *search_scope = nullptr;
4190 if (src_tld == nullptr) {
4191 search_scope = parent_scope;
4192 } else if (src_tld->parent_scope != nullptr && src_tld->parent_scope->parent != nullptr) {
4193 search_scope = src_tld->parent_scope->parent;
4194 }
4195 if (search_scope != nullptr) {
4196 Tld *tld = find_decl(g, search_scope, name);
4197 if (tld != nullptr && tld != src_tld) {
4198 bool want_err_msg = true;
4199 if (tld->id == TldIdVar) {
4200 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
4201 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
4202 want_err_msg = false;
4203 }
4204 }
4205 if (want_err_msg) {
4206 ErrorMsg *msg = add_node_error(g, source_node,
4207 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
4208 add_error_note(g, msg, tld->source_node, buf_sprintf("previous definition here"));
4209 }
4210 variable_entry->var_type = g->builtin_types.entry_invalid;
4211 }
4212 }
4213 }
42144179 }
42154180 }
42164181
src/stage1/astgen.cpp+25-18
......@@ -3200,23 +3200,6 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
32003200 add_node_error(codegen, node,
32013201 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
32023202 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3203 } else {
3204 Tld *tld = find_decl(codegen, parent_scope, name);
3205 if (tld != nullptr) {
3206 bool want_err_msg = true;
3207 if (tld->id == TldIdVar) {
3208 ZigVar *var = reinterpret_cast<TldVar *>(tld)->var;
3209 if (var != nullptr && var->var_type != nullptr && type_is_invalid(var->var_type)) {
3210 want_err_msg = false;
3211 }
3212 }
3213 if (want_err_msg) {
3214 ErrorMsg *msg = add_node_error(codegen, node,
3215 buf_sprintf("redefinition of '%s'", buf_ptr(name)));
3216 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition here"));
3217 }
3218 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3219 }
32203203 }
32213204 }
32223205 }
......@@ -3875,7 +3858,31 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode
38753858 }
38763859 }
38773860
3878 Tld *tld = find_decl(ag->codegen, scope, variable_name);
3861 Tld *tld = nullptr;
3862 {
3863 Scope *s = scope;
3864 while (s) {
3865 if (s->id == ScopeIdDecls) {
3866 ScopeDecls *decls_scope = (ScopeDecls *)s;
3867
3868 Tld *result = find_container_decl(ag->codegen, decls_scope, variable_name);
3869 if (result != nullptr) {
3870 if (tld != nullptr && tld != result) {
3871 ErrorMsg *msg = add_node_error(ag->codegen, node,
3872 buf_sprintf("ambiguous reference"));
3873 add_error_note(ag->codegen, msg, tld->source_node,
3874 buf_sprintf("declared here"));
3875 add_error_note(ag->codegen, msg, result->source_node,
3876 buf_sprintf("also declared here"));
3877 return ag->codegen->invalid_inst_src;
3878 }
3879 tld = result;
3880 }
3881 }
3882 s = s->parent;
3883 }
3884 }
3885
38793886 if (tld) {
38803887 Stage1ZirInst *decl_ref = ir_build_decl_ref(ag, scope, node, tld, lval);
38813888 if (lval == LValPtr || lval == LValAssign) {
test/behavior/error.zig+6-6
......@@ -412,19 +412,19 @@ test "function pointer with return type that is error union with payload which i
412412test "return result loc as peer result loc in inferred error set function" {
413413 const S = struct {
414414 fn doTheTest() !void {
415 if (foo(2)) |x| {
415 if (quux(2)) |x| {
416416 try expect(x.Two);
417417 } else |e| switch (e) {
418418 error.Whatever => @panic("fail"),
419419 }
420 try expectError(error.Whatever, foo(99));
420 try expectError(error.Whatever, quux(99));
421421 }
422422 const FormValue = union(enum) {
423423 One: void,
424424 Two: bool,
425425 };
426426
427 fn foo(id: u64) !FormValue {
427 fn quux(id: u64) !FormValue {
428428 return switch (id) {
429429 2 => FormValue{ .Two = true },
430430 1 => FormValue{ .One = {} },
......@@ -452,11 +452,11 @@ test "error payload type is correctly resolved" {
452452
453453test "error union comptime caching" {
454454 const S = struct {
455 fn foo(comptime arg: anytype) void {
455 fn quux(comptime arg: anytype) void {
456456 arg catch {};
457457 }
458458 };
459459
460 S.foo(@as(anyerror!void, {}));
461 S.foo(@as(anyerror!void, {}));
460 S.quux(@as(anyerror!void, {}));
461 S.quux(@as(anyerror!void, {}));
462462}
test/behavior/misc.zig+17
......@@ -505,3 +505,20 @@ test "lazy typeInfo value as generic parameter" {
505505 };
506506 S.foo(@typeInfo(@TypeOf(.{})));
507507}
508
509fn A() type {
510 return struct {
511 b: B(),
512
513 const Self = @This();
514
515 fn B() type {
516 return struct {
517 const Self = @This();
518 };
519 }
520 };
521}
522test "non-ambiguous reference of shadowed decls" {
523 try expect(A().B().Self != A().Self);
524}
test/behavior/struct.zig+2-2
......@@ -162,14 +162,14 @@ const MemberFnRand = struct {
162162};
163163
164164test "return struct byval from function" {
165 const bar = makeBar(1234, 5678);
165 const bar = makeBar2(1234, 5678);
166166 try expect(bar.y == 5678);
167167}
168168const Bar = struct {
169169 x: i32,
170170 y: i32,
171171};
172fn makeBar(x: i32, y: i32) Bar {
172fn makeBar2(x: i32, y: i32) Bar {
173173 return Bar{
174174 .x = x,
175175 .y = y,
test/compile_errors.zig+13-18
......@@ -6969,29 +6969,24 @@ pub fn addCases(ctx: *TestContext) !void {
69696969 "tmp.zig:2:30: error: cannot set section of local variable 'foo'",
69706970 });
69716971
6972 ctx.objErrStage1("inner struct member shadowing outer struct member",
6973 \\fn A() type {
6974 \\ return struct {
6975 \\ b: B(),
6976 \\
6977 \\ const Self = @This();
6978 \\
6979 \\ fn B() type {
6980 \\ return struct {
6981 \\ const Self = @This();
6982 \\ };
6972 ctx.objErrStage1("ambiguous decl reference",
6973 \\fn foo() void {}
6974 \\fn bar() void {
6975 \\ const S = struct {
6976 \\ fn baz() void {
6977 \\ foo();
69836978 \\ }
6979 \\ fn foo() void {}
69846980 \\ };
6981 \\ S.baz();
69856982 \\}
6986 \\comptime {
6987 \\ assert(A().B().Self != A().Self);
6988 \\}
6989 \\fn assert(ok: bool) void {
6990 \\ if (!ok) unreachable;
6983 \\export fn entry() void {
6984 \\ bar();
69916985 \\}
69926986 , &[_][]const u8{
6993 "tmp.zig:9:17: error: redefinition of 'Self'",
6994 "tmp.zig:5:9: note: previous definition here",
6987 "tmp.zig:5:13: error: ambiguous reference",
6988 "tmp.zig:7:9: note: declared here",
6989 "tmp.zig:1:1: note: also declared here",
69956990 });
69966991
69976992 ctx.objErrStage1("while expected bool, got optional",