authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 23:51:22-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-05-13 23:51:22-07:00
log8344a50e1c545bbeb63debc90cb91289be53b689
tree83df1936d65e78c1369acc544b2d261c2127ecf4
parent93896ef860da734cbb1247e796c0d14706b1c235

AstGen: add compile error for decl name conflicts

* Remove the ability for GenZir parent Scope to be null. Now there is a Top Scope at the top. * Introduce Scope.Namespace to contain a table of decl names in order to emit a compile error for name conflicts. * Fix use of invalid memory when reporting compile errors by duplicating decl names into a temporary heap allocated buffer. * Fix memory leak in while and for loops, not cleaning up their labeled_breaks and store_to_block_ptr_list arrays. * Fix stage2 test cases because now the source location of redundant comptime keyword compile errors is improved. * Implement compile error for local variable shadowing declaration.

3 files changed, 192 insertions(+), 84 deletions(-)

BRANCH_TODO-2
......@@ -1,8 +1,6 @@
11 * get stage2 tests passing
22 - after the error from an empty file, "has no member main" is invalidated
33 but the comptime block incorrectly does not get re-run
4 - redundant comptime wrong source loc
5 - redeclaration of 'foo' not showing 'previously declared here'
64 - segfault in one of the tests
75 - memory leaks
86 * modify stage2 tests so that only 1 uses _start and the rest use
src/AstGen.zig+183-79
......@@ -82,9 +82,11 @@ pub fn generate(gpa: *Allocator, tree: ast.Tree) InnerError!Zir {
8282 try astgen.extra.ensureTotalCapacity(gpa, tree.nodes.len + reserved_count);
8383 astgen.extra.items.len += reserved_count;
8484
85 var top_scope: Scope.Top = .{};
86
8587 var gen_scope: GenZir = .{
8688 .force_comptime = true,
87 .parent = null,
89 .parent = &top_scope.base,
8890 .anon_name_strategy = .parent,
8991 .decl_node_index = 0,
9092 .decl_line = 0,
......@@ -1514,7 +1516,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
15141516 } else if (block_gz.break_block != 0) {
15151517 break :blk block_gz.break_block;
15161518 }
1517 scope = block_gz.parent orelse break;
1519 scope = block_gz.parent;
15181520 continue;
15191521 };
15201522
......@@ -1545,6 +1547,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
15451547 },
15461548 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
15471549 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
1550 .namespace => break,
15481551 .defer_normal => {
15491552 const defer_scope = scope.cast(Scope.Defer).?;
15501553 scope = defer_scope.parent;
......@@ -1552,6 +1555,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index) Inn
15521555 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
15531556 },
15541557 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1558 .top => unreachable,
15551559 }
15561560 }
15571561 if (break_label != 0) {
......@@ -1576,7 +1580,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
15761580 const gen_zir = scope.cast(GenZir).?;
15771581 const continue_block = gen_zir.continue_block;
15781582 if (continue_block == 0) {
1579 scope = gen_zir.parent orelse break;
1583 scope = gen_zir.parent;
15801584 continue;
15811585 }
15821586 if (break_label != 0) blk: {
......@@ -1587,7 +1591,7 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
15871591 }
15881592 }
15891593 // found continue but either it has a different label, or no label
1590 scope = gen_zir.parent orelse break;
1594 scope = gen_zir.parent;
15911595 continue;
15921596 }
15931597
......@@ -1604,6 +1608,8 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: ast.Node.Index)
16041608 try unusedResultExpr(parent_gz, defer_scope.parent, expr_node);
16051609 },
16061610 .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1611 .namespace => break,
1612 .top => unreachable,
16071613 }
16081614 }
16091615 if (break_label != 0) {
......@@ -1664,11 +1670,13 @@ fn checkLabelRedefinition(astgen: *AstGen, parent_scope: *Scope, label: ast.Toke
16641670 });
16651671 }
16661672 }
1667 scope = gen_zir.parent orelse return;
1673 scope = gen_zir.parent;
16681674 },
16691675 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
16701676 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
16711677 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
1678 .namespace => break,
1679 .top => unreachable,
16721680 }
16731681 }
16741682}
......@@ -2103,7 +2111,7 @@ fn genDefers(
21032111 var scope = inner_scope;
21042112 while (scope != outer_scope) {
21052113 switch (scope.tag) {
2106 .gen_zir => scope = scope.cast(GenZir).?.parent.?,
2114 .gen_zir => scope = scope.cast(GenZir).?.parent,
21072115 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
21082116 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
21092117 .defer_normal => {
......@@ -2119,6 +2127,8 @@ fn genDefers(
21192127 const expr_node = node_datas[defer_scope.defer_node].rhs;
21202128 try unusedResultExpr(gz, defer_scope.parent, expr_node);
21212129 },
2130 .namespace => unreachable,
2131 .top => unreachable,
21222132 }
21232133 }
21242134}
......@@ -2162,12 +2172,14 @@ fn varDecl(
21622172 .local_val => {
21632173 const local_val = s.cast(Scope.LocalVal).?;
21642174 if (local_val.name == ident_name) {
2175 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2176 defer gpa.free(name);
21652177 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2166 astgen.nullTerminatedString(ident_name),
2178 name,
21672179 }, &[_]u32{
21682180 try astgen.errNoteTok(
21692181 local_val.token_src,
2170 "previous declaration is here",
2182 "previously declared here",
21712183 .{},
21722184 ),
21732185 });
......@@ -2177,20 +2189,37 @@ fn varDecl(
21772189 .local_ptr => {
21782190 const local_ptr = s.cast(Scope.LocalPtr).?;
21792191 if (local_ptr.name == ident_name) {
2192 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2193 defer gpa.free(name);
21802194 return astgen.failTokNotes(name_token, "redeclaration of '{s}'", .{
2181 astgen.nullTerminatedString(ident_name),
2195 name,
21822196 }, &[_]u32{
21832197 try astgen.errNoteTok(
21842198 local_ptr.token_src,
2185 "previous declaration is here",
2199 "previously declared here",
21862200 .{},
21872201 ),
21882202 });
21892203 }
21902204 s = local_ptr.parent;
21912205 },
2192 .gen_zir => s = s.cast(GenZir).?.parent orelse break,
2206 .namespace => {
2207 const ns = s.cast(Scope.Namespace).?;
2208 const decl_node = ns.decls.get(ident_name) orelse {
2209 s = ns.parent;
2210 continue;
2211 };
2212 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(ident_name)));
2213 defer gpa.free(name);
2214 return astgen.failTokNotes(name_token, "local shadows declaration of '{s}'", .{
2215 name,
2216 }, &[_]u32{
2217 try astgen.errNoteNode(decl_node, "declared here", .{}),
2218 });
2219 },
2220 .gen_zir => s = s.cast(GenZir).?.parent,
21932221 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
2222 .top => break,
21942223 };
21952224 }
21962225
......@@ -2676,6 +2705,7 @@ const WipDecls = struct {
26762705fn fnDecl(
26772706 astgen: *AstGen,
26782707 gz: *GenZir,
2708 scope: *Scope,
26792709 wip_decls: *WipDecls,
26802710 decl_node: ast.Node.Index,
26812711 body_node: ast.Node.Index,
......@@ -2685,6 +2715,13 @@ fn fnDecl(
26852715 const tree = astgen.tree;
26862716 const token_tags = tree.tokens.items(.tag);
26872717
2718 const fn_name_token = fn_proto.name_token orelse {
2719 return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{});
2720 };
2721 const fn_name_str_index = try astgen.identAsString(fn_name_token);
2722
2723 try astgen.declareNewName(scope, fn_name_str_index, decl_node);
2724
26882725 // We insert this at the beginning so that its instruction index marks the
26892726 // start of the top level declaration.
26902727 const block_inst = try gz.addBlock(.block_inline, fn_proto.ast.proto_node);
......@@ -2693,7 +2730,7 @@ fn fnDecl(
26932730 .force_comptime = true,
26942731 .decl_node_index = fn_proto.ast.proto_node,
26952732 .decl_line = gz.calcLine(decl_node),
2696 .parent = &gz.base,
2733 .parent = scope,
26972734 .astgen = astgen,
26982735 };
26992736 defer decl_gz.instructions.deinit(gpa);
......@@ -2891,11 +2928,6 @@ fn fnDecl(
28912928 });
28922929 };
28932930
2894 const fn_name_token = fn_proto.name_token orelse {
2895 return astgen.failTok(fn_proto.ast.fn_token, "missing function name", .{});
2896 };
2897 const fn_name_str_index = try astgen.identAsString(fn_name_token);
2898
28992931 // We add this at the end so that its instruction index marks the end range
29002932 // of the top level declaration.
29012933 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);
......@@ -2941,6 +2973,8 @@ fn globalVarDecl(
29412973 const name_token = var_decl.ast.mut_token + 1;
29422974 const name_str_index = try astgen.identAsString(name_token);
29432975
2976 try astgen.declareNewName(scope, name_str_index, node);
2977
29442978 var block_scope: GenZir = .{
29452979 .parent = scope,
29462980 .decl_node_index = node,
......@@ -3289,6 +3323,9 @@ fn structDeclInner(
32893323 };
32903324 defer block_scope.instructions.deinit(gpa);
32913325
3326 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3327 defer namespace.decls.deinit(gpa);
3328
32923329 var wip_decls: WipDecls = .{};
32933330 defer wip_decls.deinit(gpa);
32943331
......@@ -3317,14 +3354,14 @@ fn structDeclInner(
33173354 switch (node_tags[fn_proto]) {
33183355 .fn_proto_simple => {
33193356 var params: [1]ast.Node.Index = undefined;
3320 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3357 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
33213358 error.OutOfMemory => return error.OutOfMemory,
33223359 error.AnalysisFail => {},
33233360 };
33243361 continue;
33253362 },
33263363 .fn_proto_multi => {
3327 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3364 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
33283365 error.OutOfMemory => return error.OutOfMemory,
33293366 error.AnalysisFail => {},
33303367 };
......@@ -3332,14 +3369,14 @@ fn structDeclInner(
33323369 },
33333370 .fn_proto_one => {
33343371 var params: [1]ast.Node.Index = undefined;
3335 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3372 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
33363373 error.OutOfMemory => return error.OutOfMemory,
33373374 error.AnalysisFail => {},
33383375 };
33393376 continue;
33403377 },
33413378 .fn_proto => {
3342 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3379 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
33433380 error.OutOfMemory => return error.OutOfMemory,
33443381 error.AnalysisFail => {},
33453382 };
......@@ -3350,14 +3387,14 @@ fn structDeclInner(
33503387 },
33513388 .fn_proto_simple => {
33523389 var params: [1]ast.Node.Index = undefined;
3353 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3390 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
33543391 error.OutOfMemory => return error.OutOfMemory,
33553392 error.AnalysisFail => {},
33563393 };
33573394 continue;
33583395 },
33593396 .fn_proto_multi => {
3360 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
3397 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
33613398 error.OutOfMemory => return error.OutOfMemory,
33623399 error.AnalysisFail => {},
33633400 };
......@@ -3365,14 +3402,14 @@ fn structDeclInner(
33653402 },
33663403 .fn_proto_one => {
33673404 var params: [1]ast.Node.Index = undefined;
3368 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3405 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
33693406 error.OutOfMemory => return error.OutOfMemory,
33703407 error.AnalysisFail => {},
33713408 };
33723409 continue;
33733410 },
33743411 .fn_proto => {
3375 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
3412 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
33763413 error.OutOfMemory => return error.OutOfMemory,
33773414 error.AnalysisFail => {},
33783415 };
......@@ -3380,28 +3417,28 @@ fn structDeclInner(
33803417 },
33813418
33823419 .global_var_decl => {
3383 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
3420 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
33843421 error.OutOfMemory => return error.OutOfMemory,
33853422 error.AnalysisFail => {},
33863423 };
33873424 continue;
33883425 },
33893426 .local_var_decl => {
3390 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
3427 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
33913428 error.OutOfMemory => return error.OutOfMemory,
33923429 error.AnalysisFail => {},
33933430 };
33943431 continue;
33953432 },
33963433 .simple_var_decl => {
3397 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
3434 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
33983435 error.OutOfMemory => return error.OutOfMemory,
33993436 error.AnalysisFail => {},
34003437 };
34013438 continue;
34023439 },
34033440 .aligned_var_decl => {
3404 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
3441 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
34053442 error.OutOfMemory => return error.OutOfMemory,
34063443 error.AnalysisFail => {},
34073444 };
......@@ -3409,21 +3446,21 @@ fn structDeclInner(
34093446 },
34103447
34113448 .@"comptime" => {
3412 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3449 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
34133450 error.OutOfMemory => return error.OutOfMemory,
34143451 error.AnalysisFail => {},
34153452 };
34163453 continue;
34173454 },
34183455 .@"usingnamespace" => {
3419 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3456 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
34203457 error.OutOfMemory => return error.OutOfMemory,
34213458 error.AnalysisFail => {},
34223459 };
34233460 continue;
34243461 },
34253462 .test_decl => {
3426 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3463 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
34273464 error.OutOfMemory => return error.OutOfMemory,
34283465 error.AnalysisFail => {},
34293466 };
......@@ -3547,6 +3584,9 @@ fn unionDeclInner(
35473584 };
35483585 defer block_scope.instructions.deinit(gpa);
35493586
3587 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3588 defer namespace.decls.deinit(gpa);
3589
35503590 var wip_decls: WipDecls = .{};
35513591 defer wip_decls.deinit(gpa);
35523592
......@@ -3575,14 +3615,14 @@ fn unionDeclInner(
35753615 switch (node_tags[fn_proto]) {
35763616 .fn_proto_simple => {
35773617 var params: [1]ast.Node.Index = undefined;
3578 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
3618 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
35793619 error.OutOfMemory => return error.OutOfMemory,
35803620 error.AnalysisFail => {},
35813621 };
35823622 continue;
35833623 },
35843624 .fn_proto_multi => {
3585 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
3625 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
35863626 error.OutOfMemory => return error.OutOfMemory,
35873627 error.AnalysisFail => {},
35883628 };
......@@ -3590,14 +3630,14 @@ fn unionDeclInner(
35903630 },
35913631 .fn_proto_one => {
35923632 var params: [1]ast.Node.Index = undefined;
3593 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
3633 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
35943634 error.OutOfMemory => return error.OutOfMemory,
35953635 error.AnalysisFail => {},
35963636 };
35973637 continue;
35983638 },
35993639 .fn_proto => {
3600 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
3640 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
36013641 error.OutOfMemory => return error.OutOfMemory,
36023642 error.AnalysisFail => {},
36033643 };
......@@ -3608,14 +3648,14 @@ fn unionDeclInner(
36083648 },
36093649 .fn_proto_simple => {
36103650 var params: [1]ast.Node.Index = undefined;
3611 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
3651 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
36123652 error.OutOfMemory => return error.OutOfMemory,
36133653 error.AnalysisFail => {},
36143654 };
36153655 continue;
36163656 },
36173657 .fn_proto_multi => {
3618 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
3658 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
36193659 error.OutOfMemory => return error.OutOfMemory,
36203660 error.AnalysisFail => {},
36213661 };
......@@ -3623,14 +3663,14 @@ fn unionDeclInner(
36233663 },
36243664 .fn_proto_one => {
36253665 var params: [1]ast.Node.Index = undefined;
3626 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
3666 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
36273667 error.OutOfMemory => return error.OutOfMemory,
36283668 error.AnalysisFail => {},
36293669 };
36303670 continue;
36313671 },
36323672 .fn_proto => {
3633 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
3673 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
36343674 error.OutOfMemory => return error.OutOfMemory,
36353675 error.AnalysisFail => {},
36363676 };
......@@ -3638,28 +3678,28 @@ fn unionDeclInner(
36383678 },
36393679
36403680 .global_var_decl => {
3641 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
3681 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
36423682 error.OutOfMemory => return error.OutOfMemory,
36433683 error.AnalysisFail => {},
36443684 };
36453685 continue;
36463686 },
36473687 .local_var_decl => {
3648 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
3688 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
36493689 error.OutOfMemory => return error.OutOfMemory,
36503690 error.AnalysisFail => {},
36513691 };
36523692 continue;
36533693 },
36543694 .simple_var_decl => {
3655 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
3695 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
36563696 error.OutOfMemory => return error.OutOfMemory,
36573697 error.AnalysisFail => {},
36583698 };
36593699 continue;
36603700 },
36613701 .aligned_var_decl => {
3662 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
3702 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
36633703 error.OutOfMemory => return error.OutOfMemory,
36643704 error.AnalysisFail => {},
36653705 };
......@@ -3667,21 +3707,21 @@ fn unionDeclInner(
36673707 },
36683708
36693709 .@"comptime" => {
3670 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3710 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
36713711 error.OutOfMemory => return error.OutOfMemory,
36723712 error.AnalysisFail => {},
36733713 };
36743714 continue;
36753715 },
36763716 .@"usingnamespace" => {
3677 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3717 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
36783718 error.OutOfMemory => return error.OutOfMemory,
36793719 error.AnalysisFail => {},
36803720 };
36813721 continue;
36823722 },
36833723 .test_decl => {
3684 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
3724 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
36853725 error.OutOfMemory => return error.OutOfMemory,
36863726 error.AnalysisFail => {},
36873727 };
......@@ -3940,6 +3980,9 @@ fn containerDecl(
39403980 };
39413981 defer block_scope.instructions.deinit(gpa);
39423982
3983 var namespace: Scope.Namespace = .{ .parent = &gz.base };
3984 defer namespace.decls.deinit(gpa);
3985
39433986 var wip_decls: WipDecls = .{};
39443987 defer wip_decls.deinit(gpa);
39453988
......@@ -3968,14 +4011,14 @@ fn containerDecl(
39684011 switch (node_tags[fn_proto]) {
39694012 .fn_proto_simple => {
39704013 var params: [1]ast.Node.Index = undefined;
3971 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4014 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
39724015 error.OutOfMemory => return error.OutOfMemory,
39734016 error.AnalysisFail => {},
39744017 };
39754018 continue;
39764019 },
39774020 .fn_proto_multi => {
3978 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4021 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
39794022 error.OutOfMemory => return error.OutOfMemory,
39804023 error.AnalysisFail => {},
39814024 };
......@@ -3983,14 +4026,14 @@ fn containerDecl(
39834026 },
39844027 .fn_proto_one => {
39854028 var params: [1]ast.Node.Index = undefined;
3986 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4029 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
39874030 error.OutOfMemory => return error.OutOfMemory,
39884031 error.AnalysisFail => {},
39894032 };
39904033 continue;
39914034 },
39924035 .fn_proto => {
3993 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4036 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
39944037 error.OutOfMemory => return error.OutOfMemory,
39954038 error.AnalysisFail => {},
39964039 };
......@@ -4001,14 +4044,14 @@ fn containerDecl(
40014044 },
40024045 .fn_proto_simple => {
40034046 var params: [1]ast.Node.Index = undefined;
4004 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4047 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
40054048 error.OutOfMemory => return error.OutOfMemory,
40064049 error.AnalysisFail => {},
40074050 };
40084051 continue;
40094052 },
40104053 .fn_proto_multi => {
4011 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4054 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
40124055 error.OutOfMemory => return error.OutOfMemory,
40134056 error.AnalysisFail => {},
40144057 };
......@@ -4016,14 +4059,14 @@ fn containerDecl(
40164059 },
40174060 .fn_proto_one => {
40184061 var params: [1]ast.Node.Index = undefined;
4019 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4062 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
40204063 error.OutOfMemory => return error.OutOfMemory,
40214064 error.AnalysisFail => {},
40224065 };
40234066 continue;
40244067 },
40254068 .fn_proto => {
4026 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4069 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
40274070 error.OutOfMemory => return error.OutOfMemory,
40284071 error.AnalysisFail => {},
40294072 };
......@@ -4031,28 +4074,28 @@ fn containerDecl(
40314074 },
40324075
40334076 .global_var_decl => {
4034 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4077 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
40354078 error.OutOfMemory => return error.OutOfMemory,
40364079 error.AnalysisFail => {},
40374080 };
40384081 continue;
40394082 },
40404083 .local_var_decl => {
4041 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4084 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
40424085 error.OutOfMemory => return error.OutOfMemory,
40434086 error.AnalysisFail => {},
40444087 };
40454088 continue;
40464089 },
40474090 .simple_var_decl => {
4048 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4091 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
40494092 error.OutOfMemory => return error.OutOfMemory,
40504093 error.AnalysisFail => {},
40514094 };
40524095 continue;
40534096 },
40544097 .aligned_var_decl => {
4055 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4098 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
40564099 error.OutOfMemory => return error.OutOfMemory,
40574100 error.AnalysisFail => {},
40584101 };
......@@ -4060,21 +4103,21 @@ fn containerDecl(
40604103 },
40614104
40624105 .@"comptime" => {
4063 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4106 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
40644107 error.OutOfMemory => return error.OutOfMemory,
40654108 error.AnalysisFail => {},
40664109 };
40674110 continue;
40684111 },
40694112 .@"usingnamespace" => {
4070 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4113 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
40714114 error.OutOfMemory => return error.OutOfMemory,
40724115 error.AnalysisFail => {},
40734116 };
40744117 continue;
40754118 },
40764119 .test_decl => {
4077 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4120 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
40784121 error.OutOfMemory => return error.OutOfMemory,
40794122 error.AnalysisFail => {},
40804123 };
......@@ -4164,6 +4207,9 @@ fn containerDecl(
41644207 return rvalue(gz, scope, rl, gz.indexToRef(decl_inst), node);
41654208 },
41664209 .keyword_opaque => {
4210 var namespace: Scope.Namespace = .{ .parent = &gz.base };
4211 defer namespace.decls.deinit(gpa);
4212
41674213 var wip_decls: WipDecls = .{};
41684214 defer wip_decls.deinit(gpa);
41694215
......@@ -4179,14 +4225,14 @@ fn containerDecl(
41794225 switch (node_tags[fn_proto]) {
41804226 .fn_proto_simple => {
41814227 var params: [1]ast.Node.Index = undefined;
4182 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
4228 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoSimple(&params, fn_proto)) catch |err| switch (err) {
41834229 error.OutOfMemory => return error.OutOfMemory,
41844230 error.AnalysisFail => {},
41854231 };
41864232 continue;
41874233 },
41884234 .fn_proto_multi => {
4189 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
4235 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoMulti(fn_proto)) catch |err| switch (err) {
41904236 error.OutOfMemory => return error.OutOfMemory,
41914237 error.AnalysisFail => {},
41924238 };
......@@ -4194,14 +4240,14 @@ fn containerDecl(
41944240 },
41954241 .fn_proto_one => {
41964242 var params: [1]ast.Node.Index = undefined;
4197 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
4243 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProtoOne(&params, fn_proto)) catch |err| switch (err) {
41984244 error.OutOfMemory => return error.OutOfMemory,
41994245 error.AnalysisFail => {},
42004246 };
42014247 continue;
42024248 },
42034249 .fn_proto => {
4204 astgen.fnDecl(gz, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
4250 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, body, tree.fnProto(fn_proto)) catch |err| switch (err) {
42054251 error.OutOfMemory => return error.OutOfMemory,
42064252 error.AnalysisFail => {},
42074253 };
......@@ -4212,14 +4258,14 @@ fn containerDecl(
42124258 },
42134259 .fn_proto_simple => {
42144260 var params: [1]ast.Node.Index = undefined;
4215 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
4261 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoSimple(&params, member_node)) catch |err| switch (err) {
42164262 error.OutOfMemory => return error.OutOfMemory,
42174263 error.AnalysisFail => {},
42184264 };
42194265 continue;
42204266 },
42214267 .fn_proto_multi => {
4222 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
4268 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoMulti(member_node)) catch |err| switch (err) {
42234269 error.OutOfMemory => return error.OutOfMemory,
42244270 error.AnalysisFail => {},
42254271 };
......@@ -4227,14 +4273,14 @@ fn containerDecl(
42274273 },
42284274 .fn_proto_one => {
42294275 var params: [1]ast.Node.Index = undefined;
4230 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
4276 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProtoOne(&params, member_node)) catch |err| switch (err) {
42314277 error.OutOfMemory => return error.OutOfMemory,
42324278 error.AnalysisFail => {},
42334279 };
42344280 continue;
42354281 },
42364282 .fn_proto => {
4237 astgen.fnDecl(gz, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
4283 astgen.fnDecl(gz, &namespace.base, &wip_decls, member_node, 0, tree.fnProto(member_node)) catch |err| switch (err) {
42384284 error.OutOfMemory => return error.OutOfMemory,
42394285 error.AnalysisFail => {},
42404286 };
......@@ -4242,28 +4288,28 @@ fn containerDecl(
42424288 },
42434289
42444290 .global_var_decl => {
4245 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
4291 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.globalVarDecl(member_node)) catch |err| switch (err) {
42464292 error.OutOfMemory => return error.OutOfMemory,
42474293 error.AnalysisFail => {},
42484294 };
42494295 continue;
42504296 },
42514297 .local_var_decl => {
4252 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
4298 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.localVarDecl(member_node)) catch |err| switch (err) {
42534299 error.OutOfMemory => return error.OutOfMemory,
42544300 error.AnalysisFail => {},
42554301 };
42564302 continue;
42574303 },
42584304 .simple_var_decl => {
4259 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
4305 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.simpleVarDecl(member_node)) catch |err| switch (err) {
42604306 error.OutOfMemory => return error.OutOfMemory,
42614307 error.AnalysisFail => {},
42624308 };
42634309 continue;
42644310 },
42654311 .aligned_var_decl => {
4266 astgen.globalVarDecl(gz, scope, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
4312 astgen.globalVarDecl(gz, &namespace.base, &wip_decls, member_node, tree.alignedVarDecl(member_node)) catch |err| switch (err) {
42674313 error.OutOfMemory => return error.OutOfMemory,
42684314 error.AnalysisFail => {},
42694315 };
......@@ -4271,21 +4317,21 @@ fn containerDecl(
42714317 },
42724318
42734319 .@"comptime" => {
4274 astgen.comptimeDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4320 astgen.comptimeDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
42754321 error.OutOfMemory => return error.OutOfMemory,
42764322 error.AnalysisFail => {},
42774323 };
42784324 continue;
42794325 },
42804326 .@"usingnamespace" => {
4281 astgen.usingnamespaceDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4327 astgen.usingnamespaceDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
42824328 error.OutOfMemory => return error.OutOfMemory,
42834329 error.AnalysisFail => {},
42844330 };
42854331 continue;
42864332 },
42874333 .test_decl => {
4288 astgen.testDecl(gz, scope, &wip_decls, member_node) catch |err| switch (err) {
4334 astgen.testDecl(gz, &namespace.base, &wip_decls, member_node) catch |err| switch (err) {
42894335 error.OutOfMemory => return error.OutOfMemory,
42904336 error.AnalysisFail => {},
42914337 };
......@@ -4971,6 +5017,8 @@ fn whileExpr(
49715017 var loop_scope = parent_gz.makeSubBlock(scope);
49725018 loop_scope.setBreakResultLoc(rl);
49735019 defer loop_scope.instructions.deinit(astgen.gpa);
5020 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5021 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
49745022
49755023 var continue_scope = parent_gz.makeSubBlock(&loop_scope.base);
49765024 defer continue_scope.instructions.deinit(astgen.gpa);
......@@ -5178,6 +5226,8 @@ fn forExpr(
51785226 var loop_scope = parent_gz.makeSubBlock(scope);
51795227 loop_scope.setBreakResultLoc(rl);
51805228 defer loop_scope.instructions.deinit(astgen.gpa);
5229 defer loop_scope.labeled_breaks.deinit(astgen.gpa);
5230 defer loop_scope.labeled_store_to_block_ptr_list.deinit(astgen.gpa);
51815231
51825232 var cond_scope = parent_gz.makeSubBlock(&loop_scope.base);
51835233 defer cond_scope.instructions.deinit(astgen.gpa);
......@@ -6006,8 +6056,9 @@ fn identifier(
60066056 }
60076057 s = local_ptr.parent;
60086058 },
6009 .gen_zir => s = s.cast(GenZir).?.parent orelse break,
6059 .gen_zir => s = s.cast(GenZir).?.parent,
60106060 .defer_normal, .defer_error => s = s.cast(Scope.Defer).?.parent,
6061 .namespace, .top => break, // TODO look for ambiguous references to decls
60116062 };
60126063 }
60136064
......@@ -7922,6 +7973,8 @@ const Scope = struct {
79227973 local_ptr,
79237974 defer_normal,
79247975 defer_error,
7976 namespace,
7977 top,
79257978 };
79267979
79277980 /// This is always a `const` local and importantly the `inst` is a value type, not a pointer.
......@@ -7962,6 +8015,23 @@ const Scope = struct {
79628015 parent: *Scope,
79638016 defer_node: ast.Node.Index,
79648017 };
8018
8019 /// Represents a global scope that has any number of declarations in it.
8020 /// Each declaration has this as the parent scope.
8021 const Namespace = struct {
8022 const base_tag: Tag = .namespace;
8023 base: Scope = Scope{ .tag = base_tag },
8024
8025 parent: *Scope,
8026 /// Maps string table index to the source location of declaration,
8027 /// for the purposes of reporting name shadowing compile errors.
8028 decls: std.AutoHashMapUnmanaged(u32, ast.Node.Index) = .{},
8029 };
8030
8031 const Top = struct {
8032 const base_tag: Scope.Tag = .top;
8033 base: Scope = Scope{ .tag = base_tag },
8034 };
79658035};
79668036
79678037/// This is a temporary structure; references to it are valid only
......@@ -7979,7 +8049,7 @@ const GenZir = struct {
79798049 decl_node_index: ast.Node.Index,
79808050 /// The containing decl line index, absolute.
79818051 decl_line: u32,
7982 parent: ?*Scope,
8052 parent: *Scope,
79838053 /// All `GenZir` scopes for the same ZIR share this.
79848054 astgen: *AstGen,
79858055 /// Keeps track of the list of instructions in this scope only. Indexes
......@@ -8989,3 +9059,37 @@ const GenZir = struct {
89899059fn nullTerminatedString(astgen: AstGen, index: usize) [*:0]const u8 {
89909060 return @ptrCast([*:0]const u8, astgen.string_bytes.items.ptr) + index;
89919061}
9062
9063fn declareNewName(
9064 astgen: *AstGen,
9065 start_scope: *Scope,
9066 name_index: u32,
9067 node: ast.Node.Index,
9068) !void {
9069 const gpa = astgen.gpa;
9070 var scope = start_scope;
9071 while (true) {
9072 switch (scope.tag) {
9073 .gen_zir => scope = scope.cast(GenZir).?.parent,
9074 .local_val => scope = scope.cast(Scope.LocalVal).?.parent,
9075 .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent,
9076 .defer_normal, .defer_error => scope = scope.cast(Scope.Defer).?.parent,
9077 .namespace => {
9078 const ns = scope.cast(Scope.Namespace).?;
9079 const gop = try ns.decls.getOrPut(gpa, name_index);
9080 if (gop.found_existing) {
9081 const name = try gpa.dupe(u8, mem.spanZ(astgen.nullTerminatedString(name_index)));
9082 defer gpa.free(name);
9083 return astgen.failNodeNotes(node, "redeclaration of '{s}'", .{
9084 name,
9085 }, &[_]u32{
9086 try astgen.errNoteNode(gop.entry.value, "other declaration here", .{}),
9087 });
9088 }
9089 gop.entry.value = node;
9090 break;
9091 },
9092 .top => break,
9093 }
9094 }
9095}
test/stage2/test.zig+9-3
......@@ -1137,7 +1137,7 @@ pub fn addCases(ctx: *TestContext) !void {
11371137 \\ var a: comptime u32 = 0;
11381138 \\}
11391139 ,
1140 &.{":2:21: error: redundant comptime keyword in already comptime scope"},
1140 &.{":2:12: error: redundant comptime keyword in already comptime scope"},
11411141 );
11421142 case.addError(
11431143 \\pub export fn _start() void {
......@@ -1146,7 +1146,7 @@ pub fn addCases(ctx: *TestContext) !void {
11461146 \\ }
11471147 \\}
11481148 ,
1149 &.{":3:31: error: redundant comptime keyword in already comptime scope"},
1149 &.{":3:22: error: redundant comptime keyword in already comptime scope"},
11501150 );
11511151 }
11521152 {
......@@ -1195,9 +1195,15 @@ pub fn addCases(ctx: *TestContext) !void {
11951195 \\// dummy comment
11961196 \\fn entry() void {}
11971197 \\fn entry() void {}
1198 \\
1199 \\fn foo() void {
1200 \\ var foo = 1234;
1201 \\}
11981202 , &[_][]const u8{
1199 ":3:4: error: redeclaration of 'entry'",
1203 ":3:1: error: redeclaration of 'entry'",
12001204 ":2:1: note: previously declared here",
1205 ":6:9: error: local shadows declaration of 'foo'",
1206 ":5:1: note: declared here",
12011207 });
12021208
12031209 ctx.compileError("global variable redeclaration", linux_x64,