aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-08-28 10:17:47 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-08-28 13:28:34 -0400
commit6a6e2cd64f3ebb1919dd0ac53d8a1f29c56e6ec2 (patch)
tree9d698bc9013ee12ba43c83483d2cac4b63b26d7a /src
parentf30aa25cbf9c9a415963b4ea69d7efa09237a704 (diff)
downloadzig-6a6e2cd64f3ebb1919dd0ac53d8a1f29c56e6ec2.tar.gz
zig-6a6e2cd64f3ebb1919dd0ac53d8a1f29c56e6ec2.zip
AstGen: allow locals with same name as primitives with `@""` syntax
This makes local names follow the same rule as declaration names.
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig57
1 files changed, 35 insertions, 22 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 2b8e6a76a8..a425540a38 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -2385,7 +2385,7 @@ fn varDecl(
}
const ident_name = try astgen.identAsString(name_token);
- try astgen.detectLocalShadowing(scope, ident_name, name_token);
+ try astgen.detectLocalShadowing(scope, ident_name, name_token, ident_name_raw);
if (var_decl.ast.init_node == 0) {
return astgen.failNode(node, "variables must be initialized", .{});
@@ -2952,12 +2952,13 @@ fn fnDecl(
} else false;
const param_name: u32 = if (param.name_token) |name_token| blk: {
- if (mem.eql(u8, "_", tree.tokenSlice(name_token)))
+ const name_bytes = tree.tokenSlice(name_token);
+ if (mem.eql(u8, "_", name_bytes))
break :blk 0;
const param_name = try astgen.identAsString(name_token);
if (!is_extern) {
- try astgen.detectLocalShadowing(params_scope, param_name, name_token);
+ try astgen.detectLocalShadowing(params_scope, param_name, name_token, name_bytes);
}
break :blk param_name;
} else if (!is_extern) {
@@ -5035,7 +5036,7 @@ fn ifExpr(
const token_name_str = tree.tokenSlice(token_name_index);
if (mem.eql(u8, "_", token_name_str))
break :s &then_scope.base;
- try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index);
+ try astgen.detectLocalShadowing(&then_scope.base, ident_name, token_name_index, token_name_str);
payload_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -5054,11 +5055,12 @@ fn ifExpr(
.optional_payload_unsafe_ptr
else
.optional_payload_unsafe;
- if (mem.eql(u8, "_", tree.tokenSlice(ident_token)))
+ const ident_bytes = tree.tokenSlice(ident_token);
+ if (mem.eql(u8, "_", ident_bytes))
break :s &then_scope.base;
const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
const ident_name = try astgen.identAsString(ident_token);
- try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token);
+ try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);
payload_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -5100,7 +5102,7 @@ fn ifExpr(
const error_token_str = tree.tokenSlice(error_token);
if (mem.eql(u8, "_", error_token_str))
break :s &else_scope.base;
- try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token);
+ try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, error_token_str);
payload_val_scope = .{
.parent = &else_scope.base,
.gen_zir = &else_scope,
@@ -5291,11 +5293,12 @@ fn whileExpr(
.err_union_payload_unsafe;
const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
const ident_token = if (payload_is_ref) payload_token + 1 else payload_token;
- if (mem.eql(u8, "_", tree.tokenSlice(ident_token)))
+ const ident_bytes = tree.tokenSlice(ident_token);
+ if (mem.eql(u8, "_", ident_bytes))
break :s &then_scope.base;
const payload_name_loc = payload_token + @boolToInt(payload_is_ref);
const ident_name = try astgen.identAsString(payload_name_loc);
- try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc);
+ try astgen.detectLocalShadowing(&then_scope.base, ident_name, payload_name_loc, ident_bytes);
payload_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -5316,9 +5319,10 @@ fn whileExpr(
.optional_payload_unsafe;
const payload_inst = try then_scope.addUnNode(tag, cond.inst, node);
const ident_name = try astgen.identAsString(ident_token);
- if (mem.eql(u8, "_", tree.tokenSlice(ident_token)))
+ const ident_bytes = tree.tokenSlice(ident_token);
+ if (mem.eql(u8, "_", ident_bytes))
break :s &then_scope.base;
- try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token);
+ try astgen.detectLocalShadowing(&then_scope.base, ident_name, ident_token, ident_bytes);
payload_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -5374,9 +5378,10 @@ fn whileExpr(
.err_union_code;
const payload_inst = try else_scope.addUnNode(tag, cond.inst, node);
const ident_name = try astgen.identAsString(error_token);
- if (mem.eql(u8, tree.tokenSlice(error_token), "_"))
+ const ident_bytes = tree.tokenSlice(error_token);
+ if (mem.eql(u8, ident_bytes, "_"))
break :s &else_scope.base;
- try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token);
+ try astgen.detectLocalShadowing(&else_scope.base, ident_name, error_token, ident_bytes);
payload_val_scope = .{
.parent = &else_scope.base,
.gen_zir = &else_scope,
@@ -5523,7 +5528,7 @@ fn forExpr(
const name_str_index = try astgen.identAsString(ident);
const tag: Zir.Inst.Tag = if (is_ptr) .elem_ptr else .elem_val;
const payload_inst = try then_scope.addBin(tag, array_ptr, index);
- try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident);
+ try astgen.detectLocalShadowing(&then_scope.base, name_str_index, ident, value_name);
payload_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -5543,11 +5548,12 @@ fn forExpr(
ident + 2
else
break :blk payload_sub_scope;
- if (mem.eql(u8, tree.tokenSlice(index_token), "_")) {
+ const token_bytes = tree.tokenSlice(index_token);
+ if (mem.eql(u8, token_bytes, "_")) {
return astgen.failTok(index_token, "discard of index capture; omit it instead", .{});
}
const index_name = try astgen.identAsString(index_token);
- try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token);
+ try astgen.detectLocalShadowing(payload_sub_scope, index_name, index_token, token_bytes);
index_scope = .{
.parent = payload_sub_scope,
.gen_zir = &then_scope,
@@ -10059,7 +10065,7 @@ fn declareNewName(
const ns = scope.cast(Scope.Namespace).?;
const gop = try ns.decls.getOrPut(gpa, name_index);
if (gop.found_existing) {
- const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(name_index)));
+ const name = try gpa.dupe(u8, mem.span(astgen.nullTerminatedString(name_index)));
defer gpa.free(name);
return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{
name,
@@ -10094,13 +10100,17 @@ fn detectLocalShadowing(
scope: *Scope,
ident_name: u32,
name_token: ast.TokenIndex,
+ token_bytes: []const u8,
) !void {
const gpa = astgen.gpa;
- const name_slice = mem.spanZ(astgen.nullTerminatedString(ident_name));
- if (isPrimitive(name_slice)) {
- const name = try gpa.dupe(u8, name_slice);
- defer gpa.free(name);
- return astgen.failTok(name_token, "local shadows primitive '{s}'", .{name});
+ if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
+ return astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
+ token_bytes,
+ }, &[_]u32{
+ try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
+ token_bytes,
+ }),
+ });
}
var s = scope;
@@ -10108,6 +10118,7 @@ fn detectLocalShadowing(
.local_val => {
const local_val = s.cast(Scope.LocalVal).?;
if (local_val.name == ident_name) {
+ const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
const name = try gpa.dupe(u8, name_slice);
defer gpa.free(name);
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
@@ -10125,6 +10136,7 @@ fn detectLocalShadowing(
.local_ptr => {
const local_ptr = s.cast(Scope.LocalPtr).?;
if (local_ptr.name == ident_name) {
+ const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
const name = try gpa.dupe(u8, name_slice);
defer gpa.free(name);
return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
@@ -10145,6 +10157,7 @@ fn detectLocalShadowing(
s = ns.parent;
continue;
};
+ const name_slice = mem.span(astgen.nullTerminatedString(ident_name));
const name = try gpa.dupe(u8, name_slice);
defer gpa.free(name);
return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{