authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 13:36:03-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 13:39:48-07:00
log34f64432b0f1d125a5abfb750861013ac4a5d5a2
tree931dcc868a3ea9cb5b53e2f4791d391e639f9734
parentaa52bb83271edc626cd931cf9e8dfbcfc90d4cf2

remove `usingnamespace` from the language

closes #20663

43 files changed, 29 insertions(+), 910 deletions(-)

doc/langref.html.in+2-47
...@@ -3842,37 +3842,6 @@ void do_a_thing(struct Foo *foo) {...@@ -3842,37 +3842,6 @@ void do_a_thing(struct Foo *foo) {
3842 {#header_close#}3842 {#header_close#}
3843 {#header_close#}3843 {#header_close#}
38443844
3845 {#header_open|usingnamespace#}
3846 <p>
3847 {#syntax#}usingnamespace{#endsyntax#} is a declaration that mixes all the public
3848 declarations of the operand, which must be a {#link|struct#}, {#link|union#}, {#link|enum#},
3849 or {#link|opaque#}, into the namespace:
3850 </p>
3851 {#code|test_usingnamespace.zig#}
3852
3853 <p>
3854 {#syntax#}usingnamespace{#endsyntax#} has an important use case when organizing the public
3855 API of a file or package. For example, one might have <code class="file">c.zig</code> with all of the
3856 {#link|C imports|Import from C Header File#}:
3857 </p>
3858 {#syntax_block|zig|c.zig#}
3859pub usingnamespace @cImport({
3860 @cInclude("epoxy/gl.h");
3861 @cInclude("GLFW/glfw3.h");
3862 @cDefine("STBI_ONLY_PNG", "");
3863 @cDefine("STBI_NO_STDIO", "");
3864 @cInclude("stb_image.h");
3865});
3866 {#end_syntax_block#}
3867 <p>
3868 The above example demonstrates using {#syntax#}pub{#endsyntax#} to qualify the
3869 {#syntax#}usingnamespace{#endsyntax#} additionally makes the imported declarations
3870 {#syntax#}pub{#endsyntax#}. This can be used to forward declarations, giving precise control
3871 over what declarations a given file exposes.
3872 </p>
3873 {#header_close#}
3874
3875
3876 {#header_open|comptime#}3845 {#header_open|comptime#}
3877 <p>3846 <p>
3878 Zig places importance on the concept of whether an expression is known at compile-time.3847 Zig places importance on the concept of whether an expression is known at compile-time.
...@@ -6545,7 +6514,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val...@@ -6545,7 +6514,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
6545 </p>6514 </p>
6546 <ul>6515 <ul>
6547 <li>If a call to {#syntax#}@import{#endsyntax#} is analyzed, the file being imported is analyzed.</li>6516 <li>If a call to {#syntax#}@import{#endsyntax#} is analyzed, the file being imported is analyzed.</li>
6548 <li>If a type (including a file) is analyzed, all {#syntax#}comptime{#endsyntax#}, {#syntax#}usingnamespace{#endsyntax#}, and {#syntax#}export{#endsyntax#} declarations within it are analyzed.</li>6517 <li>If a type (including a file) is analyzed, all {#syntax#}comptime{#endsyntax#} and {#syntax#}export{#endsyntax#} declarations within it are analyzed.</li>
6549 <li>If a type (including a file) is analyzed, and the compilation is for a {#link|test|Zig Test#}, and the module the type is within is the root module of the compilation, then all {#syntax#}test{#endsyntax#} declarations within it are also analyzed.</li>6518 <li>If a type (including a file) is analyzed, and the compilation is for a {#link|test|Zig Test#}, and the module the type is within is the root module of the compilation, then all {#syntax#}test{#endsyntax#} declarations within it are also analyzed.</li>
6550 <li>If a reference to a named declaration (i.e. a usage of it) is analyzed, the declaration being referenced is analyzed. Declarations are order-independent, so this reference may be above or below the declaration being referenced, or even in another file entirely.</li>6519 <li>If a reference to a named declaration (i.e. a usage of it) is analyzed, the declaration being referenced is analyzed. Declarations are order-independent, so this reference may be above or below the declaration being referenced, or even in another file entirely.</li>
6551 </ul>6520 </ul>
...@@ -7782,18 +7751,6 @@ fn readU32Be() u32 {}...@@ -7782,18 +7751,6 @@ fn readU32Be() u32 {}
7782 </ul>7751 </ul>
7783 </td>7752 </td>
7784 </tr>7753 </tr>
7785 <tr>
7786 <th scope="row">
7787 <pre>{#syntax#}usingnamespace{#endsyntax#}</pre>
7788 </th>
7789 <td>
7790 {#syntax#}usingnamespace{#endsyntax#} is a top-level declaration that imports all the public declarations of the operand,
7791 which must be a struct, union, or enum, into the current scope.
7792 <ul>
7793 <li>See also {#link|usingnamespace#}</li>
7794 </ul>
7795 </td>
7796 </tr>
7797 <tr>7754 <tr>
7798 <th scope="row">7755 <th scope="row">
7799 <pre>{#syntax#}var{#endsyntax#}</pre>7756 <pre>{#syntax#}var{#endsyntax#}</pre>
...@@ -7863,7 +7820,6 @@ ComptimeDecl <- KEYWORD_comptime Block...@@ -7863,7 +7820,6 @@ ComptimeDecl <- KEYWORD_comptime Block
7863Decl7820Decl
7864 <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)7821 <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)
7865 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? GlobalVarDecl7822 / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? GlobalVarDecl
7866 / KEYWORD_usingnamespace Expr SEMICOLON
78677823
7868FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr7824FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
78697825
...@@ -8408,7 +8364,6 @@ KEYWORD_threadlocal <- 'threadlocal' end_of_word...@@ -8408,7 +8364,6 @@ KEYWORD_threadlocal <- 'threadlocal' end_of_word
8408KEYWORD_try <- 'try' end_of_word8364KEYWORD_try <- 'try' end_of_word
8409KEYWORD_union <- 'union' end_of_word8365KEYWORD_union <- 'union' end_of_word
8410KEYWORD_unreachable <- 'unreachable' end_of_word8366KEYWORD_unreachable <- 'unreachable' end_of_word
8411KEYWORD_usingnamespace <- 'usingnamespace' end_of_word
8412KEYWORD_var <- 'var' end_of_word8367KEYWORD_var <- 'var' end_of_word
8413KEYWORD_volatile <- 'volatile' end_of_word8368KEYWORD_volatile <- 'volatile' end_of_word
8414KEYWORD_while <- 'while' end_of_word8369KEYWORD_while <- 'while' end_of_word
...@@ -8424,7 +8379,7 @@ keyword <- KEYWORD_addrspace / KEYWORD_align / KEYWORD_allowzero / KEYWORD_and...@@ -8424,7 +8379,7 @@ keyword <- KEYWORD_addrspace / KEYWORD_align / KEYWORD_allowzero / KEYWORD_and
8424 / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection8379 / KEYWORD_pub / KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
8425 / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test8380 / KEYWORD_struct / KEYWORD_suspend / KEYWORD_switch / KEYWORD_test
8426 / KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable8381 / KEYWORD_threadlocal / KEYWORD_try / KEYWORD_union / KEYWORD_unreachable
8427 / KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while8382 / KEYWORD_var / KEYWORD_volatile / KEYWORD_while
8428 {#end_syntax_block#}8383 {#end_syntax_block#}
8429 {#header_close#}8384 {#header_close#}
8430 {#header_open|Zen#}8385 {#header_open|Zen#}
doc/langref/test_usingnamespace.zig deleted-8
...@@ -1,8 +0,0 @@
1test "using std namespace" {
2 const S = struct {
3 usingnamespace @import("std");
4 };
5 try S.testing.expect(true);
6}
7
8// test
lib/compiler/reduce/Walk.zig-7
...@@ -160,12 +160,6 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void {...@@ -160,12 +160,6 @@ fn walkMember(w: *Walk, decl: Ast.Node.Index) Error!void {
160 try walkExpression(w, decl);160 try walkExpression(w, decl);
161 },161 },
162162
163 .@"usingnamespace" => {
164 try w.transformations.append(.{ .delete_node = decl });
165 const expr = ast.nodeData(decl).node;
166 try walkExpression(w, expr);
167 },
168
169 .global_var_decl,163 .global_var_decl,
170 .local_var_decl,164 .local_var_decl,
171 .simple_var_decl,165 .simple_var_decl,
...@@ -520,7 +514,6 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void {...@@ -520,7 +514,6 @@ fn walkExpression(w: *Walk, node: Ast.Node.Index) Error!void {
520 .local_var_decl => unreachable,514 .local_var_decl => unreachable,
521 .simple_var_decl => unreachable,515 .simple_var_decl => unreachable,
522 .aligned_var_decl => unreachable,516 .aligned_var_decl => unreachable,
523 .@"usingnamespace" => unreachable,
524 .test_decl => unreachable,517 .test_decl => unreachable,
525 .asm_output => unreachable,518 .asm_output => unreachable,
526 .asm_input => unreachable,519 .asm_input => unreachable,
lib/docs/wasm/Walk.zig-2
...@@ -567,7 +567,6 @@ fn struct_decl(...@@ -567,7 +567,6 @@ fn struct_decl(
567 },567 },
568568
569 .@"comptime",569 .@"comptime",
570 .@"usingnamespace",
571 => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).node),570 => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).node),
572571
573 .test_decl => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).opt_token_and_node[1]),572 .test_decl => try w.expr(&namespace.base, parent_decl, ast.nodeData(member).opt_token_and_node[1]),
...@@ -639,7 +638,6 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index)...@@ -639,7 +638,6 @@ fn expr(w: *Walk, scope: *Scope, parent_decl: Decl.Index, node: Ast.Node.Index)
639 const ast = w.file.get_ast();638 const ast = w.file.get_ast();
640 switch (ast.nodeTag(node)) {639 switch (ast.nodeTag(node)) {
641 .root => unreachable, // Top-level declaration.640 .root => unreachable, // Top-level declaration.
642 .@"usingnamespace" => unreachable, // Top-level declaration.
643 .test_decl => unreachable, // Top-level declaration.641 .test_decl => unreachable, // Top-level declaration.
644 .container_field_init => unreachable, // Top-level declaration.642 .container_field_init => unreachable, // Top-level declaration.
645 .container_field_align => unreachable, // Top-level declaration.643 .container_field_align => unreachable, // Top-level declaration.
lib/docs/wasm/html_render.zig-1
...@@ -137,7 +137,6 @@ pub fn fileSourceHtml(...@@ -137,7 +137,6 @@ pub fn fileSourceHtml(
137 .keyword_try,137 .keyword_try,
138 .keyword_union,138 .keyword_union,
139 .keyword_unreachable,139 .keyword_unreachable,
140 .keyword_usingnamespace,
141 .keyword_var,140 .keyword_var,
142 .keyword_volatile,141 .keyword_volatile,
143 .keyword_allowzero,142 .keyword_allowzero,
lib/std/zig/Ast.zig-14
...@@ -755,13 +755,6 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {...@@ -755,13 +755,6 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {
755 return i - end_offset;755 return i - end_offset;
756 },756 },
757757
758 .@"usingnamespace" => {
759 const main_token: TokenIndex = tree.nodeMainToken(n);
760 const has_visib_token = tree.isTokenPrecededByTags(main_token, &.{.keyword_pub});
761 end_offset += @intFromBool(has_visib_token);
762 return main_token - end_offset;
763 },
764
765 .container_field_init,758 .container_field_init,
766 .container_field_align,759 .container_field_align,
767 .container_field,760 .container_field,
...@@ -881,7 +874,6 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex {...@@ -881,7 +874,6 @@ pub fn lastToken(tree: Ast, node: Node.Index) TokenIndex {
881 while (true) switch (tree.nodeTag(n)) {874 while (true) switch (tree.nodeTag(n)) {
882 .root => return @intCast(tree.tokens.len - 1),875 .root => return @intCast(tree.tokens.len - 1),
883876
884 .@"usingnamespace",
885 .bool_not,877 .bool_not,
886 .negation,878 .negation,
887 .bit_not,879 .bit_not,
...@@ -3033,12 +3025,6 @@ pub const Node = struct {...@@ -3033,12 +3025,6 @@ pub const Node = struct {
3033 ///3025 ///
3034 /// The `main_token` field is the first token for the source file.3026 /// The `main_token` field is the first token for the source file.
3035 root,3027 root,
3036 /// `usingnamespace expr;`.
3037 ///
3038 /// The `data` field is a `.node` to expr.
3039 ///
3040 /// The `main_token` field is the `usingnamespace` token.
3041 @"usingnamespace",
3042 /// `test {}`,3028 /// `test {}`,
3043 /// `test "name" {}`,3029 /// `test "name" {}`,
3044 /// `test identifier {}`.3030 /// `test identifier {}`.
lib/std/zig/AstGen.zig+1-88
...@@ -442,7 +442,6 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins...@@ -442,7 +442,6 @@ fn lvalExpr(gz: *GenZir, scope: *Scope, node: Ast.Node.Index) InnerError!Zir.Ins
442 const tree = astgen.tree;442 const tree = astgen.tree;
443 switch (tree.nodeTag(node)) {443 switch (tree.nodeTag(node)) {
444 .root => unreachable,444 .root => unreachable,
445 .@"usingnamespace" => unreachable,
446 .test_decl => unreachable,445 .test_decl => unreachable,
447 .global_var_decl => unreachable,446 .global_var_decl => unreachable,
448 .local_var_decl => unreachable,447 .local_var_decl => unreachable,
...@@ -637,7 +636,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE...@@ -637,7 +636,6 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
637636
638 switch (tree.nodeTag(node)) {637 switch (tree.nodeTag(node)) {
639 .root => unreachable, // Top-level declaration.638 .root => unreachable, // Top-level declaration.
640 .@"usingnamespace" => unreachable, // Top-level declaration.
641 .test_decl => unreachable, // Top-level declaration.639 .test_decl => unreachable, // Top-level declaration.
642 .container_field_init => unreachable, // Top-level declaration.640 .container_field_init => unreachable, // Top-level declaration.
643 .container_field_align => unreachable, // Top-level declaration.641 .container_field_align => unreachable, // Top-level declaration.
...@@ -4700,69 +4698,6 @@ fn comptimeDecl(...@@ -4700,69 +4698,6 @@ fn comptimeDecl(
4700 });4698 });
4701}4699}
47024700
4703fn usingnamespaceDecl(
4704 astgen: *AstGen,
4705 gz: *GenZir,
4706 scope: *Scope,
4707 wip_members: *WipMembers,
4708 node: Ast.Node.Index,
4709) InnerError!void {
4710 const tree = astgen.tree;
4711
4712 const old_hasher = astgen.src_hasher;
4713 defer astgen.src_hasher = old_hasher;
4714 astgen.src_hasher = std.zig.SrcHasher.init(.{});
4715 astgen.src_hasher.update(tree.getNodeSource(node));
4716 astgen.src_hasher.update(std.mem.asBytes(&astgen.source_column));
4717
4718 const type_expr = tree.nodeData(node).node;
4719 const is_pub = tree.isTokenPrecededByTags(tree.nodeMainToken(node), &.{.keyword_pub});
4720
4721 // Up top so the ZIR instruction index marks the start range of this
4722 // top-level declaration.
4723 const decl_inst = try gz.makeDeclaration(node);
4724 wip_members.nextDecl(decl_inst);
4725 astgen.advanceSourceCursorToNode(node);
4726
4727 // This is just needed for the `setDeclaration` call.
4728 var dummy_gz = gz.makeSubBlock(scope);
4729 defer dummy_gz.unstack();
4730
4731 var usingnamespace_gz: GenZir = .{
4732 .is_comptime = true,
4733 .decl_node_index = node,
4734 .decl_line = astgen.source_line,
4735 .parent = scope,
4736 .astgen = astgen,
4737 .instructions = gz.instructions,
4738 .instructions_top = gz.instructions.items.len,
4739 };
4740 defer usingnamespace_gz.unstack();
4741
4742 const decl_column = astgen.source_column;
4743
4744 const namespace_inst = try typeExpr(&usingnamespace_gz, &usingnamespace_gz.base, type_expr);
4745 _ = try usingnamespace_gz.addBreak(.break_inline, decl_inst, namespace_inst);
4746
4747 var hash: std.zig.SrcHash = undefined;
4748 astgen.src_hasher.final(&hash);
4749 try setDeclaration(decl_inst, .{
4750 .src_hash = hash,
4751 .src_line = usingnamespace_gz.decl_line,
4752 .src_column = decl_column,
4753 .kind = .@"usingnamespace",
4754 .name = .empty,
4755 .is_pub = is_pub,
4756 .is_threadlocal = false,
4757 .linkage = .normal,
4758 .type_gz = &dummy_gz,
4759 .align_gz = &dummy_gz,
4760 .linksection_gz = &dummy_gz,
4761 .addrspace_gz = &dummy_gz,
4762 .value_gz = &usingnamespace_gz,
4763 });
4764}
4765
4766fn testDecl(4701fn testDecl(
4767 astgen: *AstGen,4702 astgen: *AstGen,
4768 gz: *GenZir,4703 gz: *GenZir,
...@@ -5932,23 +5867,6 @@ fn containerMember(...@@ -5932,23 +5867,6 @@ fn containerMember(
5932 },5867 },
5933 };5868 };
5934 },5869 },
5935 .@"usingnamespace" => {
5936 const prev_decl_index = wip_members.decl_index;
5937 astgen.usingnamespaceDecl(gz, scope, wip_members, member_node) catch |err| switch (err) {
5938 error.OutOfMemory => return error.OutOfMemory,
5939 error.AnalysisFail => {
5940 wip_members.decl_index = prev_decl_index;
5941 try addFailedDeclaration(
5942 wip_members,
5943 gz,
5944 .@"usingnamespace",
5945 .empty,
5946 member_node,
5947 tree.isTokenPrecededByTags(tree.nodeMainToken(member_node), &.{.keyword_pub}),
5948 );
5949 },
5950 };
5951 },
5952 .test_decl => {5870 .test_decl => {
5953 const prev_decl_index = wip_members.decl_index;5871 const prev_decl_index = wip_members.decl_index;
5954 // We need to have *some* decl here so that the decl count matches what's expected.5872 // We need to have *some* decl here so that the decl count matches what's expected.
...@@ -10398,7 +10316,6 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev...@@ -10398,7 +10316,6 @@ fn nodeMayEvalToError(tree: *const Ast, start_node: Ast.Node.Index) BuiltinFn.Ev
10398 while (true) {10316 while (true) {
10399 switch (tree.nodeTag(node)) {10317 switch (tree.nodeTag(node)) {
10400 .root,10318 .root,
10401 .@"usingnamespace",
10402 .test_decl,10319 .test_decl,
10403 .switch_case,10320 .switch_case,
10404 .switch_case_inline,10321 .switch_case_inline,
...@@ -10606,7 +10523,6 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In...@@ -10606,7 +10523,6 @@ fn nodeImpliesMoreThanOnePossibleValue(tree: *const Ast, start_node: Ast.Node.In
10606 while (true) {10523 while (true) {
10607 switch (tree.nodeTag(node)) {10524 switch (tree.nodeTag(node)) {
10608 .root,10525 .root,
10609 .@"usingnamespace",
10610 .test_decl,10526 .test_decl,
10611 .switch_case,10527 .switch_case,
10612 .switch_case_inline,10528 .switch_case_inline,
...@@ -10845,7 +10761,6 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {...@@ -10845,7 +10761,6 @@ fn nodeImpliesComptimeOnly(tree: *const Ast, start_node: Ast.Node.Index) bool {
10845 while (true) {10761 while (true) {
10846 switch (tree.nodeTag(node)) {10762 switch (tree.nodeTag(node)) {
10847 .root,10763 .root,
10848 .@"usingnamespace",
10849 .test_decl,10764 .test_decl,
10850 .switch_case,10765 .switch_case,
10851 .switch_case_inline,10766 .switch_case_inline,
...@@ -13518,7 +13433,7 @@ fn scanContainer(...@@ -13518,7 +13433,7 @@ fn scanContainer(
13518 break :blk .{ .decl, ident };13433 break :blk .{ .decl, ident };
13519 },13434 },
1352013435
13521 .@"comptime", .@"usingnamespace" => {13436 .@"comptime" => {
13522 decl_count += 1;13437 decl_count += 1;
13523 continue;13438 continue;
13524 },13439 },
...@@ -13896,7 +13811,6 @@ const DeclarationName = union(enum) {...@@ -13896,7 +13811,6 @@ const DeclarationName = union(enum) {
13896 decltest: Ast.TokenIndex,13811 decltest: Ast.TokenIndex,
13897 unnamed_test,13812 unnamed_test,
13898 @"comptime",13813 @"comptime",
13899 @"usingnamespace",
13900};13814};
1390113815
13902fn addFailedDeclaration(13816fn addFailedDeclaration(
...@@ -13986,7 +13900,6 @@ fn setDeclaration(...@@ -13986,7 +13900,6 @@ fn setDeclaration(
13986 .@"test" => .@"test",13900 .@"test" => .@"test",
13987 .decltest => .decltest,13901 .decltest => .decltest,
13988 .@"comptime" => .@"comptime",13902 .@"comptime" => .@"comptime",
13989 .@"usingnamespace" => if (args.is_pub) .pub_usingnamespace else .@"usingnamespace",
13990 .@"const" => switch (args.linkage) {13903 .@"const" => switch (args.linkage) {
13991 .normal => if (args.is_pub) id: {13904 .normal => if (args.is_pub) id: {
13992 if (has_special_body) break :id .pub_const;13905 if (has_special_body) break :id .pub_const;
lib/std/zig/AstRlAnnotate.zig-4
...@@ -165,10 +165,6 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI...@@ -165,10 +165,6 @@ fn expr(astrl: *AstRlAnnotate, node: Ast.Node.Index, block: ?*Block, ri: ResultI
165 }165 }
166 return false;166 return false;
167 },167 },
168 .@"usingnamespace" => {
169 _ = try astrl.expr(tree.nodeData(node).node, block, ResultInfo.type_only);
170 return false;
171 },
172 .test_decl => {168 .test_decl => {
173 _ = try astrl.expr(tree.nodeData(node).opt_token_and_node[1], block, ResultInfo.none);169 _ = try astrl.expr(tree.nodeData(node).opt_token_and_node[1], block, ResultInfo.none);
174 return false;170 return false;
lib/std/zig/Parse.zig+1-37
...@@ -359,16 +359,6 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members {...@@ -359,16 +359,6 @@ fn parseContainerMembers(p: *Parse) Allocator.Error!Members {
359 }359 }
360 trailing = p.tokenTag(p.tok_i - 1) == .semicolon;360 trailing = p.tokenTag(p.tok_i - 1) == .semicolon;
361 },361 },
362 .keyword_usingnamespace => {
363 const opt_node = try p.expectUsingNamespaceRecoverable();
364 if (opt_node) |node| {
365 if (field_state == .seen) {
366 field_state = .{ .end = node };
367 }
368 try p.scratch.append(p.gpa, node);
369 }
370 trailing = p.tokenTag(p.tok_i - 1) == .semicolon;
371 },
372 .keyword_const,362 .keyword_const,
373 .keyword_var,363 .keyword_var,
374 .keyword_threadlocal,364 .keyword_threadlocal,
...@@ -496,7 +486,6 @@ fn findNextContainerMember(p: *Parse) void {...@@ -496,7 +486,6 @@ fn findNextContainerMember(p: *Parse) void {
496 .keyword_extern,486 .keyword_extern,
497 .keyword_inline,487 .keyword_inline,
498 .keyword_noinline,488 .keyword_noinline,
499 .keyword_usingnamespace,
500 .keyword_threadlocal,489 .keyword_threadlocal,
501 .keyword_const,490 .keyword_const,
502 .keyword_var,491 .keyword_var,
...@@ -601,7 +590,6 @@ fn expectTestDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {...@@ -601,7 +590,6 @@ fn expectTestDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {
601/// Decl590/// Decl
602/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)591/// <- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline / KEYWORD_noinline)? FnProto (SEMICOLON / Block)
603/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl592/// / (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
604/// / KEYWORD_usingnamespace Expr SEMICOLON
605fn expectTopLevelDecl(p: *Parse) !?Node.Index {593fn expectTopLevelDecl(p: *Parse) !?Node.Index {
606 const extern_export_inline_token = p.nextToken();594 const extern_export_inline_token = p.nextToken();
607 var is_extern: bool = false;595 var is_extern: bool = false;
...@@ -664,10 +652,7 @@ fn expectTopLevelDecl(p: *Parse) !?Node.Index {...@@ -664,10 +652,7 @@ fn expectTopLevelDecl(p: *Parse) !?Node.Index {
664 if (expect_var_or_fn) {652 if (expect_var_or_fn) {
665 return p.fail(.expected_var_decl_or_fn);653 return p.fail(.expected_var_decl_or_fn);
666 }654 }
667 if (p.tokenTag(p.tok_i) != .keyword_usingnamespace) {655 return p.fail(.expected_pub_item);
668 return p.fail(.expected_pub_item);
669 }
670 return try p.expectUsingNamespace();
671}656}
672657
673fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {658fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {
...@@ -680,27 +665,6 @@ fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {...@@ -680,27 +665,6 @@ fn expectTopLevelDeclRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {
680 };665 };
681}666}
682667
683fn expectUsingNamespace(p: *Parse) !Node.Index {
684 const usingnamespace_token = p.assertToken(.keyword_usingnamespace);
685 const expr = try p.expectExpr();
686 try p.expectSemicolon(.expected_semi_after_decl, false);
687 return p.addNode(.{
688 .tag = .@"usingnamespace",
689 .main_token = usingnamespace_token,
690 .data = .{ .node = expr },
691 });
692}
693
694fn expectUsingNamespaceRecoverable(p: *Parse) error{OutOfMemory}!?Node.Index {
695 return p.expectUsingNamespace() catch |err| switch (err) {
696 error.OutOfMemory => return error.OutOfMemory,
697 error.ParseError => {
698 p.findNextContainerMember();
699 return null;
700 },
701 };
702}
703
704/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr668/// FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpace? LinkSection? CallConv? EXCLAMATIONMARK? TypeExpr
705fn parseFnProto(p: *Parse) !?Node.Index {669fn parseFnProto(p: *Parse) !?Node.Index {
706 const fn_token = p.eatToken(.keyword_fn) orelse return null;670 const fn_token = p.eatToken(.keyword_fn) orelse return null;
lib/std/zig/Zir.zig+4-17
...@@ -2675,7 +2675,6 @@ pub const Inst = struct {...@@ -2675,7 +2675,6 @@ pub const Inst = struct {
2675 @"test",2675 @"test",
2676 decltest,2676 decltest,
2677 @"comptime",2677 @"comptime",
2678 @"usingnamespace",
2679 @"const",2678 @"const",
2680 @"var",2679 @"var",
2681 };2680 };
...@@ -2692,7 +2691,7 @@ pub const Inst = struct {...@@ -2692,7 +2691,7 @@ pub const Inst = struct {
2692 src_column: u32,2691 src_column: u32,
26932692
2694 kind: Kind,2693 kind: Kind,
2695 /// Always `.empty` for `kind` of `unnamed_test`, `.@"comptime"`, `.@"usingnamespace"`.2694 /// Always `.empty` for `kind` of `unnamed_test`, `.@"comptime"`
2696 name: NullTerminatedString,2695 name: NullTerminatedString,
2697 /// Always `false` for `kind` of `unnamed_test`, `.@"test"`, `.decltest`, `.@"comptime"`.2696 /// Always `false` for `kind` of `unnamed_test`, `.@"test"`, `.decltest`, `.@"comptime"`.
2698 is_pub: bool,2697 is_pub: bool,
...@@ -2723,9 +2722,6 @@ pub const Inst = struct {...@@ -2723,9 +2722,6 @@ pub const Inst = struct {
2723 decltest,2722 decltest,
2724 @"comptime",2723 @"comptime",
27252724
2726 @"usingnamespace",
2727 pub_usingnamespace,
2728
2729 const_simple,2725 const_simple,
2730 const_typed,2726 const_typed,
2731 @"const",2727 @"const",
...@@ -2762,8 +2758,6 @@ pub const Inst = struct {...@@ -2762,8 +2758,6 @@ pub const Inst = struct {
2762 return switch (id) {2758 return switch (id) {
2763 .unnamed_test,2759 .unnamed_test,
2764 .@"comptime",2760 .@"comptime",
2765 .@"usingnamespace",
2766 .pub_usingnamespace,
2767 => false,2761 => false,
2768 else => true,2762 else => true,
2769 };2763 };
...@@ -2788,8 +2782,6 @@ pub const Inst = struct {...@@ -2788,8 +2782,6 @@ pub const Inst = struct {
2788 .@"test",2782 .@"test",
2789 .decltest,2783 .decltest,
2790 .@"comptime",2784 .@"comptime",
2791 .@"usingnamespace",
2792 .pub_usingnamespace,
2793 => false, // these constructs are untyped2785 => false, // these constructs are untyped
2794 .const_simple,2786 .const_simple,
2795 .pub_const_simple,2787 .pub_const_simple,
...@@ -2821,8 +2813,6 @@ pub const Inst = struct {...@@ -2821,8 +2813,6 @@ pub const Inst = struct {
2821 .@"test",2813 .@"test",
2822 .decltest,2814 .decltest,
2823 .@"comptime",2815 .@"comptime",
2824 .@"usingnamespace",
2825 .pub_usingnamespace,
2826 => false, // these constructs are untyped2816 => false, // these constructs are untyped
2827 .const_simple,2817 .const_simple,
2828 .const_typed,2818 .const_typed,
...@@ -2865,7 +2855,6 @@ pub const Inst = struct {...@@ -2865,7 +2855,6 @@ pub const Inst = struct {
2865 .@"test" => .@"test",2855 .@"test" => .@"test",
2866 .decltest => .decltest,2856 .decltest => .decltest,
2867 .@"comptime" => .@"comptime",2857 .@"comptime" => .@"comptime",
2868 .@"usingnamespace", .pub_usingnamespace => .@"usingnamespace",
2869 .const_simple,2858 .const_simple,
2870 .const_typed,2859 .const_typed,
2871 .@"const",2860 .@"const",
...@@ -2899,7 +2888,6 @@ pub const Inst = struct {...@@ -2899,7 +2888,6 @@ pub const Inst = struct {
28992888
2900 pub fn isPub(id: Id) bool {2889 pub fn isPub(id: Id) bool {
2901 return switch (id) {2890 return switch (id) {
2902 .pub_usingnamespace,
2903 .pub_const_simple,2891 .pub_const_simple,
2904 .pub_const_typed,2892 .pub_const_typed,
2905 .pub_const,2893 .pub_const,
...@@ -2935,8 +2923,7 @@ pub const Inst = struct {...@@ -2935,8 +2923,7 @@ pub const Inst = struct {
29352923
2936 pub const Name = enum(u32) {2924 pub const Name = enum(u32) {
2937 @"comptime" = std.math.maxInt(u32),2925 @"comptime" = std.math.maxInt(u32),
2938 @"usingnamespace" = std.math.maxInt(u32) - 1,2926 unnamed_test = std.math.maxInt(u32) - 1,
2939 unnamed_test = std.math.maxInt(u32) - 2,
2940 /// Other values are `NullTerminatedString` values, i.e. index into2927 /// Other values are `NullTerminatedString` values, i.e. index into
2941 /// `string_bytes`. If the byte referenced is 0, the decl is a named2928 /// `string_bytes`. If the byte referenced is 0, the decl is a named
2942 /// test, and the actual name begins at the following byte.2929 /// test, and the actual name begins at the following byte.
...@@ -2944,13 +2931,13 @@ pub const Inst = struct {...@@ -2944,13 +2931,13 @@ pub const Inst = struct {
29442931
2945 pub fn isNamedTest(name: Name, zir: Zir) bool {2932 pub fn isNamedTest(name: Name, zir: Zir) bool {
2946 return switch (name) {2933 return switch (name) {
2947 .@"comptime", .@"usingnamespace", .unnamed_test => false,2934 .@"comptime", .unnamed_test => false,
2948 _ => zir.string_bytes[@intFromEnum(name)] == 0,2935 _ => zir.string_bytes[@intFromEnum(name)] == 0,
2949 };2936 };
2950 }2937 }
2951 pub fn toString(name: Name, zir: Zir) ?NullTerminatedString {2938 pub fn toString(name: Name, zir: Zir) ?NullTerminatedString {
2952 switch (name) {2939 switch (name) {
2953 .@"comptime", .@"usingnamespace", .unnamed_test => return null,2940 .@"comptime", .unnamed_test => return null,
2954 _ => {},2941 _ => {},
2955 }2942 }
2956 const idx: u32 = @intFromEnum(name);2943 const idx: u32 = @intFromEnum(name);
lib/std/zig/ZonGen.zig-1
...@@ -100,7 +100,6 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator...@@ -100,7 +100,6 @@ fn expr(zg: *ZonGen, node: Ast.Node.Index, dest_node: Zoir.Node.Index) Allocator
100100
101 switch (tree.nodeTag(node)) {101 switch (tree.nodeTag(node)) {
102 .root => unreachable,102 .root => unreachable,
103 .@"usingnamespace" => unreachable,
104 .test_decl => unreachable,103 .test_decl => unreachable,
105 .container_field_init => unreachable,104 .container_field_init => unreachable,
106 .container_field_align => unreachable,105 .container_field_align => unreachable,
lib/std/zig/parser_test.zig-63
...@@ -3936,14 +3936,6 @@ test "zig fmt: Block after if" {...@@ -3936,14 +3936,6 @@ test "zig fmt: Block after if" {
3936 );3936 );
3937}3937}
39383938
3939test "zig fmt: usingnamespace" {
3940 try testCanonical(
3941 \\usingnamespace @import("std");
3942 \\pub usingnamespace @import("std");
3943 \\
3944 );
3945}
3946
3947test "zig fmt: string identifier" {3939test "zig fmt: string identifier" {
3948 try testCanonical(3940 try testCanonical(
3949 \\const @"a b" = @"c d".@"e f";3941 \\const @"a b" = @"c d".@"e f";
...@@ -5087,17 +5079,6 @@ test "zig fmt: line comment after multiline single expr if statement with multil...@@ -5087,17 +5079,6 @@ test "zig fmt: line comment after multiline single expr if statement with multil
5087 );5079 );
5088}5080}
50895081
5090test "zig fmt: respect extra newline between fn and pub usingnamespace" {
5091 try testCanonical(
5092 \\fn foo() void {
5093 \\ bar();
5094 \\}
5095 \\
5096 \\pub usingnamespace baz;
5097 \\
5098 );
5099}
5100
5101test "zig fmt: respect extra newline between switch items" {5082test "zig fmt: respect extra newline between switch items" {
5102 try testCanonical(5083 try testCanonical(
5103 \\const a = switch (b) {5084 \\const a = switch (b) {
...@@ -5666,34 +5647,6 @@ test "zig fmt: canonicalize symbols (primitive types)" {...@@ -5666,34 +5647,6 @@ test "zig fmt: canonicalize symbols (primitive types)" {
5666 );5647 );
5667}5648}
56685649
5669// Never unescape names spelled like keywords.
5670test "zig fmt: canonicalize symbols (keywords)" {
5671 try testCanonical(
5672 \\const @"enum" = struct {
5673 \\ @"error": @"struct" = true,
5674 \\ const @"struct" = bool;
5675 \\};
5676 \\
5677 \\fn @"usingnamespace"(@"union": @"enum") error{@"try"}!void {
5678 \\ var @"struct" = @"union";
5679 \\ @"struct".@"error" = false;
5680 \\ if (@"struct".@"error") {
5681 \\ return @"usingnamespace"(.{ .@"error" = false });
5682 \\ } else {
5683 \\ return error.@"try";
5684 \\ }
5685 \\}
5686 \\
5687 \\test @"usingnamespace" {
5688 \\ try @"usingnamespace"(.{});
5689 \\ _ = @"return": {
5690 \\ break :@"return" 4;
5691 \\ };
5692 \\}
5693 \\
5694 );
5695}
5696
5697test "zig fmt: no space before newline before multiline string" {5650test "zig fmt: no space before newline before multiline string" {
5698 try testCanonical(5651 try testCanonical(
5699 \\const S = struct {5652 \\const S = struct {
...@@ -6156,22 +6109,6 @@ test "recovery: missing semicolon" {...@@ -6156,22 +6109,6 @@ test "recovery: missing semicolon" {
6156 });6109 });
6157}6110}
61586111
6159test "recovery: invalid container members" {
6160 try testError(
6161 \\usingnamespace;
6162 \\@foo()+
6163 \\@bar()@,
6164 \\while (a == 2) { test "" {}}
6165 \\test "" {
6166 \\ a & b
6167 \\}
6168 , &[_]Error{
6169 .expected_expr,
6170 .expected_comma_after_field,
6171 .expected_semi_after_stmt,
6172 });
6173}
6174
6175// TODO after https://github.com/ziglang/zig/issues/35 is implemented,6112// TODO after https://github.com/ziglang/zig/issues/35 is implemented,
6176// we should be able to recover from this *at any indentation level*,6113// we should be able to recover from this *at any indentation level*,
6177// reporting a parse error and yet also parsing all the decls even6114// reporting a parse error and yet also parsing all the decls even
lib/std/zig/render.zig-12
...@@ -262,17 +262,6 @@ fn renderMember(...@@ -262,17 +262,6 @@ fn renderMember(
262 return renderToken(r, tree.lastToken(decl) + 1, space); // semicolon262 return renderToken(r, tree.lastToken(decl) + 1, space); // semicolon
263 },263 },
264264
265 .@"usingnamespace" => {
266 const main_token = tree.nodeMainToken(decl);
267 const expr = tree.nodeData(decl).node;
268 if (tree.isTokenPrecededByTags(main_token, &.{.keyword_pub})) {
269 try renderToken(r, main_token - 1, .space); // pub
270 }
271 try renderToken(r, main_token, .space); // usingnamespace
272 try renderExpression(r, expr, .none);
273 return renderToken(r, tree.lastToken(expr) + 1, space); // ;
274 },
275
276 .global_var_decl,265 .global_var_decl,
277 .local_var_decl,266 .local_var_decl,
278 .simple_var_decl,267 .simple_var_decl,
...@@ -877,7 +866,6 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {...@@ -877,7 +866,6 @@ fn renderExpression(r: *Render, node: Ast.Node.Index, space: Space) Error!void {
877 .local_var_decl => unreachable,866 .local_var_decl => unreachable,
878 .simple_var_decl => unreachable,867 .simple_var_decl => unreachable,
879 .aligned_var_decl => unreachable,868 .aligned_var_decl => unreachable,
880 .@"usingnamespace" => unreachable,
881 .test_decl => unreachable,869 .test_decl => unreachable,
882 .asm_output => unreachable,870 .asm_output => unreachable,
883 .asm_input => unreachable,871 .asm_input => unreachable,
lib/std/zig/tokenizer.zig-3
...@@ -53,7 +53,6 @@ pub const Token = struct {...@@ -53,7 +53,6 @@ pub const Token = struct {
53 .{ "try", .keyword_try },53 .{ "try", .keyword_try },
54 .{ "union", .keyword_union },54 .{ "union", .keyword_union },
55 .{ "unreachable", .keyword_unreachable },55 .{ "unreachable", .keyword_unreachable },
56 .{ "usingnamespace", .keyword_usingnamespace },
57 .{ "var", .keyword_var },56 .{ "var", .keyword_var },
58 .{ "volatile", .keyword_volatile },57 .{ "volatile", .keyword_volatile },
59 .{ "while", .keyword_while },58 .{ "while", .keyword_while },
...@@ -180,7 +179,6 @@ pub const Token = struct {...@@ -180,7 +179,6 @@ pub const Token = struct {
180 keyword_try,179 keyword_try,
181 keyword_union,180 keyword_union,
182 keyword_unreachable,181 keyword_unreachable,
183 keyword_usingnamespace,
184 keyword_var,182 keyword_var,
185 keyword_volatile,183 keyword_volatile,
186 keyword_while,184 keyword_while,
...@@ -305,7 +303,6 @@ pub const Token = struct {...@@ -305,7 +303,6 @@ pub const Token = struct {
305 .keyword_try => "try",303 .keyword_try => "try",
306 .keyword_union => "union",304 .keyword_union => "union",
307 .keyword_unreachable => "unreachable",305 .keyword_unreachable => "unreachable",
308 .keyword_usingnamespace => "usingnamespace",
309 .keyword_var => "var",306 .keyword_var => "var",
310 .keyword_volatile => "volatile",307 .keyword_volatile => "volatile",
311 .keyword_while => "while",308 .keyword_while => "while",
src/InternPool.zig+1-13
...@@ -518,8 +518,6 @@ pub const Nav = struct {...@@ -518,8 +518,6 @@ pub const Nav = struct {
518 namespace: NamespaceIndex,518 namespace: NamespaceIndex,
519 zir_index: TrackedInst.Index,519 zir_index: TrackedInst.Index,
520 },520 },
521 /// TODO: this is a hack! If #20663 isn't accepted, let's figure out something a bit better.
522 is_usingnamespace: bool,
523 status: union(enum) {521 status: union(enum) {
524 /// This `Nav` is pending semantic analysis.522 /// This `Nav` is pending semantic analysis.
525 unresolved,523 unresolved,
...@@ -735,7 +733,7 @@ pub const Nav = struct {...@@ -735,7 +733,7 @@ pub const Nav = struct {
735 @"addrspace": std.builtin.AddressSpace,733 @"addrspace": std.builtin.AddressSpace,
736 /// Populated only if `bits.status == .type_resolved`.734 /// Populated only if `bits.status == .type_resolved`.
737 is_threadlocal: bool,735 is_threadlocal: bool,
738 is_usingnamespace: bool,736 _: u1 = 0,
739 };737 };
740738
741 fn unpack(repr: Repr) Nav {739 fn unpack(repr: Repr) Nav {
...@@ -749,7 +747,6 @@ pub const Nav = struct {...@@ -749,7 +747,6 @@ pub const Nav = struct {
749 assert(repr.analysis_zir_index == .none);747 assert(repr.analysis_zir_index == .none);
750 break :a null;748 break :a null;
751 },749 },
752 .is_usingnamespace = repr.bits.is_usingnamespace,
753 .status = switch (repr.bits.status) {750 .status = switch (repr.bits.status) {
754 .unresolved => .unresolved,751 .unresolved => .unresolved,
755 .type_resolved, .type_resolved_extern_decl => .{ .type_resolved = .{752 .type_resolved, .type_resolved_extern_decl => .{ .type_resolved = .{
...@@ -797,7 +794,6 @@ pub const Nav = struct {...@@ -797,7 +794,6 @@ pub const Nav = struct {
797 .is_const = false,794 .is_const = false,
798 .alignment = .none,795 .alignment = .none,
799 .@"addrspace" = .generic,796 .@"addrspace" = .generic,
800 .is_usingnamespace = nav.is_usingnamespace,
801 .is_threadlocal = false,797 .is_threadlocal = false,
802 },798 },
803 .type_resolved => |r| .{799 .type_resolved => |r| .{
...@@ -805,7 +801,6 @@ pub const Nav = struct {...@@ -805,7 +801,6 @@ pub const Nav = struct {
805 .is_const = r.is_const,801 .is_const = r.is_const,
806 .alignment = r.alignment,802 .alignment = r.alignment,
807 .@"addrspace" = r.@"addrspace",803 .@"addrspace" = r.@"addrspace",
808 .is_usingnamespace = nav.is_usingnamespace,
809 .is_threadlocal = r.is_threadlocal,804 .is_threadlocal = r.is_threadlocal,
810 },805 },
811 .fully_resolved => |r| .{806 .fully_resolved => |r| .{
...@@ -813,7 +808,6 @@ pub const Nav = struct {...@@ -813,7 +808,6 @@ pub const Nav = struct {
813 .is_const = r.is_const,808 .is_const = r.is_const,
814 .alignment = r.alignment,809 .alignment = r.alignment,
815 .@"addrspace" = r.@"addrspace",810 .@"addrspace" = r.@"addrspace",
816 .is_usingnamespace = nav.is_usingnamespace,
817 .is_threadlocal = false,811 .is_threadlocal = false,
818 },812 },
819 },813 },
...@@ -6865,8 +6859,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -6865,8 +6859,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
6865 {6859 {
6866 namespace.pub_decls.deinit(gpa);6860 namespace.pub_decls.deinit(gpa);
6867 namespace.priv_decls.deinit(gpa);6861 namespace.priv_decls.deinit(gpa);
6868 namespace.pub_usingnamespace.deinit(gpa);
6869 namespace.priv_usingnamespace.deinit(gpa);
6870 namespace.comptime_decls.deinit(gpa);6862 namespace.comptime_decls.deinit(gpa);
6871 namespace.test_decls.deinit(gpa);6863 namespace.test_decls.deinit(gpa);
6872 }6864 }
...@@ -11503,7 +11495,6 @@ pub fn createNav(...@@ -11503,7 +11495,6 @@ pub fn createNav(
11503 .@"linksection" = opts.@"linksection",11495 .@"linksection" = opts.@"linksection",
11504 .@"addrspace" = opts.@"addrspace",11496 .@"addrspace" = opts.@"addrspace",
11505 } },11497 } },
11506 .is_usingnamespace = false,
11507 }));11498 }));
11508 return index_unwrapped.wrap(ip);11499 return index_unwrapped.wrap(ip);
11509}11500}
...@@ -11518,8 +11509,6 @@ pub fn createDeclNav(...@@ -11518,8 +11509,6 @@ pub fn createDeclNav(
11518 fqn: NullTerminatedString,11509 fqn: NullTerminatedString,
11519 zir_index: TrackedInst.Index,11510 zir_index: TrackedInst.Index,
11520 namespace: NamespaceIndex,11511 namespace: NamespaceIndex,
11521 /// TODO: this is hacky! See `Nav.is_usingnamespace`.
11522 is_usingnamespace: bool,
11523) Allocator.Error!Nav.Index {11512) Allocator.Error!Nav.Index {
11524 const navs = ip.getLocal(tid).getMutableNavs(gpa);11513 const navs = ip.getLocal(tid).getMutableNavs(gpa);
1152511514
...@@ -11538,7 +11527,6 @@ pub fn createDeclNav(...@@ -11538,7 +11527,6 @@ pub fn createDeclNav(
11538 .zir_index = zir_index,11527 .zir_index = zir_index,
11539 },11528 },
11540 .status = .unresolved,11529 .status = .unresolved,
11541 .is_usingnamespace = is_usingnamespace,
11542 }));11530 }));
1154311531
11544 return nav;11532 return nav;
src/Sema.zig+15-100
...@@ -2860,7 +2860,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2860,7 +2860,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2860 sema.code.nullTerminatedString(str),2860 sema.code.nullTerminatedString(str),
2861 .no_embedded_nulls,2861 .no_embedded_nulls,
2862 );2862 );
2863 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?2863 const nav = try sema.lookupIdentifier(block, decl_name);
2864 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });2864 break :capture InternPool.CaptureValue.wrap(.{ .nav_val = nav });
2865 },2865 },
2866 .decl_ref => |str| capture: {2866 .decl_ref => |str| capture: {
...@@ -2870,7 +2870,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us...@@ -2870,7 +2870,7 @@ fn getCaptures(sema: *Sema, block: *Block, type_src: LazySrcLoc, extra_index: us
2870 sema.code.nullTerminatedString(str),2870 sema.code.nullTerminatedString(str),
2871 .no_embedded_nulls,2871 .no_embedded_nulls,
2872 );2872 );
2873 const nav = try sema.lookupIdentifier(block, LazySrcLoc.unneeded, decl_name); // TODO: could we need this src loc?2873 const nav = try sema.lookupIdentifier(block, decl_name);
2874 break :capture InternPool.CaptureValue.wrap(.{ .nav_ref = nav });2874 break :capture InternPool.CaptureValue.wrap(.{ .nav_ref = nav });
2875 },2875 },
2876 };2876 };
...@@ -6925,7 +6925,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6925,7 +6925,7 @@ fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6925 inst_data.get(sema.code),6925 inst_data.get(sema.code),
6926 .no_embedded_nulls,6926 .no_embedded_nulls,
6927 );6927 );
6928 const nav_index = try sema.lookupIdentifier(block, src, decl_name);6928 const nav_index = try sema.lookupIdentifier(block, decl_name);
6929 return sema.analyzeNavRef(block, src, nav_index);6929 return sema.analyzeNavRef(block, src, nav_index);
6930}6930}
69316931
...@@ -6940,16 +6940,16 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -6940,16 +6940,16 @@ fn zirDeclVal(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
6940 inst_data.get(sema.code),6940 inst_data.get(sema.code),
6941 .no_embedded_nulls,6941 .no_embedded_nulls,
6942 );6942 );
6943 const nav = try sema.lookupIdentifier(block, src, decl_name);6943 const nav = try sema.lookupIdentifier(block, decl_name);
6944 return sema.analyzeNavVal(block, src, nav);6944 return sema.analyzeNavVal(block, src, nav);
6945}6945}
69466946
6947fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPool.NullTerminatedString) !InternPool.Nav.Index {6947fn lookupIdentifier(sema: *Sema, block: *Block, name: InternPool.NullTerminatedString) !InternPool.Nav.Index {
6948 const pt = sema.pt;6948 const pt = sema.pt;
6949 const zcu = pt.zcu;6949 const zcu = pt.zcu;
6950 var namespace = block.namespace;6950 var namespace = block.namespace;
6951 while (true) {6951 while (true) {
6952 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |lookup| {6952 if (try sema.lookupInNamespace(block, namespace, name)) |lookup| {
6953 assert(lookup.accessible);6953 assert(lookup.accessible);
6954 return lookup.nav;6954 return lookup.nav;
6955 }6955 }
...@@ -6958,15 +6958,12 @@ fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPoo...@@ -6958,15 +6958,12 @@ fn lookupIdentifier(sema: *Sema, block: *Block, src: LazySrcLoc, name: InternPoo
6958 unreachable; // AstGen detects use of undeclared identifiers.6958 unreachable; // AstGen detects use of undeclared identifiers.
6959}6959}
69606960
6961/// This looks up a member of a specific namespace. It is affected by `usingnamespace` but6961/// This looks up a member of a specific namespace.
6962/// only for ones in the specified namespace.
6963fn lookupInNamespace(6962fn lookupInNamespace(
6964 sema: *Sema,6963 sema: *Sema,
6965 block: *Block,6964 block: *Block,
6966 src: LazySrcLoc,
6967 namespace_index: InternPool.NamespaceIndex,6965 namespace_index: InternPool.NamespaceIndex,
6968 ident_name: InternPool.NullTerminatedString,6966 ident_name: InternPool.NullTerminatedString,
6969 observe_usingnamespace: bool,
6970) CompileError!?struct {6967) CompileError!?struct {
6971 nav: InternPool.Nav.Index,6968 nav: InternPool.Nav.Index,
6972 /// If `false`, the declaration is in a different file and is not `pub`.6969 /// If `false`, the declaration is in a different file and is not `pub`.
...@@ -6975,7 +6972,6 @@ fn lookupInNamespace(...@@ -6975,7 +6972,6 @@ fn lookupInNamespace(
6975} {6972} {
6976 const pt = sema.pt;6973 const pt = sema.pt;
6977 const zcu = pt.zcu;6974 const zcu = pt.zcu;
6978 const ip = &zcu.intern_pool;
69796975
6980 try pt.ensureNamespaceUpToDate(namespace_index);6976 try pt.ensureNamespaceUpToDate(namespace_index);
69816977
...@@ -6992,75 +6988,7 @@ fn lookupInNamespace(...@@ -6992,75 +6988,7 @@ fn lookupInNamespace(
6992 } });6988 } });
6993 }6989 }
69946990
6995 if (observe_usingnamespace and (namespace.pub_usingnamespace.items.len != 0 or namespace.priv_usingnamespace.items.len != 0)) {6991 if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
6996 const gpa = sema.gpa;
6997 var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Namespace, void) = .empty;
6998 defer checked_namespaces.deinit(gpa);
6999
7000 // Keep track of name conflicts for error notes.
7001 var candidates: std.ArrayListUnmanaged(InternPool.Nav.Index) = .empty;
7002 defer candidates.deinit(gpa);
7003
7004 try checked_namespaces.put(gpa, namespace, {});
7005 var check_i: usize = 0;
7006
7007 while (check_i < checked_namespaces.count()) : (check_i += 1) {
7008 const check_ns = checked_namespaces.keys()[check_i];
7009 const Pass = enum { @"pub", priv };
7010 for ([2]Pass{ .@"pub", .priv }) |pass| {
7011 if (pass == .priv and src_file != check_ns.file_scope) {
7012 continue;
7013 }
7014
7015 const decls, const usingnamespaces = switch (pass) {
7016 .@"pub" => .{ &check_ns.pub_decls, &check_ns.pub_usingnamespace },
7017 .priv => .{ &check_ns.priv_decls, &check_ns.priv_usingnamespace },
7018 };
7019
7020 if (decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
7021 try candidates.append(gpa, nav_index);
7022 }
7023
7024 for (usingnamespaces.items) |sub_ns_nav| {
7025 try sema.ensureNavResolved(block, src, sub_ns_nav, .fully);
7026 const sub_ns_ty: Type = .fromInterned(ip.getNav(sub_ns_nav).status.fully_resolved.val);
7027 const sub_ns = zcu.namespacePtr(sub_ns_ty.getNamespaceIndex(zcu));
7028 try checked_namespaces.put(gpa, sub_ns, {});
7029 }
7030 }
7031 }
7032
7033 ignore_self: {
7034 const skip_nav = switch (sema.owner.unwrap()) {
7035 .@"comptime", .type, .func, .memoized_state => break :ignore_self,
7036 .nav_ty, .nav_val => |nav| nav,
7037 };
7038 var i: usize = 0;
7039 while (i < candidates.items.len) {
7040 if (candidates.items[i] == skip_nav) {
7041 _ = candidates.orderedRemove(i);
7042 } else {
7043 i += 1;
7044 }
7045 }
7046 }
7047
7048 switch (candidates.items.len) {
7049 0 => {},
7050 1 => return .{
7051 .nav = candidates.items[0],
7052 .accessible = true,
7053 },
7054 else => return sema.failWithOwnedErrorMsg(block, msg: {
7055 const msg = try sema.errMsg(src, "ambiguous reference", .{});
7056 errdefer msg.destroy(gpa);
7057 for (candidates.items) |candidate| {
7058 try sema.errNote(zcu.navSrcLoc(candidate), msg, "declared here", .{});
7059 }
7060 break :msg msg;
7061 }),
7062 }
7063 } else if (namespace.pub_decls.getKeyAdapted(ident_name, adapter)) |nav_index| {
7064 return .{6992 return .{
7065 .nav = nav_index,6993 .nav = nav_index,
7066 .accessible = true,6994 .accessible = true,
...@@ -13946,7 +13874,6 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13946,7 +13874,6 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13946 const zcu = pt.zcu;13874 const zcu = pt.zcu;
13947 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;13875 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
13948 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;13876 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
13949 const src = block.nodeOffset(inst_data.src_node);
13950 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);13877 const lhs_src = block.builtinCallArgSrc(inst_data.src_node, 0);
13951 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);13878 const rhs_src = block.builtinCallArgSrc(inst_data.src_node, 1);
13952 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);13879 const container_type = try sema.resolveType(block, lhs_src, extra.lhs);
...@@ -13955,7 +13882,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air...@@ -13955,7 +13882,7 @@ fn zirHasDecl(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
13955 try sema.checkNamespaceType(block, lhs_src, container_type);13882 try sema.checkNamespaceType(block, lhs_src, container_type);
1395613883
13957 const namespace = container_type.getNamespace(zcu).unwrap() orelse return .bool_false;13884 const namespace = container_type.getNamespace(zcu).unwrap() orelse return .bool_false;
13958 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {13885 if (try sema.lookupInNamespace(block, namespace, decl_name)) |lookup| {
13959 if (lookup.accessible) {13886 if (lookup.accessible) {
13960 return .bool_true;13887 return .bool_true;
13961 }13888 }
...@@ -17736,7 +17663,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17736,7 +17663,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17736 } });17663 } });
17737 };17664 };
1773817665
17739 const decls_val = try sema.typeInfoDecls(block, src, ip.loadEnumType(ty.toIntern()).namespace.toOptional());17666 const decls_val = try sema.typeInfoDecls(src, ip.loadEnumType(ty.toIntern()).namespace.toOptional());
1774017667
17741 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");17668 const type_enum_ty = try sema.getBuiltinType(src, .@"Type.Enum");
1774217669
...@@ -17849,7 +17776,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -17849,7 +17776,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
17849 } });17776 } });
17850 };17777 };
1785117778
17852 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespaceIndex(zcu).toOptional());17779 const decls_val = try sema.typeInfoDecls(src, ty.getNamespaceIndex(zcu).toOptional());
1785317780
17854 const enum_tag_ty_val = try pt.intern(.{ .opt = .{17781 const enum_tag_ty_val = try pt.intern(.{ .opt = .{
17855 .ty = (try pt.optionalType(.type_type)).toIntern(),17782 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -18044,7 +17971,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18044,7 +17971,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18044 } });17971 } });
18045 };17972 };
1804617973
18047 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));17974 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));
1804817975
18049 const backing_integer_val = try pt.intern(.{ .opt = .{17976 const backing_integer_val = try pt.intern(.{ .opt = .{
18050 .ty = (try pt.optionalType(.type_type)).toIntern(),17977 .ty = (try pt.optionalType(.type_type)).toIntern(),
...@@ -18083,7 +18010,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18083,7 +18010,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
18083 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");18010 const type_opaque_ty = try sema.getBuiltinType(src, .@"Type.Opaque");
1808418011
18085 try ty.resolveFields(pt);18012 try ty.resolveFields(pt);
18086 const decls_val = try sema.typeInfoDecls(block, src, ty.getNamespace(zcu));18013 const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu));
1808718014
18088 const field_values = .{18015 const field_values = .{
18089 // decls: []const Declaration,18016 // decls: []const Declaration,
...@@ -18105,7 +18032,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai...@@ -18105,7 +18032,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1810518032
18106fn typeInfoDecls(18033fn typeInfoDecls(
18107 sema: *Sema,18034 sema: *Sema,
18108 block: *Block,
18109 src: LazySrcLoc,18035 src: LazySrcLoc,
18110 opt_namespace: InternPool.OptionalNamespaceIndex,18036 opt_namespace: InternPool.OptionalNamespaceIndex,
18111) CompileError!InternPool.Index {18037) CompileError!InternPool.Index {
...@@ -18121,7 +18047,7 @@ fn typeInfoDecls(...@@ -18121,7 +18047,7 @@ fn typeInfoDecls(
18121 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);18047 var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa);
18122 defer seen_namespaces.deinit();18048 defer seen_namespaces.deinit();
1812318049
18124 try sema.typeInfoNamespaceDecls(block, src, opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);18050 try sema.typeInfoNamespaceDecls(opt_namespace, declaration_ty, &decl_vals, &seen_namespaces);
1812518051
18126 const array_decl_ty = try pt.arrayType(.{18052 const array_decl_ty = try pt.arrayType(.{
18127 .len = decl_vals.items.len,18053 .len = decl_vals.items.len,
...@@ -18155,8 +18081,6 @@ fn typeInfoDecls(...@@ -18155,8 +18081,6 @@ fn typeInfoDecls(
1815518081
18156fn typeInfoNamespaceDecls(18082fn typeInfoNamespaceDecls(
18157 sema: *Sema,18083 sema: *Sema,
18158 block: *Block,
18159 src: LazySrcLoc,
18160 opt_namespace_index: InternPool.OptionalNamespaceIndex,18084 opt_namespace_index: InternPool.OptionalNamespaceIndex,
18161 declaration_ty: Type,18085 declaration_ty: Type,
18162 decl_vals: *std.ArrayList(InternPool.Index),18086 decl_vals: *std.ArrayList(InternPool.Index),
...@@ -18212,15 +18136,6 @@ fn typeInfoNamespaceDecls(...@@ -18212,15 +18136,6 @@ fn typeInfoNamespaceDecls(
18212 .storage = .{ .elems = &fields },18136 .storage = .{ .elems = &fields },
18213 } }));18137 } }));
18214 }18138 }
18215
18216 for (namespace.pub_usingnamespace.items) |nav| {
18217 if (zcu.analysis_in_progress.contains(.wrap(.{ .nav_val = nav }))) {
18218 continue;
18219 }
18220 try sema.ensureNavResolved(block, src, nav, .fully);
18221 const namespace_ty: Type = .fromInterned(ip.getNav(nav).status.fully_resolved.val);
18222 try sema.typeInfoNamespaceDecls(block, src, namespace_ty.getNamespaceIndex(zcu).toOptional(), declaration_ty, decl_vals, seen_namespaces);
18223 }
18224}18139}
1822518140
18226fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {18141fn zirTypeof(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
...@@ -27709,7 +27624,7 @@ fn namespaceLookup(...@@ -27709,7 +27624,7 @@ fn namespaceLookup(
27709 const pt = sema.pt;27624 const pt = sema.pt;
27710 const zcu = pt.zcu;27625 const zcu = pt.zcu;
27711 const gpa = sema.gpa;27626 const gpa = sema.gpa;
27712 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |lookup| {27627 if (try sema.lookupInNamespace(block, namespace, decl_name)) |lookup| {
27713 if (!lookup.accessible) {27628 if (!lookup.accessible) {
27714 return sema.failWithOwnedErrorMsg(block, msg: {27629 return sema.failWithOwnedErrorMsg(block, msg: {
27715 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{27630 const msg = try sema.errMsg(src, "'{}' is not marked 'pub'", .{
src/Zcu.zig-29
...@@ -792,10 +792,6 @@ pub const Namespace = struct {...@@ -792,10 +792,6 @@ pub const Namespace = struct {
792 pub_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .empty,792 pub_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .empty,
793 /// Members of the namespace which are *not* marked `pub`.793 /// Members of the namespace which are *not* marked `pub`.
794 priv_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .empty,794 priv_decls: std.ArrayHashMapUnmanaged(InternPool.Nav.Index, void, NavNameContext, true) = .empty,
795 /// All `usingnamespace` declarations in this namespace which are marked `pub`.
796 pub_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .empty,
797 /// All `usingnamespace` declarations in this namespace which are *not* marked `pub`.
798 priv_usingnamespace: std.ArrayListUnmanaged(InternPool.Nav.Index) = .empty,
799 /// All `comptime` declarations in this namespace. We store these purely so that incremental795 /// All `comptime` declarations in this namespace. We store these purely so that incremental
800 /// compilation can re-use the existing `ComptimeUnit`s when a namespace changes.796 /// compilation can re-use the existing `ComptimeUnit`s when a namespace changes.
801 comptime_decls: std.ArrayListUnmanaged(InternPool.ComptimeUnit.Id) = .empty,797 comptime_decls: std.ArrayListUnmanaged(InternPool.ComptimeUnit.Id) = .empty,
...@@ -1303,9 +1299,6 @@ pub const SrcLoc = struct {...@@ -1303,9 +1299,6 @@ pub const SrcLoc = struct {
1303 .simple_var_decl,1299 .simple_var_decl,
1304 .aligned_var_decl,1300 .aligned_var_decl,
1305 => tree.fullVarDecl(node).?,1301 => tree.fullVarDecl(node).?,
1306 .@"usingnamespace" => {
1307 return tree.nodeToSpan(tree.nodeData(node).node);
1308 },
1309 else => unreachable,1302 else => unreachable,
1310 };1303 };
1311 if (full.ast.type_node.unwrap()) |type_node| {1304 if (full.ast.type_node.unwrap()) |type_node| {
...@@ -3391,9 +3384,6 @@ pub fn mapOldZirToNew(...@@ -3391,9 +3384,6 @@ pub fn mapOldZirToNew(
3391 // All comptime declarations, in order, for a best-effort match.3384 // All comptime declarations, in order, for a best-effort match.
3392 var comptime_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .empty;3385 var comptime_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .empty;
3393 defer comptime_decls.deinit(gpa);3386 defer comptime_decls.deinit(gpa);
3394 // All usingnamespace declarations, in order, for a best-effort match.
3395 var usingnamespace_decls: std.ArrayListUnmanaged(Zir.Inst.Index) = .empty;
3396 defer usingnamespace_decls.deinit(gpa);
33973387
3398 {3388 {
3399 var old_decl_it = old_zir.declIterator(match_item.old_inst);3389 var old_decl_it = old_zir.declIterator(match_item.old_inst);
...@@ -3401,7 +3391,6 @@ pub fn mapOldZirToNew(...@@ -3401,7 +3391,6 @@ pub fn mapOldZirToNew(
3401 const old_decl = old_zir.getDeclaration(old_decl_inst);3391 const old_decl = old_zir.getDeclaration(old_decl_inst);
3402 switch (old_decl.kind) {3392 switch (old_decl.kind) {
3403 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),3393 .@"comptime" => try comptime_decls.append(gpa, old_decl_inst),
3404 .@"usingnamespace" => try usingnamespace_decls.append(gpa, old_decl_inst),
3405 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),3394 .unnamed_test => try unnamed_tests.append(gpa, old_decl_inst),
3406 .@"test" => try named_tests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),3395 .@"test" => try named_tests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
3407 .decltest => try named_decltests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),3396 .decltest => try named_decltests.put(gpa, old_zir.nullTerminatedString(old_decl.name), old_decl_inst),
...@@ -3412,7 +3401,6 @@ pub fn mapOldZirToNew(...@@ -3412,7 +3401,6 @@ pub fn mapOldZirToNew(
34123401
3413 var unnamed_test_idx: u32 = 0;3402 var unnamed_test_idx: u32 = 0;
3414 var comptime_decl_idx: u32 = 0;3403 var comptime_decl_idx: u32 = 0;
3415 var usingnamespace_decl_idx: u32 = 0;
34163404
3417 var new_decl_it = new_zir.declIterator(match_item.new_inst);3405 var new_decl_it = new_zir.declIterator(match_item.new_inst);
3418 while (new_decl_it.next()) |new_decl_inst| {3406 while (new_decl_it.next()) |new_decl_inst| {
...@@ -3422,7 +3410,6 @@ pub fn mapOldZirToNew(...@@ -3422,7 +3410,6 @@ pub fn mapOldZirToNew(
3422 // * For named tests (`test "foo"`) and decltests (`test foo`), we also match based on name.3410 // * For named tests (`test "foo"`) and decltests (`test foo`), we also match based on name.
3423 // * For unnamed tests, we match based on order.3411 // * For unnamed tests, we match based on order.
3424 // * For comptime blocks, we match based on order.3412 // * For comptime blocks, we match based on order.
3425 // * For usingnamespace decls, we match based on order.
3426 // If we cannot match this declaration, we can't match anything nested inside of it either, so we just `continue`.3413 // If we cannot match this declaration, we can't match anything nested inside of it either, so we just `continue`.
3427 const old_decl_inst = switch (new_decl.kind) {3414 const old_decl_inst = switch (new_decl.kind) {
3428 .@"comptime" => inst: {3415 .@"comptime" => inst: {
...@@ -3430,11 +3417,6 @@ pub fn mapOldZirToNew(...@@ -3430,11 +3417,6 @@ pub fn mapOldZirToNew(
3430 defer comptime_decl_idx += 1;3417 defer comptime_decl_idx += 1;
3431 break :inst comptime_decls.items[comptime_decl_idx];3418 break :inst comptime_decls.items[comptime_decl_idx];
3432 },3419 },
3433 .@"usingnamespace" => inst: {
3434 if (usingnamespace_decl_idx == usingnamespace_decls.items.len) continue;
3435 defer usingnamespace_decl_idx += 1;
3436 break :inst usingnamespace_decls.items[usingnamespace_decl_idx];
3437 },
3438 .unnamed_test => inst: {3420 .unnamed_test => inst: {
3439 if (unnamed_test_idx == unnamed_tests.items.len) continue;3421 if (unnamed_test_idx == unnamed_tests.items.len) continue;
3440 defer unnamed_test_idx += 1;3422 defer unnamed_test_idx += 1;
...@@ -4143,7 +4125,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv...@@ -4143,7 +4125,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
4143 if (!comp.config.is_test or file.mod != zcu.main_mod) continue;4125 if (!comp.config.is_test or file.mod != zcu.main_mod) continue;
41444126
4145 const want_analysis = switch (decl.kind) {4127 const want_analysis = switch (decl.kind) {
4146 .@"usingnamespace" => unreachable,
4147 .@"const", .@"var" => unreachable,4128 .@"const", .@"var" => unreachable,
4148 .@"comptime" => unreachable,4129 .@"comptime" => unreachable,
4149 .unnamed_test => true,4130 .unnamed_test => true,
...@@ -4201,16 +4182,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv...@@ -4201,16 +4182,6 @@ fn resolveReferencesInner(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, ?Resolv
4201 }4182 }
4202 }4183 }
4203 }4184 }
4204 // Incremental compilation does not support `usingnamespace`.
4205 // These are only included to keep good reference traces in non-incremental updates.
4206 for (zcu.namespacePtr(ns).pub_usingnamespace.items) |nav| {
4207 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
4208 if (!result.contains(unit)) try unit_queue.put(gpa, unit, referencer);
4209 }
4210 for (zcu.namespacePtr(ns).priv_usingnamespace.items) |nav| {
4211 const unit: AnalUnit = .wrap(.{ .nav_val = nav });
4212 if (!result.contains(unit)) try unit_queue.put(gpa, unit, referencer);
4213 }
4214 continue;4185 continue;
4215 }4186 }
4216 if (unit_queue.pop()) |kv| {4187 if (unit_queue.pop()) |kv| {
src/Zcu/PerThread.zig+3-54
...@@ -1111,7 +1111,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1111,7 +1111,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1111 defer block.instructions.deinit(gpa);1111 defer block.instructions.deinit(gpa);
11121112
1113 const zir_decl = zir.getDeclaration(inst_resolved.inst);1113 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1114 assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace"));
11151114
1116 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });1115 const ty_src = block.src(.{ .node_offset_var_decl_ty = .zero });
1117 const init_src = block.src(.{ .node_offset_var_decl_init = .zero });1116 const init_src = block.src(.{ .node_offset_var_decl_init = .zero });
...@@ -1160,7 +1159,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1160,7 +1159,7 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1160 assert(nav_ty.zigTypeTag(zcu) == .@"fn");1159 assert(nav_ty.zigTypeTag(zcu) == .@"fn");
1161 break :is_const true;1160 break :is_const true;
1162 },1161 },
1163 .@"usingnamespace", .@"const" => true,1162 .@"const" => true,
1164 .@"var" => {1163 .@"var" => {
1165 try sema.validateVarType(1164 try sema.validateVarType(
1166 &block,1165 &block,
...@@ -1240,26 +1239,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr...@@ -1240,26 +1239,6 @@ fn analyzeNavVal(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileErr
1240 // this resolves the type `type` (which needs no resolution), not the struct itself.1239 // this resolves the type `type` (which needs no resolution), not the struct itself.
1241 try nav_ty.resolveLayout(pt);1240 try nav_ty.resolveLayout(pt);
12421241
1243 // TODO: this is jank. If #20663 is rejected, let's think about how to better model `usingnamespace`.
1244 if (zir_decl.kind == .@"usingnamespace") {
1245 if (nav_ty.toIntern() != .type_type) {
1246 return sema.fail(&block, ty_src, "expected type, found {}", .{nav_ty.fmt(pt)});
1247 }
1248 if (nav_val.toType().getNamespace(zcu) == .none) {
1249 return sema.fail(&block, ty_src, "type {} has no namespace", .{nav_val.toType().fmt(pt)});
1250 }
1251 ip.resolveNavValue(nav_id, .{
1252 .val = nav_val.toIntern(),
1253 .is_const = is_const,
1254 .alignment = .none,
1255 .@"linksection" = .none,
1256 .@"addrspace" = .generic,
1257 });
1258 // TODO: usingnamespace cannot participate in incremental compilation
1259 assert(zcu.analysis_in_progress.swapRemove(anal_unit));
1260 return .{ .val_changed = true };
1261 }
1262
1263 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {1242 const queue_linker_work, const is_owned_fn = switch (ip.indexToKey(nav_val.toIntern())) {
1264 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen1243 .func => |f| .{ true, f.owner_nav == nav_id }, // note that this lets function aliases reach codegen
1265 .variable => |v| .{ v.owner_nav == nav_id, false },1244 .variable => |v| .{ v.owner_nav == nav_id, false },
...@@ -1464,7 +1443,6 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1464,7 +1443,6 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
1464 defer _ = zcu.analysis_in_progress.swapRemove(anal_unit);1443 defer _ = zcu.analysis_in_progress.swapRemove(anal_unit);
14651444
1466 const zir_decl = zir.getDeclaration(inst_resolved.inst);1445 const zir_decl = zir.getDeclaration(inst_resolved.inst);
1467 assert(old_nav.is_usingnamespace == (zir_decl.kind == .@"usingnamespace"));
1468 const type_body = zir_decl.type_body.?;1446 const type_body = zir_decl.type_body.?;
14691447
1470 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);1448 var analysis_arena: std.heap.ArenaAllocator = .init(gpa);
...@@ -1527,7 +1505,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr...@@ -1527,7 +1505,7 @@ fn analyzeNavType(pt: Zcu.PerThread, nav_id: InternPool.Nav.Index) Zcu.CompileEr
15271505
1528 const is_const = switch (zir_decl.kind) {1506 const is_const = switch (zir_decl.kind) {
1529 .@"comptime" => unreachable,1507 .@"comptime" => unreachable,
1530 .unnamed_test, .@"test", .decltest, .@"usingnamespace", .@"const" => true,1508 .unnamed_test, .@"test", .decltest, .@"const" => true,
1531 .@"var" => false,1509 .@"var" => false,
1532 };1510 };
15331511
...@@ -2541,7 +2519,6 @@ pub fn scanNamespace(...@@ -2541,7 +2519,6 @@ pub fn scanNamespace(
25412519
2542 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(2520 try existing_by_inst.ensureTotalCapacity(gpa, @intCast(
2543 namespace.pub_decls.count() + namespace.priv_decls.count() +2521 namespace.pub_decls.count() + namespace.priv_decls.count() +
2544 namespace.pub_usingnamespace.items.len + namespace.priv_usingnamespace.items.len +
2545 namespace.comptime_decls.items.len +2522 namespace.comptime_decls.items.len +
2546 namespace.test_decls.items.len,2523 namespace.test_decls.items.len,
2547 ));2524 ));
...@@ -2554,14 +2531,6 @@ pub fn scanNamespace(...@@ -2554,14 +2531,6 @@ pub fn scanNamespace(
2554 const zir_index = ip.getNav(nav).analysis.?.zir_index;2531 const zir_index = ip.getNav(nav).analysis.?.zir_index;
2555 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .nav_val = nav }));2532 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .nav_val = nav }));
2556 }2533 }
2557 for (namespace.pub_usingnamespace.items) |nav| {
2558 const zir_index = ip.getNav(nav).analysis.?.zir_index;
2559 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .nav_val = nav }));
2560 }
2561 for (namespace.priv_usingnamespace.items) |nav| {
2562 const zir_index = ip.getNav(nav).analysis.?.zir_index;
2563 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .nav_val = nav }));
2564 }
2565 for (namespace.comptime_decls.items) |cu| {2534 for (namespace.comptime_decls.items) |cu| {
2566 const zir_index = ip.getComptimeUnit(cu).zir_index;2535 const zir_index = ip.getComptimeUnit(cu).zir_index;
2567 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .@"comptime" = cu }));2536 existing_by_inst.putAssumeCapacityNoClobber(zir_index, .wrap(.{ .@"comptime" = cu }));
...@@ -2578,8 +2547,6 @@ pub fn scanNamespace(...@@ -2578,8 +2547,6 @@ pub fn scanNamespace(
25782547
2579 namespace.pub_decls.clearRetainingCapacity();2548 namespace.pub_decls.clearRetainingCapacity();
2580 namespace.priv_decls.clearRetainingCapacity();2549 namespace.priv_decls.clearRetainingCapacity();
2581 namespace.pub_usingnamespace.clearRetainingCapacity();
2582 namespace.priv_usingnamespace.clearRetainingCapacity();
2583 namespace.comptime_decls.clearRetainingCapacity();2550 namespace.comptime_decls.clearRetainingCapacity();
2584 namespace.test_decls.clearRetainingCapacity();2551 namespace.test_decls.clearRetainingCapacity();
25852552
...@@ -2607,7 +2574,6 @@ const ScanDeclIter = struct {...@@ -2607,7 +2574,6 @@ const ScanDeclIter = struct {
2607 /// Decl scanning is run in two passes, so that we can detect when a generated2574 /// Decl scanning is run in two passes, so that we can detect when a generated
2608 /// name would clash with an explicit name and use a different one.2575 /// name would clash with an explicit name and use a different one.
2609 pass: enum { named, unnamed },2576 pass: enum { named, unnamed },
2610 usingnamespace_index: usize = 0,
2611 unnamed_test_index: usize = 0,2577 unnamed_test_index: usize = 0,
26122578
2613 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {2579 fn avoidNameConflict(iter: *ScanDeclIter, comptime fmt: []const u8, args: anytype) !InternPool.NullTerminatedString {
...@@ -2646,12 +2612,6 @@ const ScanDeclIter = struct {...@@ -2646,12 +2612,6 @@ const ScanDeclIter = struct {
2646 if (iter.pass != .unnamed) return;2612 if (iter.pass != .unnamed) return;
2647 break :name .none;2613 break :name .none;
2648 },2614 },
2649 .@"usingnamespace" => name: {
2650 if (iter.pass != .unnamed) return;
2651 const i = iter.usingnamespace_index;
2652 iter.usingnamespace_index += 1;
2653 break :name (try iter.avoidNameConflict("usingnamespace_{d}", .{i})).toOptional();
2654 },
2655 .unnamed_test => name: {2615 .unnamed_test => name: {
2656 if (iter.pass != .unnamed) return;2616 if (iter.pass != .unnamed) return;
2657 const i = iter.unnamed_test_index;2617 const i = iter.unnamed_test_index;
...@@ -2710,7 +2670,7 @@ const ScanDeclIter = struct {...@@ -2710,7 +2670,7 @@ const ScanDeclIter = struct {
2710 const name = maybe_name.unwrap().?;2670 const name = maybe_name.unwrap().?;
2711 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);2671 const fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, name);
2712 const nav = if (existing_unit) |eu| eu.unwrap().nav_val else nav: {2672 const nav = if (existing_unit) |eu| eu.unwrap().nav_val else nav: {
2713 const nav = try ip.createDeclNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index, decl.kind == .@"usingnamespace");2673 const nav = try ip.createDeclNav(gpa, pt.tid, name, fqn, tracked_inst, namespace_index);
2714 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);2674 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newNav(zcu, nav);
2715 break :nav nav;2675 break :nav nav;
2716 };2676 };
...@@ -2722,17 +2682,6 @@ const ScanDeclIter = struct {...@@ -2722,17 +2682,6 @@ const ScanDeclIter = struct {
27222682
2723 const want_analysis = switch (decl.kind) {2683 const want_analysis = switch (decl.kind) {
2724 .@"comptime" => unreachable,2684 .@"comptime" => unreachable,
2725 .@"usingnamespace" => a: {
2726 if (comp.incremental) {
2727 @panic("'usingnamespace' is not supported by incremental compilation");
2728 }
2729 if (decl.is_pub) {
2730 try namespace.pub_usingnamespace.append(gpa, nav);
2731 } else {
2732 try namespace.priv_usingnamespace.append(gpa, nav);
2733 }
2734 break :a true;
2735 },
2736 .unnamed_test, .@"test", .decltest => a: {2685 .unnamed_test, .@"test", .decltest => a: {
2737 const is_named = decl.kind != .unnamed_test;2686 const is_named = decl.kind != .unnamed_test;
2738 try namespace.test_decls.append(gpa, nav);2687 try namespace.test_decls.append(gpa, nav);
src/link/Dwarf.zig+2-2
...@@ -2489,7 +2489,7 @@ fn initWipNavInner(...@@ -2489,7 +2489,7 @@ fn initWipNavInner(
2489 const addr: Loc = .{ .addr_reloc = sym_index };2489 const addr: Loc = .{ .addr_reloc = sym_index };
2490 const loc: Loc = if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr;2490 const loc: Loc = if (decl.is_threadlocal) .{ .form_tls_address = &addr } else addr;
2491 switch (decl.kind) {2491 switch (decl.kind) {
2492 .unnamed_test, .@"test", .decltest, .@"comptime", .@"usingnamespace" => unreachable,2492 .unnamed_test, .@"test", .decltest, .@"comptime" => unreachable,
2493 .@"const" => {2493 .@"const" => {
2494 const const_ty_reloc_index = try wip_nav.refForward();2494 const const_ty_reloc_index = try wip_nav.refForward();
2495 try wip_nav.infoExprLoc(loc);2495 try wip_nav.infoExprLoc(loc);
...@@ -2775,7 +2775,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo...@@ -2775,7 +2775,7 @@ fn updateComptimeNavInner(dwarf: *Dwarf, pt: Zcu.PerThread, nav_index: InternPoo
27752775
2776 const is_test = switch (decl.kind) {2776 const is_test = switch (decl.kind) {
2777 .unnamed_test, .@"test", .decltest => true,2777 .unnamed_test, .@"test", .decltest => true,
2778 .@"comptime", .@"usingnamespace", .@"const", .@"var" => false,2778 .@"comptime", .@"const", .@"var" => false,
2779 };2779 };
2780 if (is_test) {2780 if (is_test) {
2781 // This isn't actually a comptime Nav! It's a test, so it'll definitely never be referenced at comptime.2781 // This isn't actually a comptime Nav! It's a test, so it'll definitely never be referenced at comptime.
src/print_zir.zig-1
...@@ -2588,7 +2588,6 @@ const Writer = struct {...@@ -2588,7 +2588,6 @@ const Writer = struct {
2588 }2588 }
2589 switch (decl.kind) {2589 switch (decl.kind) {
2590 .@"comptime" => try stream.writeAll("comptime"),2590 .@"comptime" => try stream.writeAll("comptime"),
2591 .@"usingnamespace" => try stream.writeAll("usingnamespace"),
2592 .unnamed_test => try stream.writeAll("test"),2591 .unnamed_test => try stream.writeAll("test"),
2593 .@"test", .decltest, .@"const", .@"var" => {2592 .@"test", .decltest, .@"const", .@"var" => {
2594 try stream.print("{s} '{s}'", .{ @tagName(decl.kind), self.code.nullTerminatedString(decl.name) });2593 try stream.print("{s} '{s}'", .{ @tagName(decl.kind), self.code.nullTerminatedString(decl.name) });
test/behavior.zig-1
...@@ -101,7 +101,6 @@ test {...@@ -101,7 +101,6 @@ test {
101 _ = @import("behavior/underscore.zig");101 _ = @import("behavior/underscore.zig");
102 _ = @import("behavior/union.zig");102 _ = @import("behavior/union.zig");
103 _ = @import("behavior/union_with_members.zig");103 _ = @import("behavior/union_with_members.zig");
104 _ = @import("behavior/usingnamespace.zig");
105 _ = @import("behavior/var_args.zig");104 _ = @import("behavior/var_args.zig");
106 // https://github.com/llvm/llvm-project/issues/118879105 // https://github.com/llvm/llvm-project/issues/118879
107 // https://github.com/llvm/llvm-project/issues/134659106 // https://github.com/llvm/llvm-project/issues/134659
test/behavior/basic.zig-21
...@@ -1107,27 +1107,6 @@ test "inline call of function with a switch inside the return statement" {...@@ -1107,27 +1107,6 @@ test "inline call of function with a switch inside the return statement" {
1107 try expect(S.foo(1) == 1);1107 try expect(S.foo(1) == 1);
1108}1108}
11091109
1110test "ambiguous reference error ignores current declaration" {
1111 const S = struct {
1112 const foo = 666;
1113
1114 const a = @This();
1115 const b = struct {
1116 const foo = a.foo;
1117 const bar = struct {
1118 bar: u32 = b.foo,
1119 };
1120
1121 comptime {
1122 _ = b.foo;
1123 }
1124 };
1125
1126 usingnamespace b;
1127 };
1128 try expect(S.b.foo == 666);
1129}
1130
1131test "pointer to zero sized global is mutable" {1110test "pointer to zero sized global is mutable" {
1132 const S = struct {1111 const S = struct {
1133 const Thing = struct {};1112 const Thing = struct {};
test/behavior/call.zig-23
...@@ -507,29 +507,6 @@ test "call inline fn through pointer" {...@@ -507,29 +507,6 @@ test "call inline fn through pointer" {
507 try f(123);507 try f(123);
508}508}
509509
510test "call coerced function" {
511 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
512
513 const T = struct {
514 x: f64,
515 const T = @This();
516 usingnamespace Implement(1);
517 const F = fn (comptime f64) type;
518 const Implement: F = opaque {
519 fn implementer(comptime val: anytype) type {
520 return opaque {
521 fn incr(self: T) T {
522 return .{ .x = self.x + val };
523 }
524 };
525 }
526 }.implementer;
527 };
528
529 const a = T{ .x = 3 };
530 try std.testing.expect(a.incr().x == 4);
531}
532
533test "call function in comptime field" {510test "call function in comptime field" {
534 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO511 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
535512
test/behavior/import.zig-10
...@@ -18,16 +18,6 @@ test "importing the same thing gives the same import" {...@@ -18,16 +18,6 @@ test "importing the same thing gives the same import" {
18 try expect(@import("std") == @import("std"));18 try expect(@import("std") == @import("std"));
19}19}
2020
21test "import in non-toplevel scope" {
22 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
24
25 const S = struct {
26 usingnamespace @import("import/a_namespace.zig");
27 };
28 try expect(@as(i32, 1234) == S.foo());
29}
30
31test "import empty file" {21test "import empty file" {
32 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;22 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
33 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;23 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
test/behavior/struct.zig-11
...@@ -236,17 +236,6 @@ test "call method with mutable reference to struct with no fields" {...@@ -236,17 +236,6 @@ test "call method with mutable reference to struct with no fields" {
236 try expect(s.do());236 try expect(s.do());
237}237}
238238
239test "usingnamespace within struct scope" {
240 const S = struct {
241 usingnamespace struct {
242 pub fn inner() i32 {
243 return 42;
244 }
245 };
246 };
247 try expect(@as(i32, 42) == S.inner());
248}
249
250test "struct field init with catch" {239test "struct field init with catch" {
251 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
252 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO241 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
test/behavior/type_info.zig-83
...@@ -592,24 +592,6 @@ test "StructField.is_comptime" {...@@ -592,24 +592,6 @@ test "StructField.is_comptime" {
592 try expect(info.fields[1].is_comptime);592 try expect(info.fields[1].is_comptime);
593}593}
594594
595test "typeInfo resolves usingnamespace declarations" {
596 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
597
598 const A = struct {
599 pub const f1 = 42;
600 };
601
602 const B = struct {
603 pub const f0 = 42;
604 pub usingnamespace A;
605 };
606
607 const decls = @typeInfo(B).@"struct".decls;
608 try expect(decls.len == 2);
609 try expectEqualStrings(decls[0].name, "f0");
610 try expectEqualStrings(decls[1].name, "f1");
611}
612
613test "value from struct @typeInfo default_value_ptr can be loaded at comptime" {595test "value from struct @typeInfo default_value_ptr can be loaded at comptime" {
614 comptime {596 comptime {
615 const a = @typeInfo(@TypeOf(.{ .foo = @as(u8, 1) })).@"struct".fields[0].default_value_ptr;597 const a = @typeInfo(@TypeOf(.{ .foo = @as(u8, 1) })).@"struct".fields[0].default_value_ptr;
...@@ -617,77 +599,12 @@ test "value from struct @typeInfo default_value_ptr can be loaded at comptime" {...@@ -617,77 +599,12 @@ test "value from struct @typeInfo default_value_ptr can be loaded at comptime" {
617 }599 }
618}600}
619601
620test "@typeInfo decls and usingnamespace" {
621 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
622 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
623 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
624
625 const A = struct {
626 pub const x = 5;
627 pub const y = 34;
628
629 comptime {}
630 };
631 const B = struct {
632 pub usingnamespace A;
633 pub const z = 56;
634
635 test {}
636 };
637 const decls = @typeInfo(B).@"struct".decls;
638 try expect(decls.len == 3);
639 try expectEqualStrings(decls[0].name, "z");
640 try expectEqualStrings(decls[1].name, "x");
641 try expectEqualStrings(decls[2].name, "y");
642}
643
644test "@typeInfo decls ignore dependency loops" {
645 const S = struct {
646 pub fn Def(comptime T: type) type {
647 std.debug.assert(@typeInfo(T).@"struct".decls.len == 1);
648 return struct {
649 const foo = u32;
650 };
651 }
652 usingnamespace Def(@This());
653 };
654 _ = S.foo;
655}
656
657test "type info of tuple of string literal default value" {602test "type info of tuple of string literal default value" {
658 const struct_field = @typeInfo(@TypeOf(.{"hi"})).@"struct".fields[0];603 const struct_field = @typeInfo(@TypeOf(.{"hi"})).@"struct".fields[0];
659 const value = struct_field.defaultValue().?;604 const value = struct_field.defaultValue().?;
660 comptime std.debug.assert(value[0] == 'h');605 comptime std.debug.assert(value[0] == 'h');
661}606}
662607
663test "@typeInfo only contains pub decls" {
664 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
665
666 const other = struct {
667 const std = @import("std");
668
669 usingnamespace struct {
670 pub const inside_non_pub_usingnamespace = 0;
671 };
672
673 pub const Enum = enum {
674 a,
675 b,
676 c,
677 };
678
679 pub const Struct = struct {
680 foo: i32,
681 };
682 };
683 const ti = @typeInfo(other);
684 const decls = ti.@"struct".decls;
685
686 try std.testing.expectEqual(2, decls.len);
687 try std.testing.expectEqualStrings("Enum", decls[0].name);
688 try std.testing.expectEqualStrings("Struct", decls[1].name);
689}
690
691test "@typeInfo function with generic return type and inferred error set" {608test "@typeInfo function with generic return type and inferred error set" {
692 const S = struct {609 const S = struct {
693 fn testFn(comptime T: type) !T {}610 fn testFn(comptime T: type) !T {}
test/behavior/usingnamespace.zig deleted-125
...@@ -1,125 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5const A = struct {
6 pub const B = bool;
7};
8
9const C = struct {
10 usingnamespace A;
11};
12
13test "basic usingnamespace" {
14 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
15 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
16
17 try std.testing.expect(C.B == bool);
18}
19
20fn Foo(comptime T: type) type {
21 return struct {
22 usingnamespace T;
23 };
24}
25
26test "usingnamespace inside a generic struct" {
27 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
28 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
29
30 const std2 = Foo(std);
31 const testing2 = Foo(std.testing);
32 try std2.testing.expect(true);
33 try testing2.expect(true);
34}
35
36usingnamespace struct {
37 pub const foo = 42;
38};
39
40test "usingnamespace does not redeclare an imported variable" {
41 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
42 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
43
44 try comptime std.testing.expect(@This().foo == 42);
45}
46
47usingnamespace @import("usingnamespace/foo.zig");
48test "usingnamespace omits mixing in private functions" {
49 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
50 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
51 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
52 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
53
54 try expect(@This().privateFunction());
55 try expect(!@This().printText());
56}
57fn privateFunction() bool {
58 return true;
59}
60
61test {
62 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
63 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
64
65 _ = @import("usingnamespace/import_segregation.zig");
66}
67
68usingnamespace @import("usingnamespace/a.zig");
69test "two files usingnamespace import each other" {
70 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
71 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
72 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
73 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
74
75 try expect(@This().ok());
76}
77
78test {
79 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
80 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
81 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
82 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
83
84 const AA = struct {
85 x: i32,
86 fn b(x: i32) @This() {
87 return .{ .x = x };
88 }
89 fn c() type {
90 return if (true) struct {
91 const expected: i32 = 42;
92 } else struct {};
93 }
94 usingnamespace c();
95 };
96 const a = AA.b(42);
97 try expect(a.x == AA.c().expected);
98}
99
100const Bar = struct {
101 usingnamespace Mixin;
102};
103
104const Mixin = struct {
105 pub fn two(self: Bar) void {
106 _ = self;
107 }
108};
109
110test "container member access usingnamespace decls" {
111 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
113
114 var foo = Bar{};
115 foo.two();
116}
117
118usingnamespace opaque {};
119
120usingnamespace @Type(.{ .@"struct" = .{
121 .layout = .auto,
122 .fields = &.{},
123 .decls = &.{},
124 .is_tuple = false,
125} });
test/behavior/usingnamespace/a.zig deleted-7
...@@ -1,7 +0,0 @@
1usingnamespace @import("b.zig");
2
3pub const a_text = "OK\n";
4
5pub fn ok() bool {
6 return @import("std").mem.eql(u8, @This().b_text, "OK\n");
7}
test/behavior/usingnamespace/b.zig deleted-3
...@@ -1,3 +0,0 @@
1usingnamespace @import("a.zig");
2
3pub const b_text = @This().a_text;
test/behavior/usingnamespace/bar.zig deleted-8
...@@ -1,8 +0,0 @@
1usingnamespace @import("other.zig");
2
3pub var saw_bar_function = false;
4pub fn bar_function() void {
5 if (@This().foo_function()) {
6 saw_bar_function = true;
7 }
8}
test/behavior/usingnamespace/foo.zig deleted-14
...@@ -1,14 +0,0 @@
1// purposefully conflicting function with main source file
2// but it's private so it should be OK
3fn privateFunction() bool {
4 return false;
5}
6
7pub fn printText() bool {
8 return privateFunction();
9}
10
11pub var saw_foo_function = false;
12pub fn foo_function() void {
13 saw_foo_function = true;
14}
test/behavior/usingnamespace/import_segregation.zig deleted-20
...@@ -1,20 +0,0 @@
1const expect = @import("std").testing.expect;
2const builtin = @import("builtin");
3
4usingnamespace @import("foo.zig");
5usingnamespace @import("bar.zig");
6
7test "no clobbering happened" {
8 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
9 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
10
11 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch.isMIPS()) {
12 // https://github.com/ziglang/zig/issues/16846
13 return error.SkipZigTest;
14 }
15
16 @This().foo_function();
17 @This().bar_function();
18 try expect(@This().saw_foo_function);
19 try expect(@This().saw_bar_function);
20}
test/behavior/usingnamespace/other.zig deleted-4
...@@ -1,4 +0,0 @@
1pub fn foo_function() bool {
2 // this one conflicts with the one from foo
3 return true;
4}
test/cases/compile_errors/bad_usingnamespace_transitive_failure.zig deleted-31
...@@ -1,31 +0,0 @@
1//! The full test name would be:
2//! struct field type resolution marks transitive error from bad usingnamespace in @typeInfo call from non-initial field type
3//!
4//! This test is rather esoteric. It's ensuring that errors triggered by `@typeInfo` analyzing
5//! a bad `usingnamespace` correctly trigger transitive errors when analyzed by struct field type
6//! resolution, meaning we don't incorrectly analyze code past the uses of `S`.
7
8const S = struct {
9 ok: u32,
10 bad: @typeInfo(T),
11};
12
13const T = struct {
14 pub usingnamespace @compileError("usingnamespace analyzed");
15};
16
17comptime {
18 const a: S = .{ .ok = 123, .bad = undefined };
19 _ = a;
20 @compileError("should not be reached");
21}
22
23comptime {
24 const b: S = .{ .ok = 123, .bad = undefined };
25 _ = b;
26 @compileError("should not be reached");
27}
28
29// error
30//
31// :14:24: error: usingnamespace analyzed
test/cases/compile_errors/usingnamespace_with_wrong_type.zig deleted-7
...@@ -1,7 +0,0 @@
1usingnamespace void;
2
3// error
4// backend=stage2
5// target=native
6//
7// :1:16: error: type void has no namespace
test/standalone/build.zig.zon-3
...@@ -48,9 +48,6 @@...@@ -48,9 +48,6 @@
48 .pkg_import = .{48 .pkg_import = .{
49 .path = "pkg_import",49 .path = "pkg_import",
50 },50 },
51 .use_alias = .{
52 .path = "use_alias",
53 },
54 .install_raw_hex = .{51 .install_raw_hex = .{
55 .path = "install_raw_hex",52 .path = "install_raw_hex",
56 },53 },
test/standalone/use_alias/build.zig deleted-17
...@@ -1,17 +0,0 @@
1const std = @import("std");
2
3pub fn build(b: *std.Build) void {
4 const test_step = b.step("test", "Test it");
5 b.default_step = test_step;
6
7 const optimize: std.builtin.OptimizeMode = .Debug;
8
9 const main = b.addTest(.{ .root_module = b.createModule(.{
10 .root_source_file = b.path("main.zig"),
11 .target = b.graph.host,
12 .optimize = optimize,
13 }) });
14 main.root_module.addIncludePath(b.path("."));
15
16 test_step.dependOn(&b.addRunArtifact(main).step);
17}
test/standalone/use_alias/c.zig deleted-1
...@@ -1 +0,0 @@
1pub usingnamespace @cImport(@cInclude("foo.h"));
test/standalone/use_alias/foo.h deleted-4
...@@ -1,4 +0,0 @@
1struct Foo {
2 int a;
3 int b;
4};
test/standalone/use_alias/main.zig deleted-11
...@@ -1,11 +0,0 @@
1const c = @import("c.zig");
2const expect = @import("std").testing.expect;
3
4test "symbol exists" {
5 var foo = c.Foo{
6 .a = 1,
7 .b = 1,
8 };
9 _ = &foo;
10 try expect(foo.a + foo.b == 2);
11}
tools/docgen.zig-1
...@@ -746,7 +746,6 @@ fn tokenizeAndPrintRaw(...@@ -746,7 +746,6 @@ fn tokenizeAndPrintRaw(
746 .keyword_try,746 .keyword_try,
747 .keyword_union,747 .keyword_union,
748 .keyword_unreachable,748 .keyword_unreachable,
749 .keyword_usingnamespace,
750 .keyword_var,749 .keyword_var,
751 .keyword_volatile,750 .keyword_volatile,
752 .keyword_allowzero,751 .keyword_allowzero,
tools/doctest.zig-1
...@@ -689,7 +689,6 @@ fn tokenizeAndPrint(arena: Allocator, out: anytype, raw_src: []const u8) !void {...@@ -689,7 +689,6 @@ fn tokenizeAndPrint(arena: Allocator, out: anytype, raw_src: []const u8) !void {
689 .keyword_try,689 .keyword_try,
690 .keyword_union,690 .keyword_union,
691 .keyword_unreachable,691 .keyword_unreachable,
692 .keyword_usingnamespace,
693 .keyword_var,692 .keyword_var,
694 .keyword_volatile,693 .keyword_volatile,
695 .keyword_allowzero,694 .keyword_allowzero,
tools/lldb_pretty_printers.py-1
...@@ -86,7 +86,6 @@ zig_keywords = {...@@ -86,7 +86,6 @@ zig_keywords = {
86 'try',86 'try',
87 'union',87 'union',
88 'unreachable',88 'unreachable',
89 'usingnamespace',
90 'var',89 'var',
91 'volatile',90 'volatile',
92 'while',91 'while',