diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-08-28 10:17:47 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-08-28 13:28:34 -0400 |
| commit | 6a6e2cd64f3ebb1919dd0ac53d8a1f29c56e6ec2 (patch) | |
| tree | 9d698bc9013ee12ba43c83483d2cac4b63b26d7a /src | |
| parent | f30aa25cbf9c9a415963b4ea69d7efa09237a704 (diff) | |
| download | zig-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.zig | 57 |
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}'", .{ |
