| ... | @@ -1156,10 +1156,8 @@ fn addOne(number: i32) i32 { | ... | @@ -1156,10 +1156,8 @@ fn addOne(number: i32) i32 { |
| 1156 | {#link|identifier|Identifiers#}, followed by a {#link|block|Blocks#} containing any valid Zig code that | 1156 | {#link|identifier|Identifiers#}, followed by a {#link|block|Blocks#} containing any valid Zig code that |
| 1157 | is allowed in a {#link|function|Functions#}. | 1157 | is allowed in a {#link|function|Functions#}. |
| 1158 | </p> | 1158 | </p> |
| 1159 | <aside> | 1159 | <p>Non-named test blocks always run during test builds and are exempt from |
| 1160 | By convention, non-named tests should only be used to {#link|make other tests run|Nested Container Tests#}. | 1160 | {#link|Skip Tests#}.</p> |
| 1161 | Non-named tests cannot be {#link|filtered|Skip Tests#}. | | |
| 1162 | </aside> | | |
| 1163 | <p> | 1161 | <p> |
| 1164 | Test declarations are similar to {#link|Functions#}: they have a return type and a block of code. The implicit | 1162 | Test declarations are similar to {#link|Functions#}: they have a return type and a block of code. The implicit |
| 1165 | return type of {#syntax#}test{#endsyntax#} is the {#link|Error Union Type#} {#syntax#}anyerror!void{#endsyntax#}, | 1163 | return type of {#syntax#}test{#endsyntax#} is the {#link|Error Union Type#} {#syntax#}anyerror!void{#endsyntax#}, |
| ... | @@ -1173,74 +1171,6 @@ fn addOne(number: i32) i32 { | ... | @@ -1173,74 +1171,6 @@ fn addOne(number: i32) i32 { |
| 1173 | </p> | 1171 | </p> |
| 1174 | {#see_also|The Global Error Set|Grammar#} | 1172 | {#see_also|The Global Error Set|Grammar#} |
| 1175 | {#header_close#} | 1173 | {#header_close#} |
| 1176 | {#header_open|Nested Container Tests#} | | |
| 1177 | <p> | | |
| 1178 | When the <kbd>zig test</kbd> tool is building a test runner, only resolved {#syntax#}test{#endsyntax#} | | |
| 1179 | declarations are included in the build. Initially, only the given Zig source file's top-level | | |
| 1180 | declarations are resolved. Unless nested {#link|containers|Containers#} are referenced from a top-level test declaration, | | |
| 1181 | nested container tests will not be resolved. | | |
| 1182 | </p> | | |
| 1183 | <p> | | |
| 1184 | The code sample below uses the {#syntax#}std.testing.refAllDecls(@This()){#endsyntax#} function call to | | |
| 1185 | reference all of the containers that are in the file including the imported Zig source file. The code | | |
| 1186 | sample also shows an alternative way to reference containers using the {#syntax#}_ = C;{#endsyntax#} | | |
| 1187 | syntax. This syntax tells the compiler to ignore the result of the expression on the right side of the | | |
| 1188 | assignment operator. | | |
| 1189 | </p> | | |
| 1190 | {#code_begin|test|testing_nested_container_tests#} | | |
| 1191 | const std = @import("std"); | | |
| 1192 | const expect = std.testing.expect; | | |
| 1193 | | | |
| 1194 | // Imported source file tests will run when referenced from a top-level test declaration. | | |
| 1195 | // The next line alone does not cause "testing_introduction.zig" tests to run. | | |
| 1196 | const imported_file = @import("testing_introduction.zig"); | | |
| 1197 | | | |
| 1198 | test { | | |
| 1199 | // To run nested container tests, either, call `refAllDecls` which will | | |
| 1200 | // reference all declarations located in the given argument. | | |
| 1201 | // `@This()` is a builtin function that returns the innermost container it is called from. | | |
| 1202 | // In this example, the innermost container is this file (implicitly a struct). | | |
| 1203 | std.testing.refAllDecls(@This()); | | |
| 1204 | | | |
| 1205 | // or, reference each container individually from a top-level test declaration. | | |
| 1206 | // The `_ = C;` syntax is a no-op reference to the identifier `C`. | | |
| 1207 | _ = S; | | |
| 1208 | _ = U; | | |
| 1209 | _ = @import("testing_introduction.zig"); | | |
| 1210 | } | | |
| 1211 | | | |
| 1212 | const S = struct { | | |
| 1213 | test "S demo test" { | | |
| 1214 | try expect(true); | | |
| 1215 | } | | |
| 1216 | | | |
| 1217 | const SE = enum { | | |
| 1218 | V, | | |
| 1219 | | | |
| 1220 | // This test won't run because its container (SE) is not referenced. | | |
| 1221 | test "This Test Won't Run" { | | |
| 1222 | try expect(false); | | |
| 1223 | } | | |
| 1224 | }; | | |
| 1225 | }; | | |
| 1226 | | | |
| 1227 | const U = union { // U is referenced by the file's top-level test declaration | | |
| 1228 | s: US, // and US is referenced here; therefore, "U.Us demo test" will run | | |
| 1229 | | | |
| 1230 | const US = struct { | | |
| 1231 | test "U.US demo test" { | | |
| 1232 | // This test is a top-level test declaration for the struct. | | |
| 1233 | // The struct is nested (declared) inside of a union. | | |
| 1234 | try expect(true); | | |
| 1235 | } | | |
| 1236 | }; | | |
| 1237 | | | |
| 1238 | test "U demo test" { | | |
| 1239 | try expect(true); | | |
| 1240 | } | | |
| 1241 | }; | | |
| 1242 | {#code_end#} | | |
| 1243 | {#header_close#} | | |
| 1244 | {#header_open|Test Failure#} | 1174 | {#header_open|Test Failure#} |
| 1245 | <p> | 1175 | <p> |
| 1246 | The default test runner checks for an {#link|error|Errors#} returned from a test. | 1176 | The default test runner checks for an {#link|error|Errors#} returned from a test. |
| ... | @@ -2856,9 +2786,11 @@ test "volatile" { | ... | @@ -2856,9 +2786,11 @@ test "volatile" { |
| 2856 | </p> | 2786 | </p> |
| 2857 | {#header_close#} | 2787 | {#header_close#} |
| 2858 | <p> | 2788 | <p> |
| 2859 | To convert one pointer type to another, use {#link|@ptrCast#}. This is an unsafe | 2789 | {#link|@ptrCast#} converts a pointer's element type to another. This |
| 2860 | operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other | 2790 | creates a new pointer that can cause undetectable illegal behavior |
| 2861 | conversions are not possible. | 2791 | depending on the loads and stores that pass through it. Generally, other |
| | 2792 | kinds of type conversions are preferable to |
| | 2793 | {#syntax#}@ptrCast{#endsyntax#} if possible. |
| 2862 | </p> | 2794 | </p> |
| 2863 | {#code_begin|test|test_pointer_casting#} | 2795 | {#code_begin|test|test_pointer_casting#} |
| 2864 | const std = @import("std"); | 2796 | const std = @import("std"); |
| ... | @@ -5075,12 +5007,12 @@ test "if error union with optional" { | ... | @@ -5075,12 +5007,12 @@ test "if error union with optional" { |
| 5075 | {#see_also|Optionals|Errors#} | 5007 | {#see_also|Optionals|Errors#} |
| 5076 | {#header_close#} | 5008 | {#header_close#} |
| 5077 | {#header_open|defer#} | 5009 | {#header_open|defer#} |
| | 5010 | <p>Executes an expression unconditionally at scope exit.</p> |
| 5078 | {#code_begin|test|test_defer#} | 5011 | {#code_begin|test|test_defer#} |
| 5079 | const std = @import("std"); | 5012 | const std = @import("std"); |
| 5080 | const expect = std.testing.expect; | 5013 | const expect = std.testing.expect; |
| 5081 | const print = std.debug.print; | 5014 | const print = std.debug.print; |
| 5082 | | 5015 | |
| 5083 | // defer will execute an expression at the end of the current scope. | | |
| 5084 | fn deferExample() !usize { | 5016 | fn deferExample() !usize { |
| 5085 | var a: usize = 1; | 5017 | var a: usize = 1; |
| 5086 | | 5018 | |
| ... | @@ -5097,10 +5029,14 @@ fn deferExample() !usize { | ... | @@ -5097,10 +5029,14 @@ fn deferExample() !usize { |
| 5097 | test "defer basics" { | 5029 | test "defer basics" { |
| 5098 | try expect((try deferExample()) == 5); | 5030 | try expect((try deferExample()) == 5); |
| 5099 | } | 5031 | } |
| | 5032 | {#code_end#} |
| | 5033 | <p>Defer expressions are evaluated in reverse order.</p> |
| | 5034 | {#code_begin|test|defer_unwind#} |
| | 5035 | const std = @import("std"); |
| | 5036 | const expect = std.testing.expect; |
| | 5037 | const print = std.debug.print; |
| 5100 | | 5038 | |
| 5101 | // If multiple defer statements are specified, they will be executed in | 5039 | test "defer unwinding" { |
| 5102 | // the reverse order they were run. | | |
| 5103 | fn deferUnwindExample() void { | | |
| 5104 | print("\n", .{}); | 5040 | print("\n", .{}); |
| 5105 | | 5041 | |
| 5106 | defer { | 5042 | defer { |
| ... | @@ -5116,63 +5052,15 @@ fn deferUnwindExample() void { | ... | @@ -5116,63 +5052,15 @@ fn deferUnwindExample() void { |
| 5116 | } | 5052 | } |
| 5117 | } | 5053 | } |
| 5118 | } | 5054 | } |
| 5119 | | | |
| 5120 | test "defer unwinding" { | | |
| 5121 | deferUnwindExample(); | | |
| 5122 | } | | |
| 5123 | {#code_end#} | 5055 | {#code_end#} |
| | 5056 | <p>Inside a defer expression the return statement is not allowed.</p> |
| 5124 | {#code_begin|test_err|test_invalid_defer|cannot return from defer expression#} | 5057 | {#code_begin|test_err|test_invalid_defer|cannot return from defer expression#} |
| 5125 | // Inside a defer expression the return statement is not allowed. | | |
| 5126 | fn deferInvalidExample() !void { | 5058 | fn deferInvalidExample() !void { |
| 5127 | defer { | 5059 | defer { |
| 5128 | return error.DeferError; | 5060 | return error.DeferError; |
| 5129 | } | 5061 | } |
| 5130 | | 5062 | |
| 5131 | return error.DeferError; | 5063 | return error.DeferError; |
| 5132 | } | | |
| 5133 | {#code_end#} | | |
| 5134 | {#code_begin|test|test_errdefer#} | | |
| 5135 | const std = @import("std"); | | |
| 5136 | const print = std.debug.print; | | |
| 5137 | | | |
| 5138 | // The errdefer keyword is similar to defer, but will only execute if the | | |
| 5139 | // scope returns with an error. | | |
| 5140 | // | | |
| 5141 | // This is especially useful in allowing a function to clean up properly | | |
| 5142 | // on error, and replaces goto error handling tactics as seen in c. | | |
| 5143 | fn deferErrorExample(is_error: bool) !void { | | |
| 5144 | print("\nstart of function\n", .{}); | | |
| 5145 | | | |
| 5146 | // This will always be executed on exit | | |
| 5147 | defer { | | |
| 5148 | print("end of function\n", .{}); | | |
| 5149 | } | | |
| 5150 | | | |
| 5151 | errdefer { | | |
| 5152 | print("encountered an error!\n", .{}); | | |
| 5153 | } | | |
| 5154 | | | |
| 5155 | if (is_error) { | | |
| 5156 | return error.DeferError; | | |
| 5157 | } | | |
| 5158 | } | | |
| 5159 | | | |
| 5160 | // The errdefer keyword also supports an alternative syntax to capture the | | |
| 5161 | // generated error. | | |
| 5162 | // | | |
| 5163 | // This is useful for printing an additional error message during clean up. | | |
| 5164 | fn deferErrorCaptureExample() !void { | | |
| 5165 | errdefer |err| { | | |
| 5166 | std.debug.print("the error is {s}\n", .{@errorName(err)}); | | |
| 5167 | } | | |
| 5168 | | | |
| 5169 | return error.DeferError; | | |
| 5170 | } | | |
| 5171 | | | |
| 5172 | test "errdefer unwinding" { | | |
| 5173 | deferErrorExample(false) catch {}; | | |
| 5174 | deferErrorExample(true) catch {}; | | |
| 5175 | deferErrorCaptureExample() catch {}; | | |
| 5176 | } | 5064 | } |
| 5177 | {#code_end#} | 5065 | {#code_end#} |
| 5178 | {#see_also|Errors#} | 5066 | {#see_also|Errors#} |
| ... | @@ -8660,7 +8548,8 @@ test "decl access by string" { | ... | @@ -8660,7 +8548,8 @@ test "decl access by string" { |
| 8660 | <pre>{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}</pre> | 8548 | <pre>{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}</pre> |
| 8661 | <p> | 8549 | <p> |
| 8662 | Converts an integer to the closest floating point representation. The return type is the inferred result type. | 8550 | Converts an integer to the closest floating point representation. The return type is the inferred result type. |
| 8663 | 			To convert the other way, use {#link|@intFromFloat#}. This cast is always safe. | 8551 | 			To convert the other way, use {#link|@intFromFloat#}. This operation is legal |
| | 8552 | for all values of all integer types. |
| 8664 | </p> | 8553 | </p> |
| 8665 | {#header_close#} | 8554 | {#header_close#} |
| 8666 | | 8555 | |
| ... | @@ -10873,6 +10762,9 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; | ... | @@ -10873,6 +10762,9 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; |
| 10873 | Some examples of tasks the build system can help with: | 10762 | Some examples of tasks the build system can help with: |
| 10874 | </p> | 10763 | </p> |
| 10875 | <ul> | 10764 | <ul> |
| | 10765 | <li>Performing tasks in parallel and caching the results.</li> |
| | 10766 | <li>Depending on other projects.</li> |
| | 10767 | <li>Providing a package for other projects to depend on.</li> |
| 10876 | <li>Creating build artifacts by executing the Zig compiler. This includes | 10768 | <li>Creating build artifacts by executing the Zig compiler. This includes |
| 10877 | building Zig source code as well as C and C++ source code.</li> | 10769 | building Zig source code as well as C and C++ source code.</li> |
| 10878 | <li>Capturing user-configured options and using those options to configure | 10770 | <li>Capturing user-configured options and using those options to configure |
| ... | @@ -10891,148 +10783,10 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; | ... | @@ -10891,148 +10783,10 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/'; |
| 10891 | to see a command-line usage help menu. This will include project-specific | 10783 | to see a command-line usage help menu. This will include project-specific |
| 10892 | options that were declared in the build.zig script. | 10784 | options that were declared in the build.zig script. |
| 10893 | </p> | 10785 | </p> |
| 10894 | | 10786 | <p> |
| 10895 | {#header_open|Building an Executable#} | 10787 | For the time being, the build system documentation is hosted externally: |
| 10896 | <p>This <code class="file">build.zig</code> file is automatically generated | 10788 | <a href="https://ziglang.org/learn/build-system/">Build System Documentation</a> |
| 10897 | by <kbd>zig init-exe</kbd>.</p> | 10789 | </p> |
| 10898 | {#code_begin|syntax|build_executable#} | | |
| 10899 | const std = @import("std"); | | |
| 10900 | | | |
| 10901 | // Although this function looks imperative, note that its job is to | | |
| 10902 | // declaratively construct a build graph that will be executed by an external | | |
| 10903 | // runner. | | |
| 10904 | pub fn build(b: *std.Build) void { | | |
| 10905 | // Standard target options allows the person running `zig build` to choose | | |
| 10906 | // what target to build for. Here we do not override the defaults, which | | |
| 10907 | // means any target is allowed, and the default is native. Other options | | |
| 10908 | // for restricting supported target set are available. | | |
| 10909 | const target = b.standardTargetOptions(.{}); | | |
| 10910 | | | |
| 10911 | // Standard optimization options allow the person running `zig build` to select | | |
| 10912 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not | | |
| 10913 | // set a preferred release mode, allowing the user to decide how to optimize. | | |
| 10914 | const optimize = b.standardOptimizeOption(.{}); | | |
| 10915 | | | |
| 10916 | const exe = b.addExecutable(.{ | | |
| 10917 | .name = "example", | | |
| 10918 | // In this case the main source file is merely a path, however, in more | | |
| 10919 | // complicated build scripts, this could be a generated file. | | |
| 10920 | .root_source_file = .{ .path = "src/main.zig" }, | | |
| 10921 | .target = target, | | |
| 10922 | .optimize = optimize, | | |
| 10923 | }); | | |
| 10924 | | | |
| 10925 | // This declares intent for the executable to be installed into the | | |
| 10926 | // standard location when the user invokes the "install" step (the default | | |
| 10927 | // step when running `zig build`). | | |
| 10928 | b.installArtifact(exe); | | |
| 10929 | | | |
| 10930 | // This *creates* a Run step in the build graph, to be executed when another | | |
| 10931 | // step is evaluated that depends on it. The next line below will establish | | |
| 10932 | // such a dependency. | | |
| 10933 | const run_cmd = b.addRunArtifact(exe); | | |
| 10934 | | | |
| 10935 | // By making the run step depend on the install step, it will be run from the | | |
| 10936 | // installation directory rather than directly from within the cache directory. | | |
| 10937 | // This is not necessary, however, if the application depends on other installed | | |
| 10938 | // files, this ensures they will be present and in the expected location. | | |
| 10939 | run_cmd.step.dependOn(b.getInstallStep()); | | |
| 10940 | | | |
| 10941 | // This allows the user to pass arguments to the application in the build | | |
| 10942 | // command itself, like this: `zig build run -- arg1 arg2 etc` | | |
| 10943 | if (b.args) |args| { | | |
| 10944 | run_cmd.addArgs(args); | | |
| 10945 | } | | |
| 10946 | | | |
| 10947 | // This creates a build step. It will be visible in the `zig build --help` menu, | | |
| 10948 | // and can be selected like this: `zig build run` | | |
| 10949 | // This will evaluate the `run` step rather than the default, which is "install". | | |
| 10950 | const run_step = b.step("run", "Run the app"); | | |
| 10951 | run_step.dependOn(&run_cmd.step); | | |
| 10952 | | | |
| 10953 | // Creates a step for unit testing. This only builds the test executable | | |
| 10954 | // but does not run it. | | |
| 10955 | const unit_tests = b.addTest(.{ | | |
| 10956 | .root_source_file = .{ .path = "src/main.zig" }, | | |
| 10957 | .target = target, | | |
| 10958 | .optimize = optimize, | | |
| 10959 | }); | | |
| 10960 | | | |
| 10961 | const run_unit_tests = b.addRunArtifact(unit_tests); | | |
| 10962 | | | |
| 10963 | // Similar to creating the run step earlier, this exposes a `test` step to | | |
| 10964 | // the `zig build --help` menu, providing a way for the user to request | | |
| 10965 | // running the unit tests. | | |
| 10966 | const test_step = b.step("test", "Run unit tests"); | | |
| 10967 | test_step.dependOn(&run_unit_tests.step); | | |
| 10968 | } | | |
| 10969 | {#code_end#} | | |
| 10970 | {#header_close#} | | |
| 10971 | | | |
| 10972 | {#header_open|Building a Library#} | | |
| 10973 | <p>This <code class="file">build.zig</code> file is automatically generated | | |
| 10974 | by <kbd>zig init-lib</kbd>.</p> | | |
| 10975 | {#code_begin|syntax|build_library#} | | |
| 10976 | const std = @import("std"); | | |
| 10977 | | | |
| 10978 | // Although this function looks imperative, note that its job is to | | |
| 10979 | // declaratively construct a build graph that will be executed by an external | | |
| 10980 | // runner. | | |
| 10981 | pub fn build(b: *std.Build) void { | | |
| 10982 | // Standard target options allows the person running `zig build` to choose | | |
| 10983 | // what target to build for. Here we do not override the defaults, which | | |
| 10984 | // means any target is allowed, and the default is native. Other options | | |
| 10985 | // for restricting supported target set are available. | | |
| 10986 | const target = b.standardTargetOptions(.{}); | | |
| 10987 | | | |
| 10988 | // Standard optimization options allow the person running `zig build` to select | | |
| 10989 | // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. Here we do not | | |
| 10990 | // set a preferred release mode, allowing the user to decide how to optimize. | | |
| 10991 | const optimize = b.standardOptimizeOption(.{}); | | |
| 10992 | | | |
| 10993 | const lib = b.addStaticLibrary(.{ | | |
| 10994 | .name = "example", | | |
| 10995 | // In this case the main source file is merely a path, however, in more | | |
| 10996 | // complicated build scripts, this could be a generated file. | | |
| 10997 | .root_source_file = .{ .path = "src/main.zig" }, | | |
| 10998 | .target = target, | | |
| 10999 | .optimize = optimize, | | |
| 11000 | }); | | |
| 11001 | | | |
| 11002 | // This declares intent for the library to be installed into the standard | | |
| 11003 | // location when the user invokes the "install" step (the default step when | | |
| 11004 | // running `zig build`). | | |
| 11005 | b.installArtifact(lib); | | |
| 11006 | | | |
| 11007 | // Creates a step for unit testing. This only builds the test executable | | |
| 11008 | // but does not run it. | | |
| 11009 | const main_tests = b.addTest(.{ | | |
| 11010 | .root_source_file = .{ .path = "src/main.zig" }, | | |
| 11011 | .target = target, | | |
| 11012 | .optimize = optimize, | | |
| 11013 | }); | | |
| 11014 | | | |
| 11015 | const run_main_tests = b.addRunArtifact(main_tests); | | |
| 11016 | | | |
| 11017 | // This creates a build step. It will be visible in the `zig build --help` menu, | | |
| 11018 | // and can be selected like this: `zig build test` | | |
| 11019 | // This will evaluate the `test` step rather than the default, which is "install". | | |
| 11020 | const test_step = b.step("test", "Run library tests"); | | |
| 11021 | test_step.dependOn(&run_main_tests.step); | | |
| 11022 | } | | |
| 11023 | {#code_end#} | | |
| 11024 | {#header_close#} | | |
| 11025 | | | |
| 11026 | {#header_open|Compiling C Source Code#} | | |
| 11027 | <pre>{#syntax#} | | |
| 11028 | lib.addCSourceFile(.{ .file = .{ .path = "src/lib.c" }, .flags = &.{ | | |
| 11029 | "-Wall", | | |
| 11030 | "-Wextra", | | |
| 11031 | "-Werror", | | |
| 11032 | } }); | | |
| 11033 | {#endsyntax#}</pre> | | |
| 11034 | {#header_close#} | | |
| 11035 | | | |
| 11036 | {#header_close#} | 10790 | {#header_close#} |
| 11037 | {#header_open|C#} | 10791 | {#header_open|C#} |
| 11038 | <p> | 10792 | <p> |