authorgravatar for jacoblevgw@gmail.comJacob G-W <jacoblevgw@gmail.com> 2021-05-27 21:29:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-06-08 18:13:12-04:00
logb57ac48773f1cb4ff34e2be1af7f5b29c2d36de7
tree48450d0a51eb1fe1bf043a727039041ab9f3c9b7
parent143688e26644b64609410a1be378b349dce983fc

stage2: compile error for ambiguous decl refrences

std: fix compile errors from this change. This is a stage1 bug.

3 files changed, 72 insertions(+), 9 deletions(-)

lib/std/zig/render.zig+7-7
......@@ -2564,8 +2564,8 @@ fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex
25642564fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
25652565 return struct {
25662566 const Self = @This();
2567 pub const Error = UnderlyingWriter.Error;
2568 pub const Writer = std.io.Writer(*Self, Error, write);
2567 pub const WriteError = UnderlyingWriter.Error;
2568 pub const Writer = std.io.Writer(*Self, WriteError, write);
25692569
25702570 underlying_writer: UnderlyingWriter,
25712571
......@@ -2591,7 +2591,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
25912591 return .{ .context = self };
25922592 }
25932593
2594 pub fn write(self: *Self, bytes: []const u8) Error!usize {
2594 pub fn write(self: *Self, bytes: []const u8) WriteError!usize {
25952595 if (bytes.len == 0)
25962596 return @as(usize, 0);
25972597
......@@ -2614,7 +2614,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
26142614 self.indent_delta = new_indent_delta;
26152615 }
26162616
2617 fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize {
2617 fn writeNoIndent(self: *Self, bytes: []const u8) WriteError!usize {
26182618 if (bytes.len == 0)
26192619 return @as(usize, 0);
26202620
......@@ -2624,7 +2624,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
26242624 return bytes.len;
26252625 }
26262626
2627 pub fn insertNewline(self: *Self) Error!void {
2627 pub fn insertNewline(self: *Self) WriteError!void {
26282628 _ = try self.writeNoIndent("\n");
26292629 }
26302630
......@@ -2634,7 +2634,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
26342634 }
26352635
26362636 /// Insert a newline unless the current line is blank
2637 pub fn maybeInsertNewline(self: *Self) Error!void {
2637 pub fn maybeInsertNewline(self: *Self) WriteError!void {
26382638 if (!self.current_line_empty)
26392639 try self.insertNewline();
26402640 }
......@@ -2675,7 +2675,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
26752675 }
26762676
26772677 /// Writes ' ' bytes if the current line is empty
2678 fn applyIndent(self: *Self) Error!void {
2678 fn applyIndent(self: *Self) WriteError!void {
26792679 const current_indent = self.currentIndent();
26802680 if (self.current_line_empty and current_indent > 0) {
26812681 if (self.disabled_offset == null) {
src/AstGen.zig+37-2
......@@ -2353,6 +2353,7 @@ fn varDecl(
23532353 .name = ident_name,
23542354 .ptr = init_scope.rl_ptr,
23552355 .token_src = name_token,
2356 .is_comptime = true,
23562357 };
23572358 return &sub_scope.base;
23582359 },
......@@ -2408,6 +2409,7 @@ fn varDecl(
24082409 .name = ident_name,
24092410 .ptr = var_data.alloc,
24102411 .token_src = name_token,
2412 .is_comptime = is_comptime,
24112413 };
24122414 return &sub_scope.base;
24132415 },
......@@ -3352,7 +3354,7 @@ fn structDeclInner(
33523354 };
33533355 defer block_scope.instructions.deinit(gpa);
33543356
3355 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3357 var namespace: Scope.Namespace = .{ .parent = scope };
33563358 defer namespace.decls.deinit(gpa);
33573359
33583360 var wip_decls: WipDecls = .{};
......@@ -5345,6 +5347,7 @@ fn forExpr(
53455347 .name = index_name,
53465348 .ptr = index_ptr,
53475349 .token_src = index_token,
5350 .is_comptime = parent_gz.force_comptime,
53485351 };
53495352 break :blk &index_scope.base;
53505353 };
......@@ -6070,9 +6073,16 @@ fn identifier(
60706073 const name_str_index = try astgen.identAsString(ident_token);
60716074 {
60726075 var s = scope;
6076 var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
6077 var hit_namespace = false;
60736078 while (true) switch (s.tag) {
60746079 .local_val => {
60756080 const local_val = s.cast(Scope.LocalVal).?;
6081 if (hit_namespace) {
6082 // captures of non-locals need to be emitted as decl_val or decl_ref
6083 // This *might* be capturable depending on if it is comptime known
6084 break;
6085 }
60766086 if (local_val.name == name_str_index) {
60776087 return rvalue(gz, scope, rl, local_val.inst, ident);
60786088 }
......@@ -6081,6 +6091,15 @@ fn identifier(
60816091 .local_ptr => {
60826092 const local_ptr = s.cast(Scope.LocalPtr).?;
60836093 if (local_ptr.name == name_str_index) {
6094 if (hit_namespace) {
6095 if (local_ptr.is_comptime)
6096 break
6097 else
6098 return astgen.failNodeNotes(ident, "'{s}' not accessible from inner function", .{ident_name}, &.{
6099 try astgen.errNoteTok(local_ptr.token_src, "declared here", .{}),
6100 // TODO add crossed function definition here note.
6101 });
6102 }
60846103 switch (rl) {
60856104 .ref, .none_or_ref => return local_ptr.ptr,
60866105 else => {
......@@ -6093,7 +6112,22 @@ fn identifier(
60936112 },
60946113 .gen_zir => s = s.cast(GenZir).?.parent,
60956114 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
6096 .namespace, .top => break, // TODO look for ambiguous references to decls
6115 // look for ambiguous references to decls
6116 .namespace => {
6117 const ns = s.cast(Scope.Namespace).?;
6118 if (ns.decls.get(name_str_index)) |i| {
6119 if (found_already) |f|
6120 return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
6121 try astgen.errNoteNode(i, "declared here", .{}),
6122 try astgen.errNoteNode(f, "also declared here", .{}),
6123 })
6124 else
6125 found_already = i;
6126 }
6127 hit_namespace = true;
6128 s = ns.parent;
6129 },
6130 .top => break,
60976131 };
60986132 }
60996133
......@@ -8042,6 +8076,7 @@ const Scope = struct {
80428076 token_src: ast.TokenIndex,
80438077 /// String table index.
80448078 name: u32,
8079 is_comptime: bool,
80458080 };
80468081
80478082 const Defer = struct {
test/stage2/test.zig+28
......@@ -943,6 +943,34 @@ pub fn addCases(ctx: *TestContext) !void {
943943 ":10:8: error: cannot return from defer expression",
944944 });
945945
946 ctx.compileError("ambiguous references", linux_x64,
947 \\const T = struct {
948 \\ const T = struct {
949 \\ fn f() void {
950 \\ _ = T;
951 \\ }
952 \\ };
953 \\};
954 , &.{
955 ":4:17: error: ambiguous reference",
956 ":1:1: note: declared here",
957 ":2:5: note: also declared here",
958 });
959
960 ctx.compileError("inner func accessing outer var", linux_x64,
961 \\pub fn f() void {
962 \\ var bar: bool = true;
963 \\ const S = struct {
964 \\ fn baz() bool {
965 \\ return bar;
966 \\ }
967 \\ };
968 \\}
969 , &.{
970 ":5:20: error: 'bar' not accessible from inner function",
971 ":2:9: note: declared here",
972 });
973
946974 ctx.compileError("global variable redeclaration", linux_x64,
947975 \\// dummy comment
948976 \\var foo = false;