mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 04:24:33 +01:00
AstGen: improve ergonomics of Scope
Adds `Scope.Unwrapped`, a simple union of pointers to already-casted scopes with `Scope.Tag` as its tag enum. This pairs very nicely with labeled switch and gets rid of almost every `scope.cast(...).?`, improving developer QOL :)
This commit is contained in:
parent
e0108dec54
commit
d840bb5118
1 changed files with 122 additions and 155 deletions
|
|
@ -2161,10 +2161,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
|||
const opt_break_label, const opt_rhs = tree.nodeData(node).opt_token_and_opt_node;
|
||||
|
||||
// Look for the label in the scope.
|
||||
var scope = parent_scope;
|
||||
find_scope: switch (scope.tag) {
|
||||
.gen_zir => {
|
||||
const gen_zir = scope.cast(GenZir).?;
|
||||
find_scope: switch (parent_scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| {
|
||||
const scope = &gen_zir.base;
|
||||
|
||||
if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| {
|
||||
// We are breaking out of a `defer` block.
|
||||
|
|
@ -2185,13 +2184,11 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
|||
}
|
||||
}
|
||||
// gz without or with different label, continue to parent scopes.
|
||||
scope = gen_zir.parent;
|
||||
continue :find_scope scope.tag;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
} else if (!gen_zir.allow_unlabeled_control_flow) {
|
||||
// This `break` is unlabeled and the gz we've found doesn't allow
|
||||
// unlabeled control flow. Continue to parent scopes.
|
||||
scope = gen_zir.parent;
|
||||
continue :find_scope scope.tag;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
}
|
||||
|
||||
const break_tag: Zir.Inst.Tag = if (gen_zir.is_inline)
|
||||
|
|
@ -2236,18 +2233,9 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
|
|||
return .unreachable_value;
|
||||
}
|
||||
},
|
||||
.local_val => {
|
||||
scope = scope.cast(Scope.LocalVal).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.local_ptr => {
|
||||
scope = scope.cast(Scope.LocalPtr).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.defer_normal, .defer_error => {
|
||||
scope = scope.cast(Scope.Defer).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.local_val => |local_val| continue :find_scope local_val.parent.unwrap(),
|
||||
.local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.namespace => {
|
||||
if (opt_break_label.unwrap()) |break_label| {
|
||||
const label_name = try astgen.identifierTokenString(break_label);
|
||||
|
|
@ -2270,10 +2258,9 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
|
|||
}
|
||||
|
||||
// Look for the label in the scope.
|
||||
var scope = parent_scope;
|
||||
find_scope: switch (scope.tag) {
|
||||
.gen_zir => {
|
||||
const gen_zir = scope.cast(GenZir).?;
|
||||
find_scope: switch (parent_scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| {
|
||||
const scope = &gen_zir.base;
|
||||
|
||||
if (gen_zir.cur_defer_node.unwrap()) |cur_defer_node| {
|
||||
return astgen.failNodeNotes(node, "cannot continue out of defer expression", .{}, &.{
|
||||
|
|
@ -2305,24 +2292,21 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
|
|||
}
|
||||
}
|
||||
// gz without or with different label, continue to parent scopes.
|
||||
scope = gen_zir.parent;
|
||||
continue :find_scope scope.tag;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
} else if (gen_zir.allow_unlabeled_control_flow) {
|
||||
// This `continue` is unlabeled. If the gz we've found doesn't
|
||||
// provide a `continue` target or corresponds to a labeled
|
||||
// `switch`, ignore it and continue to parent scopes.
|
||||
switch (gen_zir.continue_target) {
|
||||
.none, .switch_continue => {
|
||||
scope = gen_zir.parent;
|
||||
continue :find_scope scope.tag;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
},
|
||||
.@"break" => {},
|
||||
}
|
||||
} else {
|
||||
// We don't have a break label and the gz we found doesn't allow
|
||||
// unlabeled control flow, so we continue to its parent scopes.
|
||||
scope = gen_zir.parent;
|
||||
continue :find_scope scope.tag;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
}
|
||||
|
||||
switch (gen_zir.continue_target) {
|
||||
|
|
@ -2360,18 +2344,9 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
|
|||
},
|
||||
}
|
||||
},
|
||||
.local_val => {
|
||||
scope = scope.cast(Scope.LocalVal).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.local_ptr => {
|
||||
scope = scope.cast(Scope.LocalPtr).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.defer_normal, .defer_error => {
|
||||
scope = scope.cast(Scope.Defer).?.parent;
|
||||
continue :find_scope scope.tag;
|
||||
},
|
||||
.local_val => |local_val| continue :find_scope local_val.parent.unwrap(),
|
||||
.local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.namespace => {
|
||||
if (opt_break_label.unwrap()) |break_label| {
|
||||
const label_name = try astgen.identifierTokenString(break_label);
|
||||
|
|
@ -2466,33 +2441,29 @@ fn blockExpr(
|
|||
|
||||
fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: Ast.TokenIndex) !void {
|
||||
// Look for the label in the scope.
|
||||
var scope = parent_scope;
|
||||
while (true) {
|
||||
switch (scope.tag) {
|
||||
.gen_zir => {
|
||||
const gen_zir = scope.cast(GenZir).?;
|
||||
if (gen_zir.label) |prev_label| {
|
||||
if (try astgen.tokenIdentEql(label, prev_label.token)) {
|
||||
const label_name = try astgen.identifierTokenString(label);
|
||||
return astgen.failTokNotes(label, "redefinition of label '{s}'", .{
|
||||
label_name,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
prev_label.token,
|
||||
"previous definition here",
|
||||
.{},
|
||||
),
|
||||
});
|
||||
}
|
||||
find_scope: switch (parent_scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| {
|
||||
if (gen_zir.label) |prev_label| {
|
||||
if (try astgen.tokenIdentEql(label, prev_label.token)) {
|
||||
const label_name = try astgen.identifierTokenString(label);
|
||||
return astgen.failTokNotes(label, "redefinition of label '{s}'", .{
|
||||
label_name,
|
||||
}, &[_]u32{
|
||||
try astgen.errNoteTok(
|
||||
prev_label.token,
|
||||
"previous definition here",
|
||||
.{},
|
||||
),
|
||||
});
|
||||
}
|
||||
scope = gen_zir.parent;
|
||||
},
|
||||
.local_val => scope = scope.cast(Scope.LocalVal).?.parent,
|
||||
.local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
|
||||
.defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
|
||||
.namespace => break,
|
||||
.top => unreachable,
|
||||
}
|
||||
}
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
},
|
||||
.local_val => |local_val| continue :find_scope local_val.parent.unwrap(),
|
||||
.local_ptr => |local_ptr| continue :find_scope local_ptr.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.namespace => break :find_scope,
|
||||
.top => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3007,18 +2978,16 @@ fn countDefers(outer_scope: *Scope, inner_scope: *Scope) struct {
|
|||
var need_err_code = false;
|
||||
var scope = inner_scope;
|
||||
while (scope != outer_scope) {
|
||||
switch (scope.tag) {
|
||||
.gen_zir => scope = scope.cast(GenZir).?.parent,
|
||||
.local_val => scope = scope.cast(Scope.LocalVal).?.parent,
|
||||
.local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
|
||||
.defer_normal => {
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
switch (scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| scope = gen_zir.parent,
|
||||
.local_val => |local_val| scope = local_val.parent,
|
||||
.local_ptr => |local_ptr| scope = local_ptr.parent,
|
||||
.defer_normal => |defer_scope| {
|
||||
scope = defer_scope.parent;
|
||||
|
||||
have_normal = true;
|
||||
},
|
||||
.defer_error => {
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
.defer_error => |defer_scope| {
|
||||
scope = defer_scope.parent;
|
||||
|
||||
have_err = true;
|
||||
|
|
@ -3054,17 +3023,15 @@ fn genDefers(
|
|||
|
||||
var scope = inner_scope;
|
||||
while (scope != outer_scope) {
|
||||
switch (scope.tag) {
|
||||
.gen_zir => scope = scope.cast(GenZir).?.parent,
|
||||
.local_val => scope = scope.cast(Scope.LocalVal).?.parent,
|
||||
.local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
|
||||
.defer_normal => {
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
switch (scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| scope = gen_zir.parent,
|
||||
.local_val => |local_val| scope = local_val.parent,
|
||||
.local_ptr => |local_ptr| scope = local_ptr.parent,
|
||||
.defer_normal => |defer_scope| {
|
||||
scope = defer_scope.parent;
|
||||
try gz.addDefer(defer_scope.index, defer_scope.len);
|
||||
},
|
||||
.defer_error => {
|
||||
const defer_scope = scope.cast(Scope.Defer).?;
|
||||
.defer_error => |defer_scope| {
|
||||
scope = defer_scope.parent;
|
||||
switch (which_ones) {
|
||||
.both_sans_err => {
|
||||
|
|
@ -3107,10 +3074,9 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v
|
|||
|
||||
var scope = inner_scope;
|
||||
while (scope != outer_scope) {
|
||||
switch (scope.tag) {
|
||||
.gen_zir => scope = scope.cast(GenZir).?.parent,
|
||||
.local_val => {
|
||||
const s = scope.cast(Scope.LocalVal).?;
|
||||
switch (scope.unwrap()) {
|
||||
.gen_zir => |gen_zir| scope = gen_zir.parent,
|
||||
.local_val => |s| {
|
||||
if (s.used == .none and s.discarded == .none) {
|
||||
try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
|
||||
} else if (s.used != .none and s.discarded != .none) {
|
||||
|
|
@ -3120,8 +3086,7 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v
|
|||
}
|
||||
scope = s.parent;
|
||||
},
|
||||
.local_ptr => {
|
||||
const s = scope.cast(Scope.LocalPtr).?;
|
||||
.local_ptr => |s| {
|
||||
if (s.used == .none and s.discarded == .none) {
|
||||
try astgen.appendErrorTok(s.token_src, "unused {s}", .{@tagName(s.id_cat)});
|
||||
} else {
|
||||
|
|
@ -3136,10 +3101,9 @@ fn checkUsed(gz: *GenZir, outer_scope: *Scope, inner_scope: *Scope) InnerError!v
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
scope = s.parent;
|
||||
},
|
||||
.defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
|
||||
.defer_normal, .defer_error => |defer_scope| scope = defer_scope.parent,
|
||||
.namespace => unreachable,
|
||||
.top => unreachable,
|
||||
}
|
||||
|
|
@ -4805,13 +4769,11 @@ fn testDecl(
|
|||
|
||||
// Local variables, including function parameters.
|
||||
const name_str_index = try astgen.identAsString(test_name_token);
|
||||
var s = scope;
|
||||
var found_already: ?Ast.Node.Index = null; // we have found a decl with the same name already
|
||||
var num_namespaces_out: u32 = 0;
|
||||
var capturing_namespace: ?*Scope.Namespace = null;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
find_scope: switch (scope.unwrap()) {
|
||||
.local_val => |local_val| {
|
||||
if (local_val.name == name_str_index) {
|
||||
local_val.used = .fromToken(test_name_token);
|
||||
return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
|
||||
|
|
@ -4822,10 +4784,9 @@ fn testDecl(
|
|||
}),
|
||||
});
|
||||
}
|
||||
s = local_val.parent;
|
||||
continue :find_scope local_val.parent.unwrap();
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
.local_ptr => |local_ptr| {
|
||||
if (local_ptr.name == name_str_index) {
|
||||
local_ptr.used = .fromToken(test_name_token);
|
||||
return astgen.failTokNotes(test_name_token, "cannot test a {s}", .{
|
||||
|
|
@ -4836,12 +4797,11 @@ fn testDecl(
|
|||
}),
|
||||
});
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
continue :find_scope local_ptr.parent.unwrap();
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.namespace => {
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
.gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.namespace => |ns| {
|
||||
if (ns.decls.get(name_str_index)) |i| {
|
||||
if (found_already) |f| {
|
||||
return astgen.failTokNotes(test_name_token, "ambiguous reference", .{}, &.{
|
||||
|
|
@ -4854,10 +4814,10 @@ fn testDecl(
|
|||
}
|
||||
num_namespaces_out += 1;
|
||||
capturing_namespace = ns;
|
||||
s = ns.parent;
|
||||
continue :find_scope ns.parent.unwrap();
|
||||
},
|
||||
.top => break,
|
||||
};
|
||||
.top => break :find_scope,
|
||||
}
|
||||
if (found_already == null) {
|
||||
const ident_name = try astgen.identifierTokenString(test_name_token);
|
||||
return astgen.failTok(test_name_token, "use of undeclared identifier '{s}'", .{ident_name});
|
||||
|
|
@ -8409,7 +8369,6 @@ fn localVarRef(
|
|||
) InnerError!Zir.Inst.Ref {
|
||||
const astgen = gz.astgen;
|
||||
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 found_needs_tunnel: bool = undefined; // defined when `found_already != null`
|
||||
var found_namespaces_out: u32 = undefined; // defined when `found_already != null`
|
||||
|
|
@ -8419,10 +8378,8 @@ fn localVarRef(
|
|||
// defined by `num_namespaces_out != 0`
|
||||
var capturing_namespace: *Scope.Namespace = undefined;
|
||||
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
|
||||
find_scope: switch (scope.unwrap()) {
|
||||
.local_val => |local_val| {
|
||||
if (local_val.name == name_str_index) {
|
||||
// Locals cannot shadow anything, so we do not need to look for ambiguous
|
||||
// references in this case.
|
||||
|
|
@ -8445,10 +8402,9 @@ fn localVarRef(
|
|||
|
||||
return rvalueNoCoercePreRef(gz, ri, value_inst, ident);
|
||||
}
|
||||
s = local_val.parent;
|
||||
continue :find_scope local_val.parent.unwrap();
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
.local_ptr => |local_ptr| {
|
||||
if (local_ptr.name == name_str_index) {
|
||||
if (ri.rl == .discard and ri.ctx == .assignment) {
|
||||
local_ptr.discarded = .fromToken(ident_token);
|
||||
|
|
@ -8497,12 +8453,11 @@ fn localVarRef(
|
|||
},
|
||||
}
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
continue :find_scope local_ptr.parent.unwrap();
|
||||
},
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.namespace => {
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
.gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.namespace => |ns| {
|
||||
if (ns.decls.get(name_str_index)) |i| {
|
||||
if (found_already) |f| {
|
||||
return astgen.failNodeNotes(ident, "ambiguous reference", .{}, &.{
|
||||
|
|
@ -8517,10 +8472,10 @@ fn localVarRef(
|
|||
}
|
||||
num_namespaces_out += 1;
|
||||
capturing_namespace = ns;
|
||||
s = ns.parent;
|
||||
continue :find_scope ns.parent.unwrap();
|
||||
},
|
||||
.top => break,
|
||||
};
|
||||
.top => break :find_scope,
|
||||
}
|
||||
if (found_already == null) {
|
||||
const ident_name = try astgen.identifierTokenString(ident_token);
|
||||
return astgen.failNode(ident, "use of undeclared identifier '{s}'", .{ident_name});
|
||||
|
|
@ -11812,6 +11767,26 @@ const Scope = struct {
|
|||
};
|
||||
}
|
||||
|
||||
fn unwrap(base: *Scope) Unwrapped {
|
||||
return switch (base.tag) {
|
||||
inline else => |tag| @unionInit(
|
||||
Unwrapped,
|
||||
@tagName(tag),
|
||||
@alignCast(@fieldParentPtr("base", base)),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const Unwrapped = union(Tag) {
|
||||
gen_zir: *GenZir,
|
||||
local_val: *LocalVal,
|
||||
local_ptr: *LocalPtr,
|
||||
defer_normal: *Defer,
|
||||
defer_error: *Defer,
|
||||
namespace: *Namespace,
|
||||
top: *Top,
|
||||
};
|
||||
|
||||
const Tag = enum {
|
||||
gen_zir,
|
||||
local_val,
|
||||
|
|
@ -13408,11 +13383,9 @@ fn detectLocalShadowing(
|
|||
});
|
||||
}
|
||||
|
||||
var s = scope;
|
||||
var outer_scope = false;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
find_scope: switch (scope.unwrap()) {
|
||||
.local_val => |local_val| {
|
||||
if (local_val.name == ident_name) {
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
|
|
@ -13438,10 +13411,9 @@ fn detectLocalShadowing(
|
|||
),
|
||||
});
|
||||
}
|
||||
s = local_val.parent;
|
||||
continue :find_scope local_val.parent.unwrap();
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
.local_ptr => |local_ptr| {
|
||||
if (local_ptr.name == ident_name) {
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
|
|
@ -13467,14 +13439,12 @@ fn detectLocalShadowing(
|
|||
),
|
||||
});
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
continue :find_scope local_ptr.parent.unwrap();
|
||||
},
|
||||
.namespace => {
|
||||
.namespace => |ns| {
|
||||
outer_scope = true;
|
||||
const ns = s.cast(Scope.Namespace).?;
|
||||
const decl_node = ns.decls.get(ident_name) orelse {
|
||||
s = ns.parent;
|
||||
continue;
|
||||
continue :find_scope ns.parent.unwrap();
|
||||
};
|
||||
const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
|
||||
const name = try gpa.dupe(u8, name_slice);
|
||||
|
|
@ -13485,13 +13455,13 @@ fn detectLocalShadowing(
|
|||
try astgen.errNoteNode(decl_node, "declared here", .{}),
|
||||
});
|
||||
},
|
||||
.gen_zir => {
|
||||
s = s.cast(GenZir).?.parent;
|
||||
.gen_zir => |gen_zir| {
|
||||
outer_scope = true;
|
||||
continue :find_scope gen_zir.parent.unwrap();
|
||||
},
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.top => break,
|
||||
};
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.top => break :find_scope,
|
||||
}
|
||||
}
|
||||
|
||||
const LineColumn = struct { u32, u32 };
|
||||
|
|
@ -13728,10 +13698,8 @@ fn scanContainer(
|
|||
continue;
|
||||
}
|
||||
|
||||
var s = namespace.parent;
|
||||
while (true) switch (s.tag) {
|
||||
.local_val => {
|
||||
const local_val = s.cast(Scope.LocalVal).?;
|
||||
find_scope: switch (namespace.parent.unwrap()) {
|
||||
.local_val => |local_val| {
|
||||
if (local_val.name == name_str_index) {
|
||||
try astgen.appendErrorTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{
|
||||
token_bytes, @tagName(local_val.id_cat),
|
||||
|
|
@ -13743,12 +13711,11 @@ fn scanContainer(
|
|||
),
|
||||
});
|
||||
any_invalid_declarations = true;
|
||||
break;
|
||||
break :find_scope;
|
||||
}
|
||||
s = local_val.parent;
|
||||
continue :find_scope local_val.parent.unwrap();
|
||||
},
|
||||
.local_ptr => {
|
||||
const local_ptr = s.cast(Scope.LocalPtr).?;
|
||||
.local_ptr => |local_ptr| {
|
||||
if (local_ptr.name == name_str_index) {
|
||||
try astgen.appendErrorTokNotes(name_token, "declaration '{s}' shadows {s} from outer scope", .{
|
||||
token_bytes, @tagName(local_ptr.id_cat),
|
||||
|
|
@ -13760,15 +13727,15 @@ fn scanContainer(
|
|||
),
|
||||
});
|
||||
any_invalid_declarations = true;
|
||||
break;
|
||||
break :find_scope;
|
||||
}
|
||||
s = local_ptr.parent;
|
||||
continue :find_scope local_ptr.parent.unwrap();
|
||||
},
|
||||
.namespace => s = s.cast(Scope.Namespace).?.parent,
|
||||
.gen_zir => s = s.cast(GenZir).?.parent,
|
||||
.defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
|
||||
.top => break,
|
||||
};
|
||||
.namespace => |ns| continue :find_scope ns.parent.unwrap(),
|
||||
.gen_zir => |gen_zir| continue :find_scope gen_zir.parent.unwrap(),
|
||||
.defer_normal, .defer_error => |defer_scope| continue :find_scope defer_scope.parent.unwrap(),
|
||||
.top => break :find_scope,
|
||||
}
|
||||
}
|
||||
|
||||
if (!any_duplicates) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue