authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-27 21:34:13-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-27 21:34:13-07:00
logf30aa25cbf9c9a415963b4ea69d7efa09237a704
treef0150470b35bb7b55450c54dbb4553e3cc11b29f
parentcfae70ec8e736af3fcd465c78bd80e160968eea8

declarations may collide with primitives with @"" syntax

* stage2 AstGen: add missing compile error for declaring a local that shadows a primitive. Even with `@""` syntax, it may not have the same name as a primitive. * stage2 AstGen: add a compile error for a global declaration whose name matches a primitive. However it is allowed when using `@""` syntax. * stage1: delete all "declaration shadows primitive" compile errors because they are now handled by stage2 AstGen. * stage1/stage2 AstGen: notice when using `@""` syntax and: - treat `_` as a regular identifier - skip checking if an identifire is a primitive Check the new test cases for clarifications on semantics. closes #6062

8 files changed, 157 insertions(+), 86 deletions(-)

src/AstGen.zig+67-33
...@@ -2891,7 +2891,7 @@ fn fnDecl(...@@ -2891,7 +2891,7 @@ fn fnDecl(
2891 };2891 };
2892 const fn_name_str_index = try astgen.identAsString(fn_name_token);2892 const fn_name_str_index = try astgen.identAsString(fn_name_token);
28932893
2894 try astgen.declareNewName(scope, fn_name_str_index, decl_node);2894 try astgen.declareNewName(scope, fn_name_str_index, decl_node, fn_name_token);
28952895
2896 // We insert this at the beginning so that its instruction index marks the2896 // We insert this at the beginning so that its instruction index marks the
2897 // start of the top level declaration.2897 // start of the top level declaration.
...@@ -3160,7 +3160,7 @@ fn globalVarDecl(...@@ -3160,7 +3160,7 @@ fn globalVarDecl(
3160 const name_token = var_decl.ast.mut_token + 1;3160 const name_token = var_decl.ast.mut_token + 1;
3161 const name_str_index = try astgen.identAsString(name_token);3161 const name_str_index = try astgen.identAsString(name_token);
31623162
3163 try astgen.declareNewName(scope, name_str_index, node);3163 try astgen.declareNewName(scope, name_str_index, node, name_token);
31643164
3165 var block_scope: GenZir = .{3165 var block_scope: GenZir = .{
3166 .parent = scope,3166 .parent = scope,
...@@ -6319,34 +6319,36 @@ fn identifier(...@@ -6319,34 +6319,36 @@ fn identifier(
6319 }6319 }
6320 const ident_name = try astgen.identifierTokenString(ident_token);6320 const ident_name = try astgen.identifierTokenString(ident_token);
63216321
6322 if (simple_types.get(ident_name)) |zir_const_ref| {6322 if (ident_name_raw[0] != '@') {
6323 return rvalue(gz, rl, zir_const_ref, ident);6323 if (simple_types.get(ident_name)) |zir_const_ref| {
6324 }6324 return rvalue(gz, rl, zir_const_ref, ident);
6325 }
63256326
6326 if (ident_name.len >= 2) integer: {6327 if (ident_name.len >= 2) integer: {
6327 const first_c = ident_name[0];6328 const first_c = ident_name[0];
6328 if (first_c == 'i' or first_c == 'u') {6329 if (first_c == 'i' or first_c == 'u') {
6329 const signedness: std.builtin.Signedness = switch (first_c == 'i') {6330 const signedness: std.builtin.Signedness = switch (first_c == 'i') {
6330 true => .signed,6331 true => .signed,
6331 false => .unsigned,6332 false => .unsigned,
6332 };6333 };
6333 const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {6334 const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) {
6334 error.Overflow => return astgen.failNode(6335 error.Overflow => return astgen.failNode(
6335 ident,6336 ident,
6336 "primitive integer type '{s}' exceeds maximum bit width of 65535",6337 "primitive integer type '{s}' exceeds maximum bit width of 65535",
6337 .{ident_name},6338 .{ident_name},
6338 ),6339 ),
6339 error.InvalidCharacter => break :integer,6340 error.InvalidCharacter => break :integer,
6340 };6341 };
6341 const result = try gz.add(.{6342 const result = try gz.add(.{
6342 .tag = .int_type,6343 .tag = .int_type,
6343 .data = .{ .int_type = .{6344 .data = .{ .int_type = .{
6344 .src_node = gz.nodeIndexToRelative(ident),6345 .src_node = gz.nodeIndexToRelative(ident),
6345 .signedness = signedness,6346 .signedness = signedness,
6346 .bit_count = bit_count,6347 .bit_count = bit_count,
6347 } },6348 } },
6348 });6349 });
6349 return rvalue(gz, rl, result, ident);6350 return rvalue(gz, rl, result, ident);
6351 }
6350 }6352 }
6351 }6353 }
63526354
...@@ -10031,8 +10033,21 @@ fn declareNewName(...@@ -10031,8 +10033,21 @@ fn declareNewName(
10031 start_scope: *Scope,10033 start_scope: *Scope,
10032 name_index: u32,10034 name_index: u32,
10033 node: ast.Node.Index,10035 node: ast.Node.Index,
10036 name_token: ast.TokenIndex,
10034) !void {10037) !void {
10035 const gpa = astgen.gpa;10038 const gpa = astgen.gpa;
10039
10040 const token_bytes = astgen.tree.tokenSlice(name_token);
10041 if (token_bytes[0] != '@' and isPrimitive(token_bytes)) {
10042 return astgen.failTokNotes(name_token, "name shadows primitive '{s}'", .{
10043 token_bytes,
10044 }, &[_]u32{
10045 try astgen.errNoteTok(name_token, "consider using @\"{s}\" to disambiguate", .{
10046 token_bytes,
10047 }),
10048 });
10049 }
10050
10036 var scope = start_scope;10051 var scope = start_scope;
10037 while (true) {10052 while (true) {
10038 switch (scope.tag) {10053 switch (scope.tag) {
...@@ -10060,7 +10075,20 @@ fn declareNewName(...@@ -10060,7 +10075,20 @@ fn declareNewName(
10060 }10075 }
10061}10076}
1006210077
10063/// Local variables shadowing detection, including function parameters.10078fn isPrimitive(name: []const u8) bool {
10079 if (simple_types.get(name) != null) return true;
10080 if (name.len < 2) return false;
10081 const first_c = name[0];
10082 if (first_c != 'i' and first_c != 'u') return false;
10083 if (std.fmt.parseInt(u16, name[1..], 10)) |_| {
10084 return true;
10085 } else |err| switch (err) {
10086 error.Overflow => return true,
10087 error.InvalidCharacter => return false,
10088 }
10089}
10090
10091/// Local variables shadowing detection, including function parameters and primitives.
10064fn detectLocalShadowing(10092fn detectLocalShadowing(
10065 astgen: *AstGen,10093 astgen: *AstGen,
10066 scope: *Scope,10094 scope: *Scope,
...@@ -10068,13 +10096,19 @@ fn detectLocalShadowing(...@@ -10068,13 +10096,19 @@ fn detectLocalShadowing(
10068 name_token: ast.TokenIndex,10096 name_token: ast.TokenIndex,
10069) !void {10097) !void {
10070 const gpa = astgen.gpa;10098 const gpa = astgen.gpa;
10099 const name_slice = mem.spanZ(astgen.nullTerminatedString(ident_name));
10100 if (isPrimitive(name_slice)) {
10101 const name = try gpa.dupe(u8, name_slice);
10102 defer gpa.free(name);
10103 return astgen.failTok(name_token, "local shadows primitive '{s}'", .{name});
10104 }
1007110105
10072 var s = scope;10106 var s = scope;
10073 while (true) switch (s.tag) {10107 while (true) switch (s.tag) {
10074 .local_val => {10108 .local_val => {
10075 const local_val = s.cast(Scope.LocalVal).?;10109 const local_val = s.cast(Scope.LocalVal).?;
10076 if (local_val.name == ident_name) {10110 if (local_val.name == ident_name) {
10077 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));10111 const name = try gpa.dupe(u8, name_slice);
10078 defer gpa.free(name);10112 defer gpa.free(name);
10079 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{10113 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
10080 @tagName(local_val.id_cat), name,10114 @tagName(local_val.id_cat), name,
...@@ -10091,7 +10125,7 @@ fn detectLocalShadowing(...@@ -10091,7 +10125,7 @@ fn detectLocalShadowing(
10091 .local_ptr => {10125 .local_ptr => {
10092 const local_ptr = s.cast(Scope.LocalPtr).?;10126 const local_ptr = s.cast(Scope.LocalPtr).?;
10093 if (local_ptr.name == ident_name) {10127 if (local_ptr.name == ident_name) {
10094 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));10128 const name = try gpa.dupe(u8, name_slice);
10095 defer gpa.free(name);10129 defer gpa.free(name);
10096 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{10130 return astgen.failTokNotes(name_token, "redeclaration of {s} '{s}'", .{
10097 @tagName(local_ptr.id_cat), name,10131 @tagName(local_ptr.id_cat), name,
...@@ -10111,7 +10145,7 @@ fn detectLocalShadowing(...@@ -10111,7 +10145,7 @@ fn detectLocalShadowing(
10111 s = ns.parent;10145 s = ns.parent;
10112 continue;10146 continue;
10113 };10147 };
10114 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));10148 const name = try gpa.dupe(u8, name_slice);
10115 defer gpa.free(name);10149 defer gpa.free(name);
10116 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{10150 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
10117 name,10151 name,
src/stage1/all_types.hpp+1
...@@ -1125,6 +1125,7 @@ struct AstNodeContainerInitExpr {...@@ -1125,6 +1125,7 @@ struct AstNodeContainerInitExpr {
11251125
1126struct AstNodeIdentifier {1126struct AstNodeIdentifier {
1127 Buf *name;1127 Buf *name;
1128 bool is_at_syntax;
1128};1129};
11291130
1130struct AstNodeEnumLiteral {1131struct AstNodeEnumLiteral {
src/stage1/analyze.cpp-13
...@@ -3918,12 +3918,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {...@@ -3918,12 +3918,6 @@ static void add_top_level_decl(CodeGen *g, ScopeDecls *decls_scope, Tld *tld) {
3918 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition here"));3918 add_error_note(g, msg, other_tld->source_node, buf_sprintf("previous definition here"));
3919 return;3919 return;
3920 }3920 }
3921
3922 ZigType *type;
3923 if (get_primitive_type(g, tld->name, &type) != ErrorPrimitiveTypeNotFound) {
3924 add_node_error(g, tld->source_node,
3925 buf_sprintf("declaration shadows primitive type '%s'", buf_ptr(tld->name)));
3926 }
3927 }3921 }
3928}3922}
39293923
...@@ -4170,13 +4164,6 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf...@@ -4170,13 +4164,6 @@ ZigVar *add_variable(CodeGen *g, AstNode *source_node, Scope *parent_scope, Buf
4170 variable_entry->var_type = g->builtin_types.entry_invalid;4164 variable_entry->var_type = g->builtin_types.entry_invalid;
4171 } else {4165 } else {
4172 variable_entry->align_bytes = get_abi_alignment(g, var_type);4166 variable_entry->align_bytes = get_abi_alignment(g, var_type);
4173
4174 ZigType *type;
4175 if (get_primitive_type(g, name, &type) != ErrorPrimitiveTypeNotFound) {
4176 add_node_error(g, source_node,
4177 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
4178 variable_entry->var_type = g->builtin_types.entry_invalid;
4179 }
4180 }4167 }
41814168
4182 Scope *child_scope;4169 Scope *child_scope;
src/stage1/astgen.cpp+29-33
...@@ -3194,13 +3194,6 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,...@@ -3194,13 +3194,6 @@ ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
3194 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));3194 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));
3195 }3195 }
3196 variable_entry->var_type = codegen->builtin_types.entry_invalid;3196 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3197 } else {
3198 ZigType *type;
3199 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) {
3200 add_node_error(codegen, node,
3201 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name)));
3202 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3203 }
3204 }3197 }
3205 }3198 }
3206 } else {3199 } else {
...@@ -3815,35 +3808,38 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode...@@ -3815,35 +3808,38 @@ static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode
3815 Error err;3808 Error err;
3816 assert(node->type == NodeTypeIdentifier);3809 assert(node->type == NodeTypeIdentifier);
38173810
3818 Buf *variable_name = node_identifier_buf(node);3811 bool is_at_syntax;
38193812 Buf *variable_name = node_identifier_buf2(node, &is_at_syntax);
3820 if (buf_eql_str(variable_name, "_")) {3813
3821 if (lval == LValAssign) {3814 if (!is_at_syntax) {
3822 Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, node);3815 if (buf_eql_str(variable_name, "_")) {
3823 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();3816 if (lval == LValAssign) {
3824 const_instruction->value->type = get_pointer_to_type(ag->codegen,3817 Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, node);
3825 ag->codegen->builtin_types.entry_void, false);3818 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
3826 const_instruction->value->special = ConstValSpecialStatic;3819 const_instruction->value->type = get_pointer_to_type(ag->codegen,
3827 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard;3820 ag->codegen->builtin_types.entry_void, false);
3828 return &const_instruction->base;3821 const_instruction->value->special = ConstValSpecialStatic;
3822 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard;
3823 return &const_instruction->base;
3824 }
3829 }3825 }
3830 }
38313826
3832 ZigType *primitive_type;3827 ZigType *primitive_type;
3833 if ((err = get_primitive_type(ag->codegen, variable_name, &primitive_type))) {3828 if ((err = get_primitive_type(ag->codegen, variable_name, &primitive_type))) {
3834 if (err == ErrorOverflow) {3829 if (err == ErrorOverflow) {
3835 add_node_error(ag->codegen, node,3830 add_node_error(ag->codegen, node,
3836 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535",3831 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535",
3837 buf_ptr(variable_name)));3832 buf_ptr(variable_name)));
3838 return ag->codegen->invalid_inst_src;3833 return ag->codegen->invalid_inst_src;
3839 }3834 }
3840 assert(err == ErrorPrimitiveTypeNotFound);3835 assert(err == ErrorPrimitiveTypeNotFound);
3841 } else {
3842 Stage1ZirInst *value = ir_build_const_type(ag, scope, node, primitive_type);
3843 if (lval == LValPtr || lval == LValAssign) {
3844 return ir_build_ref_src(ag, scope, node, value);
3845 } else {3836 } else {
3846 return ir_expr_wrap(ag, scope, value, result_loc);3837 Stage1ZirInst *value = ir_build_const_type(ag, scope, node, primitive_type);
3838 if (lval == LValPtr || lval == LValAssign) {
3839 return ir_build_ref_src(ag, scope, node, value);
3840 } else {
3841 return ir_expr_wrap(ag, scope, value, result_loc);
3842 }
3847 }3843 }
3848 }3844 }
38493845
src/stage1/parser.cpp+16-3
...@@ -3482,8 +3482,7 @@ Error source_char_literal(const char *source, uint32_t *result, size_t *bad_inde...@@ -3482,8 +3482,7 @@ Error source_char_literal(const char *source, uint32_t *result, size_t *bad_inde
3482 }3482 }
3483}3483}
34843484
34853485static Buf *token_identifier_buf2(RootStruct *root_struct, TokenIndex token, bool *is_at_syntax) {
3486Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3487 Error err;3486 Error err;
3488 const char *source = buf_ptr(root_struct->source_code);3487 const char *source = buf_ptr(root_struct->source_code);
3489 size_t byte_offset = root_struct->token_locs[token].offset;3488 size_t byte_offset = root_struct->token_locs[token].offset;
...@@ -3495,6 +3494,7 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {...@@ -3495,6 +3494,7 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3495 assert(source[byte_offset] != '.'); // wrong token index3494 assert(source[byte_offset] != '.'); // wrong token index
34963495
3497 if (source[byte_offset] == '@') {3496 if (source[byte_offset] == '@') {
3497 *is_at_syntax = true;
3498 size_t bad_index;3498 size_t bad_index;
3499 Buf *str = buf_alloc();3499 Buf *str = buf_alloc();
3500 if ((err = source_string_literal_buf(source + byte_offset + 1, str, &bad_index))) {3500 if ((err = source_string_literal_buf(source + byte_offset + 1, str, &bad_index))) {
...@@ -3503,6 +3503,7 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {...@@ -3503,6 +3503,7 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3503 }3503 }
3504 return str;3504 return str;
3505 } else {3505 } else {
3506 *is_at_syntax = false;
3506 size_t start = byte_offset;3507 size_t start = byte_offset;
3507 for (;; byte_offset += 1) {3508 for (;; byte_offset += 1) {
3508 if (source[byte_offset] == 0) break;3509 if (source[byte_offset] == 0) break;
...@@ -3519,7 +3520,17 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {...@@ -3519,7 +3520,17 @@ Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3519 }3520 }
3520}3521}
35213522
3523Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token) {
3524 bool trash;
3525 return token_identifier_buf2(root_struct, token, &trash);
3526}
3527
3522Buf *node_identifier_buf(AstNode *node) {3528Buf *node_identifier_buf(AstNode *node) {
3529 bool trash;
3530 return node_identifier_buf2(node, &trash);
3531}
3532
3533Buf *node_identifier_buf2(AstNode *node, bool *is_at_syntax) {
3523 assert(node->type == NodeTypeIdentifier);3534 assert(node->type == NodeTypeIdentifier);
3524 // Currently, stage1 runs astgen for every comptime function call,3535 // Currently, stage1 runs astgen for every comptime function call,
3525 // resulting the allocation here wasting memory. As a workaround until3536 // resulting the allocation here wasting memory. As a workaround until
...@@ -3527,8 +3538,10 @@ Buf *node_identifier_buf(AstNode *node) {...@@ -3527,8 +3538,10 @@ Buf *node_identifier_buf(AstNode *node) {
3527 // we memoize the result into the AST here.3538 // we memoize the result into the AST here.
3528 if (node->data.identifier.name == nullptr) {3539 if (node->data.identifier.name == nullptr) {
3529 RootStruct *root_struct = node->owner->data.structure.root_struct;3540 RootStruct *root_struct = node->owner->data.structure.root_struct;
3530 node->data.identifier.name = token_identifier_buf(root_struct, node->main_token);3541 node->data.identifier.name = token_identifier_buf2(root_struct, node->main_token,
3542 &node->data.identifier.is_at_syntax);
3531 }3543 }
3544 *is_at_syntax = node->data.identifier.is_at_syntax;
3532 return node->data.identifier.name;3545 return node->data.identifier.name;
3533}3546}
35343547
src/stage1/parser.hpp+1
...@@ -19,6 +19,7 @@ void ast_print(AstNode *node, int indent);...@@ -19,6 +19,7 @@ void ast_print(AstNode *node, int indent);
19void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);19void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *context), void *context);
2020
21Buf *node_identifier_buf(AstNode *node);21Buf *node_identifier_buf(AstNode *node);
22Buf *node_identifier_buf2(AstNode *node, bool *is_at_syntax);
2223
23Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token);24Buf *token_identifier_buf(RootStruct *root_struct, TokenIndex token);
2425
test/behavior/misc.zig+12
...@@ -522,3 +522,15 @@ fn A() type {...@@ -522,3 +522,15 @@ fn A() type {
522test "non-ambiguous reference of shadowed decls" {522test "non-ambiguous reference of shadowed decls" {
523 try expect(A().B().Self != A().Self);523 try expect(A().B().Self != A().Self);
524}524}
525
526test "use of declaration with same name as primitive" {
527 const S = struct {
528 const @"u8" = u16;
529 const alias = @"u8";
530 };
531 const a: S.u8 = 300;
532 try expect(a == 300);
533
534 const b: S.alias = 300;
535 try expect(b == 300);
536}
test/compile_errors.zig+31-4
...@@ -7258,14 +7258,41 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -7258,14 +7258,41 @@ pub fn addCases(ctx: *TestContext) !void {
7258 "tmp.zig:2:17: error: expected type 'u3', found 'u8'",7258 "tmp.zig:2:17: error: expected type 'u3', found 'u8'",
7259 });7259 });
72607260
7261 ctx.objErrStage1("globally shadowing a primitive type",7261 ctx.objErrStage1("locally shadowing a primitive type",
7262 \\const u16 = u8;7262 \\export fn foo() void {
7263 \\ const u8 = u16;
7264 \\ const a: u8 = 300;
7265 \\ _ = a;
7266 \\}
7267 \\export fn bar() void {
7268 \\ const @"u8" = u16;
7269 \\ const a: @"u8" = 300;
7270 \\ _ = a;
7271 \\}
7272 , &[_][]const u8{
7273 "tmp.zig:2:11: error: local shadows primitive 'u8'",
7274 "tmp.zig:7:11: error: local shadows primitive 'u8'",
7275 });
7276
7277 ctx.objErrStage1("primitives take precedence over declarations",
7278 \\const @"u8" = u16;
7279 \\export fn entry() void {
7280 \\ const a: u8 = 300;
7281 \\ _ = a;
7282 \\}
7283 , &[_][]const u8{
7284 "tmp.zig:3:19: error: integer value 300 cannot be coerced to type 'u8'",
7285 });
7286
7287 ctx.objErrStage1("declaration with same name as primitive must use special syntax",
7288 \\const u8 = u16;
7263 \\export fn entry() void {7289 \\export fn entry() void {
7264 \\ const a: u16 = 300;7290 \\ const a: u8 = 300;
7265 \\ _ = a;7291 \\ _ = a;
7266 \\}7292 \\}
7267 , &[_][]const u8{7293 , &[_][]const u8{
7268 "tmp.zig:1:1: error: declaration shadows primitive type 'u16'",7294 "tmp.zig:1:7: error: name shadows primitive 'u8'",
7295 "tmp.zig:1:7: note: consider using @\"u8\" to disambiguate",
7269 });7296 });
72707297
7271 ctx.objErrStage1("implicitly increasing pointer alignment",7298 ctx.objErrStage1("implicitly increasing pointer alignment",