authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-19 10:38:24-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-04-19 10:38:24-07:00
logb0f6889d121cae004687e381cd7b0d8156490433
tree5c7a7f232de11e5cbba8f20a361b7cbf3b5ae93b
parent9b177a7d21250b82cd18677c5c71ab04e431120d
parent571388a93d773e02aa88173d0ffec32ff2852e61

Merge pull request 'docs: langref: Clear up terminology used for top-level doc comments' (#31920) into master

Reviewed-on: https://codeberg.org/ziglang/zig/pulls/31920 Reviewed-by: Andrew Kelley <andrew@ziglang.org>

10 files changed, 143 insertions(+), 167 deletions(-)

doc/langref.html.in+50-73
......@@ -388,22 +388,15 @@
388388 </p>
389389 {#see_also|Values|Tuples|@import|Errors|Entry Point|Source Encoding|try#}
390390 {#header_close#}
391
391392 {#header_open|Comments#}
392 <p>
393 Zig supports 3 types of comments. Normal comments are ignored, but doc comments
394 and top-level doc comments are used by the compiler to generate the package documentation.
395 </p>
396 <p>
397 The generated documentation is still experimental, and can be produced with:
398 </p>
399 {#shell_samp#}zig test -femit-docs main.zig{#end_shell_samp#}
393 <p>There are three types of comments. Normal comments are ignored, while {#link|Doc Comments#}
394 and {#link|Top-Level Doc Comments#} are used by the compiler to generate
395 the package documentation.</p>
400396 {#code|comments.zig#}
401397
402 <p>
403 There are no multiline comments in Zig (e.g. like <code class="c">/* */</code>
404 comments in C). This allows Zig to have the property that each line
405 of code can be tokenized out of context.
406 </p>
398 <p>There are no multiline comments. Zig has the property that each line
399 of code can be tokenized independently.</p>
407400 {#header_open|Doc Comments#}
408401 <p>
409402 A doc comment is one that begins with exactly three slashes (i.e.
......@@ -429,17 +422,28 @@
429422 {#header_open|Top-Level Doc Comments#}
430423 <p>
431424 A top-level doc comment is one that begins with two slashes and an exclamation
432 point: {#syntax#}//!{#endsyntax#}; it documents the current module.
425 point: {#syntax#}//!{#endsyntax#}; it documents the type which owns the containing
426 {#link|Namespace#}.
433427 </p>
434428 <p>
435429 It is a compile error if a top-level doc comment is not placed at the start
436 of a {#link|container|Containers#}, before any expressions.
430 of a namespace, before any expressions.
437431 </p>
438432 {#code|tldoc_comments.zig#}
439433
440434 {#header_close#}
441435 {#header_close#}
442436
437 {#header_open|Namespace#}
438 <p>A namespace in Zig is created by {#link|struct#}, {#link|enum#}, {#link|union#}, and {#link|opaque#}.</p>
439 <p>They contain {#link|Namespace Level Variables#},
440 {#link|function|Functions#} declarations, and {#link|comptime#} blocks.</p>
441 <p>Although namespaces use curly braces to surround their definition,
442 they should not be confused with {#link|blocks|Blocks#} or function bodies.</p>
443 <p><strong>Every Zig source file is implicitly a struct</strong>, with the keyword
444 {#syntax#}struct{#endsyntax#} and curly braces omitted.</p>
445 {#header_close#}
446
443447 {#header_open|Identifiers#}
444448 <p>
445449 Identifiers must start with an alphabetic character or underscore and may be followed
......@@ -813,7 +817,7 @@
813817 {#code|destructuring_to_existing.zig#}
814818
815819 <p>
816 A destructuring expression may only appear within a block (i.e. not at container scope).
820 A destructuring expression may only appear within a block (i.e. not at {#link|Namespace#} scope).
817821 The left hand side of the assignment must consist of a comma separated list,
818822 each element of which may be either an lvalue (for instance, an existing `var`) or a variable declaration:
819823 </p>
......@@ -993,27 +997,23 @@
993997 </p>
994998 {#see_also|Exporting a C Library#}
995999
996 {#header_open|Container Level Variables#}
997 <p>
998 {#link|Container|Containers#} level variables have static lifetime and are order-independent and lazily analyzed.
999 The initialization value of container level variables is implicitly
1000 {#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is
1001 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
1002 </p>
1003 {#code|test_container_level_variables.zig#}
1004
1005 <p>
1006 Container level variables may be declared inside a {#link|struct#}, {#link|union#}, {#link|enum#}, or {#link|opaque#}:
1007 </p>
1008 {#code|test_namespaced_container_level_variable.zig#}
1000 {#header_open|Namespace Level Variables#}
1001 <p>{#link|Namespace|Namespace#} level variables have global lifetime and are
1002 order-independent and lazily analyzed. The initialization value of
1003 namespace level variables is implicitly {#link|comptime#}. If a namespace
1004 level variable is {#syntax#}const{#endsyntax#} then its value is
1005 {#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.</p>
1006 {#code|test_namespace_level_variables.zig#}
1007 <p>Namespace level variables may be declared inside a {#link|struct#},
1008 {#link|union#}, {#link|enum#}, or {#link|opaque#}:</p>
1009 {#code|test_namespaced_variable.zig#}
10091010
10101011 {#header_close#}
10111012
1012 {#header_open|Static Local Variables#}
1013 <p>
1014 It is also possible to have local variables with static lifetime by using containers inside functions.
1015 </p>
1016 {#code|test_static_local_variable.zig#}
1013 {#header_open|Locally-Scoped Global Variables#}
1014 <p>It is also possible to have local variables with global lifetime by
1015 using {#link|namespaces|Namespace#} inside functions.</p>
1016 {#code|test_locally_scoped_global_variable.zig#}
10171017
10181018 {#header_close#}
10191019
......@@ -1022,10 +1022,8 @@
10221022 {#syntax#}threadlocal{#endsyntax#} keyword,
10231023 which makes each thread work with a separate instance of the variable:</p>
10241024 {#code|test_thread_local_variables.zig#}
1025
1026 <p>
1027 For {#link|Single Threaded Builds#}, all thread local variables are treated as regular {#link|Container Level Variables#}.
1028 </p>
1025 <p>For {#link|Single Threaded Builds#}, all thread local variables are
1026 treated as regular {#link|Namespace Level Variables#}.</p>
10291027 <p>
10301028 Thread local variables may not be {#syntax#}const{#endsyntax#}.
10311029 </p>
......@@ -2470,7 +2468,7 @@ or
24702468 <p>Unions can be declared with an enum tag type.
24712469 This turns the union into a <em>tagged</em> union, which makes it eligible
24722470 to use with {#link|switch#} expressions. When switching on tagged unions,
2473 the tag value can be obtained using an additional capture.
2471 the tag value can be obtained using an additional capture.
24742472 Tagged unions coerce to their tag type: {#link|Type Coercion: Unions and Enums#}.
24752473 </p>
24762474 {#code|test_tagged_union.zig#}
......@@ -4123,13 +4121,11 @@ fn performFn(start_value: i32) i32 {
41234121 </p>
41244122 {#code|test_fibonacci_comptime_unreachable.zig#}
41254123
4126
4127 <p>
4128 At {#link|container|Containers#} level (outside of any function), all expressions are implicitly
4129 {#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
4130 initialize complex static data. For example:
4131 </p>
4132 {#code|test_container-level_comptime_expressions.zig#}
4124 <p>At {#link|Namespace#} level (outside of any function), all expressions
4125 are implicitly {#syntax#}comptime{#endsyntax#} expressions. This means
4126 that we can use functions to initialize complex constant data. For
4127 example:</p>
4128 {#code|test_namespace-level_comptime_expressions.zig#}
41334129
41344130 <p>
41354131 When we compile this program, Zig generates the constants
......@@ -4309,7 +4305,7 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
43094305
43104306 {#header_open|Global Assembly#}
43114307 <p>
4312 When an assembly expression occurs in a {#link|container|Containers#} level {#link|comptime#} block, this is
4308 When an assembly expression occurs in a {#link|Namespace#} level {#link|comptime#} block, this is
43134309 <strong>global assembly</strong>.
43144310 </p>
43154311 <p>
......@@ -4946,25 +4942,18 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
49464942 {#header_close#}
49474943
49484944 {#header_open|@hasDecl#}
4949 <pre>{#syntax#}@hasDecl(comptime Container: type, comptime name: []const u8) bool{#endsyntax#}</pre>
4950 <p>
4951 Returns whether or not a {#link|container|Containers#} has a declaration
4952 matching {#syntax#}name{#endsyntax#}.
4953 </p>
4945 <pre>{#syntax#}@hasDecl(comptime Namespace: type, comptime name: []const u8) bool{#endsyntax#}</pre>
4946 <p>Returns whether or not a {#link|Namespace#} has a declaration matching {#syntax#}name{#endsyntax#}.</p>
49544947 {#code|test_hasDecl_builtin.zig#}
49554948
49564949 {#see_also|@hasField#}
49574950 {#header_close#}
49584951
49594952 {#header_open|@hasField#}
4960 <pre>{#syntax#}@hasField(comptime Container: type, comptime name: []const u8) bool{#endsyntax#}</pre>
4953 <pre>{#syntax#}@hasField(comptime T: type, comptime name: []const u8) bool{#endsyntax#}</pre>
49614954 <p>Returns whether the field name of a struct, union, or enum exists.</p>
4962 <p>
4963 The result is a compile time constant.
4964 </p>
4965 <p>
4966 It does not include functions, variables, or constants.
4967 </p>
4955 <p>The result is a compile time constant.</p>
4956 <p>It does not include functions, variables, or constants.</p>
49684957 {#see_also|@hasDecl#}
49694958 {#header_close#}
49704959
......@@ -5980,7 +5969,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
59805969 {#header_open|Single Threaded Builds#}
59815970 <p>Zig has a compile option <kbd>-fsingle-threaded</kbd> which has the following effects:</p>
59825971 <ul>
5983 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Container Level Variables#}.</li>
5972 <li>All {#link|Thread Local Variables#} are treated as regular {#link|Namespace Level Variables#}.</li>
59845973 <li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
59855974 <li>The {#syntax#}@import("builtin").single_threaded{#endsyntax#} becomes {#syntax#}true{#endsyntax#}
59865975 and therefore various userland APIs which read this variable become more efficient.
......@@ -6635,7 +6624,7 @@ const builtin = @import("builtin");
66356624 {#header_open|Panic Handler#}
66366625 <p>
66376626 The Zig Standard Library looks for a declaration named {#syntax#}panic{#endsyntax#} in the root module's
6638 root source file. If present, it is expected to be a namespace (container type) with declarations
6627 root source file. If present, it is expected to be a {#link|Namespace#} with declarations
66396628 providing different panic handlers.
66406629 </p>
66416630 <p>
......@@ -7755,18 +7744,6 @@ fn readU32Be() u32 {}
77557744 {#header_close#}
77567745
77577746 {#header_open|Appendix#}
7758 {#header_open|Containers#}
7759 <p>
7760 A <em>container</em> in Zig is any syntactical construct that acts as a namespace to hold {#link|variable|Container Level Variables#} and {#link|function|Functions#} declarations.
7761 Containers are also type definitions which can be instantiated.
7762 {#link|Structs|struct#}, {#link|enums|enum#}, {#link|unions|union#}, {#link|opaques|opaque#}, and even Zig source files themselves are containers.
7763 </p>
7764 <p>
7765 Although containers (except Zig source files) use curly braces to surround their definition, they should not be confused with {#link|blocks|Blocks#} or functions.
7766 Containers do not contain statements.
7767 </p>
7768 {#header_close#}
7769
77707747 {#header_open|Grammar#}
77717748 {#syntax_block|peg|grammar.peg#}
77727749Root <- skip ContainerMembers eof
doc/langref/test_container-level_comptime_expressions.zig deleted-37
......@@ -1,37 +0,0 @@
1const first_25_primes = firstNPrimes(25);
2const sum_of_first_25_primes = sum(&first_25_primes);
3
4fn firstNPrimes(comptime n: usize) [n]i32 {
5 var prime_list: [n]i32 = undefined;
6 var next_index: usize = 0;
7 var test_number: i32 = 2;
8 while (next_index < prime_list.len) : (test_number += 1) {
9 var test_prime_index: usize = 0;
10 var is_prime = true;
11 while (test_prime_index < next_index) : (test_prime_index += 1) {
12 if (test_number % prime_list[test_prime_index] == 0) {
13 is_prime = false;
14 break;
15 }
16 }
17 if (is_prime) {
18 prime_list[next_index] = test_number;
19 next_index += 1;
20 }
21 }
22 return prime_list;
23}
24
25fn sum(numbers: []const i32) i32 {
26 var result: i32 = 0;
27 for (numbers) |x| {
28 result += x;
29 }
30 return result;
31}
32
33test "variable values" {
34 try @import("std").testing.expectEqual(1060, sum_of_first_25_primes);
35}
36
37// test
doc/langref/test_container_level_variables.zig deleted-16
......@@ -1,16 +0,0 @@
1var y: i32 = add(10, x);
2const x: i32 = add(12, 34);
3
4test "container level variables" {
5 try expectEqual(46, x);
6 try expectEqual(56, y);
7}
8
9fn add(a: i32, b: i32) i32 {
10 return a + b;
11}
12
13const std = @import("std");
14const expectEqual = std.testing.expectEqual;
15
16// test
doc/langref/test_locally_scoped_global_variable.zig created+17
......@@ -0,0 +1,17 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3
4test "static local variable" {
5 try expectEqual(1235, foo());
6 try expectEqual(1236, foo());
7}
8
9fn foo() i32 {
10 const S = struct {
11 var x: i32 = 1234;
12 };
13 S.x += 1;
14 return S.x;
15}
16
17// test
doc/langref/test_namespace-level_comptime_expressions.zig created+37
......@@ -0,0 +1,37 @@
1const first_25_primes = firstNPrimes(25);
2const sum_of_first_25_primes = sum(&first_25_primes);
3
4fn firstNPrimes(comptime n: usize) [n]i32 {
5 var prime_list: [n]i32 = undefined;
6 var next_index: usize = 0;
7 var test_number: i32 = 2;
8 while (next_index < prime_list.len) : (test_number += 1) {
9 var test_prime_index: usize = 0;
10 var is_prime = true;
11 while (test_prime_index < next_index) : (test_prime_index += 1) {
12 if (test_number % prime_list[test_prime_index] == 0) {
13 is_prime = false;
14 break;
15 }
16 }
17 if (is_prime) {
18 prime_list[next_index] = test_number;
19 next_index += 1;
20 }
21 }
22 return prime_list;
23}
24
25fn sum(numbers: []const i32) i32 {
26 var result: i32 = 0;
27 for (numbers) |x| {
28 result += x;
29 }
30 return result;
31}
32
33test "variable values" {
34 try @import("std").testing.expectEqual(1060, sum_of_first_25_primes);
35}
36
37// test
doc/langref/test_namespace_level_variables.zig created+16
......@@ -0,0 +1,16 @@
1var y: i32 = add(10, x);
2const x: i32 = add(12, 34);
3
4test "container level variables" {
5 try expectEqual(46, x);
6 try expectEqual(56, y);
7}
8
9fn add(a: i32, b: i32) i32 {
10 return a + b;
11}
12
13const std = @import("std");
14const expectEqual = std.testing.expectEqual;
15
16// test
doc/langref/test_namespaced_container_level_variable.zig deleted-18
......@@ -1,18 +0,0 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3
4test "namespaced container level variable" {
5 try expectEqual(1235, foo());
6 try expectEqual(1236, foo());
7}
8
9const S = struct {
10 var x: i32 = 1234;
11};
12
13fn foo() i32 {
14 S.x += 1;
15 return S.x;
16}
17
18// test
doc/langref/test_namespaced_variable.zig created+18
......@@ -0,0 +1,18 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3
4test "namespaced container level variable" {
5 try expectEqual(1235, foo());
6 try expectEqual(1236, foo());
7}
8
9const S = struct {
10 var x: i32 = 1234;
11};
12
13fn foo() i32 {
14 S.x += 1;
15 return S.x;
16}
17
18// test
doc/langref/test_static_local_variable.zig deleted-17
......@@ -1,17 +0,0 @@
1const std = @import("std");
2const expectEqual = std.testing.expectEqual;
3
4test "static local variable" {
5 try expectEqual(1235, foo());
6 try expectEqual(1236, foo());
7}
8
9fn foo() i32 {
10 const S = struct {
11 var x: i32 = 1234;
12 };
13 S.x += 1;
14 return S.x;
15}
16
17// test
doc/langref/tldoc_comments.zig+5-6
......@@ -1,11 +1,10 @@
1//! This module provides functions for retrieving the current date and
2//! time with varying degrees of precision and accuracy. It does not
3//! depend on libc, but will use functions from it if available.
1//! Provides functions for retrieving the current date and time with varying
2//! degrees of precision and accuracy.
43
54const S = struct {
6 //! Top level comments are allowed inside a container other than a module,
7 //! but it is not very useful. Currently, when producing the package
8 //! documentation, these comments are ignored.
5 //! Top level comments are allowed inside namespaces other than the
6 //! implicit struct created by files, but it is not very useful. Currently,
7 //! when producing the package documentation, these comments are ignored.
98};
109
1110// syntax