mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
stage2: compile error for ambiguous decl refrences
std: fix compile errors from this change. This is a stage1 bug.
This commit is contained in:
parent
143688e266
commit
b57ac48773
@ -2564,8 +2564,8 @@ fn rowSize(tree: ast.Tree, exprs: []const ast.Node.Index, rtoken: ast.TokenIndex
|
||||
fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
pub const Error = UnderlyingWriter.Error;
|
||||
pub const Writer = std.io.Writer(*Self, Error, write);
|
||||
pub const WriteError = UnderlyingWriter.Error;
|
||||
pub const Writer = std.io.Writer(*Self, WriteError, write);
|
||||
|
||||
underlying_writer: UnderlyingWriter,
|
||||
|
||||
@ -2591,7 +2591,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
return .{ .context = self };
|
||||
}
|
||||
|
||||
pub fn write(self: *Self, bytes: []const u8) Error!usize {
|
||||
pub fn write(self: *Self, bytes: []const u8) WriteError!usize {
|
||||
if (bytes.len == 0)
|
||||
return @as(usize, 0);
|
||||
|
||||
@ -2614,7 +2614,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
self.indent_delta = new_indent_delta;
|
||||
}
|
||||
|
||||
fn writeNoIndent(self: *Self, bytes: []const u8) Error!usize {
|
||||
fn writeNoIndent(self: *Self, bytes: []const u8) WriteError!usize {
|
||||
if (bytes.len == 0)
|
||||
return @as(usize, 0);
|
||||
|
||||
@ -2624,7 +2624,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
return bytes.len;
|
||||
}
|
||||
|
||||
pub fn insertNewline(self: *Self) Error!void {
|
||||
pub fn insertNewline(self: *Self) WriteError!void {
|
||||
_ = try self.writeNoIndent("\n");
|
||||
}
|
||||
|
||||
@ -2634,7 +2634,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
}
|
||||
|
||||
/// Insert a newline unless the current line is blank
|
||||
pub fn maybeInsertNewline(self: *Self) Error!void {
|
||||
pub fn maybeInsertNewline(self: *Self) WriteError!void {
|
||||
if (!self.current_line_empty)
|
||||
try self.insertNewline();
|
||||
}
|
||||
@ -2675,7 +2675,7 @@ fn AutoIndentingStream(comptime UnderlyingWriter: type) type {
|
||||
}
|
||||
|
||||
/// Writes ' ' bytes if the current line is empty
|
||||
fn applyIndent(self: *Self) Error!void {
|
||||
fn applyIndent(self: *Self) WriteError!void {
|
||||
const current_indent = self.currentIndent();
|
||||
if (self.current_line_empty and current_indent > 0) {
|
||||
if (self.disabled_offset == null) {
|
||||
|
||||
@ -2353,6 +2353,7 @@ fn varDecl(
|
||||
.name = ident_name,
|
||||
.ptr = init_scope.rl_ptr,
|
||||
.token_src = name_token,
|
||||
.is_comptime = true,
|
||||
};
|
||||
return &sub_scope.base;
|
||||
},
|
||||
@ -2408,6 +2409,7 @@ fn varDecl(
|
||||
.name = ident_name,
|
||||
.ptr = var_data.alloc,
|
||||
.token_src = name_token,
|
||||
.is_comptime = is_comptime,
|
||||
};
|
||||
return &sub_scope.base;
|
||||
},
|
||||
@ -3352,7 +3354,7 @@ fn structDeclInner(
|
||||
};
|
||||
defer block_scope.instructions.deinit(gpa);
|
||||
|
||||
var namespace: Scope.Namespace = .{ .parent = &gz.base };
|
||||
var namespace: Scope.Namespace = .{ .parent = scope };
|
||||
defer namespace.decls.deinit(gpa);
|
||||
|
||||
var wip_decls: WipDecls = .{};
|
||||
@ -5345,6 +5347,7 @@ fn forExpr(
|
||||
.name = index_name,
|
||||
.ptr = index_ptr,
|
||||
.token_src = index_token,
|
||||
.is_comptime = parent_gz.force_comptime,
|
||||
};
|
||||
break :blk &index_scope.base;
|
||||
};
|
||||
@ -6070,9 +6073,16 @@ fn identifier(
|
||||
const name_str_index = try astgen.identAsString(ident_token);
|
||||
{
|
||||
var s = scope;
|
||||
var found_already: ?ast.Node.Index = null; // we have found a decl with the same name already
|
||||
var hit_namespace = false;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
if (hit_namespace) {
|
||||
// captures of non-locals need to be emitted as decl_val or decl_ref
|
||||
// This *might* be capturable depending on if it is comptime known
|
||||
break;
|
||||
}
|
||||
if (local_val.name == name_str_index) {
|
||||
return rvalue(gz, scope, rl, local_val.inst, ident);
|
||||
}
|
||||
@ -6081,6 +6091,15 @@ fn identifier(
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
if (local_ptr.name == name_str_index) {
|
||||
if (hit_namespace) {
|
||||
if (local_ptr.is_comptime)
|
||||
break
|
||||
else
|
||||
return astgen.failNodeNotes(ident, "'{s}' not accessible from inner function", .{ident_name}, &.{
|
||||
try astgen.errNoteTok(local_ptr.token_src, "declared here", .{}),
|
||||
// TODO add crossed function definition here note.
|
||||
});
|
||||
}
|
||||
switch (rl) {
|
||||
.ref, .none_or_ref => return local_ptr.ptr,
|
||||
else => {
|
||||
@ -6093,7 +6112,22 @@ fn identifier(
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.namespace, .top => break, // TODO look for ambiguous references to decls
|
||||
// look for ambiguous references to decls
|
||||
.namespace => {
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
if (ns.decls.get(name_str_index)) |i| {
|
||||
if (found_already) |f|
|
||||
return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
|
||||
try astgen.errNoteNode(i, "declared here", .{}),
|
||||
try astgen.errNoteNode(f, "also declared here", .{}),
|
||||
})
|
||||
else
|
||||
found_already = i;
|
||||
}
|
||||
hit_namespace = true;
|
||||
s = ns.parent;
|
||||
},
|
||||
.top => break,
|
||||
};
|
||||
}
|
||||
|
||||
@ -8042,6 +8076,7 @@ const Scope = struct {
|
||||
token_src: ast.TokenIndex,
|
||||
/// String table index.
|
||||
name: u32,
|
||||
is_comptime: bool,
|
||||
};
|
||||
|
||||
const Defer = struct {
|
||||
|
||||
@ -943,6 +943,34 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
":10:8: error: cannot return from defer expression",
|
||||
});
|
||||
|
||||
ctx.compileError("ambiguous references", linux_x64,
|
||||
\\const T = struct {
|
||||
\\ const T = struct {
|
||||
\\ fn f() void {
|
||||
\\ _ = T;
|
||||
\\ }
|
||||
\\ };
|
||||
\\};
|
||||
, &.{
|
||||
":4:17: error: ambiguous reference",
|
||||
":1:1: note: declared here",
|
||||
":2:5: note: also declared here",
|
||||
});
|
||||
|
||||
ctx.compileError("inner func accessing outer var", linux_x64,
|
||||
\\pub fn f() void {
|
||||
\\ var bar: bool = true;
|
||||
\\ const S = struct {
|
||||
\\ fn baz() bool {
|
||||
\\ return bar;
|
||||
\\ }
|
||||
\\ };
|
||||
\\}
|
||||
, &.{
|
||||
":5:20: error: 'bar' not accessible from inner function",
|
||||
":2:9: note: declared here",
|
||||
});
|
||||
|
||||
ctx.compileError("global variable redeclaration", linux_x64,
|
||||
\\// dummy comment
|
||||
\\var foo = false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user