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...@@ -2564,8 +2564,8 @@ fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex
2564fn AutoIndentingStream(comptime UnderlyingWriter: type) type {2564fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2565 return struct {2565 return struct {
2566 const Self = @This();2566 const Self = @This();
2567 pub const Error = UnderlyingWriter.Error;2567 pub const WriteError = UnderlyingWriter.Error;
2568 pub const Writer = std.io.Writer(*Self, Error, write);2568 pub const Writer = std.io.Writer(*Self, WriteError, write);
25692569
2570 underlying_writer: UnderlyingWriter,2570 underlying_writer: UnderlyingWriter,
25712571
...@@ -2591,7 +2591,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -2591,7 +2591,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2591 return .{ .context = self };2591 return .{ .context = self };
2592 }2592 }
25932593
2594 pub fn write(self: *Self, bytes: []const u8) Error!usize {2594 pub fn write(self: *Self, bytes: []const u8) WriteError!usize {
2595 if (bytes.len == 0)2595 if (bytes.len == 0)
2596 return @as(usize, 0);2596 return @as(usize, 0);
25972597
...@@ -2614,7 +2614,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -2614,7 +2614,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2614 self.indent_delta = new_indent_delta;2614 self.indent_delta = new_indent_delta;
2615 }2615 }
26162616
2617 fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize {2617 fn writeNoIndent(self: *Self, bytes: []const u8) WriteError!usize {
2618 if (bytes.len == 0)2618 if (bytes.len == 0)
2619 return @as(usize, 0);2619 return @as(usize, 0);
26202620
...@@ -2624,7 +2624,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -2624,7 +2624,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2624 return bytes.len;2624 return bytes.len;
2625 }2625 }
26262626
2627 pub fn insertNewline(self: *Self) Error!void {2627 pub fn insertNewline(self: *Self) WriteError!void {
2628 _ = try self.writeNoIndent("\n");2628 _ = try self.writeNoIndent("\n");
2629 }2629 }
26302630
...@@ -2634,7 +2634,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -2634,7 +2634,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2634 }2634 }
26352635
2636 /// Insert a newline unless the current line is blank2636 /// 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 {
2638 if (!self.current_line_empty)2638 if (!self.current_line_empty)
2639 try self.insertNewline();2639 try self.insertNewline();
2640 }2640 }
...@@ -2675,7 +2675,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {...@@ -2675,7 +2675,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
2675 }2675 }
26762676
2677 /// Writes ' ' bytes if the current line is empty2677 /// Writes ' ' bytes if the current line is empty
2678 fn applyIndent(self: *Self) Error!void {2678 fn applyIndent(self: *Self) WriteError!void {
2679 const current_indent = self.currentIndent();2679 const current_indent = self.currentIndent();
2680 if (self.current_line_empty and current_indent > 0) {2680 if (self.current_line_empty and current_indent > 0) {
2681 if (self.disabled_offset == null) {2681 if (self.disabled_offset == null) {
src/AstGen.zig+37-2
...@@ -2353,6 +2353,7 @@ fn varDecl(...@@ -2353,6 +2353,7 @@ fn varDecl(
2353 .name = ident_name,2353 .name = ident_name,
2354 .ptr = init_scope.rl_ptr,2354 .ptr = init_scope.rl_ptr,
2355 .token_src = name_token,2355 .token_src = name_token,
2356 .is_comptime = true,
2356 };2357 };
2357 return &sub_scope.base;2358 return &sub_scope.base;
2358 },2359 },
...@@ -2408,6 +2409,7 @@ fn varDecl(...@@ -2408,6 +2409,7 @@ fn varDecl(
2408 .name = ident_name,2409 .name = ident_name,
2409 .ptr = var_data.alloc,2410 .ptr = var_data.alloc,
2410 .token_src = name_token,2411 .token_src = name_token,
2412 .is_comptime = is_comptime,
2411 };2413 };
2412 return &sub_scope.base;2414 return &sub_scope.base;
2413 },2415 },
...@@ -3352,7 +3354,7 @@ fn structDeclInner(...@@ -3352,7 +3354,7 @@ fn structDeclInner(
3352 };3354 };
3353 defer block_scope.instructions.deinit(gpa);3355 defer block_scope.instructions.deinit(gpa);
33543356
3355 var namespace: Scope.Namespace = .{ .parent = &gz.base };3357 var namespace: Scope.Namespace = .{ .parent = scope };
3356 defer namespace.decls.deinit(gpa);3358 defer namespace.decls.deinit(gpa);
33573359
3358 var wip_decls: WipDecls = .{};3360 var wip_decls: WipDecls = .{};
...@@ -5345,6 +5347,7 @@ fn forExpr(...@@ -5345,6 +5347,7 @@ fn forExpr(
5345 .name = index_name,5347 .name = index_name,
5346 .ptr = index_ptr,5348 .ptr = index_ptr,
5347 .token_src = index_token,5349 .token_src = index_token,
5350 .is_comptime = parent_gz.force_comptime,
5348 };5351 };
5349 break :blk &index_scope.base;5352 break :blk &index_scope.base;
5350 };5353 };
...@@ -6070,9 +6073,16 @@ fn identifier(...@@ -6070,9 +6073,16 @@ fn identifier(
6070 const name_str_index = try astgen.identAsString(ident_token);6073 const name_str_index = try astgen.identAsString(ident_token);
6071 {6074 {
6072 var s = scope;6075 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;
6073 while (true) switch (s.tag) {6078 while (true) switch (s.tag) {
6074 .local_val => {6079 .local_val => {
6075 const local_val = s.cast(Scope.LocalVal).?;6080 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 }
6076 if (local_val.name == name_str_index) {6086 if (local_val.name == name_str_index) {
6077 return rvalue(gz, scope, rl, local_val.inst, ident);6087 return rvalue(gz, scope, rl, local_val.inst, ident);
6078 }6088 }
...@@ -6081,6 +6091,15 @@ fn identifier(...@@ -6081,6 +6091,15 @@ fn identifier(
6081 .local_ptr => {6091 .local_ptr => {
6082 const local_ptr = s.cast(Scope.LocalPtr).?;6092 const local_ptr = s.cast(Scope.LocalPtr).?;
6083 if (local_ptr.name == name_str_index) {6093 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 }
6084 switch (rl) {6103 switch (rl) {
6085 .ref, .none_or_ref => return local_ptr.ptr,6104 .ref, .none_or_ref => return local_ptr.ptr,
6086 else => {6105 else => {
...@@ -6093,7 +6112,22 @@ fn identifier(...@@ -6093,7 +6112,22 @@ fn identifier(
6093 },6112 },
6094 .gen_zir => s = s.cast(GenZir).?.parent,6113 .gen_zir => s = s.cast(GenZir).?.parent,
6095 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,6114 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
6096 .namespace, .top => break, // TODO look for ambiguous references to decls6115 // 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,
6097 };6131 };
6098 }6132 }
60996133
...@@ -8042,6 +8076,7 @@ const Scope = struct {...@@ -8042,6 +8076,7 @@ const Scope = struct {
8042 token_src: ast.TokenIndex,8076 token_src: ast.TokenIndex,
8043 /// String table index.8077 /// String table index.
8044 name: u32,8078 name: u32,
8079 is_comptime: bool,
8045 };8080 };
80468081
8047 const Defer = struct {8082 const Defer = struct {
test/stage2/test.zig+28
...@@ -943,6 +943,34 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -943,6 +943,34 @@ pub fn addCases(ctx: *TestContext) !void {
943 ":10:8: error: cannot return from defer expression",943 ":10:8: error: cannot return from defer expression",
944 });944 });
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
946 ctx.compileError("global variable redeclaration", linux_x64,974 ctx.compileError("global variable redeclaration", linux_x64,
947 \\// dummy comment975 \\// dummy comment
948 \\var foo = false;976 \\var foo = false;