authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-25 11:51:41-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-25 11:51:41-05:00
log47be64af5add5c146541c16dbb043ddf97f97d34
tree3fabcb50c94b254a71cdbf009f29ad1ece6b1f67
parent4556f448060b19492d7b104ff01585241ba9c256
parentf7670882aff5fb3a943057edd9da34d053b5fe59

Merge remote-tracking branch 'origin/master' into llvm6


221 files changed, 5224 insertions(+), 5546 deletions(-)

README.md-10
...@@ -5,8 +5,6 @@ clarity....@@ -5,8 +5,6 @@ clarity.
55
6[ziglang.org](http://ziglang.org)6[ziglang.org](http://ziglang.org)
77
8[Documentation](http://ziglang.org/documentation/master/)
9
10## Feature Highlights8## Feature Highlights
119
12 * Small, simple language. Focus on debugging your application rather than10 * Small, simple language. Focus on debugging your application rather than
...@@ -200,11 +198,3 @@ This is the actual compiler binary that we will install to the system....@@ -200,11 +198,3 @@ This is the actual compiler binary that we will install to the system.
200```198```
201./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast199./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
202```200```
203
204### Related Projects
205
206 * [zig-mode](https://github.com/AndreaOrru/zig-mode) - Emacs integration
207 * [zig.vim](https://github.com/zig-lang/zig.vim) - Vim configuration files
208 * [vscode-zig](https://github.com/zig-lang/vscode-zig) - Visual Studio Code extension
209 * [zig-compiler-completions](https://github.com/tiehuis/zig-compiler-completions) - bash and zsh completions for the zig compiler
210 * [NppExtension](https://github.com/ice1000/NppExtension) - Notepad++ syntax highlighting
build.zig+9-8
...@@ -10,7 +10,7 @@ const ArrayList = std.ArrayList;...@@ -10,7 +10,7 @@ const ArrayList = std.ArrayList;
10const Buffer = std.Buffer;10const Buffer = std.Buffer;
11const io = std.io;11const io = std.io;
1212
13pub fn build(b: &Builder) -> %void {13pub fn build(b: &Builder) %void {
14 const mode = b.standardReleaseOptions();14 const mode = b.standardReleaseOptions();
1515
16 var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");16 var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
...@@ -116,11 +116,12 @@ pub fn build(b: &Builder) -> %void {...@@ -116,11 +116,12 @@ pub fn build(b: &Builder) -> %void {
116 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));116 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
117 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));117 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
118 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));118 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
119 test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));119 test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter));
120 test_step.dependOn(tests.addTranslateCTests(b, test_filter));120 test_step.dependOn(tests.addTranslateCTests(b, test_filter));
121 test_step.dependOn(tests.addGenHTests(b, test_filter));
121}122}
122123
123fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {124fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) void {
124 for (dep.libdirs.toSliceConst()) |lib_dir| {125 for (dep.libdirs.toSliceConst()) |lib_dir| {
125 lib_exe_obj.addLibPath(lib_dir);126 lib_exe_obj.addLibPath(lib_dir);
126 }127 }
...@@ -135,7 +136,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {...@@ -135,7 +136,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
135 }136 }
136}137}
137138
138fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) {139fn addCppLib(b: &Builder, lib_exe_obj: &std.build.LibExeObjStep, cmake_binary_dir: []const u8, lib_name: []const u8) void {
139 const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";140 const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
140 lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",141 lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",
141 b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);142 b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
...@@ -148,7 +149,7 @@ const LibraryDep = struct {...@@ -148,7 +149,7 @@ const LibraryDep = struct {
148 includes: ArrayList([]const u8),149 includes: ArrayList([]const u8),
149};150};
150151
151fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {152fn findLLVM(b: &Builder, llvm_config_exe: []const u8) %LibraryDep {
152 const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});153 const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
153 const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});154 const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
154 const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});155 const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});
...@@ -196,7 +197,7 @@ fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {...@@ -196,7 +197,7 @@ fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {
196 return result;197 return result;
197}198}
198199
199pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {200pub fn installStdLib(b: &Builder, stdlib_files: []const u8) void {
200 var it = mem.split(stdlib_files, ";");201 var it = mem.split(stdlib_files, ";");
201 while (it.next()) |stdlib_file| {202 while (it.next()) |stdlib_file| {
202 const src_path = os.path.join(b.allocator, "std", stdlib_file) catch unreachable;203 const src_path = os.path.join(b.allocator, "std", stdlib_file) catch unreachable;
...@@ -205,7 +206,7 @@ pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {...@@ -205,7 +206,7 @@ pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {
205 }206 }
206}207}
207208
208pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {209pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
209 var it = mem.split(c_header_files, ";");210 var it = mem.split(c_header_files, ";");
210 while (it.next()) |c_header_file| {211 while (it.next()) |c_header_file| {
211 const src_path = os.path.join(b.allocator, "c_headers", c_header_file) catch unreachable;212 const src_path = os.path.join(b.allocator, "c_headers", c_header_file) catch unreachable;
...@@ -214,7 +215,7 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {...@@ -214,7 +215,7 @@ pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {
214 }215 }
215}216}
216217
217fn nextValue(index: &usize, build_info: []const u8) -> []const u8 {218fn nextValue(index: &usize, build_info: []const u8) []const u8 {
218 const start = *index;219 const start = *index;
219 while (true) : (*index += 1) {220 while (true) : (*index += 1) {
220 switch (build_info[*index]) {221 switch (build_info[*index]) {
ci/appveyor/after_build.bat+1
...@@ -8,6 +8,7 @@ SET "RELEASEDIR=zig-%ZIGVERSION%"...@@ -8,6 +8,7 @@ SET "RELEASEDIR=zig-%ZIGVERSION%"
8mkdir "%RELEASEDIR%"8mkdir "%RELEASEDIR%"
9move build-msvc-release\bin\zig.exe "%RELEASEDIR%"9move build-msvc-release\bin\zig.exe "%RELEASEDIR%"
10move build-msvc-release\lib "%RELEASEDIR%"10move build-msvc-release\lib "%RELEASEDIR%"
11move zig-cache\langref.html "%RELEASEDIR%"
1112
12SET "RELEASEZIP=zig-%ZIGVERSION%.zip"13SET "RELEASEZIP=zig-%ZIGVERSION%.zip"
1314
doc/docgen.zig+490-59
...@@ -1,14 +1,18 @@...@@ -1,14 +1,18 @@
1const builtin = @import("builtin");
1const std = @import("std");2const std = @import("std");
2const io = std.io;3const io = std.io;
3const os = std.os;4const os = std.os;
4const warn = std.debug.warn;5const warn = std.debug.warn;
5const mem = std.mem;6const mem = std.mem;
7const assert = std.debug.assert;
68
7const max_doc_file_size = 10 * 1024 * 1024;9const max_doc_file_size = 10 * 1024 * 1024;
810
9const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();11const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
12const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
13const tmp_dir_name = "docgen_tmp";
1014
11pub fn main() -> %void {15pub fn main() %void {
12 // TODO use a more general purpose allocator here16 // TODO use a more general purpose allocator here
13 var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);17 var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
14 defer inc_allocator.deinit();18 defer inc_allocator.deinit();
...@@ -43,6 +47,15 @@ pub fn main() -> %void {...@@ -43,6 +47,15 @@ pub fn main() -> %void {
43 var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);47 var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);
44 var toc = try genToc(allocator, &tokenizer);48 var toc = try genToc(allocator, &tokenizer);
4549
50 try os.makePath(allocator, tmp_dir_name);
51 defer {
52 // TODO issue #709
53 // disabled to pass CI tests, but obviously we want to implement this
54 // and then remove this workaround
55 if (builtin.os == builtin.Os.linux) {
56 os.deleteTree(allocator, tmp_dir_name) catch {};
57 }
58 }
46 try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);59 try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
47 try buffered_out_stream.flush();60 try buffered_out_stream.flush();
48}61}
...@@ -68,6 +81,7 @@ const Tokenizer = struct {...@@ -68,6 +81,7 @@ const Tokenizer = struct {
68 index: usize,81 index: usize,
69 state: State,82 state: State,
70 source_file_name: []const u8,83 source_file_name: []const u8,
84 code_node_count: usize,
7185
72 const State = enum {86 const State = enum {
73 Start,87 Start,
...@@ -77,16 +91,17 @@ const Tokenizer = struct {...@@ -77,16 +91,17 @@ const Tokenizer = struct {
77 Eof,91 Eof,
78 };92 };
7993
80 fn init(source_file_name: []const u8, buffer: []const u8) -> Tokenizer {94 fn init(source_file_name: []const u8, buffer: []const u8) Tokenizer {
81 return Tokenizer {95 return Tokenizer {
82 .buffer = buffer,96 .buffer = buffer,
83 .index = 0,97 .index = 0,
84 .state = State.Start,98 .state = State.Start,
85 .source_file_name = source_file_name,99 .source_file_name = source_file_name,
100 .code_node_count = 0,
86 };101 };
87 }102 }
88103
89 fn next(self: &Tokenizer) -> Token {104 fn next(self: &Tokenizer) Token {
90 var result = Token {105 var result = Token {
91 .id = Token.Id.Eof,106 .id = Token.Id.Eof,
92 .start = self.index,107 .start = self.index,
...@@ -178,7 +193,7 @@ const Tokenizer = struct {...@@ -178,7 +193,7 @@ const Tokenizer = struct {
178 line_end: usize,193 line_end: usize,
179 };194 };
180195
181 fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {196 fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
182 var loc = Location {197 var loc = Location {
183 .line = 0,198 .line = 0,
184 .column = 0,199 .column = 0,
...@@ -205,7 +220,7 @@ const Tokenizer = struct {...@@ -205,7 +220,7 @@ const Tokenizer = struct {
205220
206error ParseError;221error ParseError;
207222
208fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const u8, args: ...) -> error {223fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const u8, args: ...) error {
209 const loc = tokenizer.getTokenLocation(token);224 const loc = tokenizer.getTokenLocation(token);
210 warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args);225 warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args);
211 if (loc.line_start <= loc.line_end) {226 if (loc.line_start <= loc.line_end) {
...@@ -228,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const...@@ -228,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const
228 return error.ParseError;243 return error.ParseError;
229}244}
230245
231fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) -> %void {246fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) %void {
232 if (token.id != id) {247 if (token.id != id) {
233 return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));248 return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
234 }249 }
235}250}
236251
237fn eatToken(tokenizer: &Tokenizer, id: Token.Id) -> %Token {252fn eatToken(tokenizer: &Tokenizer, id: Token.Id) %Token {
238 const token = tokenizer.next();253 const token = tokenizer.next();
239 try assertToken(tokenizer, token, id);254 try assertToken(tokenizer, token, id);
240 return token;255 return token;
...@@ -251,24 +266,43 @@ const SeeAlsoItem = struct {...@@ -251,24 +266,43 @@ const SeeAlsoItem = struct {
251 token: Token,266 token: Token,
252};267};
253268
269const ExpectedOutcome = enum {
270 Succeed,
271 Fail,
272};
273
254const Code = struct {274const Code = struct {
255 id: Id,275 id: Id,
256 name: []const u8,276 name: []const u8,
257 source_token: Token,277 source_token: Token,
278 is_inline: bool,
279 mode: builtin.Mode,
280 link_objects: []const []const u8,
281 target_windows: bool,
282 link_libc: bool,
258283
259 const Id = enum {284 const Id = union(enum) {
260 Test,285 Test,
261 Exe,286 TestError: []const u8,
262 Error,287 TestSafety: []const u8,
288 Exe: ExpectedOutcome,
289 Obj: ?[]const u8,
263 };290 };
264};291};
265292
293const Link = struct {
294 url: []const u8,
295 name: []const u8,
296 token: Token,
297};
298
266const Node = union(enum) {299const Node = union(enum) {
267 Content: []const u8,300 Content: []const u8,
268 Nav,301 Nav,
269 HeaderOpen: HeaderOpen,302 HeaderOpen: HeaderOpen,
270 SeeAlso: []const SeeAlsoItem,303 SeeAlso: []const SeeAlsoItem,
271 Code: Code,304 Code: Code,
305 Link: Link,
272};306};
273307
274const Toc = struct {308const Toc = struct {
...@@ -282,9 +316,9 @@ const Action = enum {...@@ -282,9 +316,9 @@ const Action = enum {
282 Close,316 Close,
283};317};
284318
285fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {319fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
286 var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);320 var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);
287 %defer urls.deinit();321 errdefer urls.deinit();
288322
289 var header_stack_size: usize = 0;323 var header_stack_size: usize = 0;
290 var last_action = Action.Open;324 var last_action = Action.Open;
...@@ -365,7 +399,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {...@@ -365,7 +399,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
365 }399 }
366 } else if (mem.eql(u8, tag_name, "see_also")) {400 } else if (mem.eql(u8, tag_name, "see_also")) {
367 var list = std.ArrayList(SeeAlsoItem).init(allocator);401 var list = std.ArrayList(SeeAlsoItem).init(allocator);
368 %defer list.deinit();402 errdefer list.deinit();
369403
370 while (true) {404 while (true) {
371 const see_also_tok = tokenizer.next();405 const see_also_tok = tokenizer.next();
...@@ -385,6 +419,31 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {...@@ -385,6 +419,31 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
385 else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),419 else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),
386 }420 }
387 }421 }
422 } else if (mem.eql(u8, tag_name, "link")) {
423 _ = try eatToken(tokenizer, Token.Id.Separator);
424 const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
425 const name = tokenizer.buffer[name_tok.start..name_tok.end];
426
427 const url_name = blk: {
428 const tok = tokenizer.next();
429 switch (tok.id) {
430 Token.Id.BracketClose => break :blk name,
431 Token.Id.Separator => {
432 const explicit_text = try eatToken(tokenizer, Token.Id.TagContent);
433 _ = try eatToken(tokenizer, Token.Id.BracketClose);
434 break :blk tokenizer.buffer[explicit_text.start..explicit_text.end];
435 },
436 else => return parseError(tokenizer, tok, "invalid link token"),
437 }
438 };
439
440 try nodes.append(Node {
441 .Link = Link {
442 .url = try urlize(allocator, url_name),
443 .name = name,
444 .token = name_tok,
445 },
446 });
388 } else if (mem.eql(u8, tag_name, "code_begin")) {447 } else if (mem.eql(u8, tag_name, "code_begin")) {
389 _ = try eatToken(tokenizer, Token.Id.Separator);448 _ = try eatToken(tokenizer, Token.Id.Separator);
390 const code_kind_tok = try eatToken(tokenizer, Token.Id.TagContent);449 const code_kind_tok = try eatToken(tokenizer, Token.Id.TagContent);
...@@ -401,28 +460,71 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {...@@ -401,28 +460,71 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
401 }460 }
402 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];461 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
403 var code_kind_id: Code.Id = undefined;462 var code_kind_id: Code.Id = undefined;
463 var is_inline = false;
404 if (mem.eql(u8, code_kind_str, "exe")) {464 if (mem.eql(u8, code_kind_str, "exe")) {
405 code_kind_id = Code.Id.Exe;465 code_kind_id = Code.Id { .Exe = ExpectedOutcome.Succeed };
466 } else if (mem.eql(u8, code_kind_str, "exe_err")) {
467 code_kind_id = Code.Id { .Exe = ExpectedOutcome.Fail };
406 } else if (mem.eql(u8, code_kind_str, "test")) {468 } else if (mem.eql(u8, code_kind_str, "test")) {
407 code_kind_id = Code.Id.Test;469 code_kind_id = Code.Id.Test;
408 } else if (mem.eql(u8, code_kind_str, "error")) {470 } else if (mem.eql(u8, code_kind_str, "test_err")) {
409 code_kind_id = Code.Id.Error;471 code_kind_id = Code.Id { .TestError = name};
472 name = "test";
473 } else if (mem.eql(u8, code_kind_str, "test_safety")) {
474 code_kind_id = Code.Id { .TestSafety = name};
475 name = "test";
476 } else if (mem.eql(u8, code_kind_str, "obj")) {
477 code_kind_id = Code.Id { .Obj = null };
478 } else if (mem.eql(u8, code_kind_str, "obj_err")) {
479 code_kind_id = Code.Id { .Obj = name };
480 name = "test";
481 } else if (mem.eql(u8, code_kind_str, "syntax")) {
482 code_kind_id = Code.Id { .Obj = null };
483 is_inline = true;
410 } else {484 } else {
411 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);485 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);
412 }486 }
413 const source_token = try eatToken(tokenizer, Token.Id.Content);487
414 _ = try eatToken(tokenizer, Token.Id.BracketOpen);488 var mode = builtin.Mode.Debug;
415 const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);489 var link_objects = std.ArrayList([]const u8).init(allocator);
416 const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];490 defer link_objects.deinit();
417 if (!mem.eql(u8, end_tag_name, "code_end")) {491 var target_windows = false;
418 return parseError(tokenizer, end_code_tag, "expected code_end token");492 var link_libc = false;
419 }493
420 _ = try eatToken(tokenizer, Token.Id.BracketClose);494 const source_token = while (true) {
421 try nodes.append(Node {.Code = Code{495 const content_tok = try eatToken(tokenizer, Token.Id.Content);
496 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
497 const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
498 const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
499 if (mem.eql(u8, end_tag_name, "code_release_fast")) {
500 mode = builtin.Mode.ReleaseFast;
501 } else if (mem.eql(u8, end_tag_name, "code_link_object")) {
502 _ = try eatToken(tokenizer, Token.Id.Separator);
503 const obj_tok = try eatToken(tokenizer, Token.Id.TagContent);
504 try link_objects.append(tokenizer.buffer[obj_tok.start..obj_tok.end]);
505 } else if (mem.eql(u8, end_tag_name, "target_windows")) {
506 target_windows = true;
507 } else if (mem.eql(u8, end_tag_name, "link_libc")) {
508 link_libc = true;
509 } else if (mem.eql(u8, end_tag_name, "code_end")) {
510 _ = try eatToken(tokenizer, Token.Id.BracketClose);
511 break content_tok;
512 } else {
513 return parseError(tokenizer, end_code_tag, "invalid token inside code_begin: {}", end_tag_name);
514 }
515 _ = try eatToken(tokenizer, Token.Id.BracketClose);
516 } else unreachable; // TODO issue #707
517 try nodes.append(Node {.Code = Code {
422 .id = code_kind_id,518 .id = code_kind_id,
423 .name = name,519 .name = name,
424 .source_token = source_token,520 .source_token = source_token,
521 .is_inline = is_inline,
522 .mode = mode,
523 .link_objects = link_objects.toOwnedSlice(),
524 .target_windows = target_windows,
525 .link_libc = link_libc,
425 }});526 }});
527 tokenizer.code_node_count += 1;
426 } else {528 } else {
427 return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);529 return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);
428 }530 }
...@@ -438,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {...@@ -438,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
438 };540 };
439}541}
440542
441fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {543fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
442 var buf = try std.Buffer.initSize(allocator, 0);544 var buf = try std.Buffer.initSize(allocator, 0);
443 defer buf.deinit();545 defer buf.deinit();
444546
...@@ -458,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {...@@ -458,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
458 return buf.toOwnedSlice();560 return buf.toOwnedSlice();
459}561}
460562
461fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {563fn escapeHtml(allocator: &mem.Allocator, input: []const u8) %[]u8 {
462 var buf = try std.Buffer.initSize(allocator, 0);564 var buf = try std.Buffer.initSize(allocator, 0);
463 defer buf.deinit();565 defer buf.deinit();
464566
...@@ -476,14 +578,127 @@ fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {...@@ -476,14 +578,127 @@ fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
476 return buf.toOwnedSlice();578 return buf.toOwnedSlice();
477}579}
478580
581//#define VT_RED "\x1b[31;1m"
582//#define VT_GREEN "\x1b[32;1m"
583//#define VT_CYAN "\x1b[36;1m"
584//#define VT_WHITE "\x1b[37;1m"
585//#define VT_BOLD "\x1b[0;1m"
586//#define VT_RESET "\x1b[0m"
587
588const TermState = enum {
589 Start,
590 Escape,
591 LBracket,
592 Number,
593 AfterNumber,
594 Arg,
595 ArgNumber,
596 ExpectEnd,
597};
598
599error UnsupportedEscape;
600
601test "term color" {
602 const input_bytes = "A\x1b[32;1mgreen\x1b[0mB";
603 const result = try termColor(std.debug.global_allocator, input_bytes);
604 assert(mem.eql(u8, result, "A<span class=\"t32\">green</span>B"));
605}
606
607fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
608 var buf = try std.Buffer.initSize(allocator, 0);
609 defer buf.deinit();
610
611 var buf_adapter = io.BufferOutStream.init(&buf);
612 var out = &buf_adapter.stream;
613 var number_start_index: usize = undefined;
614 var first_number: usize = undefined;
615 var second_number: usize = undefined;
616 var i: usize = 0;
617 var state = TermState.Start;
618 var open_span_count: usize = 0;
619 while (i < input.len) : (i += 1) {
620 const c = input[i];
621 switch (state) {
622 TermState.Start => switch (c) {
623 '\x1b' => state = TermState.Escape,
624 else => try out.writeByte(c),
625 },
626 TermState.Escape => switch (c) {
627 '[' => state = TermState.LBracket,
628 else => return error.UnsupportedEscape,
629 },
630 TermState.LBracket => switch (c) {
631 '0'...'9' => {
632 number_start_index = i;
633 state = TermState.Number;
634 },
635 else => return error.UnsupportedEscape,
636 },
637 TermState.Number => switch (c) {
638 '0'...'9' => {},
639 else => {
640 first_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;
641 second_number = 0;
642 state = TermState.AfterNumber;
643 i -= 1;
644 },
645 },
646
647 TermState.AfterNumber => switch (c) {
648 ';' => state = TermState.Arg,
649 else => {
650 state = TermState.ExpectEnd;
651 i -= 1;
652 },
653 },
654 TermState.Arg => switch (c) {
655 '0'...'9' => {
656 number_start_index = i;
657 state = TermState.ArgNumber;
658 },
659 else => return error.UnsupportedEscape,
660 },
661 TermState.ArgNumber => switch (c) {
662 '0'...'9' => {},
663 else => {
664 second_number = std.fmt.parseInt(usize, input[number_start_index..i], 10) catch unreachable;
665 state = TermState.ExpectEnd;
666 i -= 1;
667 },
668 },
669 TermState.ExpectEnd => switch (c) {
670 'm' => {
671 state = TermState.Start;
672 while (open_span_count != 0) : (open_span_count -= 1) {
673 try out.write("</span>");
674 }
675 if (first_number != 0 or second_number != 0) {
676 try out.print("<span class=\"t{}_{}\">", first_number, second_number);
677 open_span_count += 1;
678 }
679 },
680 else => return error.UnsupportedEscape,
681 },
682 }
683 }
684 return buf.toOwnedSlice();
685}
686
479error ExampleFailedToCompile;687error ExampleFailedToCompile;
480688
481fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) -> %void {689fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) %void {
690 var code_progress_index: usize = 0;
482 for (toc.nodes) |node| {691 for (toc.nodes) |node| {
483 switch (node) {692 switch (node) {
484 Node.Content => |data| {693 Node.Content => |data| {
485 try out.write(data);694 try out.write(data);
486 },695 },
696 Node.Link => |info| {
697 if (!toc.urls.contains(info.url)) {
698 return parseError(tokenizer, info.token, "url not found: {}", info.url);
699 }
700 try out.print("<a href=\"#{}\">{}</a>", info.url, info.name);
701 },
487 Node.Nav => {702 Node.Nav => {
488 try out.write(toc.toc);703 try out.write(toc.toc);
489 },704 },
...@@ -502,65 +717,281 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io...@@ -502,65 +717,281 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
502 try out.write("</ul>\n");717 try out.write("</ul>\n");
503 },718 },
504 Node.Code => |code| {719 Node.Code => |code| {
720 code_progress_index += 1;
721 warn("docgen example code {}/{}...", code_progress_index, tokenizer.code_node_count);
722
505 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];723 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
506 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");724 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
507 const escaped_source = try escapeHtml(allocator, trimmed_raw_source);725 const escaped_source = try escapeHtml(allocator, trimmed_raw_source);
726 if (!code.is_inline) {
727 try out.print("<p class=\"file\">{}.zig</p>", code.name);
728 }
508 try out.print("<pre><code class=\"zig\">{}</code></pre>", escaped_source);729 try out.print("<pre><code class=\"zig\">{}</code></pre>", escaped_source);
509 const tmp_dir_name = "docgen_tmp";
510 try os.makePath(allocator, tmp_dir_name);
511 const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);730 const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
512 const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
513 const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);731 const tmp_source_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_ext);
514 const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
515 try io.writeFile(tmp_source_file_name, trimmed_raw_source, null);732 try io.writeFile(tmp_source_file_name, trimmed_raw_source, null);
516 733
517 switch (code.id) {734 switch (code.id) {
518 Code.Id.Exe => {735 Code.Id.Exe => |expected_outcome| {
519 {736 const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
520 const args = [][]const u8 {zig_exe, "build-exe", tmp_source_file_name, "--output", tmp_bin_file_name};737 const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
521 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);738 var build_args = std.ArrayList([]const u8).init(allocator);
739 defer build_args.deinit();
740 try build_args.appendSlice([][]const u8 {zig_exe,
741 "build-exe", tmp_source_file_name,
742 "--output", tmp_bin_file_name,
743 });
744 try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);
745 switch (code.mode) {
746 builtin.Mode.Debug => {},
747 builtin.Mode.ReleaseSafe => {
748 try build_args.append("--release-safe");
749 try out.print(" --release-safe");
750 },
751 builtin.Mode.ReleaseFast => {
752 try build_args.append("--release-fast");
753 try out.print(" --release-fast");
754 },
755 }
756 for (code.link_objects) |link_object| {
757 const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext);
758 const full_path_object = try os.path.join(allocator, tmp_dir_name, name_with_ext);
759 try build_args.append("--object");
760 try build_args.append(full_path_object);
761 try out.print(" --object {}", name_with_ext);
762 }
763 if (code.link_libc) {
764 try build_args.append("--library");
765 try build_args.append("c");
766 try out.print(" --library c");
767 }
768 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(
769 tokenizer, code.source_token, "example failed to compile");
770
771 const run_args = [][]const u8 {tmp_bin_file_name};
772
773 const result = if (expected_outcome == ExpectedOutcome.Fail) blk: {
774 const result = try os.ChildProcess.exec(allocator, run_args, null, null, max_doc_file_size);
522 switch (result.term) {775 switch (result.term) {
523 os.ChildProcess.Term.Exited => |exit_code| {776 os.ChildProcess.Term.Exited => |exit_code| {
524 if (exit_code != 0) {777 if (exit_code == 0) {
525 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);778 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
526 for (args) |arg| warn("{} ", arg) else warn("\n");779 for (run_args) |arg| warn("{} ", arg) else warn("\n");
527 return parseError(tokenizer, code.source_token, "example failed to compile");780 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
528 }781 }
529 },782 },
530 else => {783 else => {},
531 warn("{}\nThe following command crashed:\n", result.stderr);
532 for (args) |arg| warn("{} ", arg) else warn("\n");
533 return parseError(tokenizer, code.source_token, "example failed to compile");
534 },
535 }784 }
785 break :blk result;
786 } else blk: {
787 break :blk exec(allocator, run_args) catch return parseError(
788 tokenizer, code.source_token, "example crashed");
789 };
790
791
792 const escaped_stderr = try escapeHtml(allocator, result.stderr);
793 const escaped_stdout = try escapeHtml(allocator, result.stdout);
794
795 const colored_stderr = try termColor(allocator, escaped_stderr);
796 const colored_stdout = try termColor(allocator, escaped_stdout);
797
798 try out.print("\n$ ./{}\n{}{}</code></pre>\n", code.name, colored_stdout, colored_stderr);
799 },
800 Code.Id.Test => {
801 var test_args = std.ArrayList([]const u8).init(allocator);
802 defer test_args.deinit();
803
804 try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});
805 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
806 switch (code.mode) {
807 builtin.Mode.Debug => {},
808 builtin.Mode.ReleaseSafe => {
809 try test_args.append("--release-safe");
810 try out.print(" --release-safe");
811 },
812 builtin.Mode.ReleaseFast => {
813 try test_args.append("--release-fast");
814 try out.print(" --release-fast");
815 },
816 }
817 if (code.target_windows) {
818 try test_args.appendSlice([][]const u8{
819 "--target-os", "windows",
820 "--target-arch", "x86_64",
821 "--target-environ", "msvc",
822 });
823 }
824 const result = exec(allocator, test_args.toSliceConst()) catch return parseError(
825 tokenizer, code.source_token, "test failed");
826 const escaped_stderr = try escapeHtml(allocator, result.stderr);
827 const escaped_stdout = try escapeHtml(allocator, result.stdout);
828 try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
829 },
830 Code.Id.TestError => |error_match| {
831 var test_args = std.ArrayList([]const u8).init(allocator);
832 defer test_args.deinit();
833
834 try test_args.appendSlice([][]const u8 {zig_exe, "test", "--color", "on", tmp_source_file_name});
835 try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
836 switch (code.mode) {
837 builtin.Mode.Debug => {},
838 builtin.Mode.ReleaseSafe => {
839 try test_args.append("--release-safe");
840 try out.print(" --release-safe");
841 },
842 builtin.Mode.ReleaseFast => {
843 try test_args.append("--release-fast");
844 try out.print(" --release-fast");
845 },
536 }846 }
537 const args = [][]const u8 {tmp_bin_file_name};847 const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
538 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
539 switch (result.term) {848 switch (result.term) {
540 os.ChildProcess.Term.Exited => |exit_code| {849 os.ChildProcess.Term.Exited => |exit_code| {
541 if (exit_code != 0) {850 if (exit_code == 0) {
542 warn("The following command exited with code {}:\n", exit_code);851 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
543 for (args) |arg| warn("{} ", arg) else warn("\n");852 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
544 return parseError(tokenizer, code.source_token, "example exited with code {}", exit_code);853 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
545 }854 }
546 },855 },
547 else => {856 else => {
548 warn("The following command crashed:\n");857 warn("{}\nThe following command crashed:\n", result.stderr);
549 for (args) |arg| warn("{} ", arg) else warn("\n");858 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
550 return parseError(tokenizer, code.source_token, "example crashed");859 return parseError(tokenizer, code.source_token, "example compile crashed");
551 },860 },
552 }861 }
553 try out.print("<pre><code class=\"sh\">$ zig build-exe {}.zig\n$ ./{}\n{}{}</code></pre>\n", code.name, code.name, result.stderr, result.stdout);862 if (mem.indexOf(u8, result.stderr, error_match) == null) {
863 warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
864 return parseError(tokenizer, code.source_token, "example did not have expected compile error");
865 }
866 const escaped_stderr = try escapeHtml(allocator, result.stderr);
867 const colored_stderr = try termColor(allocator, escaped_stderr);
868 try out.print("\n{}</code></pre>\n", colored_stderr);
554 },869 },
555 Code.Id.Test => {870
556 @panic("TODO");871 Code.Id.TestSafety => |error_match| {
872 var test_args = std.ArrayList([]const u8).init(allocator);
873 defer test_args.deinit();
874
875 try test_args.appendSlice([][]const u8 {zig_exe, "test", tmp_source_file_name});
876 switch (code.mode) {
877 builtin.Mode.Debug => {},
878 builtin.Mode.ReleaseSafe => try test_args.append("--release-safe"),
879 builtin.Mode.ReleaseFast => try test_args.append("--release-fast"),
880 }
881
882 const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
883 switch (result.term) {
884 os.ChildProcess.Term.Exited => |exit_code| {
885 if (exit_code == 0) {
886 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
887 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
888 return parseError(tokenizer, code.source_token, "example test incorrectly succeeded");
889 }
890 },
891 else => {
892 warn("{}\nThe following command crashed:\n", result.stderr);
893 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
894 return parseError(tokenizer, code.source_token, "example compile crashed");
895 },
896 }
897 if (mem.indexOf(u8, result.stderr, error_match) == null) {
898 warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
899 return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message");
900 }
901 const escaped_stderr = try escapeHtml(allocator, result.stderr);
902 const colored_stderr = try termColor(allocator, escaped_stderr);
903 try out.print("<pre><code class=\"shell\">$ zig test {}.zig\n{}</code></pre>\n", code.name, colored_stderr);
557 },904 },
558 Code.Id.Error => {905 Code.Id.Obj => |maybe_error_match| {
559 @panic("TODO");906 const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext);
907 const tmp_obj_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_obj_ext);
908 var build_args = std.ArrayList([]const u8).init(allocator);
909 defer build_args.deinit();
910
911 try build_args.appendSlice([][]const u8 {zig_exe, "build-obj", tmp_source_file_name,
912 "--color", "on",
913 "--output", tmp_obj_file_name});
914
915 if (!code.is_inline) {
916 try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", code.name);
917 }
918
919 switch (code.mode) {
920 builtin.Mode.Debug => {},
921 builtin.Mode.ReleaseSafe => {
922 try build_args.append("--release-safe");
923 if (!code.is_inline) {
924 try out.print(" --release-safe");
925 }
926 },
927 builtin.Mode.ReleaseFast => {
928 try build_args.append("--release-fast");
929 if (!code.is_inline) {
930 try out.print(" --release-fast");
931 }
932 },
933 }
934
935 if (maybe_error_match) |error_match| {
936 const result = try os.ChildProcess.exec(allocator, build_args.toSliceConst(), null, null, max_doc_file_size);
937 switch (result.term) {
938 os.ChildProcess.Term.Exited => |exit_code| {
939 if (exit_code == 0) {
940 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
941 for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
942 return parseError(tokenizer, code.source_token, "example build incorrectly succeeded");
943 }
944 },
945 else => {
946 warn("{}\nThe following command crashed:\n", result.stderr);
947 for (build_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
948 return parseError(tokenizer, code.source_token, "example compile crashed");
949 },
950 }
951 if (mem.indexOf(u8, result.stderr, error_match) == null) {
952 warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
953 return parseError(tokenizer, code.source_token, "example did not have expected compile error message");
954 }
955 const escaped_stderr = try escapeHtml(allocator, result.stderr);
956 const colored_stderr = try termColor(allocator, escaped_stderr);
957 try out.print("\n{}\n", colored_stderr);
958 if (!code.is_inline) {
959 try out.print("</code></pre>\n");
960 }
961 } else {
962 _ = exec(allocator, build_args.toSliceConst()) catch return parseError(
963 tokenizer, code.source_token, "example failed to compile");
964 }
965 if (!code.is_inline) {
966 try out.print("</code></pre>\n");
967 }
560 },968 },
561 }969 }
970 warn("OK\n");
562 },971 },
563 }972 }
564 }973 }
565974
566}975}
976
977error ChildCrashed;
978error ChildExitError;
979
980fn exec(allocator: &mem.Allocator, args: []const []const u8) %os.ChildProcess.ExecResult {
981 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
982 switch (result.term) {
983 os.ChildProcess.Term.Exited => |exit_code| {
984 if (exit_code != 0) {
985 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
986 for (args) |arg| warn("{} ", arg) else warn("\n");
987 return error.ChildExitError;
988 }
989 },
990 else => {
991 warn("{}\nThe following command crashed:\n", result.stderr);
992 for (args) |arg| warn("{} ", arg) else warn("\n");
993 return error.ChildCrashed;
994 },
995 }
996 return result;
997}
doc/langref.html.in+1134-1028
...@@ -4,7 +4,9 @@...@@ -4,7 +4,9 @@
4 <meta charset="utf-8">4 <meta charset="utf-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />5 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
6 <title>Documentation - The Zig Programming Language</title>6 <title>Documentation - The Zig Programming Language</title>
7 <link rel="stylesheet" type="text/css" href="highlight/styles/default.css">7 <style type="text/css">
8.hljs{display:block;overflow-x:auto;padding:0.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:bold}.hljs-number,.hljs-literal,.hljs-variable,.hljs-template-variable,.hljs-tag .hljs-attr{color:#008080}.hljs-string,.hljs-doctag{color:#d14}.hljs-title,.hljs-section,.hljs-selector-id{color:#900;font-weight:bold}.hljs-subst{font-weight:normal}.hljs-type,.hljs-class .hljs-title{color:#458;font-weight:bold}.hljs-tag,.hljs-name,.hljs-attribute{color:#000080;font-weight:normal}.hljs-regexp,.hljs-link{color:#009926}.hljs-symbol,.hljs-bullet{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}
9 </style>
8 <style type="text/css">10 <style type="text/css">
9 table, th, td {11 table, th, td {
10 border-collapse: collapse;12 border-collapse: collapse;
...@@ -13,6 +15,27 @@...@@ -13,6 +15,27 @@
13 th, td {15 th, td {
14 padding: 0.1em;16 padding: 0.1em;
15 }17 }
18 .t0_1, .t37, .t37_1 {
19 font-weight: bold;
20 }
21 .t2_0 {
22 color: grey;
23 }
24 .t31_1 {
25 color: red;
26 }
27 .t32_1 {
28 color: green;
29 }
30 .t36_1 {
31 color: #0086b3;
32 }
33 .file {
34 text-decoration: underline;
35 }
36 code {
37 font-size: 12pt;
38 }
16 @media screen and (min-width: 28.75em) {39 @media screen and (min-width: 28.75em) {
17 #nav {40 #nav {
18 width: 20em;41 width: 20em;
...@@ -53,13 +76,17 @@...@@ -53,13 +76,17 @@
53 If you search for something specific in this documentation and do not find it,76 If you search for something specific in this documentation and do not find it,
54 please <a href="https://github.com/zig-lang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>.77 please <a href="https://github.com/zig-lang/www.ziglang.org/issues/new?title=I%20searched%20for%20___%20in%20the%20docs%20and%20didn%27t%20find%20it">file an issue</a> or <a href="https://webchat.freenode.net/?channels=%23zig">say something on IRC</a>.
55 </p>78 </p>
79 <p>
80 The code samples in this document are compiled and tested as part of the main test suite of Zig.
81 This HTML document depends on no external files, so you can use it offline.
82 </p>
56 {#header_close#}83 {#header_close#}
57 {#header_open|Hello World#}84 {#header_open|Hello World#}
5885
59 {#code_begin|exe|hello#}86 {#code_begin|exe|hello#}
60const std = @import("std");87const std = @import("std");
6188
62pub fn main() -> %void {89pub fn main() %void {
63 // If this program is run without stdout attached, exit with an error.90 // If this program is run without stdout attached, exit with an error.
64 var stdout_file = try std.io.getStdOut();91 var stdout_file = try std.io.getStdOut();
65 // If this program encounters pipe failure when printing to stdout, exit92 // If this program encounters pipe failure when printing to stdout, exit
...@@ -75,10 +102,14 @@ pub fn main() -> %void {...@@ -75,10 +102,14 @@ pub fn main() -> %void {
75 {#code_begin|exe|hello#}102 {#code_begin|exe|hello#}
76const warn = @import("std").debug.warn;103const warn = @import("std").debug.warn;
77104
78pub fn main() -> %void {105pub fn main() void {
79 warn("Hello, world!\n");106 warn("Hello, world!\n");
80}107}
81 {#code_end#}108 {#code_end#}
109 <p>
110 Note that we also left off the <code class="zig">%</code> from the return type.
111 In Zig, if your main function cannot fail, you may use the <code class="zig">void</code> return type.
112 </p>
82 {#see_also|Values|@import|Errors|Root Source File#}113 {#see_also|Values|@import|Errors|Root Source File#}
83 {#header_close#}114 {#header_close#}
84 {#header_open|Source Encoding#}115 {#header_open|Source Encoding#}
...@@ -101,7 +132,7 @@ const assert = std.debug.assert;...@@ -101,7 +132,7 @@ const assert = std.debug.assert;
101// error declaration, makes `error.ArgNotFound` available132// error declaration, makes `error.ArgNotFound` available
102error ArgNotFound;133error ArgNotFound;
103134
104pub fn main() -> %void {135pub fn main() %void {
105 // integers136 // integers
106 const one_plus_one: i32 = 1 + 1;137 const one_plus_one: i32 = 1 + 1;
107 warn("1 + 1 = {}\n", one_plus_one);138 warn("1 + 1 = {}\n", one_plus_one);
...@@ -354,7 +385,7 @@ pub fn main() -> %void {...@@ -354,7 +385,7 @@ pub fn main() -> %void {
354 <tr>385 <tr>
355 <td><code>noreturn</code></td>386 <td><code>noreturn</code></td>
356 <td>(none)</td>387 <td>(none)</td>
357 <td>the type of <code>break</code>, <code>continue</code>, <code>goto</code>, <code>return</code>, <code>unreachable</code>, and <code>while (true) {}</code></td>388 <td>the type of <code>break</code>, <code>continue</code>, <code>return</code>, <code>unreachable</code>, and <code>while (true) {}</code></td>
358 </tr>389 </tr>
359 <tr>390 <tr>
360 <td><code>type</code></td>391 <td><code>type</code></td>
...@@ -399,7 +430,8 @@ pub fn main() -> %void {...@@ -399,7 +430,8 @@ pub fn main() -> %void {
399 {#see_also|Nullables|this#}430 {#see_also|Nullables|this#}
400 {#header_close#}431 {#header_close#}
401 {#header_open|String Literals#}432 {#header_open|String Literals#}
402 <pre><code class="zig">const assert = @import("std").debug.assert;433 {#code_begin|test#}
434const assert = @import("std").debug.assert;
403const mem = @import("std").mem;435const mem = @import("std").mem;
404436
405test "string literals" {437test "string literals" {
...@@ -413,11 +445,10 @@ test "string literals" {...@@ -413,11 +445,10 @@ test "string literals" {
413445
414 // A C string literal is a null terminated pointer.446 // A C string literal is a null terminated pointer.
415 const null_terminated_bytes = c"hello";447 const null_terminated_bytes = c"hello";
416 assert(@typeOf(null_terminated_bytes) == &amp;const u8);448 assert(@typeOf(null_terminated_bytes) == &const u8);
417 assert(null_terminated_bytes[5] == 0);449 assert(null_terminated_bytes[5] == 0);
418}</code></pre>450}
419 <pre><code class="sh">$ zig test string_literals.zig451 {#code_end#}
420Test 1/1 string literals...OK</code></pre>
421 {#see_also|Arrays|Zig Test#}452 {#see_also|Arrays|Zig Test#}
422 {#header_open|Escape Sequences#}453 {#header_open|Escape Sequences#}
423 <table>454 <table>
...@@ -477,25 +508,29 @@ Test 1/1 string literals...OK</code></pre>...@@ -477,25 +508,29 @@ Test 1/1 string literals...OK</code></pre>
477 However, if the next line begins with <code>\\</code> then a newline is appended and508 However, if the next line begins with <code>\\</code> then a newline is appended and
478 the string literal continues.509 the string literal continues.
479 </p>510 </p>
480 <pre><code class="zig">const hello_world_in_c =511 {#code_begin|syntax#}
481 \\#include &lt;stdio.h&gt;512const hello_world_in_c =
513 \\#include <stdio.h>
482 \\514 \\
483 \\int main(int argc, char **argv) {515 \\int main(int argc, char **argv) {
484 \\ printf("hello world\n");516 \\ printf("hello world\n");
485 \\ return 0;517 \\ return 0;
486 \\}518 \\}
487;</code></pre>519;
520 {#code_end#}
488 <p>521 <p>
489 For a multiline C string literal, prepend <code>c</code> to each <code>\\</code>:522 For a multiline C string literal, prepend <code>c</code> to each <code>\\</code>:
490 </p>523 </p>
491 <pre><code class="zig">const c_string_literal =524 {#code_begin|syntax#}
492 c\\#include &lt;stdio.h&gt;525const c_string_literal =
526 c\\#include <stdio.h>
493 c\\527 c\\
494 c\\int main(int argc, char **argv) {528 c\\int main(int argc, char **argv) {
495 c\\ printf("hello world\n");529 c\\ printf("hello world\n");
496 c\\ return 0;530 c\\ return 0;
497 c\\}531 c\\}
498;</code></pre>532;
533 {#code_end#}
499 <p>534 <p>
500 In this example the variable <code>c_string_literal</code> has type <code>&amp;const char</code> and535 In this example the variable <code>c_string_literal</code> has type <code>&amp;const char</code> and
501 has a terminating null byte.536 has a terminating null byte.
...@@ -505,9 +540,10 @@ Test 1/1 string literals...OK</code></pre>...@@ -505,9 +540,10 @@ Test 1/1 string literals...OK</code></pre>
505 {#header_close#}540 {#header_close#}
506 {#header_open|Assignment#}541 {#header_open|Assignment#}
507 <p>Use <code>const</code> to assign a value to an identifier:</p>542 <p>Use <code>const</code> to assign a value to an identifier:</p>
508 <pre><code class="zig">const x = 1234;543 {#code_begin|test_err|cannot assign to constant#}
544const x = 1234;
509545
510fn foo() {546fn foo() void {
511 // It works at global scope as well as inside functions.547 // It works at global scope as well as inside functions.
512 const y = 5678;548 const y = 5678;
513549
...@@ -517,13 +553,11 @@ fn foo() {...@@ -517,13 +553,11 @@ fn foo() {
517553
518test "assignment" {554test "assignment" {
519 foo();555 foo();
520}</code></pre>556}
521 <pre><code class="sh">$ zig test test.zig557 {#code_end#}
522test.zig:8:7: error: cannot assign to constant
523 y += 1;
524 ^</code></pre>
525 <p>If you need a variable that you can modify, use <code>var</code>:</p>558 <p>If you need a variable that you can modify, use <code>var</code>:</p>
526 <pre><code class="zig">const assert = @import("std").debug.assert;559 {#code_begin|test#}
560const assert = @import("std").debug.assert;
527561
528test "var" {562test "var" {
529 var y: i32 = 5678;563 var y: i32 = 5678;
...@@ -531,38 +565,37 @@ test "var" {...@@ -531,38 +565,37 @@ test "var" {
531 y += 1;565 y += 1;
532566
533 assert(y == 5679);567 assert(y == 5679);
534}</code></pre>568}
535 <pre><code class="sh">$ zig test test.zig569 {#code_end#}
536Test 1/1 assignment...OK</code></pre>
537 <p>Variables must be initialized:</p>570 <p>Variables must be initialized:</p>
538 <pre><code class="zig">test "initialization" {571 {#code_begin|test_err#}
572test "initialization" {
539 var x: i32;573 var x: i32;
540574
541 x = 1;575 x = 1;
542}</code></pre>576}
543 <pre><code class="sh">$ zig test test.zig577 {#code_end#}
544test.zig:3:5: error: variables must be initialized
545 var x: i32;
546 ^</code></pre>
547 <p>Use <code>undefined</code> to leave variables uninitialized:</p>578 <p>Use <code>undefined</code> to leave variables uninitialized:</p>
548 <pre><code class="zig">const assert = @import("std").debug.assert;579 {#code_begin|test#}
580const assert = @import("std").debug.assert;
549581
550test "init with undefined" {582test "init with undefined" {
551 var x: i32 = undefined;583 var x: i32 = undefined;
552 x = 1;584 x = 1;
553 assert(x == 1);585 assert(x == 1);
554}</code></pre>586}
555 <pre><code class="sh">$ zig test test.zig587 {#code_end#}
556Test 1/1 init with undefined...OK</code></pre>
557 {#header_close#}588 {#header_close#}
558 {#header_close#}589 {#header_close#}
559 {#header_open|Integers#}590 {#header_open|Integers#}
560 {#header_open|Integer Literals#}591 {#header_open|Integer Literals#}
561 <pre><code class="zig">const decimal_int = 98222;592 {#code_begin|syntax#}
593const decimal_int = 98222;
562const hex_int = 0xff;594const hex_int = 0xff;
563const another_hex_int = 0xFF;595const another_hex_int = 0xFF;
564const octal_int = 0o755;596const octal_int = 0o755;
565const binary_int = 0b11110000;</code></pre>597const binary_int = 0b11110000;
598 {#code_end#}
566 {#header_close#}599 {#header_close#}
567 {#header_open|Runtime Integer Values#}600 {#header_open|Runtime Integer Values#}
568 <p>601 <p>
...@@ -573,9 +606,11 @@ const binary_int = 0b11110000;</code></pre>...@@ -573,9 +606,11 @@ const binary_int = 0b11110000;</code></pre>
573 However, once an integer value is no longer known at compile-time, it must have a606 However, once an integer value is no longer known at compile-time, it must have a
574 known size, and is vulnerable to undefined behavior.607 known size, and is vulnerable to undefined behavior.
575 </p>608 </p>
576 <pre><code class="zig">fn divide(a: i32, b: i32) -&gt; i32 {609 {#code_begin|syntax#}
610fn divide(a: i32, b: i32) i32 {
577 return a / b;611 return a / b;
578}</code></pre>612}
613 {#code_end#}
579 <p>614 <p>
580 In this function, values <code>a</code> and <code>b</code> are known only at runtime,615 In this function, values <code>a</code> and <code>b</code> are known only at runtime,
581 and thus this division operation is vulnerable to both integer overflow and616 and thus this division operation is vulnerable to both integer overflow and
...@@ -590,52 +625,53 @@ const binary_int = 0b11110000;</code></pre>...@@ -590,52 +625,53 @@ const binary_int = 0b11110000;</code></pre>
590 {#header_close#}625 {#header_close#}
591 {#header_close#}626 {#header_close#}
592 {#header_open|Floats#}627 {#header_open|Floats#}
593 {#header_close#}
594 {#header_open|Float Literals#}628 {#header_open|Float Literals#}
595 <pre><code class="zig">const floating_point = 123.0E+77;629 {#code_begin|syntax#}
630const floating_point = 123.0E+77;
596const another_float = 123.0;631const another_float = 123.0;
597const yet_another = 123.0e+77;632const yet_another = 123.0e+77;
598633
599const hex_floating_point = 0x103.70p-5;634const hex_floating_point = 0x103.70p-5;
600const another_hex_float = 0x103.70;635const another_hex_float = 0x103.70;
601const yet_another_hex_float = 0x103.70P-5;</code></pre>636const yet_another_hex_float = 0x103.70P-5;
637 {#code_end#}
602 {#header_close#}638 {#header_close#}
603 {#header_open|Floating Point Operations#}639 {#header_open|Floating Point Operations#}
604 <p>By default floating point operations use <code>Optimized</code> mode,640 <p>By default floating point operations use <code>Optimized</code> mode,
605 but you can switch to <code>Strict</code> mode on a per-block basis:</p>641 but you can switch to <code>Strict</code> mode on a per-block basis:</p>
606 <p>foo.zig</p>642 {#code_begin|obj|foo#}
607 <pre><code class="zig">const builtin = @import("builtin");643 {#code_release_fast#}
608const big = f64(1 &lt;&lt; 40);644const builtin = @import("builtin");
645const big = f64(1 << 40);
609646
610export fn foo_strict(x: f64) -&gt; f64 {647export fn foo_strict(x: f64) f64 {
611 @setFloatMode(this, builtin.FloatMode.Strict);648 @setFloatMode(this, builtin.FloatMode.Strict);
612 return x + big - big;649 return x + big - big;
613}650}
614651
615export fn foo_optimized(x: f64) -&gt; f64 {652export fn foo_optimized(x: f64) f64 {
616 return x + big - big;653 return x + big - big;
617}</code></pre>654}
618 <p>test.zig</p>655 {#code_end#}
619 <pre><code class="zig">const warn = @import("std").debug.warn;656 <p>For this test we have to separate code into two object files -
657 otherwise the optimizer figures out all the values at compile-time,
658 which operates in strict mode.</p>
659 {#code_begin|exe|float_mode#}
660 {#code_link_object|foo#}
661const warn = @import("std").debug.warn;
620662
621extern fn foo_strict(x: f64) -&gt; f64;663extern fn foo_strict(x: f64) f64;
622extern fn foo_optimized(x: f64) -&gt; f64;664extern fn foo_optimized(x: f64) f64;
623665
624pub fn main() -&gt; %void {666pub fn main() %void {
625 const x = 0.001;667 const x = 0.001;
626 warn("optimized = {}\n", foo_optimized(x));668 warn("optimized = {}\n", foo_optimized(x));
627 warn("strict = {}\n", foo_strict(x));669 warn("strict = {}\n", foo_strict(x));
628}</code></pre>670}
629 <p>For this test we have to separate code into two object files -671 {#code_end#}
630 otherwise the optimizer figures out all the values at compile-time,
631 which operates in strict mode.</p>
632 <pre><code class="sh">$ zig build-obj foo.zig --release-fast
633$ zig build-exe test.zig --object foo.o
634$ ./test
635optimized = 1.0e-2
636strict = 9.765625e-3</code></pre>
637 {#see_also|@setFloatMode|Division by Zero#}672 {#see_also|@setFloatMode|Division by Zero#}
638 {#header_close#}673 {#header_close#}
674 {#header_close#}
639 {#header_open|Operators#}675 {#header_open|Operators#}
640 {#header_open|Table of Operators#}676 {#header_open|Table of Operators#}
641 <table>677 <table>
...@@ -658,13 +694,13 @@ strict = 9.765625e-3</code></pre>...@@ -658,13 +694,13 @@ strict = 9.765625e-3</code></pre>
658a += b</code></pre></td>694a += b</code></pre></td>
659 <td>695 <td>
660 <ul>696 <ul>
661 <li><a href="#integers">Integers</a></li>697 <li>{#link|Integers#}</li>
662 <li><a href="#floats">Floats</a></li>698 <li>{#link|Floats#}</li>
663 </ul>699 </ul>
664 </td>700 </td>
665 <td>Addition.701 <td>Addition.
666 <ul>702 <ul>
667 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>703 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
668 </ul>704 </ul>
669 </td>705 </td>
670 <td>706 <td>
...@@ -676,7 +712,7 @@ a += b</code></pre></td>...@@ -676,7 +712,7 @@ a += b</code></pre></td>
676a +%= b</code></pre></td>712a +%= b</code></pre></td>
677 <td>713 <td>
678 <ul>714 <ul>
679 <li><a href="#integers">Integers</a></li>715 <li>{#link|Integers#}</li>
680 </ul>716 </ul>
681 </td>717 </td>
682 <td>Wrapping Addition.718 <td>Wrapping Addition.
...@@ -693,13 +729,13 @@ a +%= b</code></pre></td>...@@ -693,13 +729,13 @@ a +%= b</code></pre></td>
693a -= b</code></pre></td>729a -= b</code></pre></td>
694 <td>730 <td>
695 <ul>731 <ul>
696 <li><a href="#integers">Integers</a></li>732 <li>{#link|Integers#}</li>
697 <li><a href="#floats">Floats</a></li>733 <li>{#link|Floats#}</li>
698 </ul>734 </ul>
699 </td>735 </td>
700 <td>Subtraction.736 <td>Subtraction.
701 <ul>737 <ul>
702 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>738 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
703 </ul>739 </ul>
704 </td>740 </td>
705 <td>741 <td>
...@@ -711,7 +747,7 @@ a -= b</code></pre></td>...@@ -711,7 +747,7 @@ a -= b</code></pre></td>
711a -%= b</code></pre></td>747a -%= b</code></pre></td>
712 <td>748 <td>
713 <ul>749 <ul>
714 <li><a href="#integers">Integers</a></li>750 <li>{#link|Integers#}</li>
715 </ul>751 </ul>
716 </td>752 </td>
717 <td>Wrapping Subtraction.753 <td>Wrapping Subtraction.
...@@ -727,14 +763,14 @@ a -%= b</code></pre></td>...@@ -727,14 +763,14 @@ a -%= b</code></pre></td>
727 <td><pre><code class="zig">-a<code></pre></td>763 <td><pre><code class="zig">-a<code></pre></td>
728 <td>764 <td>
729 <ul>765 <ul>
730 <li><a href="#integers">Integers</a></li>766 <li>{#link|Integers#}</li>
731 <li><a href="#floats">Floats</a></li>767 <li>{#link|Floats#}</li>
732 </ul>768 </ul>
733 </td>769 </td>
734 <td>770 <td>
735 Negation.771 Negation.
736 <ul>772 <ul>
737 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>773 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
738 </ul>774 </ul>
739 </td>775 </td>
740 <td>776 <td>
...@@ -745,7 +781,7 @@ a -%= b</code></pre></td>...@@ -745,7 +781,7 @@ a -%= b</code></pre></td>
745 <td><pre><code class="zig">-%a<code></pre></td>781 <td><pre><code class="zig">-%a<code></pre></td>
746 <td>782 <td>
747 <ul>783 <ul>
748 <li><a href="#integers">Integers</a></li>784 <li>{#link|Integers#}</li>
749 </ul>785 </ul>
750 </td>786 </td>
751 <td>787 <td>
...@@ -763,13 +799,13 @@ a -%= b</code></pre></td>...@@ -763,13 +799,13 @@ a -%= b</code></pre></td>
763a *= b</code></pre></td>799a *= b</code></pre></td>
764 <td>800 <td>
765 <ul>801 <ul>
766 <li><a href="#integers">Integers</a></li>802 <li>{#link|Integers#}</li>
767 <li><a href="#floats">Floats</a></li>803 <li>{#link|Floats#}</li>
768 </ul>804 </ul>
769 </td>805 </td>
770 <td>Multiplication.806 <td>Multiplication.
771 <ul>807 <ul>
772 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>808 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
773 </ul>809 </ul>
774 </td>810 </td>
775 <td>811 <td>
...@@ -781,7 +817,7 @@ a *= b</code></pre></td>...@@ -781,7 +817,7 @@ a *= b</code></pre></td>
781a *%= b</code></pre></td>817a *%= b</code></pre></td>
782 <td>818 <td>
783 <ul>819 <ul>
784 <li><a href="#integers">Integers</a></li>820 <li>{#link|Integers#}</li>
785 </ul>821 </ul>
786 </td>822 </td>
787 <td>Wrapping Multiplication.823 <td>Wrapping Multiplication.
...@@ -798,19 +834,19 @@ a *%= b</code></pre></td>...@@ -798,19 +834,19 @@ a *%= b</code></pre></td>
798a /= b</code></pre></td>834a /= b</code></pre></td>
799 <td>835 <td>
800 <ul>836 <ul>
801 <li><a href="#integers">Integers</a></li>837 <li>{#link|Integers#}</li>
802 <li><a href="#floats">Floats</a></li>838 <li>{#link|Floats#}</li>
803 </ul>839 </ul>
804 </td>840 </td>
805 <td>Divison.841 <td>Divison.
806 <ul>842 <ul>
807 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>843 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
808 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> for integers.</li>844 <li>Can cause {#link|Division by Zero#} for integers.</li>
809 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> for floats in <a href="#float-operations">FloatMode.Optimized Mode</a>.</li>845 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li>
810 <li>For non-compile-time-known signed integers, must use846 <li>For non-compile-time-known signed integers, must use
811 <a href="#builtin-divTrunc">@divTrunc</a>,847 {#link|@divTrunc#},
812 <a href="#builtin-divFloor">@divFloor</a>, or848 {#link|@divFloor#}, or
813 <a href="#builtin-divExact">@divExact</a> instead of <code>/</code>.849 {#link|@divExact#} instead of <code>/</code>.
814 </li>850 </li>
815 </ul>851 </ul>
816 </td>852 </td>
...@@ -823,17 +859,17 @@ a /= b</code></pre></td>...@@ -823,17 +859,17 @@ a /= b</code></pre></td>
823a %= b</code></pre></td>859a %= b</code></pre></td>
824 <td>860 <td>
825 <ul>861 <ul>
826 <li><a href="#integers">Integers</a></li>862 <li>{#link|Integers#}</li>
827 <li><a href="#floats">Floats</a></li>863 <li>{#link|Floats#}</li>
828 </ul>864 </ul>
829 </td>865 </td>
830 <td>Remainder Division.866 <td>Remainder Division.
831 <ul>867 <ul>
832 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> for integers.</li>868 <li>Can cause {#link|Division by Zero#} for integers.</li>
833 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> for floats in <a href="#float-operations">FloatMode.Optimized Mode</a>.</li>869 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li>
834 <li>For non-compile-time-known signed integers, must use870 <li>For non-compile-time-known signed integers, must use
835 <a href="#builtin-rem">@rem</a> or871 {#link|@rem#} or
836 <a href="#builtin-mod">@mod</a> instead of <code>%</code>.872 {#link|@mod#} instead of <code>%</code>.
837 </li>873 </li>
838 </ul>874 </ul>
839 </td>875 </td>
...@@ -846,13 +882,13 @@ a %= b</code></pre></td>...@@ -846,13 +882,13 @@ a %= b</code></pre></td>
846a &lt;&lt;= b</code></pre></td>882a &lt;&lt;= b</code></pre></td>
847 <td>883 <td>
848 <ul>884 <ul>
849 <li><a href="#integers">Integers</a></li>885 <li>{#link|Integers#}</li>
850 </ul>886 </ul>
851 </td>887 </td>
852 <td>Bit Shift Left.888 <td>Bit Shift Left.
853 <ul>889 <ul>
854 <li>See also <a href="#builtin-shlExact">@shlExact</a>.</li>890 <li>See also {#link|@shlExact#}.</li>
855 <li>See also <a href="#builtin-shlWithOverflow">@shlWithOverflow</a>.</li>891 <li>See also {#link|@shlWithOverflow#}.</li>
856 </ul>892 </ul>
857 </td>893 </td>
858 <td>894 <td>
...@@ -864,12 +900,12 @@ a &lt;&lt;= b</code></pre></td>...@@ -864,12 +900,12 @@ a &lt;&lt;= b</code></pre></td>
864a &gt;&gt;= b</code></pre></td>900a &gt;&gt;= b</code></pre></td>
865 <td>901 <td>
866 <ul>902 <ul>
867 <li><a href="#integers">Integers</a></li>903 <li>{#link|Integers#}</li>
868 </ul>904 </ul>
869 </td>905 </td>
870 <td>Bit Shift Right.906 <td>Bit Shift Right.
871 <ul>907 <ul>
872 <li>See also <a href="#builtin-shrExact">@shrExact</a>.</li>908 <li>See also {#link|@shrExact#}.</li>
873 </ul>909 </ul>
874 </td>910 </td>
875 <td>911 <td>
...@@ -881,7 +917,7 @@ a &gt;&gt;= b</code></pre></td>...@@ -881,7 +917,7 @@ a &gt;&gt;= b</code></pre></td>
881a &amp;= b</code></pre></td>917a &amp;= b</code></pre></td>
882 <td>918 <td>
883 <ul>919 <ul>
884 <li><a href="#integers">Integers</a></li>920 <li>{#link|Integers#}</li>
885 </ul>921 </ul>
886 </td>922 </td>
887 <td>Bitwise AND.923 <td>Bitwise AND.
...@@ -895,7 +931,7 @@ a &amp;= b</code></pre></td>...@@ -895,7 +931,7 @@ a &amp;= b</code></pre></td>
895a |= b</code></pre></td>931a |= b</code></pre></td>
896 <td>932 <td>
897 <ul>933 <ul>
898 <li><a href="#integers">Integers</a></li>934 <li>{#link|Integers#}</li>
899 </ul>935 </ul>
900 </td>936 </td>
901 <td>Bitwise OR.937 <td>Bitwise OR.
...@@ -909,7 +945,7 @@ a |= b</code></pre></td>...@@ -909,7 +945,7 @@ a |= b</code></pre></td>
909a ^= b</code></pre></td>945a ^= b</code></pre></td>
910 <td>946 <td>
911 <ul>947 <ul>
912 <li><a href="#integers">Integers</a></li>948 <li>{#link|Integers#}</li>
913 </ul>949 </ul>
914 </td>950 </td>
915 <td>Bitwise XOR.951 <td>Bitwise XOR.
...@@ -922,7 +958,7 @@ a ^= b</code></pre></td>...@@ -922,7 +958,7 @@ a ^= b</code></pre></td>
922 <td><pre><code class="zig">~a<code></pre></td>958 <td><pre><code class="zig">~a<code></pre></td>
923 <td>959 <td>
924 <ul>960 <ul>
925 <li><a href="#integers">Integers</a></li>961 <li>{#link|Integers#}</li>
926 </ul>962 </ul>
927 </td>963 </td>
928 <td>964 <td>
...@@ -936,13 +972,13 @@ a ^= b</code></pre></td>...@@ -936,13 +972,13 @@ a ^= b</code></pre></td>
936 <td><pre><code class="zig">a ?? b</code></pre></td>972 <td><pre><code class="zig">a ?? b</code></pre></td>
937 <td>973 <td>
938 <ul>974 <ul>
939 <li><a href="#nullables">Nullables</a></li>975 <li>{#link|Nullables#}</li>
940 </ul>976 </ul>
941 </td>977 </td>
942 <td>If <code>a</code> is <code>null</code>,978 <td>If <code>a</code> is <code>null</code>,
943 returns <code>b</code> ("default value"),979 returns <code>b</code> ("default value"),
944 otherwise returns the unwrapped value of <code>a</code>.980 otherwise returns the unwrapped value of <code>a</code>.
945 Note that <code>b</code> may be a value of type <a href="#noreturn">noreturn</a>.981 Note that <code>b</code> may be a value of type {#link|noreturn#}.
946 </td>982 </td>
947 <td>983 <td>
948 <pre><code class="zig">const value: ?u32 = null;984 <pre><code class="zig">const value: ?u32 = null;
...@@ -954,7 +990,7 @@ unwrapped == 1234</code></pre>...@@ -954,7 +990,7 @@ unwrapped == 1234</code></pre>
954 <td><pre><code class="zig">??a</code></pre></td>990 <td><pre><code class="zig">??a</code></pre></td>
955 <td>991 <td>
956 <ul>992 <ul>
957 <li><a href="#nullables">Nullables</a></li>993 <li>{#link|Nullables#}</li>
958 </ul>994 </ul>
959 </td>995 </td>
960 <td>996 <td>
...@@ -971,13 +1007,13 @@ unwrapped == 1234</code></pre>...@@ -971,13 +1007,13 @@ unwrapped == 1234</code></pre>
971a catch |err| b</code></pre></td>1007a catch |err| b</code></pre></td>
972 <td>1008 <td>
973 <ul>1009 <ul>
974 <li><a href="#errors">Error Unions</a></li>1010 <li>{#link|Error Unions|Errors#}</li>
975 </ul>1011 </ul>
976 </td>1012 </td>
977 <td>If <code>a</code> is an <code>error</code>,1013 <td>If <code>a</code> is an <code>error</code>,
978 returns <code>b</code> ("default value"),1014 returns <code>b</code> ("default value"),
979 otherwise returns the unwrapped value of <code>a</code>.1015 otherwise returns the unwrapped value of <code>a</code>.
980 Note that <code>b</code> may be a value of type <a href="#noreturn">noreturn</a>.1016 Note that <code>b</code> may be a value of type {#link|noreturn#}.
981 <code>err</code> is the <code>error</code> and is in scope of the expression <code>b</code>.1017 <code>err</code> is the <code>error</code> and is in scope of the expression <code>b</code>.
982 </td>1018 </td>
983 <td>1019 <td>
...@@ -986,26 +1022,11 @@ const unwrapped = value catch 1234;...@@ -986,26 +1022,11 @@ const unwrapped = value catch 1234;
986unwrapped == 1234</code></pre>1022unwrapped == 1234</code></pre>
987 </td>1023 </td>
988 </tr>1024 </tr>
989 <tr>
990 <td><pre><code class="zig">%%a</code></pre></td>
991 <td>
992 <ul>
993 <li><a href="#errors">Error Unions</a></li>
994 </ul>
995 </td>
996 <td>Equivalent to:
997 <pre><code class="zig">a catch unreachable</code></pre>
998 </td>
999 <td>
1000 <pre><code class="zig">const value: %u32 = 5678;
1001%%value == 5678</code></pre>
1002 </td>
1003 </tr>
1004 <tr>1025 <tr>
1005 <td><pre><code class="zig">a and b<code></pre></td>1026 <td><pre><code class="zig">a and b<code></pre></td>
1006 <td>1027 <td>
1007 <ul>1028 <ul>
1008 <li><a href="#primitive-types">bool</a></li>1029 <li>{#link|bool|Primitive Types#}</li>
1009 </ul>1030 </ul>
1010 </td>1031 </td>
1011 <td>1032 <td>
...@@ -1020,7 +1041,7 @@ unwrapped == 1234</code></pre>...@@ -1020,7 +1041,7 @@ unwrapped == 1234</code></pre>
1020 <td><pre><code class="zig">a or b<code></pre></td>1041 <td><pre><code class="zig">a or b<code></pre></td>
1021 <td>1042 <td>
1022 <ul>1043 <ul>
1023 <li><a href="#primitive-types">bool</a></li>1044 <li>{#link|bool|Primitive Types#}</li>
1024 </ul>1045 </ul>
1025 </td>1046 </td>
1026 <td>1047 <td>
...@@ -1035,7 +1056,7 @@ unwrapped == 1234</code></pre>...@@ -1035,7 +1056,7 @@ unwrapped == 1234</code></pre>
1035 <td><pre><code class="zig">!a<code></pre></td>1056 <td><pre><code class="zig">!a<code></pre></td>
1036 <td>1057 <td>
1037 <ul>1058 <ul>
1038 <li><a href="#primitive-types">bool</a></li>1059 <li>{#link|bool|Primitive Types#}</li>
1039 </ul>1060 </ul>
1040 </td>1061 </td>
1041 <td>1062 <td>
...@@ -1049,10 +1070,10 @@ unwrapped == 1234</code></pre>...@@ -1049,10 +1070,10 @@ unwrapped == 1234</code></pre>
1049 <td><pre><code class="zig">a == b<code></pre></td>1070 <td><pre><code class="zig">a == b<code></pre></td>
1050 <td>1071 <td>
1051 <ul>1072 <ul>
1052 <li><a href="#integers">Integers</a></li>1073 <li>{#link|Integers#}</li>
1053 <li><a href="#floats">Floats</a></li>1074 <li>{#link|Floats#}</li>
1054 <li><a href="#primitive-types">bool</a></li>1075 <li>{#link|bool|Primitive Types#}</li>
1055 <li><a href="#primitive-types">type</a></li>1076 <li>{#link|type|Primitive Types#}</li>
1056 </ul>1077 </ul>
1057 </td>1078 </td>
1058 <td>1079 <td>
...@@ -1066,7 +1087,7 @@ unwrapped == 1234</code></pre>...@@ -1066,7 +1087,7 @@ unwrapped == 1234</code></pre>
1066 <td><pre><code class="zig">a == null<code></pre></td>1087 <td><pre><code class="zig">a == null<code></pre></td>
1067 <td>1088 <td>
1068 <ul>1089 <ul>
1069 <li><a href="#nullables">Nullables</a></li>1090 <li>{#link|Nullables#}</li>
1070 </ul>1091 </ul>
1071 </td>1092 </td>
1072 <td>1093 <td>
...@@ -1081,10 +1102,10 @@ value == null</code></pre>...@@ -1081,10 +1102,10 @@ value == null</code></pre>
1081 <td><pre><code class="zig">a != b<code></pre></td>1102 <td><pre><code class="zig">a != b<code></pre></td>
1082 <td>1103 <td>
1083 <ul>1104 <ul>
1084 <li><a href="#integers">Integers</a></li>1105 <li>{#link|Integers#}</li>
1085 <li><a href="#floats">Floats</a></li>1106 <li>{#link|Floats#}</li>
1086 <li><a href="#primitive-types">bool</a></li>1107 <li>{#link|bool|Primitive Types#}</li>
1087 <li><a href="#primitive-types">type</a></li>1108 <li>{#link|type|Primitive Types#}</li>
1088 </ul>1109 </ul>
1089 </td>1110 </td>
1090 <td>1111 <td>
...@@ -1098,8 +1119,8 @@ value == null</code></pre>...@@ -1098,8 +1119,8 @@ value == null</code></pre>
1098 <td><pre><code class="zig">a &gt; b<code></pre></td>1119 <td><pre><code class="zig">a &gt; b<code></pre></td>
1099 <td>1120 <td>
1100 <ul>1121 <ul>
1101 <li><a href="#integers">Integers</a></li>1122 <li>{#link|Integers#}</li>
1102 <li><a href="#floats">Floats</a></li>1123 <li>{#link|Floats#}</li>
1103 </ul>1124 </ul>
1104 </td>1125 </td>
1105 <td>1126 <td>
...@@ -1113,8 +1134,8 @@ value == null</code></pre>...@@ -1113,8 +1134,8 @@ value == null</code></pre>
1113 <td><pre><code class="zig">a &gt;= b<code></pre></td>1134 <td><pre><code class="zig">a &gt;= b<code></pre></td>
1114 <td>1135 <td>
1115 <ul>1136 <ul>
1116 <li><a href="#integers">Integers</a></li>1137 <li>{#link|Integers#}</li>
1117 <li><a href="#floats">Floats</a></li>1138 <li>{#link|Floats#}</li>
1118 </ul>1139 </ul>
1119 </td>1140 </td>
1120 <td>1141 <td>
...@@ -1128,8 +1149,8 @@ value == null</code></pre>...@@ -1128,8 +1149,8 @@ value == null</code></pre>
1128 <td><pre><code class="zig">a &lt; b<code></pre></td>1149 <td><pre><code class="zig">a &lt; b<code></pre></td>
1129 <td>1150 <td>
1130 <ul>1151 <ul>
1131 <li><a href="#integers">Integers</a></li>1152 <li>{#link|Integers#}</li>
1132 <li><a href="#floats">Floats</a></li>1153 <li>{#link|Floats#}</li>
1133 </ul>1154 </ul>
1134 </td>1155 </td>
1135 <td>1156 <td>
...@@ -1143,8 +1164,8 @@ value == null</code></pre>...@@ -1143,8 +1164,8 @@ value == null</code></pre>
1143 <td><pre><code class="zig">a &lt;= b<code></pre></td>1164 <td><pre><code class="zig">a &lt;= b<code></pre></td>
1144 <td>1165 <td>
1145 <ul>1166 <ul>
1146 <li><a href="#integers">Integers</a></li>1167 <li>{#link|Integers#}</li>
1147 <li><a href="#floats">Floats</a></li>1168 <li>{#link|Floats#}</li>
1148 </ul>1169 </ul>
1149 </td>1170 </td>
1150 <td>1171 <td>
...@@ -1158,13 +1179,13 @@ value == null</code></pre>...@@ -1158,13 +1179,13 @@ value == null</code></pre>
1158 <td><pre><code class="zig">a ++ b<code></pre></td>1179 <td><pre><code class="zig">a ++ b<code></pre></td>
1159 <td>1180 <td>
1160 <ul>1181 <ul>
1161 <li><a href="#arrays">Arrays</a></li>1182 <li>{#link|Arrays#}</li>
1162 </ul>1183 </ul>
1163 </td>1184 </td>
1164 <td>1185 <td>
1165 Array concatenation.1186 Array concatenation.
1166 <ul>1187 <ul>
1167 <li>Only available when <code>a</code> and <code>b</code> are <a href="#comptime">compile-time known</a>.1188 <li>Only available when <code>a</code> and <code>b</code> are {#link|compile-time known|comptime#}.
1168 </ul>1189 </ul>
1169 </td>1190 </td>
1170 <td>1191 <td>
...@@ -1179,13 +1200,13 @@ mem.eql(u32, together, []u32{1,2,3,4})</code></pre>...@@ -1179,13 +1200,13 @@ mem.eql(u32, together, []u32{1,2,3,4})</code></pre>
1179 <td><pre><code class="zig">a ** b<code></pre></td>1200 <td><pre><code class="zig">a ** b<code></pre></td>
1180 <td>1201 <td>
1181 <ul>1202 <ul>
1182 <li><a href="#arrays">Arrays</a></li>1203 <li>{#link|Arrays#}</li>
1183 </ul>1204 </ul>
1184 </td>1205 </td>
1185 <td>1206 <td>
1186 Array multiplication.1207 Array multiplication.
1187 <ul>1208 <ul>
1188 <li>Only available when <code>a</code> and <code>b</code> are <a href="#comptime">compile-time known</a>.1209 <li>Only available when <code>a</code> and <code>b</code> are {#link|compile-time known|comptime#}.
1189 </ul>1210 </ul>
1190 </td>1211 </td>
1191 <td>1212 <td>
...@@ -1198,7 +1219,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>...@@ -1198,7 +1219,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
1198 <td><pre><code class="zig">*a<code></pre></td>1219 <td><pre><code class="zig">*a<code></pre></td>
1199 <td>1220 <td>
1200 <ul>1221 <ul>
1201 <li><a href="#pointers">Pointers</a></li>1222 <li>{#link|Pointers#}</li>
1202 </ul>1223 </ul>
1203 </td>1224 </td>
1204 <td>1225 <td>
...@@ -1228,7 +1249,7 @@ const ptr = &amp;x;...@@ -1228,7 +1249,7 @@ const ptr = &amp;x;
1228 {#header_close#}1249 {#header_close#}
1229 {#header_open|Precedence#}1250 {#header_open|Precedence#}
1230 <pre><code>x() x[] x.y1251 <pre><code>x() x[] x.y
1231!x -x -%x ~x *x &amp;x ?x %x %%x ??x1252!x -x -%x ~x *x &amp;x ?x %x ??x
1232x{}1253x{}
1233* / % ** *%1254* / % ** *%
1234+ - ++ +% -%1255+ - ++ +% -%
...@@ -1244,7 +1265,8 @@ or...@@ -1244,7 +1265,8 @@ or
1244 {#header_close#}1265 {#header_close#}
1245 {#header_close#}1266 {#header_close#}
1246 {#header_open|Arrays#}1267 {#header_open|Arrays#}
1247 <pre><code class="zig">const assert = @import("std").debug.assert;1268 {#code_begin|test|arrays#}
1269const assert = @import("std").debug.assert;
1248const mem = @import("std").mem;1270const mem = @import("std").mem;
12491271
1250// array literal1272// array literal
...@@ -1314,7 +1336,7 @@ comptime {...@@ -1314,7 +1336,7 @@ comptime {
1314}1336}
13151337
1316// use compile-time code to initialize an array1338// use compile-time code to initialize an array
1317var fancy_array = {1339var fancy_array = init: {
1318 var initial_value: [10]Point = undefined;1340 var initial_value: [10]Point = undefined;
1319 for (initial_value) |*pt, i| {1341 for (initial_value) |*pt, i| {
1320 *pt = Point {1342 *pt = Point {
...@@ -1322,7 +1344,7 @@ var fancy_array = {...@@ -1322,7 +1344,7 @@ var fancy_array = {
1322 .y = i32(i) * 2,1344 .y = i32(i) * 2,
1323 };1345 };
1324 }1346 }
1325 initial_value1347 break :init initial_value;
1326};1348};
1327const Point = struct {1349const Point = struct {
1328 x: i32,1350 x: i32,
...@@ -1336,26 +1358,23 @@ test "compile-time array initalization" {...@@ -1336,26 +1358,23 @@ test "compile-time array initalization" {
13361358
1337// call a function to initialize an array1359// call a function to initialize an array
1338var more_points = []Point{makePoint(3)} ** 10;1360var more_points = []Point{makePoint(3)} ** 10;
1339fn makePoint(x: i32) -&gt; Point {1361fn makePoint(x: i32) Point {
1340 Point {1362 return Point {
1341 .x = x,1363 .x = x,
1342 .y = x * 2,1364 .y = x * 2,
1343 }1365 };
1344}1366}
1345test "array initialization with function calls" {1367test "array initialization with function calls" {
1346 assert(more_points[4].x == 3);1368 assert(more_points[4].x == 3);
1347 assert(more_points[4].y == 6);1369 assert(more_points[4].y == 6);
1348 assert(more_points.len == 10);1370 assert(more_points.len == 10);
1349}</code></pre>1371}
1350 <pre><code class="sh">$ zig test arrays.zig1372 {#code_end#}
1351Test 1/4 iterate over an array...OK
1352Test 2/4 modify an array...OK
1353Test 3/4 compile-time array initalization...OK
1354Test 4/4 array initialization with function calls...OK</code></pre>
1355 {#see_also|for|Slices#}1373 {#see_also|for|Slices#}
1356 {#header_close#}1374 {#header_close#}
1357 {#header_open|Pointers#}1375 {#header_open|Pointers#}
1358 <pre><code class="zig">const assert = @import("std").debug.assert;1376 {#code_begin|test#}
1377const assert = @import("std").debug.assert;
13591378
1360test "address of syntax" {1379test "address of syntax" {
1361 // Get the address of a variable:1380 // Get the address of a variable:
...@@ -1366,12 +1385,12 @@ test "address of syntax" {...@@ -1366,12 +1385,12 @@ test "address of syntax" {
1366 assert(*x_ptr == 1234);1385 assert(*x_ptr == 1234);
13671386
1368 // When you get the address of a const variable, you get a const pointer.1387 // When you get the address of a const variable, you get a const pointer.
1369 assert(@typeOf(x_ptr) == &amp;const i32);1388 assert(@typeOf(x_ptr) == &const i32);
13701389
1371 // If you want to mutate the value, you'd need an address of a mutable variable:1390 // If you want to mutate the value, you'd need an address of a mutable variable:
1372 var y: i32 = 5678;1391 var y: i32 = 5678;
1373 const y_ptr = &y;1392 const y_ptr = &y;
1374 assert(@typeOf(y_ptr) == &amp;i32);1393 assert(@typeOf(y_ptr) == &i32);
1375 *y_ptr += 1;1394 *y_ptr += 1;
1376 assert(*y_ptr == 5679);1395 assert(*y_ptr == 5679);
1377}1396}
...@@ -1381,7 +1400,7 @@ test "pointer array access" {...@@ -1381,7 +1400,7 @@ test "pointer array access" {
1381 // need such a thing, use array index syntax:1400 // need such a thing, use array index syntax:
13821401
1383 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1402 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1384 const ptr = &amp;array[1];1403 const ptr = &array[1];
13851404
1386 assert(array[2] == 3);1405 assert(array[2] == 3);
1387 ptr[1] += 1;1406 ptr[1] += 1;
...@@ -1392,10 +1411,10 @@ test "pointer slicing" {...@@ -1392,10 +1411,10 @@ test "pointer slicing" {
1392 // In Zig, we prefer using slices over null-terminated pointers.1411 // In Zig, we prefer using slices over null-terminated pointers.
1393 // You can turn a pointer into a slice using slice syntax:1412 // You can turn a pointer into a slice using slice syntax:
1394 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};1413 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1395 const ptr = &amp;array[1];1414 const ptr = &array[1];
1396 const slice = ptr[1..3];1415 const slice = ptr[1..3];
13971416
1398 assert(slice.ptr == &amp;ptr[1]);1417 assert(slice.ptr == &ptr[1]);
1399 assert(slice.len == 2);1418 assert(slice.len == 2);
14001419
1401 // Slices have bounds checking and are therefore protected1420 // Slices have bounds checking and are therefore protected
...@@ -1410,7 +1429,7 @@ comptime {...@@ -1410,7 +1429,7 @@ comptime {
1410 // Pointers work at compile-time too, as long as you don't use1429 // Pointers work at compile-time too, as long as you don't use
1411 // @ptrCast.1430 // @ptrCast.
1412 var x: i32 = 1;1431 var x: i32 = 1;
1413 const ptr = &amp;x;1432 const ptr = &x;
1414 *ptr += 1;1433 *ptr += 1;
1415 x += 1;1434 x += 1;
1416 assert(*ptr == 3);1435 assert(*ptr == 3);
...@@ -1418,7 +1437,7 @@ comptime {...@@ -1418,7 +1437,7 @@ comptime {
14181437
1419test "@ptrToInt and @intToPtr" {1438test "@ptrToInt and @intToPtr" {
1420 // To convert an integer address into a pointer, use @intToPtr:1439 // To convert an integer address into a pointer, use @intToPtr:
1421 const ptr = @intToPtr(&amp;i32, 0xdeadbeef);1440 const ptr = @intToPtr(&i32, 0xdeadbeef);
14221441
1423 // To convert a pointer to an integer, use @ptrToInt:1442 // To convert a pointer to an integer, use @ptrToInt:
1424 const addr = @ptrToInt(ptr);1443 const addr = @ptrToInt(ptr);
...@@ -1430,7 +1449,7 @@ test "@ptrToInt and @intToPtr" {...@@ -1430,7 +1449,7 @@ test "@ptrToInt and @intToPtr" {
1430comptime {1449comptime {
1431 // Zig is able to do this at compile-time, as long as1450 // Zig is able to do this at compile-time, as long as
1432 // ptr is never dereferenced.1451 // ptr is never dereferenced.
1433 const ptr = @intToPtr(&amp;i32, 0xdeadbeef);1452 const ptr = @intToPtr(&i32, 0xdeadbeef);
1434 const addr = @ptrToInt(ptr);1453 const addr = @ptrToInt(ptr);
1435 assert(@typeOf(addr) == usize);1454 assert(@typeOf(addr) == usize);
1436 assert(addr == 0xdeadbeef);1455 assert(addr == 0xdeadbeef);
...@@ -1440,34 +1459,34 @@ test "volatile" {...@@ -1440,34 +1459,34 @@ test "volatile" {
1440 // In Zig, loads and stores are assumed to not have side effects.1459 // In Zig, loads and stores are assumed to not have side effects.
1441 // If a given load or store should have side effects, such as1460 // If a given load or store should have side effects, such as
1442 // Memory Mapped Input/Output (MMIO), use `volatile`:1461 // Memory Mapped Input/Output (MMIO), use `volatile`:
1443 const mmio_ptr = @intToPtr(&amp;volatile u8, 0x12345678);1462 const mmio_ptr = @intToPtr(&volatile u8, 0x12345678);
14441463
1445 // Now loads and stores with mmio_ptr are guaranteed to all happen1464 // Now loads and stores with mmio_ptr are guaranteed to all happen
1446 // and in the same order as in source code.1465 // and in the same order as in source code.
1447 assert(@typeOf(mmio_ptr) == &amp;volatile u8);1466 assert(@typeOf(mmio_ptr) == &volatile u8);
1448}1467}
14491468
1450test "nullable pointers" {1469test "nullable pointers" {
1451 // Pointers cannot be null. If you want a null pointer, use the nullable1470 // Pointers cannot be null. If you want a null pointer, use the nullable
1452 // prefix `?` to make the pointer type nullable.1471 // prefix `?` to make the pointer type nullable.
1453 var ptr: ?&amp;i32 = null;1472 var ptr: ?&i32 = null;
14541473
1455 var x: i32 = 1;1474 var x: i32 = 1;
1456 ptr = &amp;x;1475 ptr = &x;
14571476
1458 assert(*??ptr == 1);1477 assert(*??ptr == 1);
14591478
1460 // Nullable pointers are the same size as normal pointers, because pointer1479 // Nullable pointers are the same size as normal pointers, because pointer
1461 // value 0 is used as the null value.1480 // value 0 is used as the null value.
1462 assert(@sizeOf(?&amp;i32) == @sizeOf(&amp;i32));1481 assert(@sizeOf(?&i32) == @sizeOf(&i32));
1463}1482}
14641483
1465test "pointer casting" {1484test "pointer casting" {
1466 // To convert one pointer type to another, use @ptrCast. This is an unsafe1485 // To convert one pointer type to another, use @ptrCast. This is an unsafe
1467 // operation that Zig cannot protect you against. Use @ptrCast only when other1486 // operation that Zig cannot protect you against. Use @ptrCast only when other
1468 // conversions are not possible.1487 // conversions are not possible.
1469 const bytes = []u8{0x12, 0x12, 0x12, 0x12};1488 const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
1470 const u32_ptr = @ptrCast(&amp;const u32, &amp;bytes[0]);1489 const u32_ptr = @ptrCast(&const u32, &bytes[0]);
1471 assert(*u32_ptr == 0x12121212);1490 assert(*u32_ptr == 0x12121212);
14721491
1473 // Even this example is contrived - there are better ways to do the above than1492 // Even this example is contrived - there are better ways to do the above than
...@@ -1481,23 +1500,15 @@ test "pointer casting" {...@@ -1481,23 +1500,15 @@ test "pointer casting" {
14811500
1482test "pointer child type" {1501test "pointer child type" {
1483 // pointer types have a `child` field which tells you the type they point to.1502 // pointer types have a `child` field which tells you the type they point to.
1484 assert((&amp;u32).child == u32);1503 assert((&u32).Child == u32);
1485}</code></pre>1504}
1486 <pre><code class="sh">$ zig test test.zig1505 {#code_end#}
1487Test 1/8 address of syntax...OK
1488Test 2/8 pointer array access...OK
1489Test 3/8 pointer slicing...OK
1490Test 4/8 @ptrToInt and @intToPtr...OK
1491Test 5/8 volatile...OK
1492Test 6/8 nullable pointers...OK
1493Test 7/8 pointer casting...OK
1494Test 8/8 pointer child type...OK</code></pre>
1495 {#header_open|Alignment#}1506 {#header_open|Alignment#}
1496 <p>1507 <p>
1497 Each type has an <strong>alignment</strong> - a number of bytes such that,1508 Each type has an <strong>alignment</strong> - a number of bytes such that,
1498 when a value of the type is loaded from or stored to memory,1509 when a value of the type is loaded from or stored to memory,
1499 the memory address must be evenly divisible by this number. You can use1510 the memory address must be evenly divisible by this number. You can use
1500 <a href="#builtin-alignOf">@alignOf</a> to find out this value for any type.1511 {#link|@alignOf#} to find out this value for any type.
1501 </p>1512 </p>
1502 <p>1513 <p>
1503 Alignment depends on the CPU architecture, but is always a power of two, and1514 Alignment depends on the CPU architecture, but is always a power of two, and
...@@ -1507,18 +1518,20 @@ Test 8/8 pointer child type...OK</code></pre>...@@ -1507,18 +1518,20 @@ Test 8/8 pointer child type...OK</code></pre>
1507 In Zig, a pointer type has an alignment value. If the value is equal to the1518 In Zig, a pointer type has an alignment value. If the value is equal to the
1508 alignment of the underlying type, it can be omitted from the type:1519 alignment of the underlying type, it can be omitted from the type:
1509 </p>1520 </p>
1510 <pre><code class="zig">const assert = @import("std").debug.assert;1521 {#code_begin|test#}
1522const assert = @import("std").debug.assert;
1511const builtin = @import("builtin");1523const builtin = @import("builtin");
15121524
1513test "variable alignment" {1525test "variable alignment" {
1514 var x: i32 = 1234;1526 var x: i32 = 1234;
1515 const align_of_i32 = @alignOf(@typeOf(x));1527 const align_of_i32 = @alignOf(@typeOf(x));
1516 assert(@typeOf(&amp;x) == &amp;i32);1528 assert(@typeOf(&x) == &i32);
1517 assert(&amp;i32 == &amp;align(align_of_i32) i32);1529 assert(&i32 == &align(align_of_i32) i32);
1518 if (builtin.arch == builtin.Arch.x86_64) {1530 if (builtin.arch == builtin.Arch.x86_64) {
1519 assert((&amp;i32).alignment == 4);1531 assert((&i32).alignment == 4);
1520 }1532 }
1521}</code></pre>1533}
1534 {#code_end#}
1522 <p>In the same way that a <code>&amp;i32</code> can be implicitly cast to a1535 <p>In the same way that a <code>&amp;i32</code> can be implicitly cast to a
1523 <code>&amp;const i32</code>, a pointer with a larger alignment can be implicitly1536 <code>&amp;const i32</code>, a pointer with a larger alignment can be implicitly
1524 cast to a pointer with a smaller alignment, but not vice versa.1537 cast to a pointer with a smaller alignment, but not vice versa.
...@@ -1527,72 +1540,50 @@ test "variable alignment" {...@@ -1527,72 +1540,50 @@ test "variable alignment" {
1527 You can specify alignment on variables and functions. If you do this, then1540 You can specify alignment on variables and functions. If you do this, then
1528 pointers to them get the specified alignment:1541 pointers to them get the specified alignment:
1529 </p>1542 </p>
1530 <pre><code class="zig">const assert = @import("std").debug.assert;1543 {#code_begin|test#}
1544const assert = @import("std").debug.assert;
15311545
1532var foo: u8 align(4) = 100;1546var foo: u8 align(4) = 100;
15331547
1534test "global variable alignment" {1548test "global variable alignment" {
1535 assert(@typeOf(&amp;foo).alignment == 4);1549 assert(@typeOf(&foo).alignment == 4);
1536 assert(@typeOf(&amp;foo) == &amp;align(4) u8);1550 assert(@typeOf(&foo) == &align(4) u8);
1537 const slice = (&amp;foo)[0..1];1551 const slice = (&foo)[0..1];
1538 assert(@typeOf(slice) == []align(4) u8);1552 assert(@typeOf(slice) == []align(4) u8);
1539}1553}
15401554
1541fn derp() align(@sizeOf(usize) * 2) -&gt; i32 { 1234 }1555fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
1542fn noop1() align(1) {}1556fn noop1() align(1) void {}
1543fn noop4() align(4) {}1557fn noop4() align(4) void {}
15441558
1545test "function alignment" {1559test "function alignment" {
1546 assert(derp() == 1234);1560 assert(derp() == 1234);
1547 assert(@typeOf(noop1) == fn() align(1));1561 assert(@typeOf(noop1) == fn() align(1) void);
1548 assert(@typeOf(noop4) == fn() align(4));1562 assert(@typeOf(noop4) == fn() align(4) void);
1549 noop1();1563 noop1();
1550 noop4();1564 noop4();
1551}</code></pre>1565}
1566 {#code_end#}
1552 <p>1567 <p>
1553 If you have a pointer or a slice that has a small alignment, but you know that it actually1568 If you have a pointer or a slice that has a small alignment, but you know that it actually
1554 has a bigger alignment, use <a href="#builtin-alignCast">@alignCast</a> to change the1569 has a bigger alignment, use {#link|@alignCast#} to change the
1555 pointer into a more aligned pointer. This is a no-op at runtime, but inserts a1570 pointer into a more aligned pointer. This is a no-op at runtime, but inserts a
1556 <a href="#undef-incorrect-pointer-alignment">safety check</a>:1571 {#link|safety check|Incorrect Pointer Alignment#}:
1557 </p>1572 </p>
1558 <pre><code class="zig">const assert = @import("std").debug.assert;1573 {#code_begin|test_safety|incorrect alignment#}
1574const assert = @import("std").debug.assert;
15591575
1560test "pointer alignment safety" {1576test "pointer alignment safety" {
1561 var array align(4) = []u32{0x11111111, 0x11111111};1577 var array align(4) = []u32{0x11111111, 0x11111111};
1562 const bytes = ([]u8)(array[0..]);1578 const bytes = ([]u8)(array[0..]);
1563 assert(foo(bytes) == 0x11111111);1579 assert(foo(bytes) == 0x11111111);
1564}1580}
1565fn foo(bytes: []u8) -&gt; u32 {1581fn foo(bytes: []u8) u32 {
1566 const slice4 = bytes[1..5];1582 const slice4 = bytes[1..5];
1567 const int_slice = ([]u32)(@alignCast(4, slice4));1583 const int_slice = ([]u32)(@alignCast(4, slice4));
1568 return int_slice[0];1584 return int_slice[0];
1569}</code></pre>1585}
1570 <pre><code class="sh">$ zig test test.zig1586 {#code_end#}
1571Test 1/1 pointer alignment safety...incorrect alignment
1572/home/andy/dev/zig/build/lib/zig/std/special/zigrt.zig:16:35: 0x0000000000203525 in ??? (test)
1573 @import("std").debug.panic("{}", message_ptr[0..message_len]);
1574 ^
1575/home/andy/dev/zig/build/test.zig:10:45: 0x00000000002035ec in ??? (test)
1576 const int_slice = ([]u32)(@alignCast(4, slice4));
1577 ^
1578/home/andy/dev/zig/build/test.zig:6:15: 0x0000000000203439 in ??? (test)
1579 assert(foo(bytes) == 0x11111111);
1580 ^
1581/home/andy/dev/zig/build/lib/zig/std/special/test_runner.zig:9:21: 0x00000000002162d8 in ??? (test)
1582 test_fn.func();
1583 ^
1584/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000216197 in ??? (test)
1585 return root.main();
1586 ^
1587/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000216050 in ??? (test)
1588 callMain(argc, argv, envp) catch std.os.posix.exit(1);
1589 ^
1590/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000215fa0 in ??? (test)
1591 posixCallMainAndExit()
1592 ^
1593
1594Tests failed. Use the following command to reproduce the failure:
1595./test</code></pre>
1596 {#header_close#}1587 {#header_close#}
1597 {#header_open|Type Based Alias Analysis#}1588 {#header_open|Type Based Alias Analysis#}
1598 <p>Zig uses Type Based Alias Analysis (also known as Strict Aliasing) to1589 <p>Zig uses Type Based Alias Analysis (also known as Strict Aliasing) to
...@@ -1602,14 +1593,15 @@ Tests failed. Use the following command to reproduce the failure:...@@ -1602,14 +1593,15 @@ Tests failed. Use the following command to reproduce the failure:
1602 </p>1593 </p>
1603 <p>As an example, this code produces undefined behavior:</p>1594 <p>As an example, this code produces undefined behavior:</p>
1604 <pre><code class="zig">*@ptrCast(&amp;u32, f32(12.34))</code></pre>1595 <pre><code class="zig">*@ptrCast(&amp;u32, f32(12.34))</code></pre>
1605 <p>Instead, use <a href="#builtin-bitCast">@bitCast</a>:1596 <p>Instead, use {#link|@bitCast#}:
1606 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>1597 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
1607 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>1598 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
1608 {#see_also|Slices|Memory#}1599 {#see_also|Slices|Memory#}
1609 {#header_close#}1600 {#header_close#}
1610 {#header_close#}1601 {#header_close#}
1611 {#header_open|Slices#}1602 {#header_open|Slices#}
1612 <pre><code class="zig">const assert = @import("std").debug.assert;1603 {#code_begin|test_safety|index out of bounds#}
1604const assert = @import("std").debug.assert;
16131605
1614test "basic slices" {1606test "basic slices" {
1615 var array = []i32{1, 2, 3, 4};1607 var array = []i32{1, 2, 3, 4};
...@@ -1618,38 +1610,17 @@ test "basic slices" {...@@ -1618,38 +1610,17 @@ test "basic slices" {
1618 // compile-time, whereas the slice's length is known at runtime.1610 // compile-time, whereas the slice's length is known at runtime.
1619 // Both can be accessed with the `len` field.1611 // Both can be accessed with the `len` field.
1620 const slice = array[0..array.len];1612 const slice = array[0..array.len];
1621 assert(slice.ptr == &amp;array[0]);1613 assert(slice.ptr == &array[0]);
1622 assert(slice.len == array.len);1614 assert(slice.len == array.len);
16231615
1624 // Slices have array bounds checking. If you try to access something out1616 // Slices have array bounds checking. If you try to access something out
1625 // of bounds, you'll get a safety check failure:1617 // of bounds, you'll get a safety check failure:
1626 slice[10] += 1;1618 slice[10] += 1;
1627}</code></pre>1619}
1628 <pre><code class="sh">$ zig test test.zig1620 {#code_end#}
1629Test 1/1 basic slices...index out of bounds
1630lib/zig/std/special/zigrt.zig:16:35: 0x0000000000203455 in ??? (test)
1631 @import("std").debug.panic("{}", message_ptr[0..message_len]);
1632 ^
1633test.zig:15:10: 0x0000000000203334 in ??? (test)
1634 slice[10] += 1;
1635 ^
1636lib/zig/std/special/test_runner.zig:9:21: 0x0000000000214b1a in ??? (test)
1637 test_fn.func();
1638 ^
1639lib/zig/std/special/bootstrap.zig:60:21: 0x00000000002149e7 in ??? (test)
1640 return root.main();
1641 ^
1642lib/zig/std/special/bootstrap.zig:47:13: 0x00000000002148a0 in ??? (test)
1643 callMain(argc, argv, envp) catch std.os.posix.exit(1);
1644 ^
1645lib/zig/std/special/bootstrap.zig:34:25: 0x00000000002147f0 in ??? (test)
1646 posixCallMainAndExit()
1647 ^
1648
1649Tests failed. Use the following command to reproduce the failure:
1650./test</code></pre>
1651 <p>This is one reason we prefer slices to pointers.</p>1621 <p>This is one reason we prefer slices to pointers.</p>
1652 <pre><code class="zig">const assert = @import("std").debug.assert;1622 {#code_begin|test|slices#}
1623const assert = @import("std").debug.assert;
1653const mem = @import("std").mem;1624const mem = @import("std").mem;
1654const fmt = @import("std").fmt;1625const fmt = @import("std").fmt;
16551626
...@@ -1663,8 +1634,8 @@ test "using slices for strings" {...@@ -1663,8 +1634,8 @@ test "using slices for strings" {
1663 var all_together: [100]u8 = undefined;1634 var all_together: [100]u8 = undefined;
1664 // You can use slice syntax on an array to convert an array into a slice.1635 // You can use slice syntax on an array to convert an array into a slice.
1665 const all_together_slice = all_together[0..];1636 const all_together_slice = all_together[0..];
1666 // String concatenation example:1637 // String concatenation example.
1667 const hello_world = fmt.bufPrint(all_together_slice, "{} {}", hello, world);1638 const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", hello, world);
16681639
1669 // Generally, you can use UTF-8 and not worry about whether something is a1640 // Generally, you can use UTF-8 and not worry about whether something is a
1670 // string. If you don't need to deal with individual characters, no need1641 // string. If you don't need to deal with individual characters, no need
...@@ -1674,7 +1645,7 @@ test "using slices for strings" {...@@ -1674,7 +1645,7 @@ test "using slices for strings" {
16741645
1675test "slice pointer" {1646test "slice pointer" {
1676 var array: [10]u8 = undefined;1647 var array: [10]u8 = undefined;
1677 const ptr = &amp;array[0];1648 const ptr = &array[0];
16781649
1679 // You can use slicing syntax to convert a pointer into a slice:1650 // You can use slicing syntax to convert a pointer into a slice:
1680 const slice = ptr[0..5];1651 const slice = ptr[0..5];
...@@ -1692,20 +1663,18 @@ test "slice pointer" {...@@ -1692,20 +1663,18 @@ test "slice pointer" {
1692test "slice widening" {1663test "slice widening" {
1693 // Zig supports slice widening and slice narrowing. Cast a slice of u81664 // Zig supports slice widening and slice narrowing. Cast a slice of u8
1694 // to a slice of anything else, and Zig will perform the length conversion.1665 // to a slice of anything else, and Zig will perform the length conversion.
1695 const array = []u8{0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13};1666 const array align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13};
1696 const slice = ([]const u32)(array[0..]);1667 const slice = ([]const u32)(array[0..]);
1697 assert(slice.len == 2);1668 assert(slice.len == 2);
1698 assert(slice[0] == 0x12121212);1669 assert(slice[0] == 0x12121212);
1699 assert(slice[1] == 0x13131313);1670 assert(slice[1] == 0x13131313);
1700}</code></pre>1671}
1701 <pre><code class="sh">$ zig test test.zig1672 {#code_end#}
1702Test 1/3 using slices for strings...OK
1703Test 2/3 slice pointer...OK
1704Test 3/3 slice widening...OK</code></pre>
1705 {#see_also|Pointers|for|Arrays#}1673 {#see_also|Pointers|for|Arrays#}
1706 {#header_close#}1674 {#header_close#}
1707 {#header_open|struct#}1675 {#header_open|struct#}
1708 <pre><code class="zig">// Declare a struct.1676 {#code_begin|test|structs#}
1677// Declare a struct.
1709// Zig gives no guarantees about the order of fields and whether or1678// Zig gives no guarantees about the order of fields and whether or
1710// not there will be padding.1679// not there will be padding.
1711const Point = struct {1680const Point = struct {
...@@ -1741,7 +1710,7 @@ const Vec3 = struct {...@@ -1741,7 +1710,7 @@ const Vec3 = struct {
1741 y: f32,1710 y: f32,
1742 z: f32,1711 z: f32,
17431712
1744 pub fn init(x: f32, y: f32, z: f32) -&gt; Vec3 {1713 pub fn init(x: f32, y: f32, z: f32) Vec3 {
1745 return Vec3 {1714 return Vec3 {
1746 .x = x,1715 .x = x,
1747 .y = y,1716 .y = y,
...@@ -1749,7 +1718,7 @@ const Vec3 = struct {...@@ -1749,7 +1718,7 @@ const Vec3 = struct {
1749 };1718 };
1750 }1719 }
17511720
1752 pub fn dot(self: &amp;const Vec3, other: &amp;const Vec3) -&gt; f32 {1721 pub fn dot(self: &const Vec3, other: &const Vec3) f32 {
1753 return self.x * other.x + self.y * other.y + self.z * other.z;1722 return self.x * other.x + self.y * other.y + self.z * other.z;
1754 }1723 }
1755};1724};
...@@ -1781,7 +1750,7 @@ test "struct namespaced variable" {...@@ -1781,7 +1750,7 @@ test "struct namespaced variable" {
17811750
1782// struct field order is determined by the compiler for optimal performance.1751// struct field order is determined by the compiler for optimal performance.
1783// however, you can still calculate a struct base pointer given a field pointer:1752// however, you can still calculate a struct base pointer given a field pointer:
1784fn setYBasedOnX(x: &amp;f32, y: f32) {1753fn setYBasedOnX(x: &f32, y: f32) void {
1785 const point = @fieldParentPtr(Point, "x", x);1754 const point = @fieldParentPtr(Point, "x", x);
1786 point.y = y;1755 point.y = y;
1787}1756}
...@@ -1790,22 +1759,22 @@ test "field parent pointer" {...@@ -1790,22 +1759,22 @@ test "field parent pointer" {
1790 .x = 0.1234,1759 .x = 0.1234,
1791 .y = 0.5678,1760 .y = 0.5678,
1792 };1761 };
1793 setYBasedOnX(&amp;point.x, 0.9);1762 setYBasedOnX(&point.x, 0.9);
1794 assert(point.y == 0.9);1763 assert(point.y == 0.9);
1795}1764}
17961765
1797// You can return a struct from a function. This is how we do generics1766// You can return a struct from a function. This is how we do generics
1798// in Zig:1767// in Zig:
1799fn LinkedList(comptime T: type) -&gt; type {1768fn LinkedList(comptime T: type) type {
1800 return struct {1769 return struct {
1801 pub const Node = struct {1770 pub const Node = struct {
1802 prev: ?&amp;Node,1771 prev: ?&Node,
1803 next: ?&amp;Node,1772 next: ?&Node,
1804 data: T,1773 data: T,
1805 };1774 };
18061775
1807 first: ?&amp;Node,1776 first: ?&Node,
1808 last: ?&amp;Node,1777 last: ?&Node,
1809 len: usize,1778 len: usize,
1810 };1779 };
1811}1780}
...@@ -1833,21 +1802,18 @@ test "linked list" {...@@ -1833,21 +1802,18 @@ test "linked list" {
1833 .data = 1234,1802 .data = 1234,
1834 };1803 };
1835 var list2 = LinkedList(i32) {1804 var list2 = LinkedList(i32) {
1836 .first = &amp;node,1805 .first = &node,
1837 .last = &amp;node,1806 .last = &node,
1838 .len = 1,1807 .len = 1,
1839 };1808 };
1840 assert((??list2.first).data == 1234);1809 assert((??list2.first).data == 1234);
1841}</code></pre>1810}
1842 <pre><code class="sh">$ zig test structs.zig1811 {#code_end#}
1843Test 1/4 dot product...OK
1844Test 2/4 struct namespaced variable...OK
1845Test 3/4 field parent pointer...OK
1846Test 4/4 linked list...OK</code></pre>
1847 {#see_also|comptime|@fieldParentPtr#}1812 {#see_also|comptime|@fieldParentPtr#}
1848 {#header_close#}1813 {#header_close#}
1849 {#header_open|enum#}1814 {#header_open|enum#}
1850 <pre><code class="zig">const assert = @import("std").debug.assert;1815 {#code_begin|test|enums#}
1816const assert = @import("std").debug.assert;
1851const mem = @import("std").mem;1817const mem = @import("std").mem;
18521818
1853// Declare an enum.1819// Declare an enum.
...@@ -1896,7 +1862,7 @@ const Suit = enum {...@@ -1896,7 +1862,7 @@ const Suit = enum {
1896 Diamonds,1862 Diamonds,
1897 Hearts,1863 Hearts,
18981864
1899 pub fn isClubs(self: Suit) -&gt; bool {1865 pub fn isClubs(self: Suit) bool {
1900 return self == Suit.Clubs;1866 return self == Suit.Clubs;
1901 }1867 }
1902};1868};
...@@ -1914,9 +1880,9 @@ const Foo = enum {...@@ -1914,9 +1880,9 @@ const Foo = enum {
1914test "enum variant switch" {1880test "enum variant switch" {
1915 const p = Foo.Number;1881 const p = Foo.Number;
1916 const what_is_it = switch (p) {1882 const what_is_it = switch (p) {
1917 Foo.String =&gt; "this is a string",1883 Foo.String => "this is a string",
1918 Foo.Number =&gt; "this is a number",1884 Foo.Number => "this is a number",
1919 Foo.None =&gt; "this is a none",1885 Foo.None => "this is a none",
1920 };1886 };
1921 assert(mem.eql(u8, what_is_it, "this is a number"));1887 assert(mem.eql(u8, what_is_it, "this is a number"));
1922}1888}
...@@ -1945,22 +1911,30 @@ test "@memberName" {...@@ -1945,22 +1911,30 @@ test "@memberName" {
1945// @tagName gives a []const u8 representation of an enum value:1911// @tagName gives a []const u8 representation of an enum value:
1946test "@tagName" {1912test "@tagName" {
1947 assert(mem.eql(u8, @tagName(Small.Three), "Three"));1913 assert(mem.eql(u8, @tagName(Small.Three), "Three"));
1948}</code></pre>1914}
1949 <p>TODO extern enum</p>1915 {#code_end#}
1916 {#header_open|extern enum#}
1917 <p>
1918 By default, enums are not guaranteed to be compatible with the C ABI:
1919 </p>
1920 {#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'ccc'#}
1921const Foo = enum { A, B, C };
1922export fn entry(foo: Foo) void { }
1923 {#code_end#}
1924 <p>
1925 For a C-ABI-compatible enum, use <code class="zig">extern enum</code>:
1926 </p>
1927 {#code_begin|obj#}
1928const Foo = extern enum { A, B, C };
1929export fn entry(foo: Foo) void { }
1930 {#code_end#}
1931 {#header_close#}
1950 <p>TODO packed enum</p>1932 <p>TODO packed enum</p>
1951 <pre><code class="sh">$ zig test enum.zig
1952Test 1/8 enum ordinal value...OK
1953Test 2/8 set enum ordinal value...OK
1954Test 3/8 enum method...OK
1955Test 4/8 enum variant switch...OK
1956Test 5/8 @TagType...OK
1957Test 6/8 @memberCount...OK
1958Test 7/8 @memberName...OK
1959Test 8/8 @tagName...OK</code></pre>
1960 {#see_also|@memberName|@memberCount|@tagName#}1933 {#see_also|@memberName|@memberCount|@tagName#}
1961 {#header_close#}1934 {#header_close#}
1962 {#header_open|union#}1935 {#header_open|union#}
1963 <pre><code class="zig">const assert = @import("std").debug.assert;1936 {#code_begin|test|union#}
1937const assert = @import("std").debug.assert;
1964const mem = @import("std").mem;1938const mem = @import("std").mem;
19651939
1966// A union has only 1 active field at a time.1940// A union has only 1 active field at a time.
...@@ -2008,19 +1982,19 @@ test "union variant switch" {...@@ -2008,19 +1982,19 @@ test "union variant switch" {
2008 const p = Foo { .Number = 54 };1982 const p = Foo { .Number = 54 };
2009 const what_is_it = switch (p) {1983 const what_is_it = switch (p) {
2010 // Capture by reference1984 // Capture by reference
2011 Foo.String =&gt; |*x| {1985 Foo.String => |*x| blk: {
2012 "this is a string"1986 break :blk "this is a string";
2013 },1987 },
20141988
2015 // Capture by value1989 // Capture by value
2016 Foo.Number =&gt; |x| {1990 Foo.Number => |x| blk: {
2017 assert(x == 54);1991 assert(x == 54);
2018 "this is a number"1992 break :blk "this is a number";
2019 },1993 },
20201994
2021 Foo.None =&gt; {1995 Foo.None => blk: {
2022 "this is a none"1996 break :blk "this is a none";
2023 }1997 },
2024 };1998 };
2025 assert(mem.eql(u8, what_is_it, "this is a number"));1999 assert(mem.eql(u8, what_is_it, "this is a number"));
2026}2000}
...@@ -2053,22 +2027,16 @@ const Small2 = union(enum) {...@@ -2053,22 +2027,16 @@ const Small2 = union(enum) {
2053};2027};
2054test "@tagName" {2028test "@tagName" {
2055 assert(mem.eql(u8, @tagName(Small2.C), "C"));2029 assert(mem.eql(u8, @tagName(Small2.C), "C"));
2056}</code></pre>2030}
2057 <pre><code class="sh">$ zig test union.zig2031 {#code_end#}
2058Test 1/7 simple union...OK
2059Test 2/7 declare union value...OK
2060Test 3/7 @TagType...OK
2061Test 4/7 union variant switch...OK
2062Test 5/7 @memberCount...OK
2063Test 6/7 @memberName...OK
2064Test 7/7 @tagName...OK</code></pre>
2065 <p>2032 <p>
2066 Unions with an enum tag are generated as a struct with a tag field and union field. Zig2033 Unions with an enum tag are generated as a struct with a tag field and union field. Zig
2067 sorts the order of the tag and union field by the largest alignment.2034 sorts the order of the tag and union field by the largest alignment.
2068 </p>2035 </p>
2069 {#header_close#}2036 {#header_close#}
2070 {#header_open|switch#}2037 {#header_open|switch#}
2071 <pre><code class="zig">const assert = @import("std").debug.assert;2038 {#code_begin|test|switch#}
2039const assert = @import("std").debug.assert;
2072const builtin = @import("builtin");2040const builtin = @import("builtin");
20732041
2074test "switch simple" {2042test "switch simple" {
...@@ -2082,59 +2050,59 @@ test "switch simple" {...@@ -2082,59 +2050,59 @@ test "switch simple" {
2082 // the cases and use an if.2050 // the cases and use an if.
2083 const b = switch (a) {2051 const b = switch (a) {
2084 // Multiple cases can be combined via a ','2052 // Multiple cases can be combined via a ','
2085 1, 2, 3 =&gt; 0,2053 1, 2, 3 => 0,
20862054
2087 // Ranges can be specified using the ... syntax. These are inclusive2055 // Ranges can be specified using the ... syntax. These are inclusive
2088 // both ends.2056 // both ends.
2089 5 ... 100 =&gt; 1,2057 5 ... 100 => 1,
20902058
2091 // Branches can be arbitrarily complex.2059 // Branches can be arbitrarily complex.
2092 101 =&gt; {2060 101 => blk: {
2093 const c: u64 = 5;2061 const c: u64 = 5;
2094 c * 2 + 12062 break :blk c * 2 + 1;
2095 },2063 },
20962064
2097 // Switching on arbitrary expressions is allowed as long as the2065 // Switching on arbitrary expressions is allowed as long as the
2098 // expression is known at compile-time.2066 // expression is known at compile-time.
2099 zz =&gt; zz,2067 zz => zz,
2100 comptime {2068 comptime blk: {
2101 const d: u32 = 5;2069 const d: u32 = 5;
2102 const e: u32 = 100;2070 const e: u32 = 100;
2103 d + e2071 break :blk d + e;
2104 } =&gt; 107,2072 } => 107,
21052073
2106 // The else branch catches everything not already captured.2074 // The else branch catches everything not already captured.
2107 // Else branches are mandatory unless the entire range of values2075 // Else branches are mandatory unless the entire range of values
2108 // is handled.2076 // is handled.
2109 else =&gt; 9,2077 else => 9,
2110 };2078 };
21112079
2112 assert(b == 1);2080 assert(b == 1);
2113}2081}
21142082
2115test "switch enum" {2083test "switch enum" {
2116 const Item = enum {2084 const Item = union(enum) {
2117 A: u32,2085 A: u32,
2118 C: struct { x: u8, y: u8 },2086 C: struct { x: u8, y: u8 },
2119 D,2087 D,
2120 };2088 };
21212089
2122 var a = Item.A { 3 };2090 var a = Item { .A = 3 };
21232091
2124 // Switching on more complex enums is allowed.2092 // Switching on more complex enums is allowed.
2125 const b = switch (a) {2093 const b = switch (a) {
2126 // A capture group is allowed on a match, and will return the enum2094 // A capture group is allowed on a match, and will return the enum
2127 // value matched.2095 // value matched.
2128 Item.A =&gt; |item| item,2096 Item.A => |item| item,
21292097
2130 // A reference to the matched value can be obtained using `*` syntax.2098 // A reference to the matched value can be obtained using `*` syntax.
2131 Item.C =&gt; |*item| {2099 Item.C => |*item| blk: {
2132 (*item).x += 1;2100 (*item).x += 1;
2133 62101 break :blk 6;
2134 },2102 },
21352103
2136 // No else is required if the types cases was exhaustively handled2104 // No else is required if the types cases was exhaustively handled
2137 Item.D =&gt; 8,2105 Item.D => 8,
2138 };2106 };
21392107
2140 assert(b == 3);2108 assert(b == 3);
...@@ -2142,37 +2110,35 @@ test "switch enum" {...@@ -2142,37 +2110,35 @@ test "switch enum" {
21422110
2143// Switch expressions can be used outside a function:2111// Switch expressions can be used outside a function:
2144const os_msg = switch (builtin.os) {2112const os_msg = switch (builtin.os) {
2145 builtin.Os.linux =&gt; "we found a linux user",2113 builtin.Os.linux => "we found a linux user",
2146 else =&gt; "not a linux user",2114 else => "not a linux user",
2147};2115};
21482116
2149// Inside a function, switch statements implicitly are compile-time2117// Inside a function, switch statements implicitly are compile-time
2150// evaluated if the target expression is compile-time known.2118// evaluated if the target expression is compile-time known.
2151test "switch inside function" {2119test "switch inside function" {
2152 switch (builtin.os) {2120 switch (builtin.os) {
2153 builtin.Os.windows =&gt; {2121 builtin.Os.fuchsia => {
2154 // On an OS other than windows, block is not even analyzed,2122 // On an OS other than fuchsia, block is not even analyzed,
2155 // so this compile error is not triggered.2123 // so this compile error is not triggered.
2156 // On windows this compile error would be triggered.2124 // On fuchsia this compile error would be triggered.
2157 @compileError("windows not supported");2125 @compileError("windows not supported");
2158 },2126 },
2159 else =&gt; {},2127 else => {},
2160 };2128 }
2161}</code></pre>2129}
2162 <pre><code class="sh">$ zig test switch.zig2130 {#code_end#}
2163Test 1/2 switch simple...OK
2164Test 2/2 switch enum...OK
2165Test 3/3 switch inside function...OK</code></pre>
2166 {#see_also|comptime|enum|@compileError|Compile Variables#}2131 {#see_also|comptime|enum|@compileError|Compile Variables#}
2167 {#header_close#}2132 {#header_close#}
2168 {#header_open|while#}2133 {#header_open|while#}
2169 <pre><code class="zig">const assert = @import("std").debug.assert;2134 {#code_begin|test|while#}
2135const assert = @import("std").debug.assert;
21702136
2171test "while basic" {2137test "while basic" {
2172 // A while loop is used to repeatedly execute an expression until2138 // A while loop is used to repeatedly execute an expression until
2173 // some condition is no longer true.2139 // some condition is no longer true.
2174 var i: usize = 0;2140 var i: usize = 0;
2175 while (i &lt; 10) {2141 while (i < 10) {
2176 i += 1;2142 i += 1;
2177 }2143 }
2178 assert(i == 10);2144 assert(i == 10);
...@@ -2194,7 +2160,7 @@ test "while continue" {...@@ -2194,7 +2160,7 @@ test "while continue" {
2194 var i: usize = 0;2160 var i: usize = 0;
2195 while (true) {2161 while (true) {
2196 i += 1;2162 i += 1;
2197 if (i &lt; 10)2163 if (i < 10)
2198 continue;2164 continue;
2199 break;2165 break;
2200 }2166 }
...@@ -2205,7 +2171,7 @@ test "while loop continuation expression" {...@@ -2205,7 +2171,7 @@ test "while loop continuation expression" {
2205 // You can give an expression to the while loop to execute when2171 // You can give an expression to the while loop to execute when
2206 // the loop is continued. This is respected by the continue control flow.2172 // the loop is continued. This is respected by the continue control flow.
2207 var i: usize = 0;2173 var i: usize = 0;
2208 while (i &lt; 10) : (i += 1) {}2174 while (i < 10) : (i += 1) {}
2209 assert(i == 10);2175 assert(i == 10);
2210}2176}
22112177
...@@ -2214,9 +2180,9 @@ test "while loop continuation expression, more complicated" {...@@ -2214,9 +2180,9 @@ test "while loop continuation expression, more complicated" {
2214 // expression.2180 // expression.
2215 var i1: usize = 1;2181 var i1: usize = 1;
2216 var j1: usize = 1;2182 var j1: usize = 1;
2217 while (i1 * j1 &lt; 2000) : ({ i1 *= 2; j1 *= 3; }) {2183 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
2218 const my_ij1 = i1 * j1;2184 const my_ij1 = i1 * j1;
2219 assert(my_ij1 &lt; 2000);2185 assert(my_ij1 < 2000);
2220 }2186 }
2221}2187}
22222188
...@@ -2225,12 +2191,12 @@ test "while else" {...@@ -2225,12 +2191,12 @@ test "while else" {
2225 assert(!rangeHasNumber(0, 10, 15));2191 assert(!rangeHasNumber(0, 10, 15));
2226}2192}
22272193
2228fn rangeHasNumber(begin: usize, end: usize, number: usize) -&gt; bool {2194fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
2229 var i = begin;2195 var i = begin;
2230 // While loops are expressions. The result of the expression is the2196 // While loops are expressions. The result of the expression is the
2231 // result of the else clause of a while loop, which is executed when2197 // result of the else clause of a while loop, which is executed when
2232 // the condition of the while loop is tested as false.2198 // the condition of the while loop is tested as false.
2233 return while (i &lt; end) : (i += 1) {2199 return while (i < end) : (i += 1) {
2234 if (i == number) {2200 if (i == number) {
2235 // break expressions, like return expressions, accept a value2201 // break expressions, like return expressions, accept a value
2236 // parameter. This is the result of the while expression.2202 // parameter. This is the result of the while expression.
...@@ -2238,9 +2204,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) -&gt; bool {...@@ -2238,9 +2204,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) -&gt; bool {
2238 // evaluated.2204 // evaluated.
2239 break true;2205 break true;
2240 }2206 }
2241 } else {2207 } else false;
2242 false
2243 }
2244}2208}
22452209
2246test "while null capture" {2210test "while null capture" {
...@@ -2278,22 +2242,18 @@ test "while null capture" {...@@ -2278,22 +2242,18 @@ test "while null capture" {
2278}2242}
22792243
2280var numbers_left: u32 = undefined;2244var numbers_left: u32 = undefined;
2281fn eventuallyNullSequence() -&gt; ?u32 {2245fn eventuallyNullSequence() ?u32 {
2282 return if (numbers_left == 0) {2246 return if (numbers_left == 0) null else blk: {
2283 null
2284 } else {
2285 numbers_left -= 1;2247 numbers_left -= 1;
2286 numbers_left2248 break :blk numbers_left;
2287 }2249 };
2288}2250}
2289error ReachedZero;2251error ReachedZero;
2290fn eventuallyErrorSequence() -&gt; %u32 {2252fn eventuallyErrorSequence() %u32 {
2291 return if (numbers_left == 0) {2253 return if (numbers_left == 0) error.ReachedZero else blk: {
2292 error.ReachedZero
2293 } else {
2294 numbers_left -= 1;2254 numbers_left -= 1;
2295 numbers_left2255 break :blk numbers_left;
2296 }2256 };
2297}2257}
22982258
2299test "inline while loop" {2259test "inline while loop" {
...@@ -2302,34 +2262,27 @@ test "inline while loop" {...@@ -2302,34 +2262,27 @@ test "inline while loop" {
2302 // such as use types as first class values.2262 // such as use types as first class values.
2303 comptime var i = 0;2263 comptime var i = 0;
2304 var sum: usize = 0;2264 var sum: usize = 0;
2305 inline while (i &lt; 3) : (i += 1) {2265 inline while (i < 3) : (i += 1) {
2306 const T = switch (i) {2266 const T = switch (i) {
2307 0 =&gt; f32,2267 0 => f32,
2308 1 =&gt; i8,2268 1 => i8,
2309 2 =&gt; bool,2269 2 => bool,
2310 else =&gt; unreachable,2270 else => unreachable,
2311 };2271 };
2312 sum += typeNameLength(T);2272 sum += typeNameLength(T);
2313 }2273 }
2314 assert(sum == 9);2274 assert(sum == 9);
2315}2275}
23162276
2317fn typeNameLength(comptime T: type) -&gt; usize {2277fn typeNameLength(comptime T: type) usize {
2318 return @typeName(T).len;2278 return @typeName(T).len;
2319}</code></pre>2279}
2320 <pre><code class="sh">$ zig while.zig2280 {#code_end#}
2321Test 1/8 while basic...OK
2322Test 2/8 while break...OK
2323Test 3/8 while continue...OK
2324Test 4/8 while loop continuation expression...OK
2325Test 5/8 while loop continuation expression, more complicated...OK
2326Test 6/8 while else...OK
2327Test 7/8 while null capture...OK
2328Test 8/8 inline while loop...OK</code></pre>
2329 {#see_also|if|Nullables|Errors|comptime|unreachable#}2281 {#see_also|if|Nullables|Errors|comptime|unreachable#}
2330 {#header_close#}2282 {#header_close#}
2331 {#header_open|for#}2283 {#header_open|for#}
2332 <pre><code class="zig">const assert = @import("std").debug.assert;2284 {#code_begin|test|for#}
2285const assert = @import("std").debug.assert;
23332286
2334test "for basics" {2287test "for basics" {
2335 const items = []i32 { 4, 5, 3, 4, 0 };2288 const items = []i32 { 4, 5, 3, 4, 0 };
...@@ -2387,9 +2340,9 @@ test "for else" {...@@ -2387,9 +2340,9 @@ test "for else" {
2387 } else {2340 } else {
2388 sum += ??value;2341 sum += ??value;
2389 }2342 }
2390 } else {2343 } else blk: {
2391 assert(sum == 7);2344 assert(sum == 7);
2392 sum2345 break :blk sum;
2393 };2346 };
2394}2347}
23952348
...@@ -2404,28 +2357,25 @@ test "inline for loop" {...@@ -2404,28 +2357,25 @@ test "inline for loop" {
2404 var sum: usize = 0;2357 var sum: usize = 0;
2405 inline for (nums) |i| {2358 inline for (nums) |i| {
2406 const T = switch (i) {2359 const T = switch (i) {
2407 2 =&gt; f32,2360 2 => f32,
2408 4 =&gt; i8,2361 4 => i8,
2409 6 =&gt; bool,2362 6 => bool,
2410 else =&gt; unreachable,2363 else => unreachable,
2411 };2364 };
2412 sum += typeNameLength(T);2365 sum += typeNameLength(T);
2413 }2366 }
2414 assert(sum == 9);2367 assert(sum == 9);
2415}2368}
24162369
2417fn typeNameLength(comptime T: type) -&gt; usize {2370fn typeNameLength(comptime T: type) usize {
2418 return @typeName(T).len;2371 return @typeName(T).len;
2419}</code></pre>2372}
2420 <pre><code class="sh">$ zig test for.zig2373 {#code_end#}
2421Test 1/4 for basics...OK
2422Test 2/4 for reference...OK
2423Test 3/4 for else...OK
2424Test 4/4 inline for loop...OK</code></pre>
2425 {#see_also|while|comptime|Arrays|Slices#}2374 {#see_also|while|comptime|Arrays|Slices#}
2426 {#header_close#}2375 {#header_close#}
2427 {#header_open|if#}2376 {#header_open|if#}
2428 <pre><code class="zig">// If expressions have three uses, corresponding to the three types:2377 {#code_begin|test|if#}
2378// If expressions have three uses, corresponding to the three types:
2429// * bool2379// * bool
2430// * ?T2380// * ?T
2431// * %T2381// * %T
...@@ -2439,9 +2389,9 @@ test "if boolean" {...@@ -2439,9 +2389,9 @@ test "if boolean" {
2439 if (a != b) {2389 if (a != b) {
2440 assert(true);2390 assert(true);
2441 } else if (a == 9) {2391 } else if (a == 9) {
2442 unreachable2392 unreachable;
2443 } else {2393 } else {
2444 unreachable2394 unreachable;
2445 }2395 }
24462396
2447 // If expressions are used instead of a ternary expression.2397 // If expressions are used instead of a ternary expression.
...@@ -2499,12 +2449,12 @@ test "if error union" {...@@ -2499,12 +2449,12 @@ test "if error union" {
2499 if (a) |value| {2449 if (a) |value| {
2500 assert(value == 0);2450 assert(value == 0);
2501 } else |err| {2451 } else |err| {
2502 unreachable2452 unreachable;
2503 }2453 }
25042454
2505 const b: %u32 = error.BadValue;2455 const b: %u32 = error.BadValue;
2506 if (b) |value| {2456 if (b) |value| {
2507 unreachable2457 unreachable;
2508 } else |err| {2458 } else |err| {
2509 assert(err == error.BadValue);2459 assert(err == error.BadValue);
2510 }2460 }
...@@ -2524,27 +2474,26 @@ test "if error union" {...@@ -2524,27 +2474,26 @@ test "if error union" {
2524 if (c) |*value| {2474 if (c) |*value| {
2525 *value = 9;2475 *value = 9;
2526 } else |err| {2476 } else |err| {
2527 unreachable2477 unreachable;
2528 }2478 }
25292479
2530 if (c) |value| {2480 if (c) |value| {
2531 assert(value == 9);2481 assert(value == 9);
2532 } else |err| {2482 } else |err| {
2533 unreachable2483 unreachable;
2534 }2484 }
2535}</code></pre>2485}
2536 <pre><code class="sh">$ zig test if.zig2486 {#code_end#}
2537Test 1/3 if boolean...OK
2538Test 2/3 if nullable...OK
2539Test 3/3 if error union...OK</code></pre>
2540 {#see_also|Nullables|Errors#}2487 {#see_also|Nullables|Errors#}
2541 {#header_close#}2488 {#header_close#}
2542 {#header_open|defer#}2489 {#header_open|defer#}
2543 <pre><code class="zig">const assert = @import("std").debug.assert;2490 {#code_begin|test|defer#}
2544const printf = @import("std").io.stdout.printf;2491const std = @import("std");
2492const assert = std.debug.assert;
2493const warn = std.debug.warn;
25452494
2546// defer will execute an expression at the end of the current scope.2495// defer will execute an expression at the end of the current scope.
2547fn deferExample() -&gt; usize {2496fn deferExample() usize {
2548 var a: usize = 1;2497 var a: usize = 1;
25492498
2550 {2499 {
...@@ -2554,7 +2503,7 @@ fn deferExample() -&gt; usize {...@@ -2554,7 +2503,7 @@ fn deferExample() -&gt; usize {
2554 assert(a == 2);2503 assert(a == 2);
25552504
2556 a = 5;2505 a = 5;
2557 a2506 return a;
2558}2507}
25592508
2560test "defer basics" {2509test "defer basics" {
...@@ -2563,43 +2512,43 @@ test "defer basics" {...@@ -2563,43 +2512,43 @@ test "defer basics" {
25632512
2564// If multiple defer statements are specified, they will be executed in2513// If multiple defer statements are specified, they will be executed in
2565// the reverse order they were run.2514// the reverse order they were run.
2566fn deferUnwindExample() {2515fn deferUnwindExample() void {
2567 %%printf("\n");2516 warn("\n");
25682517
2569 defer {2518 defer {
2570 %%printf("1 ");2519 warn("1 ");
2571 }2520 }
2572 defer {2521 defer {
2573 %%printf("2 ");2522 warn("2 ");
2574 }2523 }
2575 if (false) {2524 if (false) {
2576 // defers are not run if they are never executed.2525 // defers are not run if they are never executed.
2577 defer {2526 defer {
2578 %%printf("3 ");2527 warn("3 ");
2579 }2528 }
2580 }2529 }
2581}2530}
25822531
2583test "defer unwinding" {2532test "defer unwinding" {
2584 deferUnwindExample()2533 deferUnwindExample();
2585}2534}
25862535
2587// The %defer keyword is similar to defer, but will only execute if the2536// The errdefer keyword is similar to defer, but will only execute if the
2588// scope returns with an error.2537// scope returns with an error.
2589//2538//
2590// This is especially useful in allowing a function to clean up properly2539// This is especially useful in allowing a function to clean up properly
2591// on error, and replaces goto error handling tactics as seen in c.2540// on error, and replaces goto error handling tactics as seen in c.
2592error DeferError;2541error DeferError;
2593fn deferErrorExample(is_error: bool) -&gt; %void {2542fn deferErrorExample(is_error: bool) %void {
2594 %%printf("\nstart of function\n");2543 warn("\nstart of function\n");
25952544
2596 // This will always be executed on exit2545 // This will always be executed on exit
2597 defer {2546 defer {
2598 %%printf("end of function\n");2547 warn("end of function\n");
2599 }2548 }
26002549
2601 %defer {2550 errdefer {
2602 %%printf("encountered an error!\n");2551 warn("encountered an error!\n");
2603 }2552 }
26042553
2605 if (is_error) {2554 if (is_error) {
...@@ -2607,24 +2556,11 @@ fn deferErrorExample(is_error: bool) -&gt; %void {...@@ -2607,24 +2556,11 @@ fn deferErrorExample(is_error: bool) -&gt; %void {
2607 }2556 }
2608}2557}
26092558
2610test "%defer unwinding" {2559test "errdefer unwinding" {
2611 _ = deferErrorExample(false);2560 _ = deferErrorExample(false);
2612 _ = deferErrorExample(true);2561 _ = deferErrorExample(true);
2613}2562}
2614</code></pre>2563 {#code_end#}
2615 <pre><code class="sh">$ zig test defer.zig
2616Test 1/3 defer basics...OK
2617Test 2/3 defer unwinding...
26182 1 OK
2619Test 3/3 %defer unwinding...
2620start of function
2621end of function
2622
2623start of function
2624encountered an error!
2625end of function
2626OK
2627</code></pre>
2628 {#see_also|Errors#}2564 {#see_also|Errors#}
2629 {#header_close#}2565 {#header_close#}
2630 {#header_open|unreachable#}2566 {#header_open|unreachable#}
...@@ -2638,7 +2574,8 @@ OK...@@ -2638,7 +2574,8 @@ OK
2638 still emits <code>unreachable</code> as calls to <code>panic</code>.2574 still emits <code>unreachable</code> as calls to <code>panic</code>.
2639 </p>2575 </p>
2640 {#header_open|Basics#}2576 {#header_open|Basics#}
2641 <pre><code class="zig">// unreachable is used to assert that control flow will never happen upon a2577 {#code_begin|test#}
2578// unreachable is used to assert that control flow will never happen upon a
2642// particular location:2579// particular location:
2643test "basic math" {2580test "basic math" {
2644 const x = 1;2581 const x = 1;
...@@ -2647,56 +2584,34 @@ test "basic math" {...@@ -2647,56 +2584,34 @@ test "basic math" {
2647 unreachable;2584 unreachable;
2648 }2585 }
2649}2586}
26502587 {#code_end#}
2651// in fact, this is how assert is implemented:2588 <p>In fact, this is how assert is implemented:</p>
2652fn assert(ok: bool) {2589 {#code_begin|test_err#}
2590fn assert(ok: bool) void {
2653 if (!ok) unreachable; // assertion failure2591 if (!ok) unreachable; // assertion failure
2654}2592}
26552593
2656// This test will fail because we hit unreachable.2594// This test will fail because we hit unreachable.
2657test "this will fail" {2595test "this will fail" {
2658 assert(false);2596 assert(false);
2659}</code></pre>2597}
2660 <pre><code class="sh">$ zig test test.zig2598 {#code_end#}
2661Test 1/2 basic math...OK
2662Test 2/2 this will fail...reached unreachable code
2663test.zig:13:14: 0x00000000002033ac in ??? (test)
2664 if (!ok) unreachable; // assertion failure
2665 ^
2666test.zig:18:11: 0x000000000020329b in ??? (test)
2667 assert(false);
2668 ^
2669lib/zig/std/special/test_runner.zig:9:21: 0x0000000000214a7a in ??? (test)
2670 test_fn.func();
2671 ^
2672lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000214947 in ??? (test)
2673 return root.main();
2674 ^
2675lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000214800 in ??? (test)
2676 callMain(argc, argv, envp) catch std.os.posix.exit(1);
2677 ^
2678lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000214750 in ??? (test)
2679 posixCallMainAndExit()
2680 ^
2681
2682Tests failed. Use the following command to reproduce the failure:
2683./test</code></pre>
2684 {#header_close#}2599 {#header_close#}
2685 {#header_open|At Compile-Time#}2600 {#header_open|At Compile-Time#}
2686 <pre><code class="zig">const assert = @import("std").debug.assert;2601 {#code_begin|test_err|unreachable code#}
2602const assert = @import("std").debug.assert;
26872603
2688comptime {2604test "type of unreachable" {
2689 // The type of unreachable is noreturn.2605 comptime {
2606 // The type of unreachable is noreturn.
26902607
2691 // However this assertion will still fail because2608 // However this assertion will still fail because
2692 // evaluating unreachable at compile-time is a compile error.2609 // evaluating unreachable at compile-time is a compile error.
26932610
2694 assert(@typeOf(unreachable) == noreturn);2611 assert(@typeOf(unreachable) == noreturn);
2695}</code></pre>2612 }
2696 <pre><code class="sh">$ zig build-obj test.zig2613}
2697test.zig:9:12: error: unreachable code2614 {#code_end#}
2698 assert(@typeOf(unreachable) == noreturn);
2699 ^</code></pre>
2700 {#see_also|Zig Test|Build Mode|comptime#}2615 {#see_also|Zig Test|Build Mode|comptime#}
2701 {#header_close#}2616 {#header_close#}
2702 {#header_close#}2617 {#header_close#}
...@@ -2707,7 +2622,6 @@ test.zig:9:12: error: unreachable code...@@ -2707,7 +2622,6 @@ test.zig:9:12: error: unreachable code
2707 <ul>2622 <ul>
2708 <li><code>break</code></li>2623 <li><code>break</code></li>
2709 <li><code>continue</code></li>2624 <li><code>continue</code></li>
2710 <li><code>goto</code></li>
2711 <li><code>return</code></li>2625 <li><code>return</code></li>
2712 <li><code>unreachable</code></li>2626 <li><code>unreachable</code></li>
2713 <li><code>while (true) {}</code></li>2627 <li><code>while (true) {}</code></li>
...@@ -2715,31 +2629,38 @@ test.zig:9:12: error: unreachable code...@@ -2715,31 +2629,38 @@ test.zig:9:12: error: unreachable code
2715 <p>When resolving types together, such as <code>if</code> clauses or <code>switch</code> prongs,2629 <p>When resolving types together, such as <code>if</code> clauses or <code>switch</code> prongs,
2716 the <code>noreturn</code> type is compatible with every other type. Consider:2630 the <code>noreturn</code> type is compatible with every other type. Consider:
2717 </p>2631 </p>
2718 <pre><code class="zig">fn foo(condition: bool, b: u32) {2632 {#code_begin|test#}
2633fn foo(condition: bool, b: u32) void {
2719 const a = if (condition) b else return;2634 const a = if (condition) b else return;
2720 bar(a);2635 @panic("do something with a");
2721}2636}
27222637test "noreturn" {
2723extern fn bar(value: u32);</code></pre>2638 foo(false, 1);
2639}
2640 {#code_end#}
2724 <p>Another use case for <code>noreturn</code> is the <code>exit</code> function:</p>2641 <p>Another use case for <code>noreturn</code> is the <code>exit</code> function:</p>
2725 <pre><code class="zig">pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) -&gt; noreturn;2642 {#code_begin|test#}
2643 {#target_windows#}
2644pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) noreturn;
27262645
2727fn foo() {2646test "foo" {
2728 const value = bar() catch ExitProcess(1);2647 const value = bar() catch ExitProcess(1);
2729 assert(value == 1234);2648 assert(value == 1234);
2730}2649}
27312650
2732fn bar() -&gt; %u32 {2651fn bar() %u32 {
2733 return 1234;2652 return 1234;
2734}2653}
27352654
2736const assert = @import("std").debug.assert;</code></pre>2655const assert = @import("std").debug.assert;
2656 {#code_end#}
2737 {#header_close#}2657 {#header_close#}
2738 {#header_open|Functions#}2658 {#header_open|Functions#}
2739 <pre><code class="zig">const assert = @import("std").debug.assert;2659 {#code_begin|test|functions#}
2660const assert = @import("std").debug.assert;
27402661
2741// Functions are declared like this2662// Functions are declared like this
2742fn add(a: i8, b: i8) -&gt; i8 {2663fn add(a: i8, b: i8) i8 {
2743 if (a == 0) {2664 if (a == 0) {
2744 // You can still return manually if needed.2665 // You can still return manually if needed.
2745 return b;2666 return b;
...@@ -2750,84 +2671,84 @@ fn add(a: i8, b: i8) -&gt; i8 {...@@ -2750,84 +2671,84 @@ fn add(a: i8, b: i8) -&gt; i8 {
27502671
2751// The export specifier makes a function externally visible in the generated2672// The export specifier makes a function externally visible in the generated
2752// object file, and makes it use the C ABI.2673// object file, and makes it use the C ABI.
2753export fn sub(a: i8, b: i8) -&gt; i8 { a - b }2674export fn sub(a: i8, b: i8) i8 { return a - b; }
27542675
2755// The extern specifier is used to declare a function that will be resolved2676// The extern specifier is used to declare a function that will be resolved
2756// at link time, when linking statically, or at runtime, when linking2677// at link time, when linking statically, or at runtime, when linking
2757// dynamically.2678// dynamically.
2758// The stdcallcc specifier changes the calling convention of the function.2679// The stdcallcc specifier changes the calling convention of the function.
2759extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) -&gt; noreturn;2680extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) noreturn;
2760extern "c" fn atan2(a: f64, b: f64) -&gt; f64;2681extern "c" fn atan2(a: f64, b: f64) f64;
27612682
2762// coldcc makes a function use the cold calling convention.2683// The @setCold builtin tells the optimizer that a function is rarely called.
2763coldcc fn abort() -&gt; noreturn {2684fn abort() noreturn {
2685 @setCold(true);
2764 while (true) {}2686 while (true) {}
2765}2687}
27662688
2767// nakedcc makes a function not have any function prologue or epilogue.2689// nakedcc makes a function not have any function prologue or epilogue.
2768// This can be useful when integrating with assembly.2690// This can be useful when integrating with assembly.
2769nakedcc fn _start() -&gt; noreturn {2691nakedcc fn _start() noreturn {
2770 abort();2692 abort();
2771}2693}
27722694
2773// The pub specifier allows the function to be visible when importing.2695// The pub specifier allows the function to be visible when importing.
2774// Another file can use @import and call sub22696// Another file can use @import and call sub2
2775pub fn sub2(a: i8, b: i8) -&gt; i8 { a - b }2697pub fn sub2(a: i8, b: i8) i8 { return a - b; }
27762698
2777// Functions can be used as values and are equivalent to pointers.2699// Functions can be used as values and are equivalent to pointers.
2778const call2_op = fn (a: i8, b: i8) -&gt; i8;2700const call2_op = fn (a: i8, b: i8) i8;
2779fn do_op(fn_call: call2_op, op1: i8, op2: i8) -&gt; i8 {2701fn do_op(fn_call: call2_op, op1: i8, op2: i8) i8 {
2780 fn_call(op1, op2)2702 return fn_call(op1, op2);
2781}2703}
27822704
2783test "function" {2705test "function" {
2784 assert(do_op(add, 5, 6) == 11);2706 assert(do_op(add, 5, 6) == 11);
2785 assert(do_op(sub2, 5, 6) == -1);2707 assert(do_op(sub2, 5, 6) == -1);
2786}</code></pre>2708}
2787 <pre><code class="sh">$ zig test function.zig2709 {#code_end#}
2788Test 1/1 function...OK
2789</code></pre>
2790 <p>Function values are like pointers:</p>2710 <p>Function values are like pointers:</p>
2791 <pre><code class="zig">const assert = @import("std").debug.assert;2711 {#code_begin|obj#}
2712const assert = @import("std").debug.assert;
27922713
2793comptime {2714comptime {
2794 assert(@typeOf(foo) == fn());2715 assert(@typeOf(foo) == fn()void);
2795 assert(@sizeOf(fn()) == @sizeOf(?fn()));2716 assert(@sizeOf(fn()void) == @sizeOf(?fn()void));
2796}2717}
27972718
2798fn foo() { }</code></pre>2719fn foo() void { }
2799 <pre><code class="sh">$ zig build-obj test.zig</code></pre>2720 {#code_end#}
2800 {#header_open|Pass-by-value Parameters#}2721 {#header_open|Pass-by-value Parameters#}
2801 <p>2722 <p>
2802 In Zig, structs, unions, and enums with payloads cannot be passed by value2723 In Zig, structs, unions, and enums with payloads cannot be passed by value
2803 to a function.2724 to a function.
2804 </p>2725 </p>
2805 <pre><code class="zig">const Foo = struct {2726 {#code_begin|test_err|not copyable; cannot pass by value#}
2727const Foo = struct {
2806 x: i32,2728 x: i32,
2807};2729};
28082730
2809fn bar(foo: Foo) {}2731fn bar(foo: Foo) void {}
28102732
2811export fn entry() {2733test "pass aggregate type by value to function" {
2812 bar(Foo {.x = 12,});2734 bar(Foo {.x = 12,});
2813}</code></pre>2735}
2814 <pre><code class="sh">$ ./zig build-obj test.zig 2736 {#code_end#}
2815/home/andy/dev/zig/build/test.zig:5:13: error: type 'Foo' is not copyable; cannot pass by value
2816fn bar(foo: Foo) {}
2817 ^</code></pre>
2818 <p>2737 <p>
2819 Instead, one must use <code>&amp;const</code>. Zig allows implicitly casting something2738 Instead, one must use <code>&amp;const</code>. Zig allows implicitly casting something
2820 to a const pointer to it:2739 to a const pointer to it:
2821 </p>2740 </p>
2822 <pre><code class="zig">const Foo = struct {2741 {#code_begin|test#}
2742const Foo = struct {
2823 x: i32,2743 x: i32,
2824};2744};
28252745
2826fn bar(foo: &amp;const Foo) {}2746fn bar(foo: &const Foo) void {}
28272747
2828export fn entry() {2748test "implicitly cast to const pointer" {
2829 bar(Foo {.x = 12,});2749 bar(Foo {.x = 12,});
2830}</code></pre>2750}
2751 {#code_end#}
2831 <p>2752 <p>
2832 However,2753 However,
2833 the C ABI does allow passing structs and unions by value. So functions which2754 the C ABI does allow passing structs and unions by value. So functions which
...@@ -2842,9 +2763,11 @@ export fn entry() {...@@ -2842,9 +2763,11 @@ export fn entry() {
2842 <p>2763 <p>
2843 Among the top level declarations available is the error value declaration:2764 Among the top level declarations available is the error value declaration:
2844 </p>2765 </p>
2845 <pre><code class="zig">error FileNotFound;2766 {#code_begin|syntax#}
2767error FileNotFound;
2846error OutOfMemory;2768error OutOfMemory;
2847error UnexpectedToken;</code></pre>2769error UnexpectedToken;
2770 {#code_end#}
2848 <p>2771 <p>
2849 These error values are assigned an unsigned integer value greater than 0 at2772 These error values are assigned an unsigned integer value greater than 0 at
2850 compile time. You are allowed to declare the same error value more than once,2773 compile time. You are allowed to declare the same error value more than once,
...@@ -2862,7 +2785,7 @@ error UnexpectedToken;</code></pre>...@@ -2862,7 +2785,7 @@ error UnexpectedToken;</code></pre>
2862 The pure error type is one of the error values, and in the same way that pointers2785 The pure error type is one of the error values, and in the same way that pointers
2863 cannot be null, a pure error is always an error.2786 cannot be null, a pure error is always an error.
2864 </p>2787 </p>
2865 <pre><code class="zig">const pure_error = error.FileNotFound;</code></pre>2788 {#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#}
2866 <p>2789 <p>
2867 Most of the time you will not find yourself using a pure error type. Instead,2790 Most of the time you will not find yourself using a pure error type. Instead,
2868 likely you will be using the error union type. This is when you take a normal type,2791 likely you will be using the error union type. This is when you take a normal type,
...@@ -2871,32 +2794,48 @@ error UnexpectedToken;</code></pre>...@@ -2871,32 +2794,48 @@ error UnexpectedToken;</code></pre>
2871 <p>2794 <p>
2872 Here is a function to parse a string into a 64-bit integer:2795 Here is a function to parse a string into a 64-bit integer:
2873 </p>2796 </p>
2874 <pre><code class="zig">error InvalidChar;2797 {#code_begin|test#}
2798error InvalidChar;
2875error Overflow;2799error Overflow;
28762800
2877pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {2801pub fn parseU64(buf: []const u8, radix: u8) %u64 {
2878 var x: u64 = 0;2802 var x: u64 = 0;
28792803
2880 for (buf) |c| {2804 for (buf) |c| {
2881 const digit = charToDigit(c);2805 const digit = charToDigit(c);
28822806
2883 if (digit &gt;= radix) {2807 if (digit >= radix) {
2884 return error.InvalidChar;2808 return error.InvalidChar;
2885 }2809 }
28862810
2887 // x *= radix2811 // x *= radix
2888 if (@mulWithOverflow(u64, x, radix, &amp;x)) {2812 if (@mulWithOverflow(u64, x, radix, &x)) {
2889 return error.Overflow;2813 return error.Overflow;
2890 }2814 }
28912815
2892 // x += digit2816 // x += digit
2893 if (@addWithOverflow(u64, x, digit, &amp;x)) {2817 if (@addWithOverflow(u64, x, digit, &x)) {
2894 return error.Overflow;2818 return error.Overflow;
2895 }2819 }
2896 }2820 }
28972821
2898 return x;2822 return x;
2899}</code></pre>2823}
2824
2825fn charToDigit(c: u8) u8 {
2826 return switch (c) {
2827 '0' ... '9' => c - '0',
2828 'A' ... 'Z' => c - 'A' + 10,
2829 'a' ... 'z' => c - 'a' + 10,
2830 else => @maxValue(u8),
2831 };
2832}
2833
2834test "parse u64" {
2835 const result = try parseU64("1234", 10);
2836 @import("std").debug.assert(result == 1234);
2837}
2838 {#code_end#}
2900 <p>2839 <p>
2901 Notice the return type is <code>%u64</code>. This means that the function2840 Notice the return type is <code>%u64</code>. This means that the function
2902 either returns an unsigned 64 bit integer, or an error.2841 either returns an unsigned 64 bit integer, or an error.
...@@ -2916,29 +2855,35 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {...@@ -2916,29 +2855,35 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
2916 <li>You know with complete certainty it will not return an error, so want to unconditionally unwrap it.</li>2855 <li>You know with complete certainty it will not return an error, so want to unconditionally unwrap it.</li>
2917 <li>You want to take a different action for each possible error.</li>2856 <li>You want to take a different action for each possible error.</li>
2918 </ul>2857 </ul>
2919 <p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p>2858 <p>If you want to provide a default value, you can use the <code>catch</code> binary operator:</p>
2920 <pre><code class="zig">fn doAThing(str: []u8) {2859 {#code_begin|syntax#}
2860fn doAThing(str: []u8) void {
2921 const number = parseU64(str, 10) catch 13;2861 const number = parseU64(str, 10) catch 13;
2922 // ...2862 // ...
2923}</code></pre>2863}
2864 {#code_end#}
2924 <p>2865 <p>
2925 In this code, <code>number</code> will be equal to the successfully parsed string, or2866 In this code, <code>number</code> will be equal to the successfully parsed string, or
2926 a default value of 13. The type of the right hand side of the binary <code>%%</code> operator must2867 a default value of 13. The type of the right hand side of the binary <code>catch</code> operator must
2927 match the unwrapped error union type, or be of type <code>noreturn</code>.2868 match the unwrapped error union type, or be of type <code>noreturn</code>.
2928 </p>2869 </p>
2929 <p>Let's say you wanted to return the error if you got one, otherwise continue with the2870 <p>Let's say you wanted to return the error if you got one, otherwise continue with the
2930 function logic:</p>2871 function logic:</p>
2931 <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {2872 {#code_begin|syntax#}
2873fn doAThing(str: []u8) %void {
2932 const number = parseU64(str, 10) catch |err| return err;2874 const number = parseU64(str, 10) catch |err| return err;
2933 // ...2875 // ...
2934}</code></pre>2876}
2877 {#code_end#}
2935 <p>2878 <p>
2936 There is a shortcut for this. The <code>try</code> expression:2879 There is a shortcut for this. The <code>try</code> expression:
2937 </p>2880 </p>
2938 <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {2881 {#code_begin|syntax#}
2882fn doAThing(str: []u8) %void {
2939 const number = try parseU64(str, 10);2883 const number = try parseU64(str, 10);
2940 // ...2884 // ...
2941}</code></pre>2885}
2886 {#code_end#}
2942 <p>2887 <p>
2943 <code>try</code> evaluates an error union expression. If it is an error, it returns2888 <code>try</code> evaluates an error union expression. If it is an error, it returns
2944 from the current function with the same error. Otherwise, the expression results in2889 from the current function with the same error. Otherwise, the expression results in
...@@ -2948,61 +2893,60 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {...@@ -2948,61 +2893,60 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
2948 Maybe you know with complete certainty that an expression will never be an error.2893 Maybe you know with complete certainty that an expression will never be an error.
2949 In this case you can do this:2894 In this case you can do this:
2950 </p>2895 </p>
2951 <pre><code class="zig">const number = parseU64("1234", 10) catch unreachable;</code></pre>2896 {#code_begin|syntax#}const number = parseU64("1234", 10) catch unreachable;{#code_end#}
2952 <p>2897 <p>
2953 Here we know for sure that "1234" will parse successfully. So we put the2898 Here we know for sure that "1234" will parse successfully. So we put the
2954 <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates2899 <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates
2955 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the2900 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the
2956 application, if there <em>was</em> a surprise error here, the application would crash2901 application, if there <em>was</em> a surprise error here, the application would crash
2957 appropriately.2902 appropriately.
2958 </p>2903 TODO: mention error return traces
2959 <p>Again there is a syntactic shortcut for this:</p>
2960 <pre><code class="zig">const number = %%parseU64("1234", 10);</code></pre>
2961 <p>
2962 The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression catch unreachable</code>. It unwraps an error union type,
2963 and panics in debug mode if the value was an error.
2964 </p>2904 </p>
2965 <p>2905 <p>
2966 Finally, you may want to take a different action for every situation. For that, we combine2906 Finally, you may want to take a different action for every situation. For that, we combine
2967 the <code>if</code> and <code>switch</code> expression:2907 the <code>if</code> and <code>switch</code> expression:
2968 </p>2908 </p>
2969 <pre><code class="zig">fn doAThing(str: []u8) {2909 {#code_begin|syntax#}
2910fn doAThing(str: []u8) void {
2970 if (parseU64(str, 10)) |number| {2911 if (parseU64(str, 10)) |number| {
2971 doSomethingWithNumber(number);2912 doSomethingWithNumber(number);
2972 } else |err| switch (err) {2913 } else |err| switch (err) {
2973 error.Overflow =&gt; {2914 error.Overflow => {
2974 // handle overflow...2915 // handle overflow...
2975 },2916 },
2976 // we promise that InvalidChar won't happen (or crash in debug mode if it does)2917 // we promise that InvalidChar won't happen (or crash in debug mode if it does)
2977 error.InvalidChar =&gt; unreachable,2918 error.InvalidChar => unreachable,
2978 }2919 }
2979}</code></pre>2920}
2921 {#code_end#}
2980 <p>2922 <p>
2981 The other component to error handling is defer statements.2923 The other component to error handling is defer statements.
2982 In addition to an unconditional <code>defer</code>, Zig has <code>%defer</code>,2924 In addition to an unconditional <code>defer</code>, Zig has <code>errdefer</code>,
2983 which evaluates the deferred expression on block exit path if and only if2925 which evaluates the deferred expression on block exit path if and only if
2984 the function returned with an error from the block.2926 the function returned with an error from the block.
2985 </p>2927 </p>
2986 <p>2928 <p>
2987 Example:2929 Example:
2988 </p>2930 </p>
2989 <pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo {2931 {#code_begin|syntax#}
2932fn createFoo(param: i32) %Foo {
2990 const foo = try tryToAllocateFoo();2933 const foo = try tryToAllocateFoo();
2991 // now we have allocated foo. we need to free it if the function fails.2934 // now we have allocated foo. we need to free it if the function fails.
2992 // but we want to return it if the function succeeds.2935 // but we want to return it if the function succeeds.
2993 %defer deallocateFoo(foo);2936 errdefer deallocateFoo(foo);
29942937
2995 const tmp_buf = allocateTmpBuffer() ?? return error.OutOfMemory;2938 const tmp_buf = allocateTmpBuffer() ?? return error.OutOfMemory;
2996 // tmp_buf is truly a temporary resource, and we for sure want to clean it up2939 // tmp_buf is truly a temporary resource, and we for sure want to clean it up
2997 // before this block leaves scope2940 // before this block leaves scope
2998 defer deallocateTmpBuffer(tmp_buf);2941 defer deallocateTmpBuffer(tmp_buf);
29992942
3000 if (param &gt; 1337) return error.InvalidParam;2943 if (param > 1337) return error.InvalidParam;
30012944
3002 // here the %defer will not run since we're returning success from the function.2945 // here the errdefer will not run since we're returning success from the function.
3003 // but the defer will run!2946 // but the defer will run!
3004 return foo;2947 return foo;
3005}</code></pre>2948}
2949 {#code_end#}
3006 <p>2950 <p>
3007 The neat thing about this is that you get robust error handling without2951 The neat thing about this is that you get robust error handling without
3008 the verbosity and cognitive overhead of trying to make sure every exit path2952 the verbosity and cognitive overhead of trying to make sure every exit path
...@@ -3014,7 +2958,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {...@@ -3014,7 +2958,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
3014 <ul>2958 <ul>
3015 <li>These primitives give enough expressiveness that it's completely practical2959 <li>These primitives give enough expressiveness that it's completely practical
3016 to have failing to check for an error be a compile error. If you really want2960 to have failing to check for an error be a compile error. If you really want
3017 to ignore the error, you can use the <code>%%</code> prefix operator and2961 to ignore the error, you can add <code>catch unreachable</code> and
3018 get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong.2962 get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong.
3019 </li>2963 </li>
3020 <li>2964 <li>
...@@ -3034,11 +2978,13 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {...@@ -3034,11 +2978,13 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
3034 The question mark symbolizes the nullable type. You can convert a type to a nullable2978 The question mark symbolizes the nullable type. You can convert a type to a nullable
3035 type by putting a question mark in front of it, like this:2979 type by putting a question mark in front of it, like this:
3036 </p>2980 </p>
3037 <pre><code class="zig">// normal integer2981 {#code_begin|syntax#}
2982// normal integer
3038const normal_int: i32 = 1234;2983const normal_int: i32 = 1234;
30392984
3040// nullable integer2985// nullable integer
3041const nullable_int: ?i32 = 5678;</code></pre>2986const nullable_int: ?i32 = 5678;
2987 {#code_end#}
3042 <p>2988 <p>
3043 Now the variable <code>nullable_int</code> could be an <code>i32</code>, or <code>null</code>.2989 Now the variable <code>nullable_int</code> could be an <code>i32</code>, or <code>null</code>.
3044 </p>2990 </p>
...@@ -3061,7 +3007,7 @@ const nullable_int: ?i32 = 5678;</code></pre>...@@ -3061,7 +3007,7 @@ const nullable_int: ?i32 = 5678;</code></pre>
3061 Task: call malloc, if the result is null, return null.3007 Task: call malloc, if the result is null, return null.
3062 </p>3008 </p>
3063 <p>C code</p>3009 <p>C code</p>
3064 <pre><code class="c">// malloc prototype included for reference3010 <pre><code class="cpp">// malloc prototype included for reference
3065void *malloc(size_t size);3011void *malloc(size_t size);
30663012
3067struct Foo *do_a_thing(void) {3013struct Foo *do_a_thing(void) {
...@@ -3070,23 +3016,25 @@ struct Foo *do_a_thing(void) {...@@ -3070,23 +3016,25 @@ struct Foo *do_a_thing(void) {
3070 // ...3016 // ...
3071}</code></pre>3017}</code></pre>
3072 <p>Zig code</p>3018 <p>Zig code</p>
3073 <pre><code class="zig">// malloc prototype included for reference3019 {#code_begin|syntax#}
3074extern fn malloc(size: size_t) -&gt; ?&amp;u8;3020// malloc prototype included for reference
3021extern fn malloc(size: size_t) ?&u8;
30753022
3076fn doAThing() -&gt; ?&amp;Foo {3023fn doAThing() ?&Foo {
3077 const ptr = malloc(1234) ?? return null;3024 const ptr = malloc(1234) ?? return null;
3078 // ...3025 // ...
3079}</code></pre>3026}
3027 {#code_end#}
3080 <p>3028 <p>
3081 Here, Zig is at least as convenient, if not more, than C. And, the type of "ptr"3029 Here, Zig is at least as convenient, if not more, than C. And, the type of "ptr"
3082 is <code>&amp;u8</code> <em>not</em> <code>?&amp;u8</code>. The <code>??</code> operator3030 is <code>&u8</code> <em>not</em> <code>?&u8</code>. The <code>??</code> operator
3083 unwrapped the nullable type and therefore <code>ptr</code> is guaranteed to be non-null everywhere3031 unwrapped the nullable type and therefore <code>ptr</code> is guaranteed to be non-null everywhere
3084 it is used in the function.3032 it is used in the function.
3085 </p>3033 </p>
3086 <p>3034 <p>
3087 The other form of checking against NULL you might see looks like this:3035 The other form of checking against NULL you might see looks like this:
3088 </p>3036 </p>
3089 <pre><code class="c">void do_a_thing(struct Foo *foo) {3037 <pre><code class="cpp">void do_a_thing(struct Foo *foo) {
3090 // do some stuff3038 // do some stuff
30913039
3092 if (foo) {3040 if (foo) {
...@@ -3098,7 +3046,8 @@ fn doAThing() -&gt; ?&amp;Foo {...@@ -3098,7 +3046,8 @@ fn doAThing() -&gt; ?&amp;Foo {
3098 <p>3046 <p>
3099 In Zig you can accomplish the same thing:3047 In Zig you can accomplish the same thing:
3100 </p>3048 </p>
3101 <pre><code class="zig">fn doAThing(nullable_foo: ?&amp;Foo) {3049 {#code_begin|syntax#}
3050fn doAThing(nullable_foo: ?&Foo) void {
3102 // do some stuff3051 // do some stuff
31033052
3104 if (nullable_foo) |foo| {3053 if (nullable_foo) |foo| {
...@@ -3106,7 +3055,8 @@ fn doAThing() -&gt; ?&amp;Foo {...@@ -3106,7 +3055,8 @@ fn doAThing() -&gt; ?&amp;Foo {
3106 }3055 }
31073056
3108 // do some stuff3057 // do some stuff
3109}</code></pre>3058}
3059 {#code_end#}
3110 <p>3060 <p>
3111 Once again, the notable thing here is that inside the if block,3061 Once again, the notable thing here is that inside the if block,
3112 <code>foo</code> is no longer a nullable pointer, it is a pointer, which3062 <code>foo</code> is no longer a nullable pointer, it is a pointer, which
...@@ -3140,7 +3090,7 @@ fn doAThing() -&gt; ?&amp;Foo {...@@ -3140,7 +3090,7 @@ fn doAThing() -&gt; ?&amp;Foo {
3140 {#header_open|this#}3090 {#header_open|this#}
3141 <p>TODO: example of this referring to Self struct</p>3091 <p>TODO: example of this referring to Self struct</p>
3142 <p>TODO: example of this referring to recursion function</p>3092 <p>TODO: example of this referring to recursion function</p>
3143 <p>TODO: example of this referring to basic block for @setDebugSafety</p>3093 <p>TODO: example of this referring to basic block for @setRuntimeSafety</p>
3144 {#header_close#}3094 {#header_close#}
3145 {#header_open|comptime#}3095 {#header_open|comptime#}
3146 <p>3096 <p>
...@@ -3153,15 +3103,17 @@ fn doAThing() -&gt; ?&amp;Foo {...@@ -3153,15 +3103,17 @@ fn doAThing() -&gt; ?&amp;Foo {
3153 <p>3103 <p>
3154 Compile-time parameters is how Zig implements generics. It is compile-time duck typing.3104 Compile-time parameters is how Zig implements generics. It is compile-time duck typing.
3155 </p>3105 </p>
3156 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {3106 {#code_begin|syntax#}
3157 if (a &gt; b) a else b3107fn max(comptime T: type, a: T, b: T) T {
3108 return if (a > b) a else b;
3158}3109}
3159fn gimmeTheBiggerFloat(a: f32, b: f32) -&gt; f32 {3110fn gimmeTheBiggerFloat(a: f32, b: f32) f32 {
3160 max(f32, a, b)3111 return max(f32, a, b);
3161}3112}
3162fn gimmeTheBiggerInteger(a: u64, b: u64) -&gt; u64 {3113fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
3163 max(u64, a, b)3114 return max(u64, a, b);
3164}</code></pre>3115}
3116 {#code_end#}
3165 <p>3117 <p>
3166 In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions,3118 In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions,
3167 and returned from functions. However, they can only be used in expressions which are known at <em>compile-time</em>,3119 and returned from functions. However, they can only be used in expressions which are known at <em>compile-time</em>,
...@@ -3179,21 +3131,20 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) -&gt; u64 {...@@ -3179,21 +3131,20 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) -&gt; u64 {
3179 <p>3131 <p>
3180 For example, if we were to introduce another function to the above snippet:3132 For example, if we were to introduce another function to the above snippet:
3181 </p>3133 </p>
3182 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {3134 {#code_begin|test_err|unable to evaluate constant expression#}
3183 if (a &gt; b) a else b3135fn max(comptime T: type, a: T, b: T) T {
3136 return if (a > b) a else b;
3137}
3138test "try to pass a runtime type" {
3139 foo(false);
3184}3140}
3185fn letsTryToPassARuntimeType(condition: bool) {3141fn foo(condition: bool) void {
3186 const result = max(3142 const result = max(
3187 if (condition) f32 else u64,3143 if (condition) f32 else u64,
3188 1234,3144 1234,
3189 5678);3145 5678);
3190}</code></pre>3146}
3191 <p>3147 {#code_end#}
3192 Then we get this result from the compiler:
3193 </p>
3194 <pre><code class="sh">./test.zig:6:9: error: unable to evaluate constant expression
3195 if (condition) f32 else u64,
3196 ^</code></pre>
3197 <p>3148 <p>
3198 This is an error because the programmer attempted to pass a value only known at run-time3149 This is an error because the programmer attempted to pass a value only known at run-time
3199 to a function which expects a value known at compile-time.3150 to a function which expects a value known at compile-time.
...@@ -3205,38 +3156,33 @@ fn letsTryToPassARuntimeType(condition: bool) {...@@ -3205,38 +3156,33 @@ fn letsTryToPassARuntimeType(condition: bool) {
3205 <p>3156 <p>
3206 For example:3157 For example:
3207 </p>3158 </p>
3208 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {3159 {#code_begin|test_err|operator not allowed for type 'bool'#}
3209 if (a &gt; b) a else b3160fn max(comptime T: type, a: T, b: T) T {
3161 return if (a > b) a else b;
3210}3162}
3211fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {3163test "try to compare bools" {
3212 max(bool, a, b)3164 _ = max(bool, true, false);
3213}</code></pre>3165}
3214 <p>3166 {#code_end#}
3215 The code produces this error message:
3216 </p>
3217 <pre><code>./test.zig:2:11: error: operator not allowed for type 'bool'
3218 if (a &gt; b) a else b
3219 ^
3220./test.zig:5:8: note: called from here
3221 max(bool, a, b)
3222 ^</code></pre>
3223 <p>3167 <p>
3224 On the flip side, inside the function definition with the <code>comptime</code> parameter, the3168 On the flip side, inside the function definition with the <code>comptime</code> parameter, the
3225 value is known at compile-time. This means that we actually could make this work for the bool type3169 value is known at compile-time. This means that we actually could make this work for the bool type
3226 if we wanted to:3170 if we wanted to:
3227 </p>3171 </p>
3228 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {3172 {#code_begin|test#}
3173fn max(comptime T: type, a: T, b: T) T {
3229 if (T == bool) {3174 if (T == bool) {
3230 return a or b;3175 return a or b;
3231 } else if (a &gt; b) {3176 } else if (a > b) {
3232 return a;3177 return a;
3233 } else {3178 } else {
3234 return b;3179 return b;
3235 }3180 }
3236}3181}
3237fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {3182test "try to compare bools" {
3238 max(bool, a, b)3183 @import("std").debug.assert(max(bool, false, true) == true);
3239}</code></pre>3184}
3185 {#code_end#}
3240 <p>3186 <p>
3241 This works because Zig implicitly inlines <code>if</code> expressions when the condition3187 This works because Zig implicitly inlines <code>if</code> expressions when the condition
3242 is known at compile-time, and the compiler guarantees that it will skip analysis of3188 is known at compile-time, and the compiler guarantees that it will skip analysis of
...@@ -3246,9 +3192,11 @@ fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {...@@ -3246,9 +3192,11 @@ fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {
3246 This means that the actual function generated for <code>max</code> in this situation looks like3192 This means that the actual function generated for <code>max</code> in this situation looks like
3247 this:3193 this:
3248 </p>3194 </p>
3249 <pre><code class="zig">fn max(a: bool, b: bool) -&gt; bool {3195 {#code_begin|syntax#}
3196fn max(a: bool, b: bool) bool {
3250 return a or b;3197 return a or b;
3251}</code></pre>3198}
3199 {#code_end#}
3252 <p>3200 <p>
3253 All the code that dealt with compile-time known values is eliminated and we are left with only3201 All the code that dealt with compile-time known values is eliminated and we are left with only
3254 the necessary run-time code to accomplish the task.3202 the necessary run-time code to accomplish the task.
...@@ -3271,11 +3219,12 @@ fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {...@@ -3271,11 +3219,12 @@ fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {
3271 <p>3219 <p>
3272 For example:3220 For example:
3273 </p>3221 </p>
3274 <pre><code class="zig">const assert = @import("std").debug.assert;3222 {#code_begin|test|comptime_vars#}
3223const assert = @import("std").debug.assert;
32753224
3276const CmdFn = struct {3225const CmdFn = struct {
3277 name: []const u8,3226 name: []const u8,
3278 func: fn(i32) -&gt; i32,3227 func: fn(i32) i32,
3279};3228};
32803229
3281const cmd_fns = []CmdFn{3230const cmd_fns = []CmdFn{
...@@ -3283,14 +3232,14 @@ const cmd_fns = []CmdFn{...@@ -3283,14 +3232,14 @@ const cmd_fns = []CmdFn{
3283 CmdFn {.name = "two", .func = two},3232 CmdFn {.name = "two", .func = two},
3284 CmdFn {.name = "three", .func = three},3233 CmdFn {.name = "three", .func = three},
3285};3234};
3286fn one(value: i32) -&gt; i32 { value + 1 }3235fn one(value: i32) i32 { return value + 1; }
3287fn two(value: i32) -&gt; i32 { value + 2 }3236fn two(value: i32) i32 { return value + 2; }
3288fn three(value: i32) -&gt; i32 { value + 3 }3237fn three(value: i32) i32 { return value + 3; }
32893238
3290fn performFn(comptime prefix_char: u8, start_value: i32) -&gt; i32 {3239fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
3291 var result: i32 = start_value;3240 var result: i32 = start_value;
3292 comptime var i = 0;3241 comptime var i = 0;
3293 inline while (i &lt; cmd_fns.len) : (i += 1) {3242 inline while (i < cmd_fns.len) : (i += 1) {
3294 if (cmd_fns[i].name[0] == prefix_char) {3243 if (cmd_fns[i].name[0] == prefix_char) {
3295 result = cmd_fns[i].func(result);3244 result = cmd_fns[i].func(result);
3296 }3245 }
...@@ -3302,36 +3251,41 @@ test "perform fn" {...@@ -3302,36 +3251,41 @@ test "perform fn" {
3302 assert(performFn('t', 1) == 6);3251 assert(performFn('t', 1) == 6);
3303 assert(performFn('o', 0) == 1);3252 assert(performFn('o', 0) == 1);
3304 assert(performFn('w', 99) == 99);3253 assert(performFn('w', 99) == 99);
3305}</code></pre>3254}
3255 {#code_end#}
3306 <p>3256 <p>
3307 This example is a bit contrived, because the compile-time evaluation component is unnecessary;3257 This example is a bit contrived, because the compile-time evaluation component is unnecessary;
3308 this code would work fine if it was all done at run-time. But it does end up generating3258 this code would work fine if it was all done at run-time. But it does end up generating
3309 different code. In this example, the function <code>performFn</code> is generated three different times,3259 different code. In this example, the function <code>performFn</code> is generated three different times,
3310 for the different values of <code>prefix_char</code> provided:3260 for the different values of <code>prefix_char</code> provided:
3311 </p>3261 </p>
3312 <pre><code class="zig">// From the line:3262 {#code_begin|syntax#}
3263// From the line:
3313// assert(performFn('t', 1) == 6);3264// assert(performFn('t', 1) == 6);
3314fn performFn(start_value: i32) -&gt; i32 {3265fn performFn(start_value: i32) i32 {
3315 var result: i32 = start_value;3266 var result: i32 = start_value;
3316 result = two(result);3267 result = two(result);
3317 result = three(result);3268 result = three(result);
3318 return result;3269 return result;
3319}3270}
33203271 {#code_end#}
3272 {#code_begin|syntax#}
3321// From the line:3273// From the line:
3322// assert(performFn('o', 0) == 1);3274// assert(performFn('o', 0) == 1);
3323fn performFn(start_value: i32) -&gt; i32 {3275fn performFn(start_value: i32) i32 {
3324 var result: i32 = start_value;3276 var result: i32 = start_value;
3325 result = one(result);3277 result = one(result);
3326 return result;3278 return result;
3327}3279}
33283280 {#code_end#}
3281 {#code_begin|syntax#}
3329// From the line:3282// From the line:
3330// assert(performFn('w', 99) == 99);3283// assert(performFn('w', 99) == 99);
3331fn performFn(start_value: i32) -&gt; i32 {3284fn performFn(start_value: i32) i32 {
3332 var result: i32 = start_value;3285 var result: i32 = start_value;
3333 return result;3286 return result;
3334}</code></pre>3287}
3288 {#code_end#}
3335 <p>3289 <p>
3336 Note that this happens even in a debug build; in a release build these generated functions still3290 Note that this happens even in a debug build; in a release build these generated functions still
3337 pass through rigorous LLVM optimizations. The important thing to note, however, is not that this3291 pass through rigorous LLVM optimizations. The important thing to note, however, is not that this
...@@ -3347,16 +3301,15 @@ fn performFn(start_value: i32) -&gt; i32 {...@@ -3347,16 +3301,15 @@ fn performFn(start_value: i32) -&gt; i32 {
3347 use a <code>comptime</code> expression to guarantee that the expression will be evaluated at compile-time.3301 use a <code>comptime</code> expression to guarantee that the expression will be evaluated at compile-time.
3348 If this cannot be accomplished, the compiler will emit an error. For example:3302 If this cannot be accomplished, the compiler will emit an error. For example:
3349 </p>3303 </p>
3350 <pre><code class="zig">extern fn exit() -&gt; unreachable;3304 {#code_begin|test_err|unable to evaluate constant expression#}
3305extern fn exit() noreturn;
33513306
3352fn foo() {3307test "foo" {
3353 comptime {3308 comptime {
3354 exit();3309 exit();
3355 }3310 }
3356}</code></pre>3311}
3357 <pre><code>./test.zig:5:9: error: unable to evaluate constant expression3312 {#code_end#}
3358 exit();
3359 ^</code></pre>
3360 <p>3313 <p>
3361 It doesn't make sense that a program could call <code>exit()</code> (or any other external function)3314 It doesn't make sense that a program could call <code>exit()</code> (or any other external function)
3362 at compile-time, so this is a compile error. However, a <code>comptime</code> expression does much3315 at compile-time, so this is a compile error. However, a <code>comptime</code> expression does much
...@@ -3367,7 +3320,7 @@ fn foo() {...@@ -3367,7 +3320,7 @@ fn foo() {
3367 </p>3320 </p>
3368 <ul>3321 <ul>
3369 <li>All variables are <code>comptime</code> variables.</li>3322 <li>All variables are <code>comptime</code> variables.</li>
3370 <li>All <code>if</code>, <code>while</code>, <code>for</code>, <code>switch</code>, and <code>goto</code>3323 <li>All <code>if</code>, <code>while</code>, <code>for</code>, and <code>switch</code>
3371 expressions are evaluated at compile-time, or emit a compile error if this is not possible.</li>3324 expressions are evaluated at compile-time, or emit a compile error if this is not possible.</li>
3372 <li>All function calls cause the compiler to interpret the function at compile-time, emitting a3325 <li>All function calls cause the compiler to interpret the function at compile-time, emitting a
3373 compile error if the function tries to do something that has global run-time side effects.</li>3326 compile error if the function tries to do something that has global run-time side effects.</li>
...@@ -3379,10 +3332,11 @@ fn foo() {...@@ -3379,10 +3332,11 @@ fn foo() {
3379 <p>3332 <p>
3380 Let's look at an example:3333 Let's look at an example:
3381 </p>3334 </p>
3382 <pre><code class="zig">const assert = @import("std").debug.assert;3335 {#code_begin|test#}
3336const assert = @import("std").debug.assert;
33833337
3384fn fibonacci(index: u32) -&gt; u32 {3338fn fibonacci(index: u32) u32 {
3385 if (index &lt; 2) return index;3339 if (index < 2) return index;
3386 return fibonacci(index - 1) + fibonacci(index - 2);3340 return fibonacci(index - 1) + fibonacci(index - 2);
3387}3341}
33883342
...@@ -3394,16 +3348,16 @@ test "fibonacci" {...@@ -3394,16 +3348,16 @@ test "fibonacci" {
3394 comptime {3348 comptime {
3395 assert(fibonacci(7) == 13);3349 assert(fibonacci(7) == 13);
3396 }3350 }
3397}</code></pre>3351}
3398 <pre><code>$ zig test test.zig3352 {#code_end#}
3399Test 1/1 testFibonacci...OK</code></pre>
3400 <p>3353 <p>
3401 Imagine if we had forgotten the base case of the recursive function and tried to run the tests:3354 Imagine if we had forgotten the base case of the recursive function and tried to run the tests:
3402 </p>3355 </p>
3403 <pre><code class="zig">const assert = @import("std").debug.assert;3356 {#code_begin|test_err|operation caused overflow#}
3357const assert = @import("std").debug.assert;
34043358
3405fn fibonacci(index: u32) -&gt; u32 {3359fn fibonacci(index: u32) u32 {
3406 //if (index &lt; 2) return index;3360 //if (index < 2) return index;
3407 return fibonacci(index - 1) + fibonacci(index - 2);3361 return fibonacci(index - 1) + fibonacci(index - 2);
3408}3362}
34093363
...@@ -3411,35 +3365,8 @@ test "fibonacci" {...@@ -3411,35 +3365,8 @@ test "fibonacci" {
3411 comptime {3365 comptime {
3412 assert(fibonacci(7) == 13);3366 assert(fibonacci(7) == 13);
3413 }3367 }
3414}</code></pre>3368}
3415 <pre><code>$ zig test test.zig3369 {#code_end#}
3416./test.zig:3:28: error: operation caused overflow
3417 return fibonacci(index - 1) + fibonacci(index - 2);
3418 ^
3419./test.zig:3:21: note: called from here
3420 return fibonacci(index - 1) + fibonacci(index - 2);
3421 ^
3422./test.zig:3:21: note: called from here
3423 return fibonacci(index - 1) + fibonacci(index - 2);
3424 ^
3425./test.zig:3:21: note: called from here
3426 return fibonacci(index - 1) + fibonacci(index - 2);
3427 ^
3428./test.zig:3:21: note: called from here
3429 return fibonacci(index - 1) + fibonacci(index - 2);
3430 ^
3431./test.zig:3:21: note: called from here
3432 return fibonacci(index - 1) + fibonacci(index - 2);
3433 ^
3434./test.zig:3:21: note: called from here
3435 return fibonacci(index - 1) + fibonacci(index - 2);
3436 ^
3437./test.zig:3:21: note: called from here
3438 return fibonacci(index - 1) + fibonacci(index - 2);
3439 ^
3440./test.zig:14:25: note: called from here
3441 assert(fibonacci(7) == 13);
3442 ^</code></pre>
3443 <p>3370 <p>
3444 The compiler produces an error which is a stack trace from trying to evaluate the3371 The compiler produces an error which is a stack trace from trying to evaluate the
3445 function at compile-time.3372 function at compile-time.
...@@ -3449,10 +3376,11 @@ test "fibonacci" {...@@ -3449,10 +3376,11 @@ test "fibonacci" {
3449 undefined behavior, which is always a compile error if the compiler knows it happened.3376 undefined behavior, which is always a compile error if the compiler knows it happened.
3450 But what would have happened if we used a signed integer?3377 But what would have happened if we used a signed integer?
3451 </p>3378 </p>
3452 <pre><code class="zig">const assert = @import("std").debug.assert;3379 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
3380const assert = @import("std").debug.assert;
34533381
3454fn fibonacci(index: i32) -&gt; i32 {3382fn fibonacci(index: i32) i32 {
3455 //if (index &lt; 2) return index;3383 //if (index < 2) return index;
3456 return fibonacci(index - 1) + fibonacci(index - 2);3384 return fibonacci(index - 1) + fibonacci(index - 2);
3457}3385}
34583386
...@@ -3460,61 +3388,31 @@ test "fibonacci" {...@@ -3460,61 +3388,31 @@ test "fibonacci" {
3460 comptime {3388 comptime {
3461 assert(fibonacci(7) == 13);3389 assert(fibonacci(7) == 13);
3462 }3390 }
3463}</code></pre>3391}
3464 <pre><code>./test.zig:3:21: error: evaluation exceeded 1000 backwards branches3392 {#code_end#}
3465 return fibonacci(index - 1) + fibonacci(index - 2);
3466 ^
3467./test.zig:3:21: note: called from here
3468 return fibonacci(index - 1) + fibonacci(index - 2);
3469 ^
3470./test.zig:3:21: note: called from here
3471 return fibonacci(index - 1) + fibonacci(index - 2);
3472 ^
3473./test.zig:3:21: note: called from here
3474 return fibonacci(index - 1) + fibonacci(index - 2);
3475 ^
3476./test.zig:3:21: note: called from here
3477 return fibonacci(index - 1) + fibonacci(index - 2);
3478 ^
3479./test.zig:3:21: note: called from here
3480 return fibonacci(index - 1) + fibonacci(index - 2);
3481 ^
3482./test.zig:3:21: note: called from here
3483 return fibonacci(index - 1) + fibonacci(index - 2);
3484 ^
3485./test.zig:3:21: note: called from here
3486 return fibonacci(index - 1) + fibonacci(index - 2);
3487 ^
3488./test.zig:3:21: note: called from here
3489 return fibonacci(index - 1) + fibonacci(index - 2);
3490 ^
3491./test.zig:3:21: note: called from here
3492 return fibonacci(index - 1) + fibonacci(index - 2);
3493 ^
3494./test.zig:3:21: note: called from here
3495 return fibonacci(index - 1) + fibonacci(index - 2);
3496 ^
3497./test.zig:3:21: note: called from here
3498 return fibonacci(index - 1) + fibonacci(index - 2);
3499 ^</code></pre>
3500 <p>3393 <p>
3501 The compiler noticed that evaluating this function at compile-time took a long time,3394 The compiler noticed that evaluating this function at compile-time took a long time,
3502 and thus emitted a compile error and gave up. If the programmer wants to increase3395 and thus emitted a compile error and gave up. If the programmer wants to increase
3503 the budget for compile-time computation, they can use a built-in function called3396 the budget for compile-time computation, they can use a built-in function called
3504 <a href="#builtin-setEvalBranchQuota">@setEvalBranchQuota</a> to change the default number 1000 to something else.3397 {#link|@setEvalBranchQuota#} to change the default number 1000 to something else.
3505 </p>3398 </p>
3506 <p>3399 <p>
3507 What if we fix the base case, but put the wrong value in the <code>assert</code> line?3400 What if we fix the base case, but put the wrong value in the <code>assert</code> line?
3508 </p>3401 </p>
3509 <pre><code class="zig">comptime {3402 {#code_begin|test_err|encountered @panic at compile-time#}
3510 assert(fibonacci(7) == 99999);3403const assert = @import("std").debug.assert;
3511}</code></pre>3404
3512 <pre><code>./test.zig:15:14: error: unable to evaluate constant expression3405fn fibonacci(index: i32) i32 {
3513 if (!ok) unreachable;3406 if (index < 2) return index;
3514 ^3407 return fibonacci(index - 1) + fibonacci(index - 2);
3515./test.zig:10:15: note: called from here3408}
3409
3410test "fibonacci" {
3411 comptime {
3516 assert(fibonacci(7) == 99999);3412 assert(fibonacci(7) == 99999);
3517 ^</code></pre>3413 }
3414}
3415 {#code_end#}
3518 <p>3416 <p>
3519 What happened is Zig started interpreting the <code>assert</code> function with the3417 What happened is Zig started interpreting the <code>assert</code> function with the
3520 parameter <code>ok</code> set to <code>false</code>. When the interpreter hit3418 parameter <code>ok</code> set to <code>false</code>. When the interpreter hit
...@@ -3528,17 +3426,18 @@ test "fibonacci" {...@@ -3528,17 +3426,18 @@ test "fibonacci" {
3528 <code>comptime</code> expressions. This means that we can use functions to3426 <code>comptime</code> expressions. This means that we can use functions to
3529 initialize complex static data. For example:3427 initialize complex static data. For example:
3530 </p>3428 </p>
3531 <pre><code class="zig">const first_25_primes = firstNPrimes(25);3429 {#code_begin|test#}
3430const first_25_primes = firstNPrimes(25);
3532const sum_of_first_25_primes = sum(first_25_primes);3431const sum_of_first_25_primes = sum(first_25_primes);
35333432
3534fn firstNPrimes(comptime n: usize) -&gt; [n]i32 {3433fn firstNPrimes(comptime n: usize) [n]i32 {
3535 var prime_list: [n]i32 = undefined;3434 var prime_list: [n]i32 = undefined;
3536 var next_index: usize = 0;3435 var next_index: usize = 0;
3537 var test_number: i32 = 2;3436 var test_number: i32 = 2;
3538 while (next_index &lt; prime_list.len) : (test_number += 1) {3437 while (next_index < prime_list.len) : (test_number += 1) {
3539 var test_prime_index: usize = 0;3438 var test_prime_index: usize = 0;
3540 var is_prime = true;3439 var is_prime = true;
3541 while (test_prime_index &lt; next_index) : (test_prime_index += 1) {3440 while (test_prime_index < next_index) : (test_prime_index += 1) {
3542 if (test_number % prime_list[test_prime_index] == 0) {3441 if (test_number % prime_list[test_prime_index] == 0) {
3543 is_prime = false;3442 is_prime = false;
3544 break;3443 break;
...@@ -3552,19 +3451,24 @@ fn firstNPrimes(comptime n: usize) -&gt; [n]i32 {...@@ -3552,19 +3451,24 @@ fn firstNPrimes(comptime n: usize) -&gt; [n]i32 {
3552 return prime_list;3451 return prime_list;
3553}3452}
35543453
3555fn sum(numbers: []i32) -&gt; i32 {3454fn sum(numbers: []const i32) i32 {
3556 var result: i32 = 0;3455 var result: i32 = 0;
3557 for (numbers) |x| {3456 for (numbers) |x| {
3558 result += x;3457 result += x;
3559 }3458 }
3560 return result;3459 return result;
3561}</code></pre>3460}
3461
3462test "variable values" {
3463 @import("std").debug.assert(sum_of_first_25_primes == 1060);
3464}
3465 {#code_end#}
3562 <p>3466 <p>
3563 When we compile this program, Zig generates the constants3467 When we compile this program, Zig generates the constants
3564 with the answer pre-computed. Here are the lines from the generated LLVM IR:3468 with the answer pre-computed. Here are the lines from the generated LLVM IR:
3565 </p>3469 </p>
3566 <pre><code>@0 = internal unnamed_addr constant [25 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61, i32 67, i32 71, i32 73, i32 79, i32 83, i32 89, i32 97]3470 <pre><code class="llvm">@0 = internal unnamed_addr constant [25 x i32] [i32 2, i32 3, i32 5, i32 7, i32 11, i32 13, i32 17, i32 19, i32 23, i32 29, i32 31, i32 37, i32 41, i32 43, i32 47, i32 53, i32 59, i32 61, i32 67, i32 71, i32 73, i32 79, i32 83, i32 89, i32 97]
3567 @1 = internal unnamed_addr constant i32 1060</code></pre>3471@1 = internal unnamed_addr constant i32 1060</code></pre>
3568 <p>3472 <p>
3569 Note that we did not have to do anything special with the syntax of these functions. For example,3473 Note that we did not have to do anything special with the syntax of these functions. For example,
3570 we could call the <code>sum</code> function as is with a slice of numbers whose length and values were3474 we could call the <code>sum</code> function as is with a slice of numbers whose length and values were
...@@ -3582,12 +3486,14 @@ fn sum(numbers: []i32) -&gt; i32 {...@@ -3582,12 +3486,14 @@ fn sum(numbers: []i32) -&gt; i32 {
3582 Here is an example of a generic <code>List</code> data structure, that we will instantiate with3486 Here is an example of a generic <code>List</code> data structure, that we will instantiate with
3583 the type <code>i32</code>. In Zig we refer to the type as <code>List(i32)</code>.3487 the type <code>i32</code>. In Zig we refer to the type as <code>List(i32)</code>.
3584 </p>3488 </p>
3585 <pre><code class="zig">fn List(comptime T: type) -&gt; type {3489 {#code_begin|syntax#}
3586 struct {3490fn List(comptime T: type) type {
3491 return struct {
3587 items: []T,3492 items: []T,
3588 len: usize,3493 len: usize,
3589 }3494 };
3590}</code></pre>3495}
3496 {#code_end#}
3591 <p>3497 <p>
3592 That's it. It's a function that returns an anonymous <code>struct</code>. For the purposes of error messages3498 That's it. It's a function that returns an anonymous <code>struct</code>. For the purposes of error messages
3593 and debugging, Zig infers the name <code>"List(i32)"</code> from the function name and parameters invoked when creating3499 and debugging, Zig infers the name <code>"List(i32)"</code> from the function name and parameters invoked when creating
...@@ -3597,10 +3503,12 @@ fn sum(numbers: []i32) -&gt; i32 {...@@ -3597,10 +3503,12 @@ fn sum(numbers: []i32) -&gt; i32 {
3597 To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type3503 To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type
3598 a name, we assign it to a constant:3504 a name, we assign it to a constant:
3599 </p>3505 </p>
3600 <pre><code class="zig">const Node = struct {3506 {#code_begin|syntax#}
3601 next: &amp;Node,3507const Node = struct {
3508 next: &Node,
3602 name: []u8,3509 name: []u8,
3603};</code></pre>3510};
3511 {#code_end#}
3604 <p>3512 <p>
3605 This works because all top level declarations are order-independent, and as long as there isn't3513 This works because all top level declarations are order-independent, and as long as there isn't
3606 an actual infinite regression, values can refer to themselves, directly or indirectly. In this case,3514 an actual infinite regression, values can refer to themselves, directly or indirectly. In this case,
...@@ -3618,7 +3526,7 @@ const warn = @import("std").debug.warn;...@@ -3618,7 +3526,7 @@ const warn = @import("std").debug.warn;
3618const a_number: i32 = 1234;3526const a_number: i32 = 1234;
3619const a_string = "foobar";3527const a_string = "foobar";
36203528
3621pub fn main() {3529pub fn main() void {
3622 warn("here is a string: '{}' here is a number: {}\n", a_string, a_number);3530 warn("here is a string: '{}' here is a number: {}\n", a_string, a_number);
3623}3531}
3624 {#code_end#}3532 {#code_end#}
...@@ -3627,8 +3535,9 @@ pub fn main() {...@@ -3627,8 +3535,9 @@ pub fn main() {
3627 Let's crack open the implementation of this and see how it works:3535 Let's crack open the implementation of this and see how it works:
3628 </p>3536 </p>
36293537
3630 <pre><code class="zig">/// Calls print and then flushes the buffer.3538 {#code_begin|syntax#}
3631pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt; %void {3539/// Calls print and then flushes the buffer.
3540pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void {
3632 const State = enum {3541 const State = enum {
3633 Start,3542 Start,
3634 OpenBrace,3543 OpenBrace,
...@@ -3641,36 +3550,36 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt...@@ -3641,36 +3550,36 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
36413550
3642 inline for (format) |c, i| {3551 inline for (format) |c, i| {
3643 switch (state) {3552 switch (state) {
3644 State.Start =&gt; switch (c) {3553 State.Start => switch (c) {
3645 '{' =&gt; {3554 '{' => {
3646 if (start_index &lt; i) try self.write(format[start_index...i]);3555 if (start_index < i) try self.write(format[start_index..i]);
3647 state = State.OpenBrace;3556 state = State.OpenBrace;
3648 },3557 },
3649 '}' =&gt; {3558 '}' => {
3650 if (start_index &lt; i) try self.write(format[start_index...i]);3559 if (start_index < i) try self.write(format[start_index..i]);
3651 state = State.CloseBrace;3560 state = State.CloseBrace;
3652 },3561 },
3653 else =&gt; {},3562 else => {},
3654 },3563 },
3655 State.OpenBrace =&gt; switch (c) {3564 State.OpenBrace => switch (c) {
3656 '{' =&gt; {3565 '{' => {
3657 state = State.Start;3566 state = State.Start;
3658 start_index = i;3567 start_index = i;
3659 },3568 },
3660 '}' =&gt; {3569 '}' => {
3661 try self.printValue(args[next_arg]);3570 try self.printValue(args[next_arg]);
3662 next_arg += 1;3571 next_arg += 1;
3663 state = State.Start;3572 state = State.Start;
3664 start_index = i + 1;3573 start_index = i + 1;
3665 },3574 },
3666 else =&gt; @compileError("Unknown format character: " ++ c),3575 else => @compileError("Unknown format character: " ++ c),
3667 },3576 },
3668 State.CloseBrace =&gt; switch (c) {3577 State.CloseBrace => switch (c) {
3669 '}' =&gt; {3578 '}' => {
3670 state = State.Start;3579 state = State.Start;
3671 start_index = i;3580 start_index = i;
3672 },3581 },
3673 else =&gt; @compileError("Single '}' encountered in format string"),3582 else => @compileError("Single '}' encountered in format string"),
3674 },3583 },
3675 }3584 }
3676 }3585 }
...@@ -3682,11 +3591,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt...@@ -3682,11 +3591,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
3682 @compileError("Incomplete format string: " ++ format);3591 @compileError("Incomplete format string: " ++ format);
3683 }3592 }
3684 }3593 }
3685 if (start_index &lt; format.len) {3594 if (start_index < format.len) {
3686 try self.write(format[start_index...format.len]);3595 try self.write(format[start_index..format.len]);
3687 }3596 }
3688 try self.flush();3597 try self.flush();
3689}</code></pre>3598}
3599 {#code_end#}
3690 <p>3600 <p>
3691 This is a proof of concept implementation; the actual function in the standard library has more3601 This is a proof of concept implementation; the actual function in the standard library has more
3692 formatting capabilities.3602 formatting capabilities.
...@@ -3698,19 +3608,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt...@@ -3698,19 +3608,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
3698 When this function is analyzed from our example code above, Zig partially evaluates the function3608 When this function is analyzed from our example code above, Zig partially evaluates the function
3699 and emits a function that actually looks like this:3609 and emits a function that actually looks like this:
3700 </p>3610 </p>
3701 <pre><code class="zig">pub fn printf(self: &amp;OutStream, arg0: i32, arg1: []const u8) -&gt; %void {3611 {#code_begin|syntax#}
3612pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) %void {
3702 try self.write("here is a string: '");3613 try self.write("here is a string: '");
3703 try self.printValue(arg0);3614 try self.printValue(arg0);
3704 try self.write("' here is a number: ");3615 try self.write("' here is a number: ");
3705 try self.printValue(arg1);3616 try self.printValue(arg1);
3706 try self.write("\n");3617 try self.write("\n");
3707 try self.flush();3618 try self.flush();
3708}</code></pre>3619}
3620 {#code_end#}
3709 <p>3621 <p>
3710 <code>printValue</code> is a function that takes a parameter of any type, and does different things depending3622 <code>printValue</code> is a function that takes a parameter of any type, and does different things depending
3711 on the type:3623 on the type:
3712 </p>3624 </p>
3713 <pre><code class="zig">pub fn printValue(self: &amp;OutStream, value: var) -&gt; %void {3625 {#code_begin|syntax#}
3626pub fn printValue(self: &OutStream, value: var) %void {
3714 const T = @typeOf(value);3627 const T = @typeOf(value);
3715 if (@isInteger(T)) {3628 if (@isInteger(T)) {
3716 return self.printInt(T, value);3629 return self.printInt(T, value);
...@@ -3722,18 +3635,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt...@@ -3722,18 +3635,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
3722 } else {3635 } else {
3723 @compileError("Unable to print type '" ++ @typeName(T) ++ "'");3636 @compileError("Unable to print type '" ++ @typeName(T) ++ "'");
3724 }3637 }
3725}</code></pre>3638}
3639 {#code_end#}
3726 <p>3640 <p>
3727 And now, what happens if we give too many arguments to <code>printf</code>?3641 And now, what happens if we give too many arguments to <code>printf</code>?
3728 </p>3642 </p>
3729 <pre><code class="zig">warn("here is a string: '{}' here is a number: {}\n",3643 {#code_begin|test_err|Unused arguments#}
3730 a_string, a_number, a_number);</code></pre>3644const warn = @import("std").debug.warn;
3731 <pre><code>.../std/io.zig:147:17: error: Unused arguments3645
3732 @compileError("Unused arguments");3646const a_number: i32 = 1234;
3733 ^3647const a_string = "foobar";
3734./test.zig:7:23: note: called from here3648
3735 warn("here is a number: {} and here is a string: {}\n",3649test "printf too many arguments" {
3736 ^</code></pre>3650 warn("here is a string: '{}' here is a number: {}\n",
3651 a_string, a_number, a_number);
3652}
3653 {#code_end#}
3737 <p>3654 <p>
3738 Zig gives programmers the tools needed to protect themselves against their own mistakes.3655 Zig gives programmers the tools needed to protect themselves against their own mistakes.
3739 </p>3656 </p>
...@@ -3748,7 +3665,7 @@ const a_number: i32 = 1234;...@@ -3748,7 +3665,7 @@ const a_number: i32 = 1234;
3748const a_string = "foobar";3665const a_string = "foobar";
3749const fmt = "here is a string: '{}' here is a number: {}\n";3666const fmt = "here is a string: '{}' here is a number: {}\n";
37503667
3751pub fn main() {3668pub fn main() void {
3752 warn(fmt, a_string, a_number);3669 warn(fmt, a_string, a_number);
3753}3670}
3754 {#code_end#}3671 {#code_end#}
...@@ -3786,7 +3703,7 @@ pub fn main() {...@@ -3786,7 +3703,7 @@ pub fn main() {
3786 at compile time.3703 at compile time.
3787 </p>3704 </p>
3788 {#header_open|@addWithOverflow#}3705 {#header_open|@addWithOverflow#}
3789 <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &amp;T) -&gt; bool</code></pre>3706 <pre><code class="zig">@addWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
3790 <p>3707 <p>
3791 Performs <code>*result = a + b</code>. If overflow or underflow occurs,3708 Performs <code>*result = a + b</code>. If overflow or underflow occurs,
3792 stores the overflowed bits in <code>result</code> and returns <code>true</code>.3709 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
...@@ -3836,7 +3753,7 @@ pub fn main() {...@@ -3836,7 +3753,7 @@ pub fn main() {
3836 <code>?fn()</code>, or <code>[]T</code>. It returns the same type as <code>ptr</code>3753 <code>?fn()</code>, or <code>[]T</code>. It returns the same type as <code>ptr</code>
3837 except with the alignment adjusted to the new value.3754 except with the alignment adjusted to the new value.
3838 </p>3755 </p>
3839 <p>A <a href="#undef-incorrect-pointer-alignment">pointer alignment safety check</a> is added3756 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
3840 to the generated code to make sure the pointer is aligned as promised.</p>3757 to the generated code to make sure the pointer is aligned as promised.</p>
38413758
3842 {#header_close#}3759 {#header_close#}
...@@ -3849,11 +3766,11 @@ pub fn main() {...@@ -3849,11 +3766,11 @@ pub fn main() {
3849 </p>3766 </p>
3850 <pre><code class="zig">const assert = @import("std").debug.assert;3767 <pre><code class="zig">const assert = @import("std").debug.assert;
3851comptime {3768comptime {
3852 assert(&amp;u32 == &amp;align(@alignOf(u32)) u32);3769 assert(&u32 == &align(@alignOf(u32)) u32);
3853}</code></pre>3770}</code></pre>
3854 <p>3771 <p>
3855 The result is a target-specific compile time constant. It is guaranteed to be3772 The result is a target-specific compile time constant. It is guaranteed to be
3856 less than or equal to <a href="#builtin-sizeOf">@sizeOf(T)</a>.3773 less than or equal to {#link|@sizeOf(T)|@sizeOf#}.
3857 </p>3774 </p>
3858 {#see_also|Alignment#}3775 {#see_also|Alignment#}
3859 {#header_close#}3776 {#header_close#}
...@@ -3933,7 +3850,7 @@ comptime {...@@ -3933,7 +3850,7 @@ comptime {
39333850
3934 {#header_close#}3851 {#header_close#}
3935 {#header_open|@cmpxchg#}3852 {#header_open|@cmpxchg#}
3936 <pre><code class="zig">@cmpxchg(ptr: &amp;T, cmp: T, new: T, success_order: AtomicOrder, fail_order: AtomicOrder) -&gt; bool</code></pre>3853 <pre><code class="zig">@cmpxchg(ptr: &T, cmp: T, new: T, success_order: AtomicOrder, fail_order: AtomicOrder) -&gt; bool</code></pre>
3937 <p>3854 <p>
3938 This function performs an atomic compare exchange operation.3855 This function performs an atomic compare exchange operation.
3939 </p>3856 </p>
...@@ -3970,42 +3887,46 @@ comptime {...@@ -3970,42 +3887,46 @@ comptime {
3970 This function can be used to do "printf debugging" on3887 This function can be used to do "printf debugging" on
3971 compile-time executing code.3888 compile-time executing code.
3972 </p>3889 </p>
3973<pre><code class="zig">const warn = @import("std").debug.warn;3890 {#code_begin|test_err|found compile log statement#}
3891const warn = @import("std").debug.warn;
39743892
3975const num1 = {3893const num1 = blk: {
3976 var val1: i32 = 99;3894 var val1: i32 = 99;
3977 @compileLog("comptime val1 = ", val1); 3895 @compileLog("comptime val1 = ", val1);
3978 val1 = val1 + 1;3896 val1 = val1 + 1;
3979 val13897 break :blk val1;
3980};3898};
39813899
3982pub fn main() -&gt; %void {3900test "main" {
3983 @compileLog("comptime in main"); 3901 @compileLog("comptime in main");
39843902
3985 warn("Runtime in main, num1 = {}.\n", num1);3903 warn("Runtime in main, num1 = {}.\n", num1);
3986}</code></pre>3904}
39873905 {#code_end#}
3988 </p>3906 </p>
3989 <p>3907 <p>
3990 will ouput:3908 will ouput:
3991 </p>3909 </p>
3992
3993<pre><code class="sh">$ zig build-exe test.zig
3994| "comptime in main"
3995| "comptime val1 = ", 99
3996test.zig:14:5: error: found compile log statement
3997 @compileLog("comptime in main");
3998 ^
3999test.zig:6:2: error: found compile log statement
4000 @compileLog("comptime val1 = ", val1);
4001 ^</code></pre>
4002 <p>3910 <p>
4003 If all <code>@compileLog</code> calls are removed or 3911 If all <code>@compileLog</code> calls are removed or
4004 not encountered by analysis, the3912 not encountered by analysis, the
4005 program compiles successfully and the generated executable prints:3913 program compiles successfully and the generated executable prints:
4006 </p> 3914 </p>
4007<pre><code class="sh">Runtime in main, num1 = 100.</code></pre>3915 {#code_begin|test#}
4008{{@ctheader_open:z}}3916const warn = @import("std").debug.warn;
3917
3918const num1 = blk: {
3919 var val1: i32 = 99;
3920 val1 = val1 + 1;
3921 break :blk val1;
3922};
3923
3924test "main" {
3925 warn("Runtime in main, num1 = {}.\n", num1);
3926}
3927 {#code_end#}
3928 {#header_close#}
3929 {#header_open|@ctz#}
4009 <pre><code class="zig">@ctz(x: T) -&gt; U</code></pre>3930 <pre><code class="zig">@ctz(x: T) -&gt; U</code></pre>
4010 <p>3931 <p>
4011 This function counts the number of trailing zeroes in <code>x</code> which is an integer3932 This function counts the number of trailing zeroes in <code>x</code> which is an integer
...@@ -4110,7 +4031,7 @@ test.zig:6:2: error: found compile log statement...@@ -4110,7 +4031,7 @@ test.zig:6:2: error: found compile log statement
4110 </p>4031 </p>
4111 {#header_close#}4032 {#header_close#}
4112 {#header_open|@errorReturnTrace#}4033 {#header_open|@errorReturnTrace#}
4113 <pre><code class="zig">@errorReturnTrace() -&gt; ?&amp;builtin.StackTrace</code></pre>4034 <pre><code class="zig">@errorReturnTrace() -&gt; ?&builtin.StackTrace</code></pre>
4114 <p>4035 <p>
4115 If the binary is built with error return tracing, and this function is invoked in a4036 If the binary is built with error return tracing, and this function is invoked in a
4116 function that calls a function with an error or error union return type, returns a4037 function that calls a function with an error or error union return type, returns a
...@@ -4129,7 +4050,7 @@ test.zig:6:2: error: found compile log statement...@@ -4129,7 +4050,7 @@ test.zig:6:2: error: found compile log statement
4129 {#header_close#}4050 {#header_close#}
4130 {#header_open|@fieldParentPtr#}4051 {#header_open|@fieldParentPtr#}
4131 <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,4052 <pre><code class="zig">@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,
4132 field_ptr: &amp;T) -&gt; &amp;ParentType</code></pre>4053 field_ptr: &T) -&gt; &ParentType</code></pre>
4133 <p>4054 <p>
4134 Given a pointer to a field, returns the base pointer of a struct.4055 Given a pointer to a field, returns the base pointer of a struct.
4135 </p>4056 </p>
...@@ -4173,12 +4094,15 @@ test.zig:6:2: error: found compile log statement...@@ -4173,12 +4094,15 @@ test.zig:6:2: error: found compile log statement
4173 <p>4094 <p>
4174 This calls a function, in the same way that invoking an expression with parentheses does:4095 This calls a function, in the same way that invoking an expression with parentheses does:
4175 </p>4096 </p>
4176 <pre><code class="zig">const assert = @import("std").debug.assert;4097 {#code_begin|test#}
4098const assert = @import("std").debug.assert;
4099
4177test "inline function call" {4100test "inline function call" {
4178 assert(@inlineCall(add, 3, 9) == 12);4101 assert(@inlineCall(add, 3, 9) == 12);
4179}4102}
41804103
4181fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>4104fn add(a: i32, b: i32) i32 { return a + b; }
4105 {#code_end#}
4182 <p>4106 <p>
4183 Unlike a normal function call, however, <code>@inlineCall</code> guarantees that the call4107 Unlike a normal function call, however, <code>@inlineCall</code> guarantees that the call
4184 will be inlined. If the call cannot be inlined, a compile error is emitted.4108 will be inlined. If the call cannot be inlined, a compile error is emitted.
...@@ -4188,7 +4112,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>...@@ -4188,7 +4112,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>
4188 {#header_open|@intToPtr#}4112 {#header_open|@intToPtr#}
4189 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) -&gt; DestType</code></pre>4113 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) -&gt; DestType</code></pre>
4190 <p>4114 <p>
4191 Converts an integer to a pointer. To convert the other way, use <a href="#builtin-ptrToInt">@ptrToInt</a>.4115 Converts an integer to a pointer. To convert the other way, use {#link|@ptrToInt#}.
4192 </p>4116 </p>
4193 {#header_close#}4117 {#header_close#}
4194 {#header_open|@IntType#}4118 {#header_open|@IntType#}
...@@ -4222,7 +4146,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>...@@ -4222,7 +4146,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>
4222 <p>TODO</p>4146 <p>TODO</p>
4223 {#header_close#}4147 {#header_close#}
4224 {#header_open|@memcpy#}4148 {#header_open|@memcpy#}
4225 <pre><code class="zig">@memcpy(noalias dest: &amp;u8, noalias source: &amp;const u8, byte_count: usize)</code></pre>4149 <pre><code class="zig">@memcpy(noalias dest: &u8, noalias source: &const u8, byte_count: usize)</code></pre>
4226 <p>4150 <p>
4227 This function copies bytes from one region of memory to another. <code>dest</code> and4151 This function copies bytes from one region of memory to another. <code>dest</code> and
4228 <code>source</code> are both pointers and must not overlap.4152 <code>source</code> are both pointers and must not overlap.
...@@ -4240,7 +4164,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>...@@ -4240,7 +4164,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>
4240mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>4164mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>
4241 {#header_close#}4165 {#header_close#}
4242 {#header_open|@memset#}4166 {#header_open|@memset#}
4243 <pre><code class="zig">@memset(dest: &amp;u8, c: u8, byte_count: usize)</code></pre>4167 <pre><code class="zig">@memset(dest: &u8, c: u8, byte_count: usize)</code></pre>
4244 <p>4168 <p>
4245 This function sets a region of memory to <code>c</code>. <code>dest</code> is a pointer.4169 This function sets a region of memory to <code>c</code>. <code>dest</code> is a pointer.
4246 </p>4170 </p>
...@@ -4279,7 +4203,7 @@ mem.set(u8, dest, c);</code></pre>...@@ -4279,7 +4203,7 @@ mem.set(u8, dest, c);</code></pre>
4279 {#see_also|@rem#}4203 {#see_also|@rem#}
4280 {#header_close#}4204 {#header_close#}
4281 {#header_open|@mulWithOverflow#}4205 {#header_open|@mulWithOverflow#}
4282 <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &amp;T) -&gt; bool</code></pre>4206 <pre><code class="zig">@mulWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
4283 <p>4207 <p>
4284 Performs <code>*result = a * b</code>. If overflow or underflow occurs,4208 Performs <code>*result = a * b</code>. If overflow or underflow occurs,
4285 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4209 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
...@@ -4318,17 +4242,19 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>...@@ -4318,17 +4242,19 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>
4318 This is typically used for type safety when interacting with C code that does not expose struct details.4242 This is typically used for type safety when interacting with C code that does not expose struct details.
4319 Example:4243 Example:
4320 </p>4244 </p>
4321 <pre><code class="zig">const Derp = @OpaqueType();4245 {#code_begin|test_err|expected type '&Derp', found '&Wat'#}
4246const Derp = @OpaqueType();
4322const Wat = @OpaqueType();4247const Wat = @OpaqueType();
43234248
4324extern fn bar(d: &amp;Derp);4249extern fn bar(d: &Derp) void;
4325export fn foo(w: &amp;Wat) {4250export fn foo(w: &Wat) void {
4326 bar(w);4251 bar(w);
4327}</code></pre>4252}
4328 <pre><code class="sh">$ ./zig build-obj test.zig4253
4329test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'4254test "call foo" {
4330 bar(w);4255 foo(undefined);
4331 ^</code></pre>4256}
4257 {#code_end#}
4332 {#header_close#}4258 {#header_close#}
4333 {#header_open|@panic#}4259 {#header_open|@panic#}
4334 <pre><code class="zig">@panic(message: []const u8) -&gt; noreturn</code></pre>4260 <pre><code class="zig">@panic(message: []const u8) -&gt; noreturn</code></pre>
...@@ -4363,7 +4289,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4363,7 +4289,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4363 <li><code>fn()</code></li>4289 <li><code>fn()</code></li>
4364 <li><code>?fn()</code></li>4290 <li><code>?fn()</code></li>
4365 </ul>4291 </ul>
4366 <p>To convert the other way, use <a href="#builtin-intToPtr">@intToPtr</a></p>4292 <p>To convert the other way, use {#link|@intToPtr#}</p>
43674293
4368 {#header_close#}4294 {#header_close#}
4369 {#header_open|@rem#}4295 {#header_open|@rem#}
...@@ -4393,10 +4319,16 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4393,10 +4319,16 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4393 This function is only valid within function scope.4319 This function is only valid within function scope.
4394 </p>4320 </p>
4395 {#header_close#}4321 {#header_close#}
4396 {#header_open|@setDebugSafety#}4322 {#header_open|@setCold#}
4397 <pre><code class="zig">@setDebugSafety(scope, safety_on: bool)</code></pre>4323 <pre><code class="zig">@setCold(is_cold: bool)</code></pre>
4324 <p>
4325 Tells the optimizer that a function is rarely called.
4326 </p>
4327 {#header_close#}
4328 {#header_open|@setRuntimeSafety#}
4329 <pre><code class="zig">@setRuntimeSafety(safety_on: bool)</code></pre>
4398 <p>4330 <p>
4399 Sets whether debug safety checks are on for a given scope.4331 Sets whether runtime safety checks are on for the scope that contains the function call.
4400 </p>4332 </p>
44014333
4402 {#header_close#}4334 {#header_close#}
...@@ -4413,22 +4345,24 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4413,22 +4345,24 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4413 <p>4345 <p>
4414 Example:4346 Example:
4415 </p>4347 </p>
4416 <pre><code class="zig">comptime {4348 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
4417 var i = 0;4349test "foo" {
4418 while (i &lt; 1001) : (i += 1) {}4350 comptime {
4419}</code></pre>4351 var i = 0;
4420 <pre><code class="sh">$ ./zig build-obj test.zig4352 while (i < 1001) : (i += 1) {}
4421/home/andy/dev/zig/build/test.zig:3:5: error: evaluation exceeded 1000 backwards branches4353 }
4422 while (i &lt; 1001) : (i += 1) {}4354}
4423 ^</code></pre>4355 {#code_end#}
4424 <p>Now we use <code>@setEvalBranchQuota</code>:</p>4356 <p>Now we use <code class="zig">@setEvalBranchQuota</code>:</p>
4425 <pre><code class="zig">comptime {4357 {#code_begin|test#}
4426 @setEvalBranchQuota(1001);4358test "foo" {
4427 var i = 0;4359 comptime {
4428 while (i &lt; 1001) : (i += 1) {}4360 @setEvalBranchQuota(1001);
4429}</code></pre>4361 var i = 0;
4430 <pre><code class="sh">$ ./zig build-obj test.zig</code></pre>4362 while (i < 1001) : (i += 1) {}
4431 <p>(no output because it worked fine)</p>4363 }
4364}
4365 {#code_end#}
44324366
4433 {#see_also|comptime#}4367 {#see_also|comptime#}
4434 {#header_close#}4368 {#header_close#}
...@@ -4437,10 +4371,12 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4437,10 +4371,12 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4437 <p>4371 <p>
4438 Sets the floating point mode for a given scope. Possible values are:4372 Sets the floating point mode for a given scope. Possible values are:
4439 </p>4373 </p>
4440 <pre><code class="zig">pub const FloatMode = enum {4374 {#code_begin|syntax#}
4375pub const FloatMode = enum {
4441 Optimized,4376 Optimized,
4442 Strict,4377 Strict,
4443};</code></pre>4378};
4379 {#code_end#}
4444 <ul>4380 <ul>
4445 <li>4381 <li>
4446 <code>Optimized</code> (default) - Floating point operations may do all of the following:4382 <code>Optimized</code> (default) - Floating point operations may do all of the following:
...@@ -4486,7 +4422,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4486,7 +4422,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4486 {#see_also|@shrExact|@shlWithOverflow#}4422 {#see_also|@shrExact|@shlWithOverflow#}
4487 {#header_close#}4423 {#header_close#}
4488 {#header_open|@shlWithOverflow#}4424 {#header_open|@shlWithOverflow#}
4489 <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &amp;T) -&gt; bool</code></pre>4425 <pre><code class="zig">@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: &T) -&gt; bool</code></pre>
4490 <p>4426 <p>
4491 Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs,4427 Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs,
4492 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4428 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
...@@ -4520,7 +4456,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'...@@ -4520,7 +4456,7 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4520 </p>4456 </p>
4521 {#header_close#}4457 {#header_close#}
4522 {#header_open|@subWithOverflow#}4458 {#header_open|@subWithOverflow#}
4523 <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &amp;T) -&gt; bool</code></pre>4459 <pre><code class="zig">@subWithOverflow(comptime T: type, a: T, b: T, result: &T) -&gt; bool</code></pre>
4524 <p>4460 <p>
4525 Performs <code>*result = a - b</code>. If overflow or underflow occurs,4461 Performs <code>*result = a - b</code>. If overflow or underflow occurs,
4526 stores the overflowed bits in <code>result</code> and returns <code>true</code>.4462 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
...@@ -4556,7 +4492,8 @@ const b: u8 = @truncate(u8, a);...@@ -4556,7 +4492,8 @@ const b: u8 = @truncate(u8, a);
4556 <p>4492 <p>
4557 Returns which kind of type something is. Possible values:4493 Returns which kind of type something is. Possible values:
4558 </p>4494 </p>
4559 <pre><code class="zig">pub const TypeId = enum {4495 {#code_begin|syntax#}
4496pub const TypeId = enum {
4560 Type,4497 Type,
4561 Void,4498 Void,
4562 Bool,4499 Bool,
...@@ -4574,7 +4511,6 @@ const b: u8 = @truncate(u8, a);...@@ -4574,7 +4511,6 @@ const b: u8 = @truncate(u8, a);
4574 ErrorUnion,4511 ErrorUnion,
4575 Error,4512 Error,
4576 Enum,4513 Enum,
4577 EnumTag,
4578 Union,4514 Union,
4579 Fn,4515 Fn,
4580 Namespace,4516 Namespace,
...@@ -4582,8 +4518,8 @@ const b: u8 = @truncate(u8, a);...@@ -4582,8 +4518,8 @@ const b: u8 = @truncate(u8, a);
4582 BoundFn,4518 BoundFn,
4583 ArgTuple,4519 ArgTuple,
4584 Opaque,4520 Opaque,
4585};</code></pre>4521};
45864522 {#code_end#}
4587 {#header_close#}4523 {#header_close#}
4588 {#header_open|@typeName#}4524 {#header_open|@typeName#}
4589 <pre><code class="zig">@typeName(T: type) -&gt; []u8</code></pre>4525 <pre><code class="zig">@typeName(T: type) -&gt; []u8</code></pre>
...@@ -4606,27 +4542,29 @@ const b: u8 = @truncate(u8, a);...@@ -4606,27 +4542,29 @@ const b: u8 = @truncate(u8, a);
4606 Zig has three build modes:4542 Zig has three build modes:
4607 </p>4543 </p>
4608 <ul>4544 <ul>
4609 <li><a href="#build-mode-debug">Debug</a> (default)</li>4545 <li>{#link|Debug#} (default)</li>
4610 <li><a href="#build-mode-release-fast">ReleaseFast</a></li>4546 <li>{#link|ReleaseFast#}</li>
4611 <li><a href="#build-mode-release-safe">ReleaseSafe</a></li>4547 <li>{#link|ReleaseSafe#}</li>
4612 </ul>4548 </ul>
4613 <p>4549 <p>
4614 To add standard build options to a <code>build.zig</code> file:4550 To add standard build options to a <code>build.zig</code> file:
4615 </p>4551 </p>
4616 <pre><code class="sh">const Builder = @import("std").build.Builder;4552 {#code_begin|syntax#}
4553const Builder = @import("std").build.Builder;
46174554
4618pub fn build(b: &amp;Builder) {4555pub fn build(b: &Builder) %void {
4619 const exe = b.addExecutable("example", "example.zig");4556 const exe = b.addExecutable("example", "example.zig");
4620 exe.setBuildMode(b.standardReleaseOptions());4557 exe.setBuildMode(b.standardReleaseOptions());
4621 b.default_step.dependOn(&amp;exe.step);4558 b.default_step.dependOn(&exe.step);
4622}</code></pre>4559}
4560 {#code_end#}
4623 <p>4561 <p>
4624 This causes these options to be available:4562 This causes these options to be available:
4625 </p>4563 </p>
4626 <pre><code class="sh"> -Drelease-safe=(bool) optimizations on and safety on4564 <pre><code class="shell"> -Drelease-safe=(bool) optimizations on and safety on
4627 -Drelease-fast=(bool) optimizations on and safety off</code></pre>4565 -Drelease-fast=(bool) optimizations on and safety off</code></pre>
4628 {#header_open|Debug#}4566 {#header_open|Debug#}
4629 <pre><code class="sh">$ zig build-exe example.zig</code></pre>4567 <pre><code class="shell">$ zig build-exe example.zig</code></pre>
4630 <ul>4568 <ul>
4631 <li>Fast compilation speed</li>4569 <li>Fast compilation speed</li>
4632 <li>Safety checks enabled</li>4570 <li>Safety checks enabled</li>
...@@ -4634,7 +4572,7 @@ pub fn build(b: &amp;Builder) {...@@ -4634,7 +4572,7 @@ pub fn build(b: &amp;Builder) {
4634 </ul>4572 </ul>
4635 {#header_close#}4573 {#header_close#}
4636 {#header_open|ReleaseFast#}4574 {#header_open|ReleaseFast#}
4637 <pre><code class="sh">$ zig build-exe example.zig --release-fast</code></pre>4575 <pre><code class="shell">$ zig build-exe example.zig --release-fast</code></pre>
4638 <ul>4576 <ul>
4639 <li>Fast runtime performance</li>4577 <li>Fast runtime performance</li>
4640 <li>Safety checks disabled</li>4578 <li>Safety checks disabled</li>
...@@ -4642,7 +4580,7 @@ pub fn build(b: &amp;Builder) {...@@ -4642,7 +4580,7 @@ pub fn build(b: &amp;Builder) {
4642 </ul>4580 </ul>
4643 {#header_close#}4581 {#header_close#}
4644 {#header_open|ReleaseSafe#}4582 {#header_open|ReleaseSafe#}
4645 <pre><code class="sh">$ zig build-exe example.zig --release-safe</code></pre>4583 <pre><code class="shell">$ zig build-exe example.zig --release-safe</code></pre>
4646 <ul>4584 <ul>
4647 <li>Medium runtime performance</li>4585 <li>Medium runtime performance</li>
4648 <li>Safety checks enabled</li>4586 <li>Safety checks enabled</li>
...@@ -4657,79 +4595,47 @@ pub fn build(b: &amp;Builder) {...@@ -4657,79 +4595,47 @@ pub fn build(b: &amp;Builder) {
4657 detected at compile-time, Zig emits an error. Most undefined behavior that4595 detected at compile-time, Zig emits an error. Most undefined behavior that
4658 cannot be detected at compile-time can be detected at runtime. In these cases,4596 cannot be detected at compile-time can be detected at runtime. In these cases,
4659 Zig has safety checks. Safety checks can be disabled on a per-block basis4597 Zig has safety checks. Safety checks can be disabled on a per-block basis
4660 with <code>@setDebugSafety</code>. The <a href="#build-mode-release-fast">ReleaseFast</a>4598 with <code>@setRuntimeSafety</code>. The {#link|ReleaseFast#}
4661 build mode disables all safety checks in order to facilitate optimizations.4599 build mode disables all safety checks in order to facilitate optimizations.
4662 </p>4600 </p>
4663 <p>4601 <p>
4664 When a safety check fails, Zig crashes with a stack trace, like this:4602 When a safety check fails, Zig crashes with a stack trace, like this:
4665 </p>4603 </p>
4666 <pre><code class="zig">test "safety check" {4604 {#code_begin|test_err|reached unreachable code#}
4605test "safety check" {
4667 unreachable;4606 unreachable;
4668}</code></pre>4607}
4669 <pre><code class="sh">$ zig test test.zig4608 {#code_end#}
4670Test 1/1 safety check...reached unreachable code
4671/home/andy/dev/zig/build/lib/zig/std/special/zigrt.zig:16:35: 0x000000000020331c in ??? (test)
4672 @import("std").debug.panic("{}", message_ptr[0...message_len]);
4673 ^
4674/home/andy/dev/zig/build/test.zig:2:5: 0x0000000000203297 in ??? (test)
4675 unreachable;
4676 ^
4677/home/andy/dev/zig/build/lib/zig/std/special/test_runner.zig:9:21: 0x0000000000214b0a in ??? (test)
4678 test_fn.func();
4679 ^
4680/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:50:21: 0x0000000000214a17 in ??? (test)
4681 return root.main();
4682 ^
4683/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:37:13: 0x00000000002148d0 in ??? (test)
4684 callMain(argc, argv, envp) catch exit(1);
4685 ^
4686/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:30:20: 0x0000000000214820 in ??? (test)
4687 callMainAndExit()
4688 ^
4689
4690Tests failed. Use the following command to reproduce the failure:
4691./test</code></pre>
4692 {#header_open|Reaching Unreachable Code#}4609 {#header_open|Reaching Unreachable Code#}
4693 <p>At compile-time:</p>4610 <p>At compile-time:</p>
4694 <pre><code class="zig">comptime {4611 {#code_begin|test_err|unable to evaluate constant expression#}
4612comptime {
4695 assert(false);4613 assert(false);
4696}4614}
4697fn assert(ok: bool) {4615fn assert(ok: bool) void {
4698 if (!ok) unreachable; // assertion failure4616 if (!ok) unreachable; // assertion failure
4699}</code></pre>4617}
4700 <pre><code class="sh">$ zig build-obj test.zig4618 {#code_end#}
4701/home/andy/dev/zig/build/test.zig:5:14: error: unable to evaluate constant expression
4702 if (!ok) unreachable; // assertion failure
4703 ^
4704/home/andy/dev/zig/build/test.zig:2:11: note: called from here
4705 assert(false);
4706 ^
4707/home/andy/dev/zig/build/test.zig:1:10: note: called from here
4708comptime {
4709 ^</code></pre>
4710 <p>At runtime crashes with the message <code>reached unreachable code</code> and a stack trace.</p>4619 <p>At runtime crashes with the message <code>reached unreachable code</code> and a stack trace.</p>
4711 {#header_close#}4620 {#header_close#}
4712 {#header_open|Index out of Bounds#}4621 {#header_open|Index out of Bounds#}
4713 <p>At compile-time:</p>4622 <p>At compile-time:</p>
4714 <pre><code class="zig">comptime {4623 {#code_begin|test_err|index 5 outside array of size 5#}
4624comptime {
4715 const array = "hello";4625 const array = "hello";
4716 const garbage = array[5];4626 const garbage = array[5];
4717}</code></pre>4627}
4718 <pre><code class="sh">$ zig build-obj test.zig4628 {#code_end#}
4719/home/andy/dev/zig/build/test.zig:3:26: error: index 5 outside array of size 5
4720 const garbage = array[5];
4721 ^</code></pre>
4722 <p>At runtime crashes with the message <code>index out of bounds</code> and a stack trace.</p>4629 <p>At runtime crashes with the message <code>index out of bounds</code> and a stack trace.</p>
4723 {#header_close#}4630 {#header_close#}
4724 {#header_open|Cast Negative Number to Unsigned Integer#}4631 {#header_open|Cast Negative Number to Unsigned Integer#}
4725 <p>At compile-time:</p>4632 <p>At compile-time:</p>
4726 <pre><code class="zig">comptime {4633 {#code_begin|test_err|attempt to cast negative value to unsigned integer#}
4634comptime {
4727 const value: i32 = -1;4635 const value: i32 = -1;
4728 const unsigned = u32(value);4636 const unsigned = u32(value);
4729}</code></pre>4637}
4730 <pre><code class="sh">$ zig build-obj test.zig test.zig:3:25: error: attempt to cast negative value to unsigned integer4638 {#code_end#}
4731 const unsigned = u32(value);
4732 ^</code></pre>
4733 <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p>4639 <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p>
4734 <p>4640 <p>
4735 If you are trying to obtain the maximum value of an unsigned integer, use <code>@maxValue(T)</code>,4641 If you are trying to obtain the maximum value of an unsigned integer, use <code>@maxValue(T)</code>,
...@@ -4738,14 +4644,12 @@ comptime {...@@ -4738,14 +4644,12 @@ comptime {
4738 {#header_close#}4644 {#header_close#}
4739 {#header_open|Cast Truncates Data#}4645 {#header_open|Cast Truncates Data#}
4740 <p>At compile-time:</p>4646 <p>At compile-time:</p>
4741 <pre><code class="zig">comptime {4647 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#}
4648comptime {
4742 const spartan_count: u16 = 300;4649 const spartan_count: u16 = 300;
4743 const byte = u8(spartan_count);4650 const byte = u8(spartan_count);
4744}</code></pre>4651}
4745 <pre><code class="sh">$ zig build-obj test.zig4652 {#code_end#}
4746test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits
4747 const byte = u8(spartan_count);
4748 ^</code></pre>
4749 <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p>4653 <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p>
4750 <p>4654 <p>
4751 If you are trying to truncate bits, use <code>@truncate(T, value)</code>,4655 If you are trying to truncate bits, use <code>@truncate(T, value)</code>,
...@@ -4767,14 +4671,12 @@ test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits...@@ -4767,14 +4671,12 @@ test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits
4767 <li><code>@divExact</code> (division)</li>4671 <li><code>@divExact</code> (division)</li>
4768 </ul>4672 </ul>
4769 <p>Example with addition at compile-time:</p>4673 <p>Example with addition at compile-time:</p>
4770 <pre><code class="zig">comptime {4674 {#code_begin|test_err|operation caused overflow#}
4675comptime {
4771 var byte: u8 = 255;4676 var byte: u8 = 255;
4772 byte += 1;4677 byte += 1;
4773}</code></pre>4678}
4774 <pre><code class="sh">$ zig build-obj test.zig4679 {#code_end#}
4775/home/andy/dev/zig/build/test.zig:3:10: error: operation caused overflow
4776 byte += 1;
4777 ^</code></pre>
4778 <p>At runtime crashes with the message <code>integer overflow</code> and a stack trace.</p>4680 <p>At runtime crashes with the message <code>integer overflow</code> and a stack trace.</p>
4779 {#header_close#}4681 {#header_close#}
4780 {#header_open|Standard Library Math Functions#}4682 {#header_open|Standard Library Math Functions#}
...@@ -4789,23 +4691,20 @@ test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits...@@ -4789,23 +4691,20 @@ test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits
4789 <li><code>@import("std").math.shl</code></li>4691 <li><code>@import("std").math.shl</code></li>
4790 </ul>4692 </ul>
4791 <p>Example of catching an overflow for addition:</p>4693 <p>Example of catching an overflow for addition:</p>
4792 <pre><code class="zig">const math = @import("std").math;4694 {#code_begin|exe_err#}
4695const math = @import("std").math;
4793const warn = @import("std").debug.warn;4696const warn = @import("std").debug.warn;
4794pub fn main() -&gt; %void {4697pub fn main() %void {
4795 var byte: u8 = 255;4698 var byte: u8 = 255;
47964699
4797 byte = if (math.add(u8, byte, 1)) |result| {4700 byte = if (math.add(u8, byte, 1)) |result| result else |err| {
4798 result
4799 } else |err| {
4800 warn("unable to add one: {}\n", @errorName(err));4701 warn("unable to add one: {}\n", @errorName(err));
4801 return err;4702 return err;
4802 };4703 };
48034704
4804 warn("result: {}\n", byte);4705 warn("result: {}\n", byte);
4805}</code></pre>4706}
4806 <pre><code class="sh">$ zig build-exe test.zig4707 {#code_end#}
4807$ ./test
4808unable to add one: Overflow</code></pre>
4809 {#header_close#}4708 {#header_close#}
4810 {#header_open|Builtin Overflow Functions#}4709 {#header_open|Builtin Overflow Functions#}
4811 <p>4710 <p>
...@@ -4821,20 +4720,19 @@ unable to add one: Overflow</code></pre>...@@ -4821,20 +4720,19 @@ unable to add one: Overflow</code></pre>
4821 <p>4720 <p>
4822 Example of <code>@addWithOverflow</code>:4721 Example of <code>@addWithOverflow</code>:
4823 </p>4722 </p>
4824 <pre><code class="zig">const warn = @import("std").debug.warn;4723 {#code_begin|exe#}
4825pub fn main() -&gt; %void {4724const warn = @import("std").debug.warn;
4725pub fn main() %void {
4826 var byte: u8 = 255;4726 var byte: u8 = 255;
48274727
4828 var result: u8 = undefined;4728 var result: u8 = undefined;
4829 if (@addWithOverflow(u8, byte, 10, &amp;result)) {4729 if (@addWithOverflow(u8, byte, 10, &result)) {
4830 warn("overflowed result: {}\n", result);4730 warn("overflowed result: {}\n", result);
4831 } else {4731 } else {
4832 warn("result: {}\n", result);4732 warn("result: {}\n", result);
4833 }4733 }
4834}</code></pre>4734}
4835 <pre><code class="sh">$ zig build-exe test.zig4735 {#code_end#}
4836$ ./test
4837overflowed result: 9</code></pre>
4838 {#header_close#}4736 {#header_close#}
4839 {#header_open|Wrapping Operations#}4737 {#header_open|Wrapping Operations#}
4840 <p>4738 <p>
...@@ -4846,7 +4744,8 @@ overflowed result: 9</code></pre>...@@ -4846,7 +4744,8 @@ overflowed result: 9</code></pre>
4846 <li><code>-%</code> (wraparound negation)</li>4744 <li><code>-%</code> (wraparound negation)</li>
4847 <li><code>*%</code> (wraparound multiplication)</li>4745 <li><code>*%</code> (wraparound multiplication)</li>
4848 </ul>4746 </ul>
4849 <pre><code class="zig">const assert = @import("std").debug.assert;4747 {#code_begin|test#}
4748const assert = @import("std").debug.assert;
48504749
4851test "wraparound addition and subtraction" {4750test "wraparound addition and subtraction" {
4852 const x: i32 = @maxValue(i32);4751 const x: i32 = @maxValue(i32);
...@@ -4854,56 +4753,49 @@ test "wraparound addition and subtraction" {...@@ -4854,56 +4753,49 @@ test "wraparound addition and subtraction" {
4854 assert(min_val == @minValue(i32));4753 assert(min_val == @minValue(i32));
4855 const max_val = min_val -% 1;4754 const max_val = min_val -% 1;
4856 assert(max_val == @maxValue(i32));4755 assert(max_val == @maxValue(i32));
4857}</code></pre>4756}
4757 {#code_end#}
4858 {#header_close#}4758 {#header_close#}
4859 {#header_close#}4759 {#header_close#}
4860 {#header_open|Exact Left Shift Overflow#}4760 {#header_open|Exact Left Shift Overflow#}
4861 <p>At compile-time:</p>4761 <p>At compile-time:</p>
4862 <pre><code class="zig">comptime {4762 {#code_begin|test_err|operation caused overflow#}
4863 const x = @shlExact(u8(0b01010101), 2);4763comptime {
4864}</code></pre>
4865 <pre><code class="sh">$ zig build-obj test.zig
4866/home/andy/dev/zig/build/test.zig:2:15: error: operation caused overflow
4867 const x = @shlExact(u8(0b01010101), 2);4764 const x = @shlExact(u8(0b01010101), 2);
4868 ^</code></pre>4765}
4766 {#code_end#}
4869 <p>At runtime crashes with the message <code>left shift overflowed bits</code> and a stack trace.</p>4767 <p>At runtime crashes with the message <code>left shift overflowed bits</code> and a stack trace.</p>
4870 {#header_close#}4768 {#header_close#}
4871 {#header_open|Exact Right Shift Overflow#}4769 {#header_open|Exact Right Shift Overflow#}
4872 <p>At compile-time:</p>4770 <p>At compile-time:</p>
4873 <pre><code class="zig">comptime {4771 {#code_begin|test_err|exact shift shifted out 1 bits#}
4874 const x = @shrExact(u8(0b10101010), 2);4772comptime {
4875}</code></pre>
4876 <pre><code class="sh">$ zig build-obj test.zig
4877/home/andy/dev/zig/build/test.zig:2:15: error: exact shift shifted out 1 bits
4878 const x = @shrExact(u8(0b10101010), 2);4773 const x = @shrExact(u8(0b10101010), 2);
4879 ^</code></pre>4774}
4775 {#code_end#}
4880 <p>At runtime crashes with the message <code>right shift overflowed bits</code> and a stack trace.</p>4776 <p>At runtime crashes with the message <code>right shift overflowed bits</code> and a stack trace.</p>
4881 {#header_close#}4777 {#header_close#}
4882 {#header_open|Division by Zero#}4778 {#header_open|Division by Zero#}
4883 <p>At compile-time:</p>4779 <p>At compile-time:</p>
4884 <pre><code class="zig">comptime {4780 {#code_begin|test_err|division by zero#}
4781comptime {
4885 const a: i32 = 1;4782 const a: i32 = 1;
4886 const b: i32 = 0;4783 const b: i32 = 0;
4887 const c = a / b;4784 const c = a / b;
4888}</code></pre>4785}
4889 <pre><code class="sh">$ zig build-obj test.zig4786 {#code_end#}
4890/home/andy/dev/zig/build/test.zig:4:17: error: division by zero is undefined
4891 const c = a / b;
4892 ^</code></pre>
4893 <p>At runtime crashes with the message <code>division by zero</code> and a stack trace.</p>4787 <p>At runtime crashes with the message <code>division by zero</code> and a stack trace.</p>
48944788
4895 {#header_close#}4789 {#header_close#}
4896 {#header_open|Remainder Division by Zero#}4790 {#header_open|Remainder Division by Zero#}
4897 <p>At compile-time:</p>4791 <p>At compile-time:</p>
4898 <pre><code class="zig">comptime {4792 {#code_begin|test_err|division by zero#}
4793comptime {
4899 const a: i32 = 10;4794 const a: i32 = 10;
4900 const b: i32 = 0;4795 const b: i32 = 0;
4901 const c = a % b;4796 const c = a % b;
4902}</code></pre>4797}
4903 <pre><code class="sh">$ zig build-obj test.zig4798 {#code_end#}
4904/home/andy/dev/zig/build/test.zig:4:17: error: division by zero is undefined
4905 const c = a % b;
4906 ^</code></pre>
4907 <p>At runtime crashes with the message <code>remainder division by zero</code> and a stack trace.</p>4799 <p>At runtime crashes with the message <code>remainder division by zero</code> and a stack trace.</p>
49084800
4909 {#header_close#}4801 {#header_close#}
...@@ -4915,20 +4807,18 @@ test "wraparound addition and subtraction" {...@@ -4915,20 +4807,18 @@ test "wraparound addition and subtraction" {
4915 {#header_close#}4807 {#header_close#}
4916 {#header_open|Attempt to Unwrap Null#}4808 {#header_open|Attempt to Unwrap Null#}
4917 <p>At compile-time:</p>4809 <p>At compile-time:</p>
4918 <pre><code class="zig">comptime {4810 {#code_begin|test_err|unable to unwrap null#}
4811comptime {
4919 const nullable_number: ?i32 = null;4812 const nullable_number: ?i32 = null;
4920 const number = ??nullable_number;4813 const number = ??nullable_number;
4921}</code></pre>4814}
4922 <pre><code class="sh">$ zig build-obj test.zig4815 {#code_end#}
4923/home/andy/dev/zig/build/test.zig:3:20: error: unable to unwrap null
4924 const number = ??nullable_number;
4925 ^</code></pre>
4926 <p>At runtime crashes with the message <code>attempt to unwrap null</code> and a stack trace.</p>4816 <p>At runtime crashes with the message <code>attempt to unwrap null</code> and a stack trace.</p>
4927 <p>One way to avoid this crash is to test for null instead of assuming non-null, with4817 <p>One way to avoid this crash is to test for null instead of assuming non-null, with
4928 the <code>if</code> expression:</p>4818 the <code>if</code> expression:</p>
4929 {#code_begin|exe|test#}4819 {#code_begin|exe|test#}
4930const warn = @import("std").debug.warn;4820const warn = @import("std").debug.warn;
4931pub fn main() {4821pub fn main() void {
4932 const nullable_number: ?i32 = null;4822 const nullable_number: ?i32 = null;
49334823
4934 if (nullable_number) |number| {4824 if (nullable_number) |number| {
...@@ -4941,26 +4831,24 @@ pub fn main() {...@@ -4941,26 +4831,24 @@ pub fn main() {
4941 {#header_close#}4831 {#header_close#}
4942 {#header_open|Attempt to Unwrap Error#}4832 {#header_open|Attempt to Unwrap Error#}
4943 <p>At compile-time:</p>4833 <p>At compile-time:</p>
4944 <pre><code class="zig">comptime {4834 {#code_begin|test_err|unable to unwrap error 'UnableToReturnNumber'#}
4945 const number = %%getNumberOrFail();4835comptime {
4836 const number = getNumberOrFail() catch unreachable;
4946}4837}
49474838
4948error UnableToReturnNumber;4839error UnableToReturnNumber;
49494840
4950fn getNumberOrFail() -&gt; %i32 {4841fn getNumberOrFail() %i32 {
4951 return error.UnableToReturnNumber;4842 return error.UnableToReturnNumber;
4952}</code></pre>4843}
4953 <pre><code class="sh">$ zig build-obj test.zig4844 {#code_end#}
4954/home/andy/dev/zig/build/test.zig:2:20: error: unable to unwrap error 'UnableToReturnNumber'
4955 const number = %%getNumberOrFail();
4956 ^</code></pre>
4957 <p>At runtime crashes with the message <code>attempt to unwrap error: ErrorCode</code> and a stack trace.</p>4845 <p>At runtime crashes with the message <code>attempt to unwrap error: ErrorCode</code> and a stack trace.</p>
4958 <p>One way to avoid this crash is to test for an error instead of assuming a successful result, with4846 <p>One way to avoid this crash is to test for an error instead of assuming a successful result, with
4959 the <code>if</code> expression:</p>4847 the <code>if</code> expression:</p>
4960 {#code_begin|exe|test#}4848 {#code_begin|exe#}
4961const warn = @import("std").debug.warn;4849const warn = @import("std").debug.warn;
49624850
4963pub fn main() {4851pub fn main() void {
4964 const result = getNumberOrFail();4852 const result = getNumberOrFail();
49654853
4966 if (result) |number| {4854 if (result) |number| {
...@@ -4972,23 +4860,21 @@ pub fn main() {...@@ -4972,23 +4860,21 @@ pub fn main() {
49724860
4973error UnableToReturnNumber;4861error UnableToReturnNumber;
49744862
4975fn getNumberOrFail() -> %i32 {4863fn getNumberOrFail() %i32 {
4976 return error.UnableToReturnNumber;4864 return error.UnableToReturnNumber;
4977}4865}
4978 {#code_end#}4866 {#code_end#}
4979 {#header_close#}4867 {#header_close#}
4980 {#header_open|Invalid Error Code#}4868 {#header_open|Invalid Error Code#}
4981 <p>At compile-time:</p>4869 <p>At compile-time:</p>
4982 <pre><code class="zig">error AnError;4870 {#code_begin|test_err|integer value 11 represents no error#}
4871error AnError;
4983comptime {4872comptime {
4984 const err = error.AnError;4873 const err = error.AnError;
4985 const number = u32(err) + 10;4874 const number = u32(err) + 10;
4986 const invalid_err = error(number);4875 const invalid_err = error(number);
4987}</code></pre>4876}
4988 <pre><code class="sh">$ zig build-obj test.zig4877 {#code_end#}
4989/home/andy/dev/zig/build/test.zig:5:30: error: integer value 11 represents no error
4990 const invalid_err = error(number);
4991 ^</code></pre>
4992 <p>At runtime crashes with the message <code>invalid error code</code> and a stack trace.</p>4878 <p>At runtime crashes with the message <code>invalid error code</code> and a stack trace.</p>
4993 {#header_close#}4879 {#header_close#}
4994 {#header_open|Invalid Enum Cast#}4880 {#header_open|Invalid Enum Cast#}
...@@ -5020,17 +4906,26 @@ comptime {...@@ -5020,17 +4906,26 @@ comptime {
5020 which the compiler makes available to every Zig source file. It contains4906 which the compiler makes available to every Zig source file. It contains
5021 compile-time constants such as the current target, endianness, and release mode.4907 compile-time constants such as the current target, endianness, and release mode.
5022 </p>4908 </p>
5023 <pre><code class="zig">const builtin = @import("builtin");4909 {#code_begin|syntax#}
5024const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';</code></pre>4910const builtin = @import("builtin");
4911const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';
4912 {#code_end#}
5025 <p>4913 <p>
5026 Example of what is imported with <code>@import("builtin")</code>:4914 Example of what is imported with <code>@import("builtin")</code>:
5027 </p>4915 </p>
5028 <pre><code class="zig">pub const Os = enum {4916 {#code_begin|syntax#}
4917pub const StackTrace = struct {
4918 index: usize,
4919 instruction_addresses: []usize,
4920};
4921
4922pub const Os = enum {
5029 freestanding,4923 freestanding,
4924 ananas,
5030 cloudabi,4925 cloudabi,
5031 darwin,
5032 dragonfly,4926 dragonfly,
5033 freebsd,4927 freebsd,
4928 fuchsia,
5034 ios,4929 ios,
5035 kfreebsd,4930 kfreebsd,
5036 linux,4931 linux,
...@@ -5055,12 +4950,15 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';</code></p...@@ -5055,12 +4950,15 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';</code></p
5055 tvos,4950 tvos,
5056 watchos,4951 watchos,
5057 mesa3d,4952 mesa3d,
4953 contiki,
4954 zen,
5058};4955};
50594956
5060pub const Arch = enum {4957pub const Arch = enum {
5061 armv8_2a,4958 armv8_2a,
5062 armv8_1a,4959 armv8_1a,
5063 armv8,4960 armv8,
4961 armv8r,
5064 armv8m_baseline,4962 armv8m_baseline,
5065 armv8m_mainline,4963 armv8m_mainline,
5066 armv7,4964 armv7,
...@@ -5068,6 +4966,7 @@ pub const Arch = enum {...@@ -5068,6 +4966,7 @@ pub const Arch = enum {
5068 armv7m,4966 armv7m,
5069 armv7s,4967 armv7s,
5070 armv7k,4968 armv7k,
4969 armv7ve,
5071 armv6,4970 armv6,
5072 armv6m,4971 armv6m,
5073 armv6k,4972 armv6k,
...@@ -5087,16 +4986,20 @@ pub const Arch = enum {...@@ -5087,16 +4986,20 @@ pub const Arch = enum {
5087 mips64,4986 mips64,
5088 mips64el,4987 mips64el,
5089 msp430,4988 msp430,
4989 nios2,
5090 powerpc,4990 powerpc,
5091 powerpc64,4991 powerpc64,
5092 powerpc64le,4992 powerpc64le,
5093 r600,4993 r600,
5094 amdgcn,4994 amdgcn,
4995 riscv32,
4996 riscv64,
5095 sparc,4997 sparc,
5096 sparcv9,4998 sparcv9,
5097 sparcel,4999 sparcel,
5098 s390x,5000 s390x,
5099 tce,5001 tce,
5002 tcele,
5100 thumb,5003 thumb,
5101 thumbeb,5004 thumbeb,
5102 i386,5005 i386,
...@@ -5122,7 +5025,9 @@ pub const Arch = enum {...@@ -5122,7 +5025,9 @@ pub const Arch = enum {
5122 renderscript32,5025 renderscript32,
5123 renderscript64,5026 renderscript64,
5124};5027};
5028
5125pub const Environ = enum {5029pub const Environ = enum {
5030 unknown,
5126 gnu,5031 gnu,
5127 gnuabi64,5032 gnuabi64,
5128 gnueabi,5033 gnueabi,
...@@ -5140,6 +5045,7 @@ pub const Environ = enum {...@@ -5140,6 +5045,7 @@ pub const Environ = enum {
5140 cygnus,5045 cygnus,
5141 amdopencl,5046 amdopencl,
5142 coreclr,5047 coreclr,
5048 opencl,
5143};5049};
51445050
5145pub const ObjectFormat = enum {5051pub const ObjectFormat = enum {
...@@ -5147,6 +5053,7 @@ pub const ObjectFormat = enum {...@@ -5147,6 +5053,7 @@ pub const ObjectFormat = enum {
5147 coff,5053 coff,
5148 elf,5054 elf,
5149 macho,5055 macho,
5056 wasm,
5150};5057};
51515058
5152pub const GlobalLinkage = enum {5059pub const GlobalLinkage = enum {
...@@ -5171,15 +5078,53 @@ pub const Mode = enum {...@@ -5171,15 +5078,53 @@ pub const Mode = enum {
5171 ReleaseFast,5078 ReleaseFast,
5172};5079};
51735080
5174pub const is_big_endian = false;5081pub const TypeId = enum {
5082 Type,
5083 Void,
5084 Bool,
5085 NoReturn,
5086 Int,
5087 Float,
5088 Pointer,
5089 Array,
5090 Struct,
5091 FloatLiteral,
5092 IntLiteral,
5093 UndefinedLiteral,
5094 NullLiteral,
5095 Nullable,
5096 ErrorUnion,
5097 Error,
5098 Enum,
5099 Union,
5100 Fn,
5101 Namespace,
5102 Block,
5103 BoundFn,
5104 ArgTuple,
5105 Opaque,
5106};
5107
5108pub const FloatMode = enum {
5109 Optimized,
5110 Strict,
5111};
5112
5113pub const Endian = enum {
5114 Big,
5115 Little,
5116};
5117
5118pub const endian = Endian.Little;
5175pub const is_test = false;5119pub const is_test = false;
5176pub const os = Os.linux;5120pub const os = Os.linux;
5177pub const arch = Arch.x86_64;5121pub const arch = Arch.x86_64;
5178pub const environ = Environ.gnu;5122pub const environ = Environ.gnu;
5179pub const object_format = ObjectFormat.elf;5123pub const object_format = ObjectFormat.elf;
5180pub const mode = Mode.ReleaseFast;5124pub const mode = Mode.Debug;
5181pub const link_libs = [][]const u8 {5125pub const link_libc = false;
5182};</code></pre>5126pub const have_error_return_tracing = true;
5127 {#code_end#}
5183 {#see_also|Build Mode#}5128 {#see_also|Build Mode#}
5184 {#header_close#}5129 {#header_close#}
5185 {#header_open|Root Source File#}5130 {#header_open|Root Source File#}
...@@ -5230,16 +5175,19 @@ pub const link_libs = [][]const u8 {...@@ -5230,16 +5175,19 @@ pub const link_libs = [][]const u8 {
5230 {#see_also|Primitive Types#}5175 {#see_also|Primitive Types#}
5231 {#header_close#}5176 {#header_close#}
5232 {#header_open|C String Literals#}5177 {#header_open|C String Literals#}
5233 <pre><code class="zig">extern fn puts(&amp;const u8);5178 {#code_begin|exe#}
5179 {#link_libc#}
5180extern fn puts(&const u8) void;
52345181
5235pub fn main() -&gt; %void {5182pub fn main() void {
5236 puts(c"this has a null terminator");5183 puts(c"this has a null terminator");
5237 puts(5184 puts(
5238 c\\and so5185 c\\and so
5239 c\\does this5186 c\\does this
5240 c\\multiline C string literal5187 c\\multiline C string literal
5241 );5188 );
5242}</code></pre>5189}
5190 {#code_end#}
5243 {#see_also|String Literals#}5191 {#see_also|String Literals#}
5244 {#header_close#}5192 {#header_close#}
5245 {#header_open|Import from C Header File#}5193 {#header_open|Import from C Header File#}
...@@ -5247,40 +5195,49 @@ pub fn main() -&gt; %void {...@@ -5247,40 +5195,49 @@ pub fn main() -&gt; %void {
5247 The <code>@cImport</code> builtin function can be used5195 The <code>@cImport</code> builtin function can be used
5248 to directly import symbols from .h files:5196 to directly import symbols from .h files:
5249 </p>5197 </p>
5250 <pre><code class="zig">const c = @cImport(@cInclude("stdio.h"));5198 {#code_begin|exe#}
5251pub fn main() -&gt; %void {5199 {#link_libc#}
5252 c.printf("hello\n");5200const c = @cImport({
5253}</code></pre>5201 // See https://github.com/zig-lang/zig/issues/515
5202 @cDefine("_NO_CRT_STDIO_INLINE", "1");
5203 @cInclude("stdio.h");
5204});
5205pub fn main() void {
5206 _ = c.printf(c"hello\n");
5207}
5208 {#code_end#}
5254 <p>5209 <p>
5255 The <code>@cImport</code> function takes an expression as a parameter.5210 The <code>@cImport</code> function takes an expression as a parameter.
5256 This expression is evaluated at compile-time and is used to control5211 This expression is evaluated at compile-time and is used to control
5257 preprocessor directives and include multiple .h files:5212 preprocessor directives and include multiple .h files:
5258 </p>5213 </p>
5259 <pre><code class="zig">const builtin = @import("builtin");5214 {#code_begin|syntax#}
5215const builtin = @import("builtin");
52605216
5261const c = @cImport({5217const c = @cImport({
5262 @cDefine("NDEBUG", builtin.mode == builtin.Mode.ReleaseFast);5218 @cDefine("NDEBUG", builtin.mode == builtin.Mode.ReleaseFast);
5263 if (something) {5219 if (something) {
5264 @cDefine("_GNU_SOURCE", {});5220 @cDefine("_GNU_SOURCE", {});
5265 }5221 }
5266 @cInclude("stdlib.h")5222 @cInclude("stdlib.h");
5267 if (something) {5223 if (something) {
5268 @cUndef("_GNU_SOURCE");5224 @cUndef("_GNU_SOURCE");
5269 }5225 }
5270 @cInclude("soundio.h");5226 @cInclude("soundio.h");
5271});</code></pre>5227});
5228 {#code_end#}
5272 {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#}5229 {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#}
5273 {#header_close#}5230 {#header_close#}
5274 {#header_open|Mixing Object Files#}5231 {#header_open|Mixing Object Files#}
5275 <p>5232 <p>
5276 You can mix Zig object files with any other object files that respect the C ABI. Example:5233 You can mix Zig object files with any other object files that respect the C ABI. Example:
5277 </p>5234 </p>
5278 {#header_close#}5235 <p class="file">base64.zig</p>
5279 {#header_open|base64.zig#}5236 {#code_begin|syntax#}
5280 <pre><code class="zig">const base64 = @import("std").base64;5237const base64 = @import("std").base64;
52815238
5282export fn decode_base_64(dest_ptr: &amp;u8, dest_len: usize,5239export fn decode_base_64(dest_ptr: &u8, dest_len: usize,
5283 source_ptr: &amp;const u8, source_len: usize) -&gt; usize5240 source_ptr: &const u8, source_len: usize) usize
5284{5241{
5285 const src = source_ptr[0..source_len];5242 const src = source_ptr[0..source_len];
5286 const dest = dest_ptr[0..dest_len];5243 const dest = dest_ptr[0..dest_len];
...@@ -5289,9 +5246,9 @@ export fn decode_base_64(dest_ptr: &amp;u8, dest_len: usize,...@@ -5289,9 +5246,9 @@ export fn decode_base_64(dest_ptr: &amp;u8, dest_len: usize,
5289 base64_decoder.decode(dest[0..decoded_size], src);5246 base64_decoder.decode(dest[0..decoded_size], src);
5290 return decoded_size;5247 return decoded_size;
5291}5248}
5292</code></pre>5249 {#code_end#}
5293{{teheader_open:st.c}}5250 <p class="file">test.c</p>
5294 <pre><code class="c">// This header is generated by zig from base64.zig5251 <pre><code class="cpp">// This header is generated by zig from base64.zig
5295#include "base64.h"5252#include "base64.h"
52965253
5297#include &lt;string.h&gt;5254#include &lt;string.h&gt;
...@@ -5307,11 +5264,11 @@ int main(int argc, char **argv) {...@@ -5307,11 +5264,11 @@ int main(int argc, char **argv) {
53075264
5308 return 0;5265 return 0;
5309}</code></pre>5266}</code></pre>
5310 {#header_close#}5267 <p class="file">build.zig</p>
5311 {#header_open|build.zig#}5268 {#code_begin|syntax#}
5312 <pre><code class="zig">const Builder = @import("std").build.Builder;5269const Builder = @import("std").build.Builder;
53135270
5314pub fn build(b: &amp;Builder) {5271pub fn build(b: &Builder) %void {
5315 const obj = b.addObject("base64", "base64.zig");5272 const obj = b.addObject("base64", "base64.zig");
53165273
5317 const exe = b.addCExecutable("test");5274 const exe = b.addCExecutable("test");
...@@ -5322,11 +5279,12 @@ pub fn build(b: &amp;Builder) {...@@ -5322,11 +5279,12 @@ pub fn build(b: &amp;Builder) {
5322 exe.addObject(obj);5279 exe.addObject(obj);
5323 exe.setOutputPath(".");5280 exe.setOutputPath(".");
53245281
5325 b.default_step.dependOn(&amp;exe.step);5282 b.default_step.dependOn(&exe.step);
5326}</code></pre>5283}
5284 {#code_end#}
5327 {#header_close#}5285 {#header_close#}
5328 {#header_open|Terminal#}5286 {#header_open|Terminal#}
5329 <pre><code class="sh">$ zig build5287 <pre><code class="shell">$ zig build
5330$ ./test5288$ ./test
5331all your base are belong to us</code></pre>5289all your base are belong to us</code></pre>
5332 {#see_also|Targets|Zig Build System#}5290 {#see_also|Targets|Zig Build System#}
...@@ -5338,11 +5296,12 @@ all your base are belong to us</code></pre>...@@ -5338,11 +5296,12 @@ all your base are belong to us</code></pre>
5338 what it looks like to execute <code>zig targets</code> on a Linux x86_645296 what it looks like to execute <code>zig targets</code> on a Linux x86_64
5339 computer:5297 computer:
5340 </p>5298 </p>
5341 <pre><code class="sh">$ zig targets5299 <pre><code class="shell">$ zig targets
5342Architectures:5300Architectures:
5343 armv8_2a5301 armv8_2a
5344 armv8_1a5302 armv8_1a
5345 armv85303 armv8
5304 armv8r
5346 armv8m_baseline5305 armv8m_baseline
5347 armv8m_mainline5306 armv8m_mainline
5348 armv75307 armv7
...@@ -5350,6 +5309,7 @@ Architectures:...@@ -5350,6 +5309,7 @@ Architectures:
5350 armv7m5309 armv7m
5351 armv7s5310 armv7s
5352 armv7k5311 armv7k
5312 armv7ve
5353 armv65313 armv6
5354 armv6m5314 armv6m
5355 armv6k5315 armv6k
...@@ -5369,16 +5329,20 @@ Architectures:...@@ -5369,16 +5329,20 @@ Architectures:
5369 mips645329 mips64
5370 mips64el5330 mips64el
5371 msp4305331 msp430
5332 nios2
5372 powerpc5333 powerpc
5373 powerpc645334 powerpc64
5374 powerpc64le5335 powerpc64le
5375 r6005336 r600
5376 amdgcn5337 amdgcn
5338 riscv32
5339 riscv64
5377 sparc5340 sparc
5378 sparcv95341 sparcv9
5379 sparcel5342 sparcel
5380 s390x5343 s390x
5381 tce5344 tce
5345 tcele
5382 thumb5346 thumb
5383 thumbeb5347 thumbeb
5384 i3865348 i386
...@@ -5392,6 +5356,7 @@ Architectures:...@@ -5392,6 +5356,7 @@ Architectures:
5392 amdil645356 amdil64
5393 hsail5357 hsail
5394 hsail645358 hsail64
5359 spir
5395 spir645360 spir64
5396 kalimbav35361 kalimbav3
5397 kalimbav45362 kalimbav4
...@@ -5405,10 +5370,11 @@ Architectures:...@@ -5405,10 +5370,11 @@ Architectures:
54055370
5406Operating Systems:5371Operating Systems:
5407 freestanding5372 freestanding
5373 ananas
5408 cloudabi5374 cloudabi
5409 darwin
5410 dragonfly5375 dragonfly
5411 freebsd5376 freebsd
5377 fuchsia
5412 ios5378 ios
5413 kfreebsd5379 kfreebsd
5414 linux (native)5380 linux (native)
...@@ -5433,8 +5399,11 @@ Operating Systems:...@@ -5433,8 +5399,11 @@ Operating Systems:
5433 tvos5399 tvos
5434 watchos5400 watchos
5435 mesa3d5401 mesa3d
5402 contiki
5403 zen
54365404
5437Environments:5405Environments:
5406 unknown
5438 gnu (native)5407 gnu (native)
5439 gnuabi645408 gnuabi64
5440 gnueabi5409 gnueabi
...@@ -5451,7 +5420,8 @@ Environments:...@@ -5451,7 +5420,8 @@ Environments:
5451 itanium5420 itanium
5452 cygnus5421 cygnus
5453 amdopencl5422 amdopencl
5454 coreclr</code></pre>5423 coreclr
5424 opencl</code></pre>
5455 <p>5425 <p>
5456 The Zig Standard Library (<code>@import("std")</code>) has architecture, environment, and operating sytsem5426 The Zig Standard Library (<code>@import("std")</code>) has architecture, environment, and operating sytsem
5457 abstractions, and thus takes additional work to support more platforms. It currently supports5427 abstractions, and thus takes additional work to support more platforms. It currently supports
...@@ -5518,7 +5488,8 @@ coding style....@@ -5518,7 +5488,8 @@ coding style.
5518 </p>5488 </p>
5519 {#header_close#}5489 {#header_close#}
5520 {#header_open|Examples#}5490 {#header_open|Examples#}
5521 <pre><code class="zig">const namespace_name = @import("dir_name/file_name.zig");5491 {#code_begin|syntax#}
5492const namespace_name = @import("dir_name/file_name.zig");
5522var global_var: i32 = undefined;5493var global_var: i32 = undefined;
5523const const_name = 42;5494const const_name = 42;
5524const primitive_type_alias = f32;5495const primitive_type_alias = f32;
...@@ -5527,7 +5498,7 @@ const string_alias = []u8;...@@ -5527,7 +5498,7 @@ const string_alias = []u8;
5527const StructName = struct {};5498const StructName = struct {};
5528const StructAlias = StructName;5499const StructAlias = StructName;
55295500
5530fn functionName(param_name: TypeName) {5501fn functionName(param_name: TypeName) void {
5531 var functionPointer = functionName;5502 var functionPointer = functionName;
5532 functionPointer();5503 functionPointer();
5533 functionPointer = otherFunction;5504 functionPointer = otherFunction;
...@@ -5535,34 +5506,35 @@ fn functionName(param_name: TypeName) {...@@ -5535,34 +5506,35 @@ fn functionName(param_name: TypeName) {
5535}5506}
5536const functionAlias = functionName;5507const functionAlias = functionName;
55375508
5538fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) -&gt; type {5509fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type {
5539 return List(ChildType, fixed_size);5510 return List(ChildType, fixed_size);
5540}5511}
55415512
5542fn ShortList(comptime T: type, comptime n: usize) -&gt; type {5513fn ShortList(comptime T: type, comptime n: usize) type {
5543 struct {5514 return struct {
5544 field_name: [n]T,5515 field_name: [n]T,
5545 fn methodName() {}5516 fn methodName() void {}
5546 }5517 };
5547}5518}
55485519
5549// The word XML loses its casing when used in Zig identifiers.5520// The word XML loses its casing when used in Zig identifiers.
5550const xml_document =5521const xml_document =
5551 \\&lt;?xml version="1.0" encoding="UTF-8"?&gt;5522 \\<?xml version="1.0" encoding="UTF-8"?>
5552 \\&lt;document&gt;5523 \\<document>
5553 \\&lt;/document&gt;5524 \\</document>
5554;5525;
5555const XmlParser = struct {};5526const XmlParser = struct {};
55565527
5557// The initials BE (Big Endian) are just another word in Zig identifier names.5528// The initials BE (Big Endian) are just another word in Zig identifier names.
5558fn readU32Be() -&gt; u32 {}</code></pre>5529fn readU32Be() u32 {}
5530 {#code_end#}
5559 <p>5531 <p>
5560 See the Zig Standard Library for more examples.5532 See the Zig Standard Library for more examples.
5561 </p>5533 </p>
5562 {#header_close#}5534 {#header_close#}
5563 {#header_close#}5535 {#header_close#}
5564 {#header_open|Grammar#}5536 {#header_open|Grammar#}
5565 <pre><code>Root = many(TopLevelItem) EOF5537 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF
55665538
5567TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl5539TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl
55685540
...@@ -5586,7 +5558,7 @@ UseDecl = "use" Expression ";"...@@ -5586,7 +5558,7 @@ UseDecl = "use" Expression ";"
55865558
5587ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"5559ExternDecl = "extern" option(String) (FnProto | VariableDeclaration) ";"
55885560
5589FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)5561FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") TypeExpr
55905562
5591FnDef = option("inline" | "export") FnProto Block5563FnDef = option("inline" | "export") FnProto Block
55925564
...@@ -5646,7 +5618,7 @@ TryExpression = "try" Expression...@@ -5646,7 +5618,7 @@ TryExpression = "try" Expression
56465618
5647BreakExpression = "break" option(":" Symbol) option(Expression)5619BreakExpression = "break" option(":" Symbol) option(Expression)
56485620
5649Defer(body) = option("%") "defer" body5621Defer(body) = ("defer" | "deferror") body
56505622
5651IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))5623IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
56525624
...@@ -5733,8 +5705,142 @@ ContainerDecl = option("extern" | "packed")...@@ -5733,8 +5705,142 @@ ContainerDecl = option("extern" | "packed")
5733 <p>TODO: document changes from a31b23c46ba2a8c28df01adc1aa0b4d878b9a5cf (compile time reflection additions)</p>5705 <p>TODO: document changes from a31b23c46ba2a8c28df01adc1aa0b4d878b9a5cf (compile time reflection additions)</p>
5734 {#header_close#}5706 {#header_close#}
5735 </div>5707 </div>
5736 <script src="highlight/highlight.pack.js"></script>5708 <script>
5737 <script>hljs.initHighlightingOnLoad();</script>5709/*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */
5710!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset<r[0].offset?e:r:"start"===r[0].event?e:r:e.length?e:r}function o(e){function r(e){return" "+e.nodeName+'="'+n(e.value).replace('"',"&quot;")+'"'}s+="<"+t(e)+E.map.call(e.attributes,r).join("")+">"}function u(e){s+="</"+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='<span class="'+a,o=t?"":C;return i+=e+'">',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"<unnamed>")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?"<br>":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="</span>",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("cpp",function(t){var e={cN:"keyword",b:"\\b[a-z\\d_]*_t\\b"},r={cN:"string",v:[{b:'(u8?|U)?L?"',e:'"',i:"\\n",c:[t.BE]},{b:'(u8?|U)?R"',e:'"',c:[t.BE]},{b:"'\\\\?.",e:"'",i:"."}]},s={cN:"number",v:[{b:"\\b(0b[01']+)"},{b:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{b:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],r:0},i={cN:"meta",b:/#\s*[a-z]+\b/,e:/$/,k:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},c:[{b:/\\\n/,r:0},t.inherit(r,{cN:"meta-string"}),{cN:"meta-string",b:/<[^\n>]*>/,e:/$/,i:"\\n"},t.CLCM,t.CBCM]},a=t.IR+"\\s*\\(",c={keyword:"int float while private char catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignof constexpr decltype noexcept static_assert thread_local restrict _Bool complex _Complex _Imaginary atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and or not",built_in:"std string cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap array shared_ptr abort abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr",literal:"true false nullptr NULL"},n=[e,t.CLCM,t.CBCM,s,r];return{aliases:["c","cc","h","c++","h++","hpp"],k:c,i:"</",c:n.concat([i,{b:"\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",e:">",k:c,c:["self",e]},{b:t.IR+"::",k:c},{v:[{b:/=/,e:/;/},{b:/\(/,e:/\)/},{bK:"new throw return else",e:/;/}],k:c,c:n.concat([{b:/\(/,e:/\)/,k:c,c:n.concat(["self"]),r:0}]),r:0},{cN:"function",b:"("+t.IR+"[\\*&\\s]+)+"+a,rB:!0,e:/[{;=]/,eE:!0,k:c,i:/[^\w\s\*&]/,c:[{b:a,rB:!0,c:[t.TM],r:0},{cN:"params",b:/\(/,e:/\)/,k:c,r:0,c:[t.CLCM,t.CBCM,r,s,e]},t.CLCM,t.CBCM,i]},{cN:"class",bK:"class struct",e:/[{;:]/,c:[{b:/</,e:/>/,c:["self"]},t.TM]}]),exports:{preprocessor:i,strings:r,k:c}}});hljs.registerLanguage("llvm",function(e){var n="([-a-zA-Z$._][\\w\\-$.]*)";return{k:"begin end true false declare define global constant private linker_private internal available_externally linkonce linkonce_odr weak weak_odr appending dllimport dllexport common default hidden protected extern_weak external thread_local zeroinitializer undef null to tail target triple datalayout volatile nuw nsw nnan ninf nsz arcp fast exact inbounds align addrspace section alias module asm sideeffect gc dbg linker_private_weak attributes blockaddress initialexec localdynamic localexec prefix unnamed_addr ccc fastcc coldcc x86_stdcallcc x86_fastcallcc arm_apcscc arm_aapcscc arm_aapcs_vfpcc ptx_device ptx_kernel intel_ocl_bicc msp430_intrcc spir_func spir_kernel x86_64_sysvcc x86_64_win64cc x86_thiscallcc cc c signext zeroext inreg sret nounwind noreturn noalias nocapture byval nest readnone readonly inlinehint noinline alwaysinline optsize ssp sspreq noredzone noimplicitfloat naked builtin cold nobuiltin noduplicate nonlazybind optnone returns_twice sanitize_address sanitize_memory sanitize_thread sspstrong uwtable returned type opaque eq ne slt sgt sle sge ult ugt ule uge oeq one olt ogt ole oge ord uno ueq une x acq_rel acquire alignstack atomic catch cleanup filter inteldialect max min monotonic nand personality release seq_cst singlethread umax umin unordered xchg add fadd sub fsub mul fmul udiv sdiv fdiv urem srem frem shl lshr ashr and or xor icmp fcmp phi call trunc zext sext fptrunc fpext uitofp sitofp fptoui fptosi inttoptr ptrtoint bitcast addrspacecast select va_arg ret br switch invoke unwind unreachable indirectbr landingpad resume malloc alloca free load store getelementptr extractelement insertelement shufflevector getresult extractvalue insertvalue atomicrmw cmpxchg fence argmemonly double",c:[{cN:"keyword",b:"i\\d+"},e.C(";","\\n",{r:0}),e.QSM,{cN:"string",v:[{b:'"',e:'[^\\\\]"'}],r:0},{cN:"title",v:[{b:"@"+n},{b:"@\\d+"},{b:"!"+n},{b:"!\\d+"+n}]},{cN:"symbol",v:[{b:"%"+n},{b:"%\\d+"},{b:"#\\d+"}]},{cN:"number",v:[{b:"0[xX][a-fA-F0-9]+"},{b:"-?\\d+(?:[.]\\d+)?(?:[eE][-+]?\\d+(?:[.]\\d+)?)?"}],r:0}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("shell",function(s){return{aliases:["console"],c:[{cN:"meta",b:"^\\s{0,3}[\\w\\d\\[\\]()@-]*[>%$#]",starts:{e:"$",sL:"bash"}}]}});
5711 </script>
5712 <script>
5713hljs.registerLanguage("zig", function(t) {
5714 var e = {
5715 cN: "keyword",
5716 b: "\\b[a-z\\d_]*_t\\b"
5717 },
5718 r = {
5719 cN: "string",
5720 v: [{
5721 b: '(u8?|U)?L?"',
5722 e: '"',
5723 i: "\\n",
5724 c: [t.BE]
5725 }, {
5726 b: '(u8?|U)?R"',
5727 e: '"',
5728 c: [t.BE]
5729 }, {
5730 b: "'\\\\?.",
5731 e: "'",
5732 i: "."
5733 }]
5734 },
5735 s = {
5736 cN: "number",
5737 v: [{
5738 b: "\\b(0b[01']+)"
5739 }, {
5740 b: "(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"
5741 }, {
5742 b: "(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"
5743 }],
5744 r: 0
5745 },
5746 i = {
5747 cN: "meta",
5748 b: /#\s*[a-z]+\b/,
5749 e: /$/,
5750 k: {
5751 "meta-keyword": "zzzzzzdisable"
5752 },
5753 c: [{
5754 b: /\\\n/,
5755 r: 0
5756 }, t.inherit(r, {
5757 cN: "meta-string"
5758 }), {
5759 cN: "meta-string",
5760 b: /<[^\n>]*>/,
5761 e: /$/,
5762 i: "\\n"
5763 }, t.CLCM, t.CBCM]
5764 },
5765 a = t.IR + "\\s*\\(",
5766 c = {
5767 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong",
5768 built_in: "breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchg fence divExact truncate",
5769 literal: "true false null undefined"
5770 },
5771 n = [e, t.CLCM, t.CBCM, s, r];
5772 return {
5773 aliases: ["c", "cc", "h", "c++", "h++", "hpp"],
5774 k: c,
5775 i: "</",
5776 c: n.concat([i, {
5777 b: "\\b(deque|list|queue|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",
5778 e: ">",
5779 k: c,
5780 c: ["self", e]
5781 }, {
5782 b: t.IR + "::",
5783 k: c
5784 }, {
5785 v: [{
5786 b: /=/,
5787 e: /;/
5788 }, {
5789 b: /\(/,
5790 e: /\)/
5791 }, {
5792 bK: "new throw return else",
5793 e: /;/
5794 }],
5795 k: c,
5796 c: n.concat([{
5797 b: /\(/,
5798 e: /\)/,
5799 k: c,
5800 c: n.concat(["self"]),
5801 r: 0
5802 }]),
5803 r: 0
5804 }, {
5805 cN: "function",
5806 b: "(" + t.IR + "[\\*&\\s]+)+" + a,
5807 rB: !0,
5808 e: /[{;=]/,
5809 eE: !0,
5810 k: c,
5811 i: /[^\w\s\*&]/,
5812 c: [{
5813 b: a,
5814 rB: !0,
5815 c: [t.TM],
5816 r: 0
5817 }, {
5818 cN: "params",
5819 b: /\(/,
5820 e: /\)/,
5821 k: c,
5822 r: 0,
5823 c: [t.CLCM, t.CBCM, r, s, e]
5824 }, t.CLCM, t.CBCM, i]
5825 }, {
5826 cN: "class",
5827 bK: "class struct",
5828 e: /[{;:]/,
5829 c: [{
5830 b: /</,
5831 e: />/,
5832 c: ["self"]
5833 }, t.TM]
5834 }]),
5835 exports: {
5836 preprocessor: i,
5837 strings: r,
5838 k: c
5839 }
5840 }
5841});
5842 hljs.initHighlightingOnLoad();
5843 </script>
5738 </body>5844 </body>
5739</html>5845</html>
57405846
example/cat/main.zig+4-4
...@@ -5,7 +5,7 @@ const os = std.os;...@@ -5,7 +5,7 @@ const os = std.os;
5const warn = std.debug.warn;5const warn = std.debug.warn;
6const allocator = std.debug.global_allocator;6const allocator = std.debug.global_allocator;
77
8pub fn main() -> %void {8pub fn main() %void {
9 var args_it = os.args();9 var args_it = os.args();
10 const exe = try unwrapArg(??args_it.next(allocator));10 const exe = try unwrapArg(??args_it.next(allocator));
11 var catted_anything = false;11 var catted_anything = false;
...@@ -36,12 +36,12 @@ pub fn main() -> %void {...@@ -36,12 +36,12 @@ pub fn main() -> %void {
36 }36 }
37}37}
3838
39fn usage(exe: []const u8) -> %void {39fn usage(exe: []const u8) %void {
40 warn("Usage: {} [FILE]...\n", exe);40 warn("Usage: {} [FILE]...\n", exe);
41 return error.Invalid;41 return error.Invalid;
42}42}
4343
44fn cat_file(stdout: &io.File, file: &io.File) -> %void {44fn cat_file(stdout: &io.File, file: &io.File) %void {
45 var buf: [1024 * 4]u8 = undefined;45 var buf: [1024 * 4]u8 = undefined;
4646
47 while (true) {47 while (true) {
...@@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {...@@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
61 }61 }
62}62}
6363
64fn unwrapArg(arg: %[]u8) -> %[]u8 {64fn unwrapArg(arg: %[]u8) %[]u8 {
65 return arg catch |err| {65 return arg catch |err| {
66 warn("Unable to parse command line: {}\n", err);66 warn("Unable to parse command line: {}\n", err);
67 return err;67 return err;
example/guess_number/main.zig+1-1
...@@ -5,7 +5,7 @@ const fmt = std.fmt;...@@ -5,7 +5,7 @@ const fmt = std.fmt;
5const Rand = std.rand.Rand;5const Rand = std.rand.Rand;
6const os = std.os;6const os = std.os;
77
8pub fn main() -> %void {8pub fn main() %void {
9 var stdout_file = try io.getStdOut();9 var stdout_file = try io.getStdOut();
10 var stdout_file_stream = io.FileOutStream.init(&stdout_file);10 var stdout_file_stream = io.FileOutStream.init(&stdout_file);
11 const stdout = &stdout_file_stream.stream;11 const stdout = &stdout_file_stream.stream;
example/hello_world/hello.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const std = @import("std");1const std = @import("std");
22
3pub fn main() -> %void {3pub fn main() %void {
4 // If this program is run without stdout attached, exit with an error.4 // If this program is run without stdout attached, exit with an error.
5 var stdout_file = try std.io.getStdOut();5 var stdout_file = try std.io.getStdOut();
6 // If this program encounters pipe failure when printing to stdout, exit6 // If this program encounters pipe failure when printing to stdout, exit
example/hello_world/hello_libc.zig+1-1
...@@ -7,7 +7,7 @@ const c = @cImport({...@@ -7,7 +7,7 @@ const c = @cImport({
77
8const msg = c"Hello, world!\n";8const msg = c"Hello, world!\n";
99
10export fn main(argc: c_int, argv: &&u8) -> c_int {10export fn main(argc: c_int, argv: &&u8) c_int {
11 if (c.printf(msg) != c_int(c.strlen(msg)))11 if (c.printf(msg) != c_int(c.strlen(msg)))
12 return -1;12 return -1;
1313
example/hello_world/hello_windows.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1use @import("std").os.windows;1use @import("std").os.windows;
22
3export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) -> INT {3export fn WinMain(hInstance: HINSTANCE, hPrevInstance: HINSTANCE, lpCmdLine: PWSTR, nCmdShow: INT) INT {
4 _ = MessageBoxA(null, c"hello", c"title", 0);4 _ = MessageBoxA(null, c"hello", c"title", 0);
5 return 0;5 return 0;
6}6}
example/mix_o_files/base64.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const base64 = @import("std").base64;1const base64 = @import("std").base64;
22
3export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) -> usize {3export fn decode_base_64(dest_ptr: &u8, dest_len: usize, source_ptr: &const u8, source_len: usize) usize {
4 const src = source_ptr[0..source_len];4 const src = source_ptr[0..source_len];
5 const dest = dest_ptr[0..dest_len];5 const dest = dest_ptr[0..dest_len];
6 const base64_decoder = base64.standard_decoder_unsafe;6 const base64_decoder = base64.standard_decoder_unsafe;
example/mix_o_files/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 const obj = b.addObject("base64", "base64.zig");4 const obj = b.addObject("base64", "base64.zig");
55
6 const exe = b.addCExecutable("test");6 const exe = b.addCExecutable("test");
example/shared_library/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));4 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
55
6 const exe = b.addCExecutable("test");6 const exe = b.addCExecutable("test");
example/shared_library/mathtest.zig+1-1
...@@ -1,3 +1,3 @@...@@ -1,3 +1,3 @@
1export fn add(a: i32, b: i32) -> i32 {1export fn add(a: i32, b: i32) i32 {
2 return a + b;2 return a + b;
3}3}
src-self-hosted/ast.zig+15-17
...@@ -20,7 +20,7 @@ pub const Node = struct {...@@ -20,7 +20,7 @@ pub const Node = struct {
20 FloatLiteral,20 FloatLiteral,
21 };21 };
2222
23 pub fn iterate(base: &Node, index: usize) -> ?&Node {23 pub fn iterate(base: &Node, index: usize) ?&Node {
24 return switch (base.id) {24 return switch (base.id) {
25 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),25 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
26 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),26 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
...@@ -35,7 +35,7 @@ pub const Node = struct {...@@ -35,7 +35,7 @@ pub const Node = struct {
35 };35 };
36 }36 }
3737
38 pub fn destroy(base: &Node, allocator: &mem.Allocator) {38 pub fn destroy(base: &Node, allocator: &mem.Allocator) void {
39 return switch (base.id) {39 return switch (base.id) {
40 Id.Root => allocator.destroy(@fieldParentPtr(NodeRoot, "base", base)),40 Id.Root => allocator.destroy(@fieldParentPtr(NodeRoot, "base", base)),
41 Id.VarDecl => allocator.destroy(@fieldParentPtr(NodeVarDecl, "base", base)),41 Id.VarDecl => allocator.destroy(@fieldParentPtr(NodeVarDecl, "base", base)),
...@@ -55,7 +55,7 @@ pub const NodeRoot = struct {...@@ -55,7 +55,7 @@ pub const NodeRoot = struct {
55 base: Node,55 base: Node,
56 decls: ArrayList(&Node),56 decls: ArrayList(&Node),
5757
58 pub fn iterate(self: &NodeRoot, index: usize) -> ?&Node {58 pub fn iterate(self: &NodeRoot, index: usize) ?&Node {
59 if (index < self.decls.len) {59 if (index < self.decls.len) {
60 return self.decls.items[self.decls.len - index - 1];60 return self.decls.items[self.decls.len - index - 1];
61 }61 }
...@@ -76,7 +76,7 @@ pub const NodeVarDecl = struct {...@@ -76,7 +76,7 @@ pub const NodeVarDecl = struct {
76 align_node: ?&Node,76 align_node: ?&Node,
77 init_node: ?&Node,77 init_node: ?&Node,
7878
79 pub fn iterate(self: &NodeVarDecl, index: usize) -> ?&Node {79 pub fn iterate(self: &NodeVarDecl, index: usize) ?&Node {
80 var i = index;80 var i = index;
8181
82 if (self.type_node) |type_node| {82 if (self.type_node) |type_node| {
...@@ -102,7 +102,7 @@ pub const NodeIdentifier = struct {...@@ -102,7 +102,7 @@ pub const NodeIdentifier = struct {
102 base: Node,102 base: Node,
103 name_token: Token,103 name_token: Token,
104104
105 pub fn iterate(self: &NodeIdentifier, index: usize) -> ?&Node {105 pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
106 return null;106 return null;
107 }107 }
108};108};
...@@ -113,7 +113,7 @@ pub const NodeFnProto = struct {...@@ -113,7 +113,7 @@ pub const NodeFnProto = struct {
113 fn_token: Token,113 fn_token: Token,
114 name_token: ?Token,114 name_token: ?Token,
115 params: ArrayList(&Node),115 params: ArrayList(&Node),
116 return_type: ?&Node,116 return_type: &Node,
117 var_args_token: ?Token,117 var_args_token: ?Token,
118 extern_token: ?Token,118 extern_token: ?Token,
119 inline_token: ?Token,119 inline_token: ?Token,
...@@ -122,7 +122,7 @@ pub const NodeFnProto = struct {...@@ -122,7 +122,7 @@ pub const NodeFnProto = struct {
122 lib_name: ?&Node, // populated if this is an extern declaration122 lib_name: ?&Node, // populated if this is an extern declaration
123 align_expr: ?&Node, // populated if align(A) is present123 align_expr: ?&Node, // populated if align(A) is present
124124
125 pub fn iterate(self: &NodeFnProto, index: usize) -> ?&Node {125 pub fn iterate(self: &NodeFnProto, index: usize) ?&Node {
126 var i = index;126 var i = index;
127127
128 if (self.body_node) |body_node| {128 if (self.body_node) |body_node| {
...@@ -130,10 +130,8 @@ pub const NodeFnProto = struct {...@@ -130,10 +130,8 @@ pub const NodeFnProto = struct {
130 i -= 1;130 i -= 1;
131 }131 }
132132
133 if (self.return_type) |return_type| {133 if (i < 1) return self.return_type;
134 if (i < 1) return return_type;134 i -= 1;
135 i -= 1;
136 }
137135
138 if (self.align_expr) |align_expr| {136 if (self.align_expr) |align_expr| {
139 if (i < 1) return align_expr;137 if (i < 1) return align_expr;
...@@ -160,7 +158,7 @@ pub const NodeParamDecl = struct {...@@ -160,7 +158,7 @@ pub const NodeParamDecl = struct {
160 type_node: &Node,158 type_node: &Node,
161 var_args_token: ?Token,159 var_args_token: ?Token,
162160
163 pub fn iterate(self: &NodeParamDecl, index: usize) -> ?&Node {161 pub fn iterate(self: &NodeParamDecl, index: usize) ?&Node {
164 var i = index;162 var i = index;
165163
166 if (i < 1) return self.type_node;164 if (i < 1) return self.type_node;
...@@ -176,7 +174,7 @@ pub const NodeBlock = struct {...@@ -176,7 +174,7 @@ pub const NodeBlock = struct {
176 end_token: Token,174 end_token: Token,
177 statements: ArrayList(&Node),175 statements: ArrayList(&Node),
178176
179 pub fn iterate(self: &NodeBlock, index: usize) -> ?&Node {177 pub fn iterate(self: &NodeBlock, index: usize) ?&Node {
180 var i = index;178 var i = index;
181179
182 if (i < self.statements.len) return self.statements.items[i];180 if (i < self.statements.len) return self.statements.items[i];
...@@ -198,7 +196,7 @@ pub const NodeInfixOp = struct {...@@ -198,7 +196,7 @@ pub const NodeInfixOp = struct {
198 BangEqual,196 BangEqual,
199 };197 };
200198
201 pub fn iterate(self: &NodeInfixOp, index: usize) -> ?&Node {199 pub fn iterate(self: &NodeInfixOp, index: usize) ?&Node {
202 var i = index;200 var i = index;
203201
204 if (i < 1) return self.lhs;202 if (i < 1) return self.lhs;
...@@ -234,7 +232,7 @@ pub const NodePrefixOp = struct {...@@ -234,7 +232,7 @@ pub const NodePrefixOp = struct {
234 volatile_token: ?Token,232 volatile_token: ?Token,
235 };233 };
236234
237 pub fn iterate(self: &NodePrefixOp, index: usize) -> ?&Node {235 pub fn iterate(self: &NodePrefixOp, index: usize) ?&Node {
238 var i = index;236 var i = index;
239237
240 switch (self.op) {238 switch (self.op) {
...@@ -258,7 +256,7 @@ pub const NodeIntegerLiteral = struct {...@@ -258,7 +256,7 @@ pub const NodeIntegerLiteral = struct {
258 base: Node,256 base: Node,
259 token: Token,257 token: Token,
260258
261 pub fn iterate(self: &NodeIntegerLiteral, index: usize) -> ?&Node {259 pub fn iterate(self: &NodeIntegerLiteral, index: usize) ?&Node {
262 return null;260 return null;
263 }261 }
264};262};
...@@ -267,7 +265,7 @@ pub const NodeFloatLiteral = struct {...@@ -267,7 +265,7 @@ pub const NodeFloatLiteral = struct {
267 base: Node,265 base: Node,
268 token: Token,266 token: Token,
269267
270 pub fn iterate(self: &NodeFloatLiteral, index: usize) -> ?&Node {268 pub fn iterate(self: &NodeFloatLiteral, index: usize) ?&Node {
271 return null;269 return null;
272 }270 }
273};271};
src-self-hosted/ir.zig+1-1
...@@ -33,7 +33,7 @@ pub const Instruction = struct {...@@ -33,7 +33,7 @@ pub const Instruction = struct {
33 TypeOf,33 TypeOf,
34 ToPtrType,34 ToPtrType,
35 PtrTypeChild,35 PtrTypeChild,
36 SetDebugSafety,36 SetRuntimeSafety,
37 SetFloatMode,37 SetFloatMode,
38 ArrayType,38 ArrayType,
39 SliceType,39 SliceType,
src-self-hosted/llvm.zig+1-1
...@@ -7,7 +7,7 @@ pub const ModuleRef = removeNullability(c.LLVMModuleRef);...@@ -7,7 +7,7 @@ pub const ModuleRef = removeNullability(c.LLVMModuleRef);
7pub const ContextRef = removeNullability(c.LLVMContextRef);7pub const ContextRef = removeNullability(c.LLVMContextRef);
8pub const BuilderRef = removeNullability(c.LLVMBuilderRef);8pub const BuilderRef = removeNullability(c.LLVMBuilderRef);
99
10fn removeNullability(comptime T: type) -> type {10fn removeNullability(comptime T: type) type {
11 comptime assert(@typeId(T) == builtin.TypeId.Nullable);11 comptime assert(@typeId(T) == builtin.TypeId.Nullable);
12 return T.Child;12 return T.Child;
13}13}
src-self-hosted/main.zig+10-10
...@@ -20,7 +20,7 @@ error ZigInstallationNotFound;...@@ -20,7 +20,7 @@ error ZigInstallationNotFound;
2020
21const default_zig_cache_name = "zig-cache";21const default_zig_cache_name = "zig-cache";
2222
23pub fn main() -> %void {23pub fn main() %void {
24 main2() catch |err| {24 main2() catch |err| {
25 if (err != error.InvalidCommandLineArguments) {25 if (err != error.InvalidCommandLineArguments) {
26 warn("{}\n", @errorName(err));26 warn("{}\n", @errorName(err));
...@@ -39,7 +39,7 @@ const Cmd = enum {...@@ -39,7 +39,7 @@ const Cmd = enum {
39 Targets,39 Targets,
40};40};
4141
42fn badArgs(comptime format: []const u8, args: ...) -> error {42fn badArgs(comptime format: []const u8, args: ...) error {
43 var stderr = try io.getStdErr();43 var stderr = try io.getStdErr();
44 var stderr_stream_adapter = io.FileOutStream.init(&stderr);44 var stderr_stream_adapter = io.FileOutStream.init(&stderr);
45 const stderr_stream = &stderr_stream_adapter.stream;45 const stderr_stream = &stderr_stream_adapter.stream;
...@@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) -> error {...@@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) -> error {
48 return error.InvalidCommandLineArguments;48 return error.InvalidCommandLineArguments;
49}49}
5050
51pub fn main2() -> %void {51pub fn main2() %void {
52 const allocator = std.heap.c_allocator;52 const allocator = std.heap.c_allocator;
5353
54 const args = try os.argsAlloc(allocator);54 const args = try os.argsAlloc(allocator);
...@@ -371,7 +371,7 @@ pub fn main2() -> %void {...@@ -371,7 +371,7 @@ pub fn main2() -> %void {
371 defer allocator.free(full_cache_dir);371 defer allocator.free(full_cache_dir);
372372
373 const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix);373 const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix);
374 %defer allocator.free(zig_lib_dir);374 errdefer allocator.free(zig_lib_dir);
375375
376 const module = try Module.create(allocator, root_name, zig_root_source_file,376 const module = try Module.create(allocator, root_name, zig_root_source_file,
377 Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir);377 Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir);
...@@ -472,7 +472,7 @@ pub fn main2() -> %void {...@@ -472,7 +472,7 @@ pub fn main2() -> %void {
472 }472 }
473}473}
474474
475fn printUsage(stream: &io.OutStream) -> %void {475fn printUsage(stream: &io.OutStream) %void {
476 try stream.write(476 try stream.write(
477 \\Usage: zig [command] [options]477 \\Usage: zig [command] [options]
478 \\478 \\
...@@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) -> %void {...@@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) -> %void {
548 );548 );
549}549}
550550
551fn printZen() -> %void {551fn printZen() %void {
552 var stdout_file = try io.getStdErr();552 var stdout_file = try io.getStdErr();
553 try stdout_file.write(553 try stdout_file.write(
554 \\554 \\
...@@ -569,7 +569,7 @@ fn printZen() -> %void {...@@ -569,7 +569,7 @@ fn printZen() -> %void {
569}569}
570570
571/// Caller must free result571/// Caller must free result
572fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 {572fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) %[]u8 {
573 if (zig_install_prefix_arg) |zig_install_prefix| {573 if (zig_install_prefix_arg) |zig_install_prefix| {
574 return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {574 return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
575 warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));575 warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));
...@@ -585,9 +585,9 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const...@@ -585,9 +585,9 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const
585}585}
586586
587/// Caller must free result587/// Caller must free result
588fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 {588fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8 {
589 const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");589 const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");
590 %defer allocator.free(test_zig_dir);590 errdefer allocator.free(test_zig_dir);
591591
592 const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig");592 const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig");
593 defer allocator.free(test_index_file);593 defer allocator.free(test_index_file);
...@@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]...@@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]
599}599}
600600
601/// Caller must free result601/// Caller must free result
602fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 {602fn findZigLibDir(allocator: &mem.Allocator) %[]u8 {
603 const self_exe_path = try os.selfExeDirPath(allocator);603 const self_exe_path = try os.selfExeDirPath(allocator);
604 defer allocator.free(self_exe_path);604 defer allocator.free(self_exe_path);
605605
src-self-hosted/module.zig+18-18
...@@ -110,22 +110,22 @@ pub const Module = struct {...@@ -110,22 +110,22 @@ pub const Module = struct {
110 };110 };
111111
112 pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target,112 pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target,
113 kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module113 kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) %&Module
114 {114 {
115 var name_buffer = try Buffer.init(allocator, name);115 var name_buffer = try Buffer.init(allocator, name);
116 %defer name_buffer.deinit();116 errdefer name_buffer.deinit();
117117
118 const context = c.LLVMContextCreate() ?? return error.OutOfMemory;118 const context = c.LLVMContextCreate() ?? return error.OutOfMemory;
119 %defer c.LLVMContextDispose(context);119 errdefer c.LLVMContextDispose(context);
120120
121 const module = c.LLVMModuleCreateWithNameInContext(name_buffer.ptr(), context) ?? return error.OutOfMemory;121 const module = c.LLVMModuleCreateWithNameInContext(name_buffer.ptr(), context) ?? return error.OutOfMemory;
122 %defer c.LLVMDisposeModule(module);122 errdefer c.LLVMDisposeModule(module);
123123
124 const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory;124 const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory;
125 %defer c.LLVMDisposeBuilder(builder);125 errdefer c.LLVMDisposeBuilder(builder);
126126
127 const module_ptr = try allocator.create(Module);127 const module_ptr = try allocator.create(Module);
128 %defer allocator.destroy(module_ptr);128 errdefer allocator.destroy(module_ptr);
129129
130 *module_ptr = Module {130 *module_ptr = Module {
131 .allocator = allocator,131 .allocator = allocator,
...@@ -185,11 +185,11 @@ pub const Module = struct {...@@ -185,11 +185,11 @@ pub const Module = struct {
185 return module_ptr;185 return module_ptr;
186 }186 }
187187
188 fn dump(self: &Module) {188 fn dump(self: &Module) void {
189 c.LLVMDumpModule(self.module);189 c.LLVMDumpModule(self.module);
190 }190 }
191191
192 pub fn destroy(self: &Module) {192 pub fn destroy(self: &Module) void {
193 c.LLVMDisposeBuilder(self.builder);193 c.LLVMDisposeBuilder(self.builder);
194 c.LLVMDisposeModule(self.module);194 c.LLVMDisposeModule(self.module);
195 c.LLVMContextDispose(self.context);195 c.LLVMContextDispose(self.context);
...@@ -198,7 +198,7 @@ pub const Module = struct {...@@ -198,7 +198,7 @@ pub const Module = struct {
198 self.allocator.destroy(self);198 self.allocator.destroy(self);
199 }199 }
200200
201 pub fn build(self: &Module) -> %void {201 pub fn build(self: &Module) %void {
202 if (self.llvm_argv.len != 0) {202 if (self.llvm_argv.len != 0) {
203 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,203 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
204 [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });204 [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
...@@ -211,13 +211,13 @@ pub const Module = struct {...@@ -211,13 +211,13 @@ pub const Module = struct {
211 try printError("unable to get real path '{}': {}", root_src_path, err);211 try printError("unable to get real path '{}': {}", root_src_path, err);
212 return err;212 return err;
213 };213 };
214 %defer self.allocator.free(root_src_real_path);214 errdefer self.allocator.free(root_src_real_path);
215215
216 const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| {216 const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| {
217 try printError("unable to open '{}': {}", root_src_real_path, err);217 try printError("unable to open '{}': {}", root_src_real_path, err);
218 return err;218 return err;
219 };219 };
220 %defer self.allocator.free(source_code);220 errdefer self.allocator.free(source_code);
221 source_code[source_code.len - 3] = '\n';221 source_code[source_code.len - 3] = '\n';
222 source_code[source_code.len - 2] = '\n';222 source_code[source_code.len - 2] = '\n';
223 source_code[source_code.len - 1] = '\n';223 source_code[source_code.len - 1] = '\n';
...@@ -244,16 +244,16 @@ pub const Module = struct {...@@ -244,16 +244,16 @@ pub const Module = struct {
244 var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);244 var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);
245 defer parser.deinit();245 defer parser.deinit();
246246
247 const root_node = try parser.parse();247 const tree = try parser.parse();
248 defer parser.freeAst(root_node);248 defer tree.deinit();
249249
250 var stderr_file = try std.io.getStdErr();250 var stderr_file = try std.io.getStdErr();
251 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);251 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
252 const out_stream = &stderr_file_out_stream.stream;252 const out_stream = &stderr_file_out_stream.stream;
253 try parser.renderAst(out_stream, root_node);253 try parser.renderAst(out_stream, tree.root_node);
254254
255 warn("====fmt:====\n");255 warn("====fmt:====\n");
256 try parser.renderSource(out_stream, root_node);256 try parser.renderSource(out_stream, tree.root_node);
257257
258 warn("====ir:====\n");258 warn("====ir:====\n");
259 warn("TODO\n\n");259 warn("TODO\n\n");
...@@ -263,11 +263,11 @@ pub const Module = struct {...@@ -263,11 +263,11 @@ pub const Module = struct {
263 263
264 }264 }
265265
266 pub fn link(self: &Module, out_file: ?[]const u8) -> %void {266 pub fn link(self: &Module, out_file: ?[]const u8) %void {
267 warn("TODO link");267 warn("TODO link");
268 }268 }
269269
270 pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) -> %&LinkLib {270 pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) %&LinkLib {
271 const is_libc = mem.eql(u8, name, "c");271 const is_libc = mem.eql(u8, name, "c");
272272
273 if (is_libc) {273 if (is_libc) {
...@@ -297,7 +297,7 @@ pub const Module = struct {...@@ -297,7 +297,7 @@ pub const Module = struct {
297 }297 }
298};298};
299299
300fn printError(comptime format: []const u8, args: ...) -> %void {300fn printError(comptime format: []const u8, args: ...) %void {
301 var stderr_file = try std.io.getStdErr();301 var stderr_file = try std.io.getStdErr();
302 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);302 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
303 const out_stream = &stderr_file_out_stream.stream;303 const out_stream = &stderr_file_out_stream.stream;
src-self-hosted/parser.zig+89-132
...@@ -20,14 +20,25 @@ pub const Parser = struct {...@@ -20,14 +20,25 @@ pub const Parser = struct {
20 put_back_tokens: [2]Token,20 put_back_tokens: [2]Token,
21 put_back_count: usize,21 put_back_count: usize,
22 source_file_name: []const u8,22 source_file_name: []const u8,
23 cleanup_root_node: ?&ast.NodeRoot,23
24 pub const Tree = struct {
25 root_node: &ast.NodeRoot,
26
27 pub fn deinit(self: &const Tree) void {
28 // TODO free the whole arena
29 }
30 };
2431
25 // This memory contents are used only during a function call. It's used to repurpose memory;32 // This memory contents are used only during a function call. It's used to repurpose memory;
26 // specifically so that freeAst can be guaranteed to succeed.33 // we reuse the same bytes for the stack data structure used by parsing, tree rendering, and
34 // source rendering.
27 const utility_bytes_align = @alignOf( union { a: RenderAstFrame, b: State, c: RenderState } );35 const utility_bytes_align = @alignOf( union { a: RenderAstFrame, b: State, c: RenderState } );
28 utility_bytes: []align(utility_bytes_align) u8,36 utility_bytes: []align(utility_bytes_align) u8,
2937
30 pub fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator, source_file_name: []const u8) -> Parser {38 /// `allocator` should be an arena allocator. Parser never calls free on anything. After you're
39 /// done with a Parser, free the arena. After the arena is freed, no member functions of Parser
40 /// may be called.
41 pub fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator, source_file_name: []const u8) Parser {
31 return Parser {42 return Parser {
32 .allocator = allocator,43 .allocator = allocator,
33 .tokenizer = tokenizer,44 .tokenizer = tokenizer,
...@@ -35,12 +46,10 @@ pub const Parser = struct {...@@ -35,12 +46,10 @@ pub const Parser = struct {
35 .put_back_count = 0,46 .put_back_count = 0,
36 .source_file_name = source_file_name,47 .source_file_name = source_file_name,
37 .utility_bytes = []align(utility_bytes_align) u8{},48 .utility_bytes = []align(utility_bytes_align) u8{},
38 .cleanup_root_node = null,
39 };49 };
40 }50 }
4151
42 pub fn deinit(self: &Parser) {52 pub fn deinit(self: &Parser) void {
43 assert(self.cleanup_root_node == null);
44 self.allocator.free(self.utility_bytes);53 self.allocator.free(self.utility_bytes);
45 }54 }
4655
...@@ -54,7 +63,7 @@ pub const Parser = struct {...@@ -54,7 +63,7 @@ pub const Parser = struct {
54 NullableField: &?&ast.Node,63 NullableField: &?&ast.Node,
55 List: &ArrayList(&ast.Node),64 List: &ArrayList(&ast.Node),
5665
57 pub fn store(self: &const DestPtr, value: &ast.Node) -> %void {66 pub fn store(self: &const DestPtr, value: &ast.Node) %void {
58 switch (*self) {67 switch (*self) {
59 DestPtr.Field => |ptr| *ptr = value,68 DestPtr.Field => |ptr| *ptr = value,
60 DestPtr.NullableField => |ptr| *ptr = value,69 DestPtr.NullableField => |ptr| *ptr = value,
...@@ -88,52 +97,16 @@ pub const Parser = struct {...@@ -88,52 +97,16 @@ pub const Parser = struct {
88 Statement: &ast.NodeBlock,97 Statement: &ast.NodeBlock,
89 };98 };
9099
91 pub fn freeAst(self: &Parser, root_node: &ast.NodeRoot) {100 /// Returns an AST tree, allocated with the parser's allocator.
92 // utility_bytes is big enough to do this iteration since we were able to do101 /// Result should be freed with `freeAst` when done.
93 // the parsing in the first place102 pub fn parse(self: &Parser) %Tree {
94 comptime assert(@sizeOf(State) >= @sizeOf(&ast.Node));
95
96 var stack = self.initUtilityArrayList(&ast.Node);
97 defer self.deinitUtilityArrayList(stack);
98
99 stack.append(&root_node.base) catch unreachable;
100 while (stack.popOrNull()) |node| {
101 var i: usize = 0;
102 while (node.iterate(i)) |child| : (i += 1) {
103 if (child.iterate(0) != null) {
104 stack.append(child) catch unreachable;
105 } else {
106 child.destroy(self.allocator);
107 }
108 }
109 node.destroy(self.allocator);
110 }
111 }
112
113 pub fn parse(self: &Parser) -> %&ast.NodeRoot {
114 const result = self.parseInner() catch |err| x: {
115 if (self.cleanup_root_node) |root_node| {
116 self.freeAst(root_node);
117 }
118 break :x err;
119 };
120 self.cleanup_root_node = null;
121 return result;
122 }
123
124 pub fn parseInner(self: &Parser) -> %&ast.NodeRoot {
125 var stack = self.initUtilityArrayList(State);103 var stack = self.initUtilityArrayList(State);
126 defer self.deinitUtilityArrayList(stack);104 defer self.deinitUtilityArrayList(stack);
127105
128 const root_node = x: {106 const root_node = try self.createRoot();
129 const root_node = try self.createRoot();107 // TODO errdefer arena free root node
130 %defer self.allocator.destroy(root_node);108
131 // This stack append has to succeed for freeAst to work109 try stack.append(State.TopLevel);
132 try stack.append(State.TopLevel);
133 break :x root_node;
134 };
135 assert(self.cleanup_root_node == null);
136 self.cleanup_root_node = root_node;
137110
138 while (true) {111 while (true) {
139 //{112 //{
...@@ -159,7 +132,7 @@ pub const Parser = struct {...@@ -159,7 +132,7 @@ pub const Parser = struct {
159 stack.append(State { .TopLevelExtern = token }) catch unreachable;132 stack.append(State { .TopLevelExtern = token }) catch unreachable;
160 continue;133 continue;
161 },134 },
162 Token.Id.Eof => return root_node,135 Token.Id.Eof => return Tree {.root_node = root_node},
163 else => {136 else => {
164 self.putBackToken(token);137 self.putBackToken(token);
165 // TODO shouldn't need this cast138 // TODO shouldn't need this cast
...@@ -211,7 +184,7 @@ pub const Parser = struct {...@@ -211,7 +184,7 @@ pub const Parser = struct {
211 Token.Id.StringLiteral => {184 Token.Id.StringLiteral => {
212 @panic("TODO extern with string literal");185 @panic("TODO extern with string literal");
213 },186 },
214 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {187 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
215 stack.append(State.TopLevel) catch unreachable;188 stack.append(State.TopLevel) catch unreachable;
216 const fn_token = try self.eatToken(Token.Id.Keyword_fn);189 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
217 // TODO shouldn't need this cast190 // TODO shouldn't need this cast
...@@ -439,15 +412,11 @@ pub const Parser = struct {...@@ -439,15 +412,11 @@ pub const Parser = struct {
439 if (token.id == Token.Id.Keyword_align) {412 if (token.id == Token.Id.Keyword_align) {
440 @panic("TODO fn proto align");413 @panic("TODO fn proto align");
441 }414 }
442 if (token.id == Token.Id.Arrow) {415 self.putBackToken(token);
443 stack.append(State {416 stack.append(State {
444 .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type},417 .TypeExpr = DestPtr {.Field = &fn_proto.return_type},
445 }) catch unreachable;418 }) catch unreachable;
446 continue;419 continue;
447 } else {
448 self.putBackToken(token);
449 continue;
450 }
451 },420 },
452421
453 State.ParamDecl => |fn_proto| {422 State.ParamDecl => |fn_proto| {
...@@ -575,9 +544,8 @@ pub const Parser = struct {...@@ -575,9 +544,8 @@ pub const Parser = struct {
575 }544 }
576 }545 }
577546
578 fn createRoot(self: &Parser) -> %&ast.NodeRoot {547 fn createRoot(self: &Parser) %&ast.NodeRoot {
579 const node = try self.allocator.create(ast.NodeRoot);548 const node = try self.allocator.create(ast.NodeRoot);
580 %defer self.allocator.destroy(node);
581549
582 *node = ast.NodeRoot {550 *node = ast.NodeRoot {
583 .base = ast.Node {.id = ast.Node.Id.Root},551 .base = ast.Node {.id = ast.Node.Id.Root},
...@@ -587,10 +555,9 @@ pub const Parser = struct {...@@ -587,10 +555,9 @@ pub const Parser = struct {
587 }555 }
588556
589 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,557 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
590 extern_token: &const ?Token) -> %&ast.NodeVarDecl558 extern_token: &const ?Token) %&ast.NodeVarDecl
591 {559 {
592 const node = try self.allocator.create(ast.NodeVarDecl);560 const node = try self.allocator.create(ast.NodeVarDecl);
593 %defer self.allocator.destroy(node);
594561
595 *node = ast.NodeVarDecl {562 *node = ast.NodeVarDecl {
596 .base = ast.Node {.id = ast.Node.Id.VarDecl},563 .base = ast.Node {.id = ast.Node.Id.VarDecl},
...@@ -610,10 +577,9 @@ pub const Parser = struct {...@@ -610,10 +577,9 @@ pub const Parser = struct {
610 }577 }
611578
612 fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,579 fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,
613 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto580 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) %&ast.NodeFnProto
614 {581 {
615 const node = try self.allocator.create(ast.NodeFnProto);582 const node = try self.allocator.create(ast.NodeFnProto);
616 %defer self.allocator.destroy(node);
617583
618 *node = ast.NodeFnProto {584 *node = ast.NodeFnProto {
619 .base = ast.Node {.id = ast.Node.Id.FnProto},585 .base = ast.Node {.id = ast.Node.Id.FnProto},
...@@ -621,7 +587,7 @@ pub const Parser = struct {...@@ -621,7 +587,7 @@ pub const Parser = struct {
621 .name_token = null,587 .name_token = null,
622 .fn_token = *fn_token,588 .fn_token = *fn_token,
623 .params = ArrayList(&ast.Node).init(self.allocator),589 .params = ArrayList(&ast.Node).init(self.allocator),
624 .return_type = null,590 .return_type = undefined,
625 .var_args_token = null,591 .var_args_token = null,
626 .extern_token = *extern_token,592 .extern_token = *extern_token,
627 .inline_token = *inline_token,593 .inline_token = *inline_token,
...@@ -633,9 +599,8 @@ pub const Parser = struct {...@@ -633,9 +599,8 @@ pub const Parser = struct {
633 return node;599 return node;
634 }600 }
635601
636 fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl {602 fn createParamDecl(self: &Parser) %&ast.NodeParamDecl {
637 const node = try self.allocator.create(ast.NodeParamDecl);603 const node = try self.allocator.create(ast.NodeParamDecl);
638 %defer self.allocator.destroy(node);
639604
640 *node = ast.NodeParamDecl {605 *node = ast.NodeParamDecl {
641 .base = ast.Node {.id = ast.Node.Id.ParamDecl},606 .base = ast.Node {.id = ast.Node.Id.ParamDecl},
...@@ -648,9 +613,8 @@ pub const Parser = struct {...@@ -648,9 +613,8 @@ pub const Parser = struct {
648 return node;613 return node;
649 }614 }
650615
651 fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock {616 fn createBlock(self: &Parser, begin_token: &const Token) %&ast.NodeBlock {
652 const node = try self.allocator.create(ast.NodeBlock);617 const node = try self.allocator.create(ast.NodeBlock);
653 %defer self.allocator.destroy(node);
654618
655 *node = ast.NodeBlock {619 *node = ast.NodeBlock {
656 .base = ast.Node {.id = ast.Node.Id.Block},620 .base = ast.Node {.id = ast.Node.Id.Block},
...@@ -661,9 +625,8 @@ pub const Parser = struct {...@@ -661,9 +625,8 @@ pub const Parser = struct {
661 return node;625 return node;
662 }626 }
663627
664 fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp {628 fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) %&ast.NodeInfixOp {
665 const node = try self.allocator.create(ast.NodeInfixOp);629 const node = try self.allocator.create(ast.NodeInfixOp);
666 %defer self.allocator.destroy(node);
667630
668 *node = ast.NodeInfixOp {631 *node = ast.NodeInfixOp {
669 .base = ast.Node {.id = ast.Node.Id.InfixOp},632 .base = ast.Node {.id = ast.Node.Id.InfixOp},
...@@ -675,9 +638,8 @@ pub const Parser = struct {...@@ -675,9 +638,8 @@ pub const Parser = struct {
675 return node;638 return node;
676 }639 }
677640
678 fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp {641 fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) %&ast.NodePrefixOp {
679 const node = try self.allocator.create(ast.NodePrefixOp);642 const node = try self.allocator.create(ast.NodePrefixOp);
680 %defer self.allocator.destroy(node);
681643
682 *node = ast.NodePrefixOp {644 *node = ast.NodePrefixOp {
683 .base = ast.Node {.id = ast.Node.Id.PrefixOp},645 .base = ast.Node {.id = ast.Node.Id.PrefixOp},
...@@ -688,9 +650,8 @@ pub const Parser = struct {...@@ -688,9 +650,8 @@ pub const Parser = struct {
688 return node;650 return node;
689 }651 }
690652
691 fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier {653 fn createIdentifier(self: &Parser, name_token: &const Token) %&ast.NodeIdentifier {
692 const node = try self.allocator.create(ast.NodeIdentifier);654 const node = try self.allocator.create(ast.NodeIdentifier);
693 %defer self.allocator.destroy(node);
694655
695 *node = ast.NodeIdentifier {656 *node = ast.NodeIdentifier {
696 .base = ast.Node {.id = ast.Node.Id.Identifier},657 .base = ast.Node {.id = ast.Node.Id.Identifier},
...@@ -699,9 +660,8 @@ pub const Parser = struct {...@@ -699,9 +660,8 @@ pub const Parser = struct {
699 return node;660 return node;
700 }661 }
701662
702 fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral {663 fn createIntegerLiteral(self: &Parser, token: &const Token) %&ast.NodeIntegerLiteral {
703 const node = try self.allocator.create(ast.NodeIntegerLiteral);664 const node = try self.allocator.create(ast.NodeIntegerLiteral);
704 %defer self.allocator.destroy(node);
705665
706 *node = ast.NodeIntegerLiteral {666 *node = ast.NodeIntegerLiteral {
707 .base = ast.Node {.id = ast.Node.Id.IntegerLiteral},667 .base = ast.Node {.id = ast.Node.Id.IntegerLiteral},
...@@ -710,9 +670,8 @@ pub const Parser = struct {...@@ -710,9 +670,8 @@ pub const Parser = struct {
710 return node;670 return node;
711 }671 }
712672
713 fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral {673 fn createFloatLiteral(self: &Parser, token: &const Token) %&ast.NodeFloatLiteral {
714 const node = try self.allocator.create(ast.NodeFloatLiteral);674 const node = try self.allocator.create(ast.NodeFloatLiteral);
715 %defer self.allocator.destroy(node);
716675
717 *node = ast.NodeFloatLiteral {676 *node = ast.NodeFloatLiteral {
718 .base = ast.Node {.id = ast.Node.Id.FloatLiteral},677 .base = ast.Node {.id = ast.Node.Id.FloatLiteral},
...@@ -721,40 +680,36 @@ pub const Parser = struct {...@@ -721,40 +680,36 @@ pub const Parser = struct {
721 return node;680 return node;
722 }681 }
723682
724 fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier {683 fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) %&ast.NodeIdentifier {
725 const node = try self.createIdentifier(name_token);684 const node = try self.createIdentifier(name_token);
726 %defer self.allocator.destroy(node);
727 try dest_ptr.store(&node.base);685 try dest_ptr.store(&node.base);
728 return node;686 return node;
729 }687 }
730688
731 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl {689 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) %&ast.NodeParamDecl {
732 const node = try self.createParamDecl();690 const node = try self.createParamDecl();
733 %defer self.allocator.destroy(node);
734 try list.append(&node.base);691 try list.append(&node.base);
735 return node;692 return node;
736 }693 }
737694
738 fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token,695 fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token,
739 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,696 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
740 inline_token: &const ?Token) -> %&ast.NodeFnProto697 inline_token: &const ?Token) %&ast.NodeFnProto
741 {698 {
742 const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);699 const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
743 %defer self.allocator.destroy(node);
744 try list.append(&node.base);700 try list.append(&node.base);
745 return node;701 return node;
746 }702 }
747703
748 fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token,704 fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token,
749 mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl705 mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) %&ast.NodeVarDecl
750 {706 {
751 const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);707 const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
752 %defer self.allocator.destroy(node);
753 try list.append(&node.base);708 try list.append(&node.base);
754 return node;709 return node;
755 }710 }
756711
757 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) -> error {712 fn parseError(self: &Parser, token: &const Token, comptime fmt: []const u8, args: ...) error {
758 const loc = self.tokenizer.getTokenLocation(token);713 const loc = self.tokenizer.getTokenLocation(token);
759 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);714 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
760 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);715 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
...@@ -775,24 +730,24 @@ pub const Parser = struct {...@@ -775,24 +730,24 @@ pub const Parser = struct {
775 return error.ParseError;730 return error.ParseError;
776 }731 }
777732
778 fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) -> %void {733 fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) %void {
779 if (token.id != id) {734 if (token.id != id) {
780 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));735 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
781 }736 }
782 }737 }
783738
784 fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token {739 fn eatToken(self: &Parser, id: @TagType(Token.Id)) %Token {
785 const token = self.getNextToken();740 const token = self.getNextToken();
786 try self.expectToken(token, id);741 try self.expectToken(token, id);
787 return token;742 return token;
788 }743 }
789744
790 fn putBackToken(self: &Parser, token: &const Token) {745 fn putBackToken(self: &Parser, token: &const Token) void {
791 self.put_back_tokens[self.put_back_count] = *token;746 self.put_back_tokens[self.put_back_count] = *token;
792 self.put_back_count += 1;747 self.put_back_count += 1;
793 }748 }
794749
795 fn getNextToken(self: &Parser) -> Token {750 fn getNextToken(self: &Parser) Token {
796 if (self.put_back_count != 0) {751 if (self.put_back_count != 0) {
797 const put_back_index = self.put_back_count - 1;752 const put_back_index = self.put_back_count - 1;
798 const put_back_token = self.put_back_tokens[put_back_index];753 const put_back_token = self.put_back_tokens[put_back_index];
...@@ -808,7 +763,7 @@ pub const Parser = struct {...@@ -808,7 +763,7 @@ pub const Parser = struct {
808 indent: usize,763 indent: usize,
809 };764 };
810765
811 pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) -> %void {766 pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
812 var stack = self.initUtilityArrayList(RenderAstFrame);767 var stack = self.initUtilityArrayList(RenderAstFrame);
813 defer self.deinitUtilityArrayList(stack);768 defer self.deinitUtilityArrayList(stack);
814769
...@@ -847,7 +802,7 @@ pub const Parser = struct {...@@ -847,7 +802,7 @@ pub const Parser = struct {
847 Indent: usize,802 Indent: usize,
848 };803 };
849804
850 pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) -> %void {805 pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
851 var stack = self.initUtilityArrayList(RenderState);806 var stack = self.initUtilityArrayList(RenderState);
852 defer self.deinitUtilityArrayList(stack);807 defer self.deinitUtilityArrayList(stack);
853808
...@@ -1039,14 +994,12 @@ pub const Parser = struct {...@@ -1039,14 +994,12 @@ pub const Parser = struct {
1039 if (fn_proto.align_expr != null) {994 if (fn_proto.align_expr != null) {
1040 @panic("TODO");995 @panic("TODO");
1041 }996 }
1042 if (fn_proto.return_type) |return_type| {997 try stream.print(" ");
1043 try stream.print(" -> ");998 if (fn_proto.body_node) |body_node| {
1044 if (fn_proto.body_node) |body_node| {999 try stack.append(RenderState { .Expression = body_node});
1045 try stack.append(RenderState { .Expression = body_node});1000 try stack.append(RenderState { .Text = " "});
1046 try stack.append(RenderState { .Text = " "});
1047 }
1048 try stack.append(RenderState { .Expression = return_type});
1049 }1001 }
1002 try stack.append(RenderState { .Expression = fn_proto.return_type});
1050 },1003 },
1051 RenderState.Statement => |base| {1004 RenderState.Statement => |base| {
1052 switch (base.id) {1005 switch (base.id) {
...@@ -1066,7 +1019,7 @@ pub const Parser = struct {...@@ -1066,7 +1019,7 @@ pub const Parser = struct {
1066 }1019 }
1067 }1020 }
10681021
1069 fn initUtilityArrayList(self: &Parser, comptime T: type) -> ArrayList(T) {1022 fn initUtilityArrayList(self: &Parser, comptime T: type) ArrayList(T) {
1070 const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);1023 const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);
1071 self.utility_bytes = self.allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);1024 self.utility_bytes = self.allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
1072 const typed_slice = ([]T)(self.utility_bytes);1025 const typed_slice = ([]T)(self.utility_bytes);
...@@ -1077,7 +1030,7 @@ pub const Parser = struct {...@@ -1077,7 +1030,7 @@ pub const Parser = struct {
1077 };1030 };
1078 }1031 }
10791032
1080 fn deinitUtilityArrayList(self: &Parser, list: var) {1033 fn deinitUtilityArrayList(self: &Parser, list: var) void {
1081 self.utility_bytes = ([]align(utility_bytes_align) u8)(list.items);1034 self.utility_bytes = ([]align(utility_bytes_align) u8)(list.items);
1082 }1035 }
10831036
...@@ -1085,7 +1038,7 @@ pub const Parser = struct {...@@ -1085,7 +1038,7 @@ pub const Parser = struct {
10851038
1086var fixed_buffer_mem: [100 * 1024]u8 = undefined;1039var fixed_buffer_mem: [100 * 1024]u8 = undefined;
10871040
1088fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {1041fn testParse(source: []const u8, allocator: &mem.Allocator) %[]u8 {
1089 var padded_source: [0x100]u8 = undefined;1042 var padded_source: [0x100]u8 = undefined;
1090 std.mem.copy(u8, padded_source[0..source.len], source);1043 std.mem.copy(u8, padded_source[0..source.len], source);
1091 padded_source[source.len + 0] = '\n';1044 padded_source[source.len + 0] = '\n';
...@@ -1096,30 +1049,34 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {...@@ -1096,30 +1049,34 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
1096 var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");1049 var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
1097 defer parser.deinit();1050 defer parser.deinit();
10981051
1099 const root_node = try parser.parse();1052 const tree = try parser.parse();
1100 defer parser.freeAst(root_node);1053 defer tree.deinit();
11011054
1102 var buffer = try std.Buffer.initSize(allocator, 0);1055 var buffer = try std.Buffer.initSize(allocator, 0);
1103 var buffer_out_stream = io.BufferOutStream.init(&buffer);1056 var buffer_out_stream = io.BufferOutStream.init(&buffer);
1104 try parser.renderSource(&buffer_out_stream.stream, root_node);1057 try parser.renderSource(&buffer_out_stream.stream, tree.root_node);
1105 return buffer.toOwnedSlice();1058 return buffer.toOwnedSlice();
1106}1059}
11071060
1061error TestFailed;
1062error NondeterministicMemoryUsage;
1063error MemoryLeakDetected;
1064
1108// TODO test for memory leaks1065// TODO test for memory leaks
1109// TODO test for valid frees1066// TODO test for valid frees
1110fn testCanonical(source: []const u8) {1067fn testCanonical(source: []const u8) %void {
1111 const needed_alloc_count = x: {1068 const needed_alloc_count = x: {
1112 // Try it once with unlimited memory, make sure it works1069 // Try it once with unlimited memory, make sure it works
1113 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);1070 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1114 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));1071 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
1115 const result_source = testParse(source, &failing_allocator.allocator) catch @panic("test failed");1072 const result_source = try testParse(source, &failing_allocator.allocator);
1116 if (!mem.eql(u8, result_source, source)) {1073 if (!mem.eql(u8, result_source, source)) {
1117 warn("\n====== expected this output: =========\n");1074 warn("\n====== expected this output: =========\n");
1118 warn("{}", source);1075 warn("{}", source);
1119 warn("\n======== instead found this: =========\n");1076 warn("\n======== instead found this: =========\n");
1120 warn("{}", result_source);1077 warn("{}", result_source);
1121 warn("\n======================================\n");1078 warn("\n======================================\n");
1122 @panic("test failed");1079 return error.TestFailed;
1123 }1080 }
1124 failing_allocator.allocator.free(result_source);1081 failing_allocator.allocator.free(result_source);
1125 break :x failing_allocator.index;1082 break :x failing_allocator.index;
...@@ -1130,7 +1087,7 @@ fn testCanonical(source: []const u8) {...@@ -1130,7 +1087,7 @@ fn testCanonical(source: []const u8) {
1130 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);1087 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1131 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);1088 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
1132 if (testParse(source, &failing_allocator.allocator)) |_| {1089 if (testParse(source, &failing_allocator.allocator)) |_| {
1133 @panic("non-deterministic memory usage");1090 return error.NondeterministicMemoryUsage;
1134 } else |err| {1091 } else |err| {
1135 assert(err == error.OutOfMemory);1092 assert(err == error.OutOfMemory);
1136 // TODO make this pass1093 // TODO make this pass
...@@ -1139,19 +1096,19 @@ fn testCanonical(source: []const u8) {...@@ -1139,19 +1096,19 @@ fn testCanonical(source: []const u8) {
1139 // fail_index, needed_alloc_count,1096 // fail_index, needed_alloc_count,
1140 // failing_allocator.allocated_bytes, failing_allocator.freed_bytes,1097 // failing_allocator.allocated_bytes, failing_allocator.freed_bytes,
1141 // failing_allocator.index, failing_allocator.deallocations);1098 // failing_allocator.index, failing_allocator.deallocations);
1142 // @panic("memory leak detected");1099 // return error.MemoryLeakDetected;
1143 //}1100 //}
1144 }1101 }
1145 }1102 }
1146}1103}
11471104
1148test "zig fmt" {1105test "zig fmt" {
1149 testCanonical(1106 try testCanonical(
1150 \\extern fn puts(s: &const u8) -> c_int;1107 \\extern fn puts(s: &const u8) c_int;
1151 \\1108 \\
1152 );1109 );
11531110
1154 testCanonical(1111 try testCanonical(
1155 \\const a = b;1112 \\const a = b;
1156 \\pub const a = b;1113 \\pub const a = b;
1157 \\var a = b;1114 \\var a = b;
...@@ -1163,44 +1120,44 @@ test "zig fmt" {...@@ -1163,44 +1120,44 @@ test "zig fmt" {
1163 \\1120 \\
1164 );1121 );
11651122
1166 testCanonical(1123 try testCanonical(
1167 \\extern var foo: c_int;1124 \\extern var foo: c_int;
1168 \\1125 \\
1169 );1126 );
11701127
1171 testCanonical(1128 try testCanonical(
1172 \\var foo: c_int align(1);1129 \\var foo: c_int align(1);
1173 \\1130 \\
1174 );1131 );
11751132
1176 testCanonical(1133 try testCanonical(
1177 \\fn main(argc: c_int, argv: &&u8) -> c_int {1134 \\fn main(argc: c_int, argv: &&u8) c_int {
1178 \\ const a = b;1135 \\ const a = b;
1179 \\}1136 \\}
1180 \\1137 \\
1181 );1138 );
11821139
1183 testCanonical(1140 try testCanonical(
1184 \\fn foo(argc: c_int, argv: &&u8) -> c_int {1141 \\fn foo(argc: c_int, argv: &&u8) c_int {
1185 \\ return 0;1142 \\ return 0;
1186 \\}1143 \\}
1187 \\1144 \\
1188 );1145 );
11891146
1190 testCanonical(1147 try testCanonical(
1191 \\extern fn f1(s: &align(&u8) u8) -> c_int;1148 \\extern fn f1(s: &align(&u8) u8) c_int;
1192 \\1149 \\
1193 );1150 );
11941151
1195 testCanonical(1152 try testCanonical(
1196 \\extern fn f1(s: &&align(1) &const &volatile u8) -> c_int;1153 \\extern fn f1(s: &&align(1) &const &volatile u8) c_int;
1197 \\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) -> c_int;1154 \\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) c_int;
1198 \\extern fn f3(s: &align(1) const volatile u8) -> c_int;1155 \\extern fn f3(s: &align(1) const volatile u8) c_int;
1199 \\1156 \\
1200 );1157 );
12011158
1202 testCanonical(1159 try testCanonical(
1203 \\fn f1(a: bool, b: bool) -> bool {1160 \\fn f1(a: bool, b: bool) bool {
1204 \\ a != b;1161 \\ a != b;
1205 \\ return a == b;1162 \\ return a == b;
1206 \\}1163 \\}
src-self-hosted/target.zig+6-6
...@@ -11,7 +11,7 @@ pub const Target = union(enum) {...@@ -11,7 +11,7 @@ pub const Target = union(enum) {
11 Native,11 Native,
12 Cross: CrossTarget,12 Cross: CrossTarget,
1313
14 pub fn oFileExt(self: &const Target) -> []const u8 {14 pub fn oFileExt(self: &const Target) []const u8 {
15 const environ = switch (*self) {15 const environ = switch (*self) {
16 Target.Native => builtin.environ,16 Target.Native => builtin.environ,
17 Target.Cross => |t| t.environ,17 Target.Cross => |t| t.environ,
...@@ -22,28 +22,28 @@ pub const Target = union(enum) {...@@ -22,28 +22,28 @@ pub const Target = union(enum) {
22 };22 };
23 }23 }
2424
25 pub fn exeFileExt(self: &const Target) -> []const u8 {25 pub fn exeFileExt(self: &const Target) []const u8 {
26 return switch (self.getOs()) {26 return switch (self.getOs()) {
27 builtin.Os.windows => ".exe",27 builtin.Os.windows => ".exe",
28 else => "",28 else => "",
29 };29 };
30 }30 }
3131
32 pub fn getOs(self: &const Target) -> builtin.Os {32 pub fn getOs(self: &const Target) builtin.Os {
33 return switch (*self) {33 return switch (*self) {
34 Target.Native => builtin.os,34 Target.Native => builtin.os,
35 Target.Cross => |t| t.os,35 Target.Cross => |t| t.os,
36 };36 };
37 }37 }
3838
39 pub fn isDarwin(self: &const Target) -> bool {39 pub fn isDarwin(self: &const Target) bool {
40 return switch (self.getOs()) {40 return switch (self.getOs()) {
41 builtin.Os.ios, builtin.Os.macosx => true,41 builtin.Os.ios, builtin.Os.macosx => true,
42 else => false,42 else => false,
43 };43 };
44 }44 }
4545
46 pub fn isWindows(self: &const Target) -> bool {46 pub fn isWindows(self: &const Target) bool {
47 return switch (self.getOs()) {47 return switch (self.getOs()) {
48 builtin.Os.windows => true,48 builtin.Os.windows => true,
49 else => false,49 else => false,
...@@ -51,7 +51,7 @@ pub const Target = union(enum) {...@@ -51,7 +51,7 @@ pub const Target = union(enum) {
51 }51 }
52};52};
5353
54pub fn initializeAll() {54pub fn initializeAll() void {
55 c.LLVMInitializeAllTargets();55 c.LLVMInitializeAllTargets();
56 c.LLVMInitializeAllTargetInfos();56 c.LLVMInitializeAllTargetInfos();
57 c.LLVMInitializeAllTargetMCs();57 c.LLVMInitializeAllTargetMCs();
src-self-hosted/tokenizer.zig+9-11
...@@ -16,7 +16,6 @@ pub const Token = struct {...@@ -16,7 +16,6 @@ pub const Token = struct {
16 KeywordId{.bytes="and", .id = Id.Keyword_and},16 KeywordId{.bytes="and", .id = Id.Keyword_and},
17 KeywordId{.bytes="asm", .id = Id.Keyword_asm},17 KeywordId{.bytes="asm", .id = Id.Keyword_asm},
18 KeywordId{.bytes="break", .id = Id.Keyword_break},18 KeywordId{.bytes="break", .id = Id.Keyword_break},
19 KeywordId{.bytes="coldcc", .id = Id.Keyword_coldcc},
20 KeywordId{.bytes="comptime", .id = Id.Keyword_comptime},19 KeywordId{.bytes="comptime", .id = Id.Keyword_comptime},
21 KeywordId{.bytes="const", .id = Id.Keyword_const},20 KeywordId{.bytes="const", .id = Id.Keyword_const},
22 KeywordId{.bytes="continue", .id = Id.Keyword_continue},21 KeywordId{.bytes="continue", .id = Id.Keyword_continue},
...@@ -54,7 +53,7 @@ pub const Token = struct {...@@ -54,7 +53,7 @@ pub const Token = struct {
54 KeywordId{.bytes="while", .id = Id.Keyword_while},53 KeywordId{.bytes="while", .id = Id.Keyword_while},
55 };54 };
5655
57 fn getKeyword(bytes: []const u8) -> ?Id {56 fn getKeyword(bytes: []const u8) ?Id {
58 for (keywords) |kw| {57 for (keywords) |kw| {
59 if (mem.eql(u8, kw.bytes, bytes)) {58 if (mem.eql(u8, kw.bytes, bytes)) {
60 return kw.id;59 return kw.id;
...@@ -97,7 +96,6 @@ pub const Token = struct {...@@ -97,7 +96,6 @@ pub const Token = struct {
97 Keyword_and,96 Keyword_and,
98 Keyword_asm,97 Keyword_asm,
99 Keyword_break,98 Keyword_break,
100 Keyword_coldcc,
101 Keyword_comptime,99 Keyword_comptime,
102 Keyword_const,100 Keyword_const,
103 Keyword_continue,101 Keyword_continue,
...@@ -148,7 +146,7 @@ pub const Tokenizer = struct {...@@ -148,7 +146,7 @@ pub const Tokenizer = struct {
148 line_end: usize,146 line_end: usize,
149 };147 };
150148
151 pub fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {149 pub fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
152 var loc = Location {150 var loc = Location {
153 .line = 0,151 .line = 0,
154 .column = 0,152 .column = 0,
...@@ -173,13 +171,13 @@ pub const Tokenizer = struct {...@@ -173,13 +171,13 @@ pub const Tokenizer = struct {
173 }171 }
174172
175 /// For debugging purposes173 /// For debugging purposes
176 pub fn dump(self: &Tokenizer, token: &const Token) {174 pub fn dump(self: &Tokenizer, token: &const Token) void {
177 std.debug.warn("{} \"{}\"\n", @tagName(token.id), self.buffer[token.start..token.end]);175 std.debug.warn("{} \"{}\"\n", @tagName(token.id), self.buffer[token.start..token.end]);
178 }176 }
179177
180 /// buffer must end with "\n\n\n". This is so that attempting to decode178 /// buffer must end with "\n\n\n". This is so that attempting to decode
181 /// a the 3 trailing bytes of a 4-byte utf8 sequence is never a buffer overflow.179 /// a the 3 trailing bytes of a 4-byte utf8 sequence is never a buffer overflow.
182 pub fn init(buffer: []const u8) -> Tokenizer {180 pub fn init(buffer: []const u8) Tokenizer {
183 std.debug.assert(buffer[buffer.len - 1] == '\n');181 std.debug.assert(buffer[buffer.len - 1] == '\n');
184 std.debug.assert(buffer[buffer.len - 2] == '\n');182 std.debug.assert(buffer[buffer.len - 2] == '\n');
185 std.debug.assert(buffer[buffer.len - 3] == '\n');183 std.debug.assert(buffer[buffer.len - 3] == '\n');
...@@ -214,7 +212,7 @@ pub const Tokenizer = struct {...@@ -214,7 +212,7 @@ pub const Tokenizer = struct {
214 Period2,212 Period2,
215 };213 };
216214
217 pub fn next(self: &Tokenizer) -> Token {215 pub fn next(self: &Tokenizer) Token {
218 if (self.pending_invalid_token) |token| {216 if (self.pending_invalid_token) |token| {
219 self.pending_invalid_token = null;217 self.pending_invalid_token = null;
220 return token;218 return token;
...@@ -530,11 +528,11 @@ pub const Tokenizer = struct {...@@ -530,11 +528,11 @@ pub const Tokenizer = struct {
530 return result;528 return result;
531 }529 }
532530
533 pub fn getTokenSlice(self: &const Tokenizer, token: &const Token) -> []const u8 {531 pub fn getTokenSlice(self: &const Tokenizer, token: &const Token) []const u8 {
534 return self.buffer[token.start..token.end];532 return self.buffer[token.start..token.end];
535 }533 }
536534
537 fn checkLiteralCharacter(self: &Tokenizer) {535 fn checkLiteralCharacter(self: &Tokenizer) void {
538 if (self.pending_invalid_token != null) return;536 if (self.pending_invalid_token != null) return;
539 const invalid_length = self.getInvalidCharacterLength();537 const invalid_length = self.getInvalidCharacterLength();
540 if (invalid_length == 0) return;538 if (invalid_length == 0) return;
...@@ -545,7 +543,7 @@ pub const Tokenizer = struct {...@@ -545,7 +543,7 @@ pub const Tokenizer = struct {
545 };543 };
546 }544 }
547545
548 fn getInvalidCharacterLength(self: &Tokenizer) -> u3 {546 fn getInvalidCharacterLength(self: &Tokenizer) u3 {
549 const c0 = self.buffer[self.index];547 const c0 = self.buffer[self.index];
550 if (c0 < 0x80) {548 if (c0 < 0x80) {
551 if (c0 < 0x20 or c0 == 0x7f) {549 if (c0 < 0x20 or c0 == 0x7f) {
...@@ -638,7 +636,7 @@ test "tokenizer - illegal unicode codepoints" {...@@ -638,7 +636,7 @@ test "tokenizer - illegal unicode codepoints" {
638 testTokenize("//\xe2\x80\xaa", []Token.Id{});636 testTokenize("//\xe2\x80\xaa", []Token.Id{});
639}637}
640638
641fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) {639fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
642 // (test authors, just make this bigger if you need it)640 // (test authors, just make this bigger if you need it)
643 var padded_source: [0x100]u8 = undefined;641 var padded_source: [0x100]u8 = undefined;
644 std.mem.copy(u8, padded_source[0..source.len], source);642 std.mem.copy(u8, padded_source[0..source.len], source);
src/all_types.hpp+16-5
...@@ -1108,6 +1108,7 @@ struct TypeTableEntry {...@@ -1108,6 +1108,7 @@ struct TypeTableEntry {
11081108
1109 bool zero_bits;1109 bool zero_bits;
1110 bool is_copyable;1110 bool is_copyable;
1111 bool gen_h_loop_flag;
11111112
1112 union {1113 union {
1113 TypeTableEntryPointer pointer;1114 TypeTableEntryPointer pointer;
...@@ -1204,6 +1205,9 @@ struct FnTableEntry {...@@ -1204,6 +1205,9 @@ struct FnTableEntry {
1204 AstNode *set_alignstack_node;1205 AstNode *set_alignstack_node;
1205 uint32_t alignstack_value;1206 uint32_t alignstack_value;
12061207
1208 AstNode *set_cold_node;
1209 bool is_cold;
1210
1207 ZigList<FnExport> export_list;1211 ZigList<FnExport> export_list;
1208 bool calls_errorable_function;1212 bool calls_errorable_function;
1209};1213};
...@@ -1250,7 +1254,8 @@ enum BuiltinFnId {...@@ -1250,7 +1254,8 @@ enum BuiltinFnId {
1250 BuiltinFnIdMod,1254 BuiltinFnIdMod,
1251 BuiltinFnIdTruncate,1255 BuiltinFnIdTruncate,
1252 BuiltinFnIdIntType,1256 BuiltinFnIdIntType,
1253 BuiltinFnIdSetDebugSafety,1257 BuiltinFnIdSetCold,
1258 BuiltinFnIdSetRuntimeSafety,
1254 BuiltinFnIdSetFloatMode,1259 BuiltinFnIdSetFloatMode,
1255 BuiltinFnIdTypeName,1260 BuiltinFnIdTypeName,
1256 BuiltinFnIdCanImplicitCast,1261 BuiltinFnIdCanImplicitCast,
...@@ -1830,7 +1835,8 @@ enum IrInstructionId {...@@ -1830,7 +1835,8 @@ enum IrInstructionId {
1830 IrInstructionIdTypeOf,1835 IrInstructionIdTypeOf,
1831 IrInstructionIdToPtrType,1836 IrInstructionIdToPtrType,
1832 IrInstructionIdPtrTypeChild,1837 IrInstructionIdPtrTypeChild,
1833 IrInstructionIdSetDebugSafety,1838 IrInstructionIdSetCold,
1839 IrInstructionIdSetRuntimeSafety,
1834 IrInstructionIdSetFloatMode,1840 IrInstructionIdSetFloatMode,
1835 IrInstructionIdArrayType,1841 IrInstructionIdArrayType,
1836 IrInstructionIdSliceType,1842 IrInstructionIdSliceType,
...@@ -2202,11 +2208,16 @@ struct IrInstructionPtrTypeChild {...@@ -2202,11 +2208,16 @@ struct IrInstructionPtrTypeChild {
2202 IrInstruction *value;2208 IrInstruction *value;
2203};2209};
22042210
2205struct IrInstructionSetDebugSafety {2211struct IrInstructionSetCold {
2206 IrInstruction base;2212 IrInstruction base;
22072213
2208 IrInstruction *scope_value;2214 IrInstruction *is_cold;
2209 IrInstruction *debug_safety_on;2215};
2216
2217struct IrInstructionSetRuntimeSafety {
2218 IrInstruction base;
2219
2220 IrInstruction *safety_on;
2210};2221};
22112222
2212struct IrInstructionSetFloatMode {2223struct IrInstructionSetFloatMode {
src/analyze.cpp+126-50
...@@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t...@@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
609 buf_resize(&entry->name, 0);609 buf_resize(&entry->name, 0);
610 buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));610 buf_appendf(&entry->name, "[%" ZIG_PRI_u64 "]%s", array_size, buf_ptr(&child_type->name));
611611
612 if (!entry->zero_bits) {612 if (entry->zero_bits) {
613 entry->di_type = ZigLLVMCreateDebugArrayType(g->dbuilder, 0,
614 0, child_type->di_type, 0);
615 } else {
613 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref,616 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref,
614 (unsigned int)array_size) : nullptr;617 (unsigned int)array_size) : nullptr;
615618
...@@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
915 if (fn_type_id->alignment != 0) {918 if (fn_type_id->alignment != 0) {
916 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);919 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
917 }920 }
918 if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {921 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
919 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
920 }
921 skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type;922 skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type;
922923
923 // next, loop over the parameters again and compute debug information924 // next, loop over the parameters again and compute debug information
...@@ -1079,7 +1080,7 @@ TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1079,7 +1080,7 @@ TypeTableEntry *get_generic_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1079 const char *comma_str = (i == 0) ? "" : ",";1080 const char *comma_str = (i == 0) ? "" : ",";
1080 buf_appendf(&fn_type->name, "%svar", comma_str);1081 buf_appendf(&fn_type->name, "%svar", comma_str);
1081 }1082 }
1082 buf_appendf(&fn_type->name, ")->var");1083 buf_appendf(&fn_type->name, ")var");
10831084
1084 fn_type->data.fn.fn_type_id = *fn_type_id;1085 fn_type->data.fn.fn_type_id = *fn_type_id;
1085 fn_type->data.fn.is_generic = true;1086 fn_type->data.fn.is_generic = true;
...@@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **...@@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
1155 return true;1156 return true;
1156}1157}
11571158
1159static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1160 switch (type_entry->id) {
1161 case TypeTableEntryIdInvalid:
1162 case TypeTableEntryIdVar:
1163 zig_unreachable();
1164 case TypeTableEntryIdMetaType:
1165 case TypeTableEntryIdUnreachable:
1166 case TypeTableEntryIdNumLitFloat:
1167 case TypeTableEntryIdNumLitInt:
1168 case TypeTableEntryIdUndefLit:
1169 case TypeTableEntryIdNullLit:
1170 case TypeTableEntryIdErrorUnion:
1171 case TypeTableEntryIdPureError:
1172 case TypeTableEntryIdNamespace:
1173 case TypeTableEntryIdBlock:
1174 case TypeTableEntryIdBoundFn:
1175 case TypeTableEntryIdArgTuple:
1176 case TypeTableEntryIdOpaque:
1177 return false;
1178 case TypeTableEntryIdVoid:
1179 case TypeTableEntryIdBool:
1180 case TypeTableEntryIdInt:
1181 case TypeTableEntryIdFloat:
1182 case TypeTableEntryIdPointer:
1183 case TypeTableEntryIdArray:
1184 case TypeTableEntryIdFn:
1185 return true;
1186 case TypeTableEntryIdStruct:
1187 return type_entry->data.structure.layout == ContainerLayoutPacked;
1188 case TypeTableEntryIdUnion:
1189 return type_entry->data.unionation.layout == ContainerLayoutPacked;
1190 case TypeTableEntryIdMaybe:
1191 {
1192 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1193 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
1194 }
1195 case TypeTableEntryIdEnum:
1196 return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
1197 }
1198 zig_unreachable();
1199}
1200
1201static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1202 switch (type_entry->id) {
1203 case TypeTableEntryIdInvalid:
1204 case TypeTableEntryIdVar:
1205 zig_unreachable();
1206 case TypeTableEntryIdMetaType:
1207 case TypeTableEntryIdNumLitFloat:
1208 case TypeTableEntryIdNumLitInt:
1209 case TypeTableEntryIdUndefLit:
1210 case TypeTableEntryIdNullLit:
1211 case TypeTableEntryIdErrorUnion:
1212 case TypeTableEntryIdPureError:
1213 case TypeTableEntryIdNamespace:
1214 case TypeTableEntryIdBlock:
1215 case TypeTableEntryIdBoundFn:
1216 case TypeTableEntryIdArgTuple:
1217 return false;
1218 case TypeTableEntryIdOpaque:
1219 case TypeTableEntryIdUnreachable:
1220 case TypeTableEntryIdVoid:
1221 case TypeTableEntryIdBool:
1222 return true;
1223 case TypeTableEntryIdInt:
1224 switch (type_entry->data.integral.bit_count) {
1225 case 8:
1226 case 16:
1227 case 32:
1228 case 64:
1229 case 128:
1230 return true;
1231 default:
1232 return false;
1233 }
1234 case TypeTableEntryIdFloat:
1235 return true;
1236 case TypeTableEntryIdArray:
1237 return type_allowed_in_extern(g, type_entry->data.array.child_type);
1238 case TypeTableEntryIdFn:
1239 return type_entry->data.fn.fn_type_id.cc == CallingConventionC;
1240 case TypeTableEntryIdPointer:
1241 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
1242 case TypeTableEntryIdStruct:
1243 return type_entry->data.structure.layout == ContainerLayoutExtern;
1244 case TypeTableEntryIdMaybe:
1245 {
1246 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1247 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
1248 }
1249 case TypeTableEntryIdEnum:
1250 return type_entry->data.enumeration.layout == ContainerLayoutExtern;
1251 case TypeTableEntryIdUnion:
1252 return type_entry->data.unionation.layout == ContainerLayoutExtern;
1253 }
1254 zig_unreachable();
1255}
1256
1158static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {1257static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
1159 assert(proto_node->type == NodeTypeFnProto);1258 assert(proto_node->type == NodeTypeFnProto);
1160 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;1259 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
...@@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1205 }1304 }
1206 }1305 }
12071306
1307 if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, type_entry)) {
1308 add_node_error(g, param_node->data.param_decl.type,
1309 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'",
1310 buf_ptr(&type_entry->name),
1311 calling_convention_name(fn_type_id.cc)));
1312 return g->builtin_types.entry_invalid;
1313 }
1314
1208 switch (type_entry->id) {1315 switch (type_entry->id) {
1209 case TypeTableEntryIdInvalid:1316 case TypeTableEntryIdInvalid:
1210 return g->builtin_types.entry_invalid;1317 return g->builtin_types.entry_invalid;
...@@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c...@@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
1269 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?1376 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
1270 g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);1377 g->builtin_types.entry_void : analyze_type_expr(g, child_scope, fn_proto->return_type);
12711378
1379 if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
1380 add_node_error(g, fn_proto->return_type,
1381 buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",
1382 buf_ptr(&fn_type_id.return_type->name),
1383 calling_convention_name(fn_type_id.cc)));
1384 return g->builtin_types.entry_invalid;
1385 }
1386
1272 switch (fn_type_id.return_type->id) {1387 switch (fn_type_id.return_type->id) {
1273 case TypeTableEntryIdInvalid:1388 case TypeTableEntryIdInvalid:
1274 return g->builtin_types.entry_invalid;1389 return g->builtin_types.entry_invalid;
...@@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {...@@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
1421 enum_type->di_type = tag_di_type;1536 enum_type->di_type = tag_di_type;
1422}1537}
14231538
1424static bool type_allowed_in_packed_struct(TypeTableEntry *type_entry) {
1425 switch (type_entry->id) {
1426 case TypeTableEntryIdInvalid:
1427 case TypeTableEntryIdVar:
1428 zig_unreachable();
1429 case TypeTableEntryIdMetaType:
1430 case TypeTableEntryIdUnreachable:
1431 case TypeTableEntryIdNumLitFloat:
1432 case TypeTableEntryIdNumLitInt:
1433 case TypeTableEntryIdUndefLit:
1434 case TypeTableEntryIdNullLit:
1435 case TypeTableEntryIdErrorUnion:
1436 case TypeTableEntryIdPureError:
1437 case TypeTableEntryIdNamespace:
1438 case TypeTableEntryIdBlock:
1439 case TypeTableEntryIdBoundFn:
1440 case TypeTableEntryIdArgTuple:
1441 case TypeTableEntryIdOpaque:
1442 return false;
1443 case TypeTableEntryIdVoid:
1444 case TypeTableEntryIdBool:
1445 case TypeTableEntryIdInt:
1446 case TypeTableEntryIdFloat:
1447 case TypeTableEntryIdPointer:
1448 case TypeTableEntryIdArray:
1449 case TypeTableEntryIdUnion:
1450 case TypeTableEntryIdFn:
1451 return true;
1452 case TypeTableEntryIdStruct:
1453 return type_entry->data.structure.layout == ContainerLayoutPacked;
1454 case TypeTableEntryIdMaybe:
1455 {
1456 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1457 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
1458 }
1459 case TypeTableEntryIdEnum:
1460 return type_entry->data.enumeration.decl_node->data.container_decl.init_arg_expr != nullptr;
1461 }
1462 zig_unreachable();
1463}
14641539
1465TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],1540TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
1466 TypeTableEntry *field_types[], size_t field_count)1541 TypeTableEntry *field_types[], size_t field_count)
...@@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {...@@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
1864 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;1939 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
18651940
1866 TypeTableEntry *tag_type = union_type->data.unionation.tag_type;1941 TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
1867 if (tag_type == nullptr) {1942 if (tag_type == nullptr || tag_type->zero_bits) {
1868 assert(most_aligned_union_member != nullptr);1943 assert(most_aligned_union_member != nullptr);
18691944
1870 if (padding_in_bits > 0) {1945 if (padding_in_bits > 0) {
...@@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {...@@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
25062581
2507 if (create_enum_type) {2582 if (create_enum_type) {
2508 ImportTableEntry *import = get_scope_import(scope);2583 ImportTableEntry *import = get_scope_import(scope);
2509 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);2584 uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 :
2510 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);2585 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
2586 uint64_t tag_debug_align_in_bits = tag_type->zero_bits ? 0 :
2587 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
2511 // TODO get a more accurate debug scope2588 // TODO get a more accurate debug scope
2512 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,2589 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
2513 ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),2590 ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),
...@@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) {...@@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) {
25862663
2587static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) {2664static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) {
2588 add_node_error(g, proto_node,2665 add_node_error(g, proto_node,
2589 buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) -> unreachable', found '%s'",2666 buf_sprintf("expected 'fn([]const u8, ?&builtin.StackTrace) unreachable', found '%s'",
2590 buf_ptr(&fn_type->name)));2667 buf_ptr(&fn_type->name)));
2591}2668}
25922669
...@@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {...@@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
3448TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {3525TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
3449 assert(type_entry->id == TypeTableEntryIdUnion);3526 assert(type_entry->id == TypeTableEntryIdUnion);
3450 assert(type_entry->data.unionation.zero_bits_known);3527 assert(type_entry->data.unionation.zero_bits_known);
3451 assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
3452 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {3528 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
3453 TypeUnionField *field = &type_entry->data.unionation.fields[i];3529 TypeUnionField *field = &type_entry->data.unionation.fields[i];
3454 if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {3530 if (bigint_cmp(&field->enum_field->value, tag) == CmpEQ) {
src/ast_render.cpp+4-5
...@@ -92,7 +92,7 @@ static const char *return_string(ReturnKind kind) {...@@ -92,7 +92,7 @@ static const char *return_string(ReturnKind kind) {
92static const char *defer_string(ReturnKind kind) {92static const char *defer_string(ReturnKind kind) {
93 switch (kind) {93 switch (kind) {
94 case ReturnKindUnconditional: return "defer";94 case ReturnKindUnconditional: return "defer";
95 case ReturnKindError: return "%defer";95 case ReturnKindError: return "errdefer";
96 }96 }
97 zig_unreachable();97 zig_unreachable();
98}98}
...@@ -450,10 +450,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {...@@ -450,10 +450,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
450 }450 }
451451
452 AstNode *return_type_node = node->data.fn_proto.return_type;452 AstNode *return_type_node = node->data.fn_proto.return_type;
453 if (return_type_node != nullptr) {453 assert(return_type_node != nullptr);
454 fprintf(ar->f, " -> ");454 fprintf(ar->f, " ");
455 render_node_grouped(ar, return_type_node);455 render_node_grouped(ar, return_type_node);
456 }
457 break;456 break;
458 }457 }
459 case NodeTypeFnDef:458 case NodeTypeFnDef:
src/codegen.cpp+270-81
...@@ -485,11 +485,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {...@@ -485,11 +485,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
485 addLLVMFnAttr(fn_table_entry->llvm_value, "naked");485 addLLVMFnAttr(fn_table_entry->llvm_value, "naked");
486 } else {486 } else {
487 LLVMSetFunctionCallConv(fn_table_entry->llvm_value, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc));487 LLVMSetFunctionCallConv(fn_table_entry->llvm_value, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc));
488 if (fn_type->data.fn.fn_type_id.cc == CallingConventionCold) {
489 ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
490 }
491 }488 }
492489
490 bool want_cold = fn_table_entry->is_cold || fn_type->data.fn.fn_type_id.cc == CallingConventionCold;
491 if (want_cold) {
492 ZigLLVMAddFunctionAttrCold(fn_table_entry->llvm_value);
493 }
494
495
493 LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));496 LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));
494497
495 if (linkage == GlobalLinkageIdInternal) {498 if (linkage == GlobalLinkageIdInternal) {
...@@ -803,7 +806,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {...@@ -803,7 +806,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
803 return true;806 return true;
804}807}
805808
806static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {809static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
807 if (g->build_mode == BuildModeFastRelease)810 if (g->build_mode == BuildModeFastRelease)
808 return false;811 return false;
809812
...@@ -898,7 +901,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace...@@ -898,7 +901,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
898 LLVMBuildUnreachable(g->builder);901 LLVMBuildUnreachable(g->builder);
899}902}
900903
901static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {904static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
902 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);905 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
903}906}
904907
...@@ -1137,7 +1140,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {...@@ -1137,7 +1140,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
1137 return fn_val;1140 return fn_val;
1138}1141}
11391142
1140static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {1143static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
1141 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);1144 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
1142 LLVMValueRef err_ret_trace_val = g->cur_err_ret_trace_val;1145 LLVMValueRef err_ret_trace_val = g->cur_err_ret_trace_val;
1143 if (err_ret_trace_val == nullptr) {1146 if (err_ret_trace_val == nullptr) {
...@@ -1176,7 +1179,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,...@@ -1176,7 +1179,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
1176 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);1179 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
11771180
1178 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);1181 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);
1179 gen_debug_safety_crash(g, PanicMsgIdBoundsCheckFailure);1182 gen_safety_crash(g, PanicMsgIdBoundsCheckFailure);
11801183
1181 if (upper_value) {1184 if (upper_value) {
1182 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);1185 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);
...@@ -1187,7 +1190,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,...@@ -1187,7 +1190,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
1187 LLVMPositionBuilderAtEnd(g->builder, ok_block);1190 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1188}1191}
11891192
1190static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type,1193static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, TypeTableEntry *actual_type,
1191 TypeTableEntry *wanted_type, LLVMValueRef expr_val)1194 TypeTableEntry *wanted_type, LLVMValueRef expr_val)
1192{1195{
1193 assert(actual_type->id == wanted_type->id);1196 assert(actual_type->id == wanted_type->id);
...@@ -1206,7 +1209,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ...@@ -1206,7 +1209,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12061209
1207 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&1210 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&
1208 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&1211 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
1209 want_debug_safety)1212 want_runtime_safety)
1210 {1213 {
1211 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);1214 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
1212 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");1215 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");
...@@ -1216,7 +1219,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ...@@ -1216,7 +1219,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
1216 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1219 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12171220
1218 LLVMPositionBuilderAtEnd(g->builder, fail_block);1221 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1219 gen_debug_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);1222 gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
12201223
1221 LLVMPositionBuilderAtEnd(g->builder, ok_block);1224 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1222 }1225 }
...@@ -1240,7 +1243,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ...@@ -1240,7 +1243,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
1240 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");1243 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
1241 } else if (actual_type->id == TypeTableEntryIdInt) {1244 } else if (actual_type->id == TypeTableEntryIdInt) {
1242 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");1245 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
1243 if (!want_debug_safety) {1246 if (!want_runtime_safety) {
1244 return trunc_val;1247 return trunc_val;
1245 }1248 }
1246 LLVMValueRef orig_val;1249 LLVMValueRef orig_val;
...@@ -1255,7 +1258,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ...@@ -1255,7 +1258,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
1255 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1258 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12561259
1257 LLVMPositionBuilderAtEnd(g->builder, fail_block);1260 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1258 gen_debug_safety_crash(g, PanicMsgIdCastTruncatedData);1261 gen_safety_crash(g, PanicMsgIdCastTruncatedData);
12591262
1260 LLVMPositionBuilderAtEnd(g->builder, ok_block);1263 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1261 return trunc_val;1264 return trunc_val;
...@@ -1283,7 +1286,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS...@@ -1283,7 +1286,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS
1283 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);1286 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
12841287
1285 LLVMPositionBuilderAtEnd(g->builder, fail_block);1288 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1286 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);1289 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
12871290
1288 LLVMPositionBuilderAtEnd(g->builder, ok_block);1291 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1289 return result;1292 return result;
...@@ -1491,7 +1494,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,...@@ -1491,7 +1494,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
1491 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1494 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
14921495
1493 LLVMPositionBuilderAtEnd(g->builder, fail_block);1496 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1494 gen_debug_safety_crash(g, PanicMsgIdShlOverflowedBits);1497 gen_safety_crash(g, PanicMsgIdShlOverflowedBits);
14951498
1496 LLVMPositionBuilderAtEnd(g->builder, ok_block);1499 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1497 return result;1500 return result;
...@@ -1516,7 +1519,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry,...@@ -1516,7 +1519,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry,
1516 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1519 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
15171520
1518 LLVMPositionBuilderAtEnd(g->builder, fail_block);1521 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1519 gen_debug_safety_crash(g, PanicMsgIdShrOverflowedBits);1522 gen_safety_crash(g, PanicMsgIdShrOverflowedBits);
15201523
1521 LLVMPositionBuilderAtEnd(g->builder, ok_block);1524 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1522 return result;1525 return result;
...@@ -1562,14 +1565,14 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {...@@ -1562,14 +1565,14 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
1562 }1565 }
1563}1566}
15641567
1565static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,1568static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
1566 LLVMValueRef val1, LLVMValueRef val2,1569 LLVMValueRef val1, LLVMValueRef val2,
1567 TypeTableEntry *type_entry, DivKind div_kind)1570 TypeTableEntry *type_entry, DivKind div_kind)
1568{1571{
1569 ZigLLVMSetFastMath(g->builder, want_fast_math);1572 ZigLLVMSetFastMath(g->builder, want_fast_math);
15701573
1571 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);1574 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
1572 if (want_debug_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {1575 if (want_runtime_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {
1573 LLVMValueRef is_zero_bit;1576 LLVMValueRef is_zero_bit;
1574 if (type_entry->id == TypeTableEntryIdInt) {1577 if (type_entry->id == TypeTableEntryIdInt) {
1575 is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");1578 is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
...@@ -1583,7 +1586,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1583,7 +1586,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1583 LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block);1586 LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block);
15841587
1585 LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block);1588 LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block);
1586 gen_debug_safety_crash(g, PanicMsgIdDivisionByZero);1589 gen_safety_crash(g, PanicMsgIdDivisionByZero);
15871590
1588 LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block);1591 LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block);
15891592
...@@ -1600,7 +1603,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1600,7 +1603,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1600 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);1603 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);
16011604
1602 LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block);1605 LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block);
1603 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);1606 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
16041607
1605 LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block);1608 LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block);
1606 }1609 }
...@@ -1612,7 +1615,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1612,7 +1615,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1612 case DivKindFloat:1615 case DivKindFloat:
1613 return result;1616 return result;
1614 case DivKindExact:1617 case DivKindExact:
1615 if (want_debug_safety) {1618 if (want_runtime_safety) {
1616 LLVMValueRef floored = gen_floor(g, result, type_entry);1619 LLVMValueRef floored = gen_floor(g, result, type_entry);
1617 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");1620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
1618 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");1621 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
...@@ -1621,7 +1624,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1621,7 +1624,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1621 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1624 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16221625
1623 LLVMPositionBuilderAtEnd(g->builder, fail_block);1626 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1624 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);1627 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16251628
1626 LLVMPositionBuilderAtEnd(g->builder, ok_block);1629 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1627 }1630 }
...@@ -1669,7 +1672,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1669,7 +1672,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1669 return LLVMBuildUDiv(g->builder, val1, val2, "");1672 return LLVMBuildUDiv(g->builder, val1, val2, "");
1670 }1673 }
1671 case DivKindExact:1674 case DivKindExact:
1672 if (want_debug_safety) {1675 if (want_runtime_safety) {
1673 LLVMValueRef remainder_val;1676 LLVMValueRef remainder_val;
1674 if (type_entry->data.integral.is_signed) {1677 if (type_entry->data.integral.is_signed) {
1675 remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");1678 remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");
...@@ -1683,7 +1686,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1683,7 +1686,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
1683 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);1686 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16841687
1685 LLVMPositionBuilderAtEnd(g->builder, fail_block);1688 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1686 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);1689 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16871690
1688 LLVMPositionBuilderAtEnd(g->builder, ok_block);1691 LLVMPositionBuilderAtEnd(g->builder, ok_block);
1689 }1692 }
...@@ -1721,14 +1724,14 @@ enum RemKind {...@@ -1721,14 +1724,14 @@ enum RemKind {
1721 RemKindMod,1724 RemKindMod,
1722};1725};
17231726
1724static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_math,1727static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
1725 LLVMValueRef val1, LLVMValueRef val2,1728 LLVMValueRef val1, LLVMValueRef val2,
1726 TypeTableEntry *type_entry, RemKind rem_kind)1729 TypeTableEntry *type_entry, RemKind rem_kind)
1727{1730{
1728 ZigLLVMSetFastMath(g->builder, want_fast_math);1731 ZigLLVMSetFastMath(g->builder, want_fast_math);
17291732
1730 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);1733 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
1731 if (want_debug_safety) {1734 if (want_runtime_safety) {
1732 LLVMValueRef is_zero_bit;1735 LLVMValueRef is_zero_bit;
1733 if (type_entry->id == TypeTableEntryIdInt) {1736 if (type_entry->id == TypeTableEntryIdInt) {
1734 LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ;1737 LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ;
...@@ -1743,7 +1746,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_m...@@ -1743,7 +1746,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_m
1743 LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block);1746 LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block);
17441747
1745 LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block);1748 LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block);
1746 gen_debug_safety_crash(g, PanicMsgIdRemainderDivisionByZero);1749 gen_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
17471750
1748 LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block);1751 LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block);
1749 }1752 }
...@@ -1789,8 +1792,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1789,8 +1792,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1789 op_id == IrBinOpBitShiftRightExact);1792 op_id == IrBinOpBitShiftRightExact);
1790 TypeTableEntry *type_entry = op1->value.type;1793 TypeTableEntry *type_entry = op1->value.type;
17911794
1792 bool want_debug_safety = bin_op_instruction->safety_check_on &&1795 bool want_runtime_safety = bin_op_instruction->safety_check_on &&
1793 ir_want_debug_safety(g, &bin_op_instruction->base);1796 ir_want_runtime_safety(g, &bin_op_instruction->base);
17941797
1795 LLVMValueRef op1_value = ir_llvm_value(g, op1);1798 LLVMValueRef op1_value = ir_llvm_value(g, op1);
1796 LLVMValueRef op2_value = ir_llvm_value(g, op2);1799 LLVMValueRef op2_value = ir_llvm_value(g, op2);
...@@ -1838,7 +1841,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1838,7 +1841,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1838 bool is_wrapping = (op_id == IrBinOpAddWrap);1841 bool is_wrapping = (op_id == IrBinOpAddWrap);
1839 if (is_wrapping) {1842 if (is_wrapping) {
1840 return LLVMBuildAdd(g->builder, op1_value, op2_value, "");1843 return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
1841 } else if (want_debug_safety) {1844 } else if (want_runtime_safety) {
1842 return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);1845 return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);
1843 } else if (type_entry->data.integral.is_signed) {1846 } else if (type_entry->data.integral.is_signed) {
1844 return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");1847 return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
...@@ -1863,7 +1866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1863,7 +1866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1863 bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);1866 bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);
1864 if (is_sloppy) {1867 if (is_sloppy) {
1865 return LLVMBuildShl(g->builder, op1_value, op2_casted, "");1868 return LLVMBuildShl(g->builder, op1_value, op2_casted, "");
1866 } else if (want_debug_safety) {1869 } else if (want_runtime_safety) {
1867 return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);1870 return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);
1868 } else if (type_entry->data.integral.is_signed) {1871 } else if (type_entry->data.integral.is_signed) {
1869 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");1872 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");
...@@ -1884,7 +1887,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1884,7 +1887,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1884 } else {1887 } else {
1885 return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");1888 return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");
1886 }1889 }
1887 } else if (want_debug_safety) {1890 } else if (want_runtime_safety) {
1888 return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);1891 return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);
1889 } else if (type_entry->data.integral.is_signed) {1892 } else if (type_entry->data.integral.is_signed) {
1890 return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");1893 return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");
...@@ -1901,7 +1904,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1901,7 +1904,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1901 bool is_wrapping = (op_id == IrBinOpSubWrap);1904 bool is_wrapping = (op_id == IrBinOpSubWrap);
1902 if (is_wrapping) {1905 if (is_wrapping) {
1903 return LLVMBuildSub(g->builder, op1_value, op2_value, "");1906 return LLVMBuildSub(g->builder, op1_value, op2_value, "");
1904 } else if (want_debug_safety) {1907 } else if (want_runtime_safety) {
1905 return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);1908 return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);
1906 } else if (type_entry->data.integral.is_signed) {1909 } else if (type_entry->data.integral.is_signed) {
1907 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");1910 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
...@@ -1920,7 +1923,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1920,7 +1923,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1920 bool is_wrapping = (op_id == IrBinOpMultWrap);1923 bool is_wrapping = (op_id == IrBinOpMultWrap);
1921 if (is_wrapping) {1924 if (is_wrapping) {
1922 return LLVMBuildMul(g->builder, op1_value, op2_value, "");1925 return LLVMBuildMul(g->builder, op1_value, op2_value, "");
1923 } else if (want_debug_safety) {1926 } else if (want_runtime_safety) {
1924 return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);1927 return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);
1925 } else if (type_entry->data.integral.is_signed) {1928 } else if (type_entry->data.integral.is_signed) {
1926 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");1929 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
...@@ -1931,22 +1934,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,...@@ -1931,22 +1934,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
1931 zig_unreachable();1934 zig_unreachable();
1932 }1935 }
1933 case IrBinOpDivUnspecified:1936 case IrBinOpDivUnspecified:
1934 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1937 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1935 op1_value, op2_value, type_entry, DivKindFloat);1938 op1_value, op2_value, type_entry, DivKindFloat);
1936 case IrBinOpDivExact:1939 case IrBinOpDivExact:
1937 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1940 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1938 op1_value, op2_value, type_entry, DivKindExact);1941 op1_value, op2_value, type_entry, DivKindExact);
1939 case IrBinOpDivTrunc:1942 case IrBinOpDivTrunc:
1940 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1943 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1941 op1_value, op2_value, type_entry, DivKindTrunc);1944 op1_value, op2_value, type_entry, DivKindTrunc);
1942 case IrBinOpDivFloor:1945 case IrBinOpDivFloor:
1943 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1946 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1944 op1_value, op2_value, type_entry, DivKindFloor);1947 op1_value, op2_value, type_entry, DivKindFloor);
1945 case IrBinOpRemRem:1948 case IrBinOpRemRem:
1946 return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1949 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1947 op1_value, op2_value, type_entry, RemKindRem);1950 op1_value, op2_value, type_entry, RemKindRem);
1948 case IrBinOpRemMod:1951 case IrBinOpRemMod:
1949 return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),1952 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1950 op1_value, op2_value, type_entry, RemKindMod);1953 op1_value, op2_value, type_entry, RemKindMod);
1951 }1954 }
1952 zig_unreachable();1955 zig_unreachable();
...@@ -2004,7 +2007,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -2004,7 +2007,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2004 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");2007 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
2005 } else if (src_size == 1) {2008 } else if (src_size == 1) {
2006 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);2009 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
2007 if (ir_want_debug_safety(g, &cast_instruction->base)) {2010 if (ir_want_runtime_safety(g, &cast_instruction->base)) {
2008 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");2011 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
2009 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);2012 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
2010 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");2013 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
...@@ -2013,7 +2016,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,...@@ -2013,7 +2016,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
2013 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2016 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
20142017
2015 LLVMPositionBuilderAtEnd(g->builder, fail_block);2018 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2016 gen_debug_safety_crash(g, PanicMsgIdSliceWidenRemainder);2019 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
20172020
2018 LLVMPositionBuilderAtEnd(g->builder, ok_block);2021 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2019 }2022 }
...@@ -2108,7 +2111,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa...@@ -2108,7 +2111,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
2108 int_type = actual_type;2111 int_type = actual_type;
2109 }2112 }
2110 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2113 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
2111 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base), int_type,2114 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), int_type,
2112 instruction->base.value.type, target_val);2115 instruction->base.value.type, target_val);
2113}2116}
21142117
...@@ -2130,7 +2133,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,...@@ -2130,7 +2133,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
2130 TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;2133 TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;
21312134
2132 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2135 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
2133 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),2136 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
2134 instruction->target->value.type, tag_int_type, target_val);2137 instruction->target->value.type, tag_int_type, target_val);
2135}2138}
21362139
...@@ -2144,7 +2147,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I...@@ -2144,7 +2147,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
21442147
2145 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2148 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21462149
2147 if (ir_want_debug_safety(g, &instruction->base)) {2150 if (ir_want_runtime_safety(g, &instruction->base)) {
2148 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);2151 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
2149 LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");2152 LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
2150 LLVMValueRef ok_bit;2153 LLVMValueRef ok_bit;
...@@ -2168,7 +2171,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I...@@ -2168,7 +2171,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
2168 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);2171 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
21692172
2170 LLVMPositionBuilderAtEnd(g->builder, fail_block);2173 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2171 gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);2174 gen_safety_crash(g, PanicMsgIdInvalidErrorCode);
21722175
2173 LLVMPositionBuilderAtEnd(g->builder, ok_block);2176 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2174 }2177 }
...@@ -2185,11 +2188,11 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I...@@ -2185,11 +2188,11 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
2185 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2188 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21862189
2187 if (actual_type->id == TypeTableEntryIdPureError) {2190 if (actual_type->id == TypeTableEntryIdPureError) {
2188 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),2191 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
2189 g->err_tag_type, wanted_type, target_val);2192 g->err_tag_type, wanted_type, target_val);
2190 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {2193 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
2191 if (!type_has_bits(actual_type->data.error.child_type)) {2194 if (!type_has_bits(actual_type->data.error.child_type)) {
2192 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),2195 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
2193 g->err_tag_type, wanted_type, target_val);2196 g->err_tag_type, wanted_type, target_val);
2194 } else {2197 } else {
2195 zig_panic("TODO");2198 zig_panic("TODO");
...@@ -2202,8 +2205,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I...@@ -2202,8 +2205,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
2202static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,2205static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
2203 IrInstructionUnreachable *unreachable_instruction)2206 IrInstructionUnreachable *unreachable_instruction)
2204{2207{
2205 if (ir_want_debug_safety(g, &unreachable_instruction->base)) {2208 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
2206 gen_debug_safety_crash(g, PanicMsgIdUnreachable);2209 gen_safety_crash(g, PanicMsgIdUnreachable);
2207 } else {2210 } else {
2208 LLVMBuildUnreachable(g->builder);2211 LLVMBuildUnreachable(g->builder);
2209 }2212 }
...@@ -2245,7 +2248,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst...@@ -2245,7 +2248,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
2245 } else if (expr_type->id == TypeTableEntryIdInt) {2248 } else if (expr_type->id == TypeTableEntryIdInt) {
2246 if (op_id == IrUnOpNegationWrap) {2249 if (op_id == IrUnOpNegationWrap) {
2247 return LLVMBuildNeg(g->builder, expr, "");2250 return LLVMBuildNeg(g->builder, expr, "");
2248 } else if (ir_want_debug_safety(g, &un_op_instruction->base)) {2251 } else if (ir_want_runtime_safety(g, &un_op_instruction->base)) {
2249 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));2252 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
2250 return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr);2253 return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr);
2251 } else if (expr_type->data.integral.is_signed) {2254 } else if (expr_type->data.integral.is_signed) {
...@@ -2314,7 +2317,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,...@@ -2314,7 +2317,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
2314 var->align_bytes, 0, 0);2317 var->align_bytes, 0, 0);
2315 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));2318 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
2316 } else {2319 } else {
2317 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);2320 bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base);
2318 if (want_safe) {2321 if (want_safe) {
2319 TypeTableEntry *usize = g->builtin_types.entry_usize;2322 TypeTableEntry *usize = g->builtin_types.entry_usize;
2320 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);2323 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
...@@ -2406,7 +2409,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI...@@ -2406,7 +2409,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
2406 if (!type_has_bits(array_type))2409 if (!type_has_bits(array_type))
2407 return nullptr;2410 return nullptr;
24082411
2409 bool safety_check_on = ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on;2412 bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;
24102413
2411 if (array_type->id == TypeTableEntryIdArray) {2414 if (array_type->id == TypeTableEntryIdArray) {
2412 if (safety_check_on) {2415 if (safety_check_on) {
...@@ -2590,7 +2593,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -2590,7 +2593,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
2590 return bitcasted_union_field_ptr;2593 return bitcasted_union_field_ptr;
2591 }2594 }
25922595
2593 if (ir_want_debug_safety(g, &instruction->base)) {2596 if (ir_want_runtime_safety(g, &instruction->base)) {
2594 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");2597 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
2595 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");2598 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
25962599
...@@ -2603,7 +2606,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab...@@ -2603,7 +2606,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
2603 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);2606 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
26042607
2605 LLVMPositionBuilderAtEnd(g->builder, bad_block);2608 LLVMPositionBuilderAtEnd(g->builder, bad_block);
2606 gen_debug_safety_crash(g, PanicMsgIdBadUnionField);2609 gen_safety_crash(g, PanicMsgIdBadUnionField);
26072610
2608 LLVMPositionBuilderAtEnd(g->builder, ok_block);2611 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2609 }2612 }
...@@ -2773,14 +2776,14 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,...@@ -2773,14 +2776,14 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
2773 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;2776 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
2774 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);2777 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
2775 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);2778 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
2776 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {2779 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
2777 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);2780 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
2778 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");2781 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
2779 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");2782 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");
2780 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);2783 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
27812784
2782 LLVMPositionBuilderAtEnd(g->builder, fail_block);2785 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2783 gen_debug_safety_crash(g, PanicMsgIdUnwrapMaybeFail);2786 gen_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
27842787
2785 LLVMPositionBuilderAtEnd(g->builder, ok_block);2788 LLVMPositionBuilderAtEnd(g->builder, ok_block);
2786 }2789 }
...@@ -2910,7 +2913,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI...@@ -2910,7 +2913,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
2910 }2913 }
29112914
2912 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);2915 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
2913 if (ir_want_debug_safety(g, &instruction->base)) {2916 if (ir_want_runtime_safety(g, &instruction->base)) {
2914 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));2917 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
2915 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);2918 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);
2916 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);2919 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
...@@ -2932,7 +2935,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable...@@ -2932,7 +2935,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
29322935
2933 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;2936 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
2934 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);2937 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
2935 if (ir_want_debug_safety(g, &instruction->base)) {2938 if (ir_want_runtime_safety(g, &instruction->base)) {
2936 size_t field_count = enum_type->data.enumeration.src_field_count;2939 size_t field_count = enum_type->data.enumeration.src_field_count;
29372940
2938 // if the field_count can't fit in the bits of the enum_type, then it can't possibly2941 // if the field_count can't fit in the bits of the enum_type, then it can't possibly
...@@ -2985,8 +2988,8 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I...@@ -2985,8 +2988,8 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
2985 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);2988 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
2986 assert(target_val);2989 assert(target_val);
29872990
2988 bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);2991 bool want_runtime_safety = ir_want_runtime_safety(g, &instruction->base);
2989 if (!want_debug_safety) {2992 if (!want_runtime_safety) {
2990 return target_val;2993 return target_val;
2991 }2994 }
29922995
...@@ -3035,7 +3038,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I...@@ -3035,7 +3038,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
3035 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);3038 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
30363039
3037 LLVMPositionBuilderAtEnd(g->builder, fail_block);3040 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3038 gen_debug_safety_crash(g, PanicMsgIdIncorrectAlignment);3041 gen_safety_crash(g, PanicMsgIdIncorrectAlignment);
30393042
3040 LLVMPositionBuilderAtEnd(g->builder, ok_block);3043 LLVMPositionBuilderAtEnd(g->builder, ok_block);
30413044
...@@ -3173,7 +3176,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3173,7 +3176,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31733176
3174 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;3177 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
31753178
3176 bool want_debug_safety = instruction->safety_check_on && ir_want_debug_safety(g, &instruction->base);3179 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
31773180
3178 if (array_type->id == TypeTableEntryIdArray) {3181 if (array_type->id == TypeTableEntryIdArray) {
3179 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);3182 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
...@@ -3184,7 +3187,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3184,7 +3187,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
3184 end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);3187 end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);
3185 }3188 }
31863189
3187 if (want_debug_safety) {3190 if (want_runtime_safety) {
3188 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);3191 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
3189 if (instruction->end) {3192 if (instruction->end) {
3190 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,3193 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
...@@ -3195,7 +3198,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3195,7 +3198,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
3195 if (!type_has_bits(array_type)) {3198 if (!type_has_bits(array_type)) {
3196 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");3199 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
31973200
3198 // TODO if debug safety is on, store 0xaaaaaaa in ptr field3201 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field
3199 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");3202 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
3200 gen_store_untyped(g, len_value, len_field_ptr, 0, false);3203 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3201 return tmp_struct_ptr;3204 return tmp_struct_ptr;
...@@ -3219,7 +3222,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3219,7 +3222,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
3219 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);3222 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
3220 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);3223 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
32213224
3222 if (want_debug_safety) {3225 if (want_runtime_safety) {
3223 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);3226 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
3224 }3227 }
32253228
...@@ -3243,7 +3246,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3243,7 +3246,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
3243 assert(len_index != SIZE_MAX);3246 assert(len_index != SIZE_MAX);
32443247
3245 LLVMValueRef prev_end = nullptr;3248 LLVMValueRef prev_end = nullptr;
3246 if (!instruction->end || want_debug_safety) {3249 if (!instruction->end || want_runtime_safety) {
3247 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");3250 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
3248 prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");3251 prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
3249 }3252 }
...@@ -3256,7 +3259,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst...@@ -3256,7 +3259,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
3256 end_val = prev_end;3259 end_val = prev_end;
3257 }3260 }
32583261
3259 if (want_debug_safety) {3262 if (want_runtime_safety) {
3260 assert(prev_end);3263 assert(prev_end);
3261 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);3264 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
3262 if (instruction->end) {3265 if (instruction->end) {
...@@ -3429,7 +3432,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3429,7 +3432,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3429 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);3432 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
3430 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);3433 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
34313434
3432 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {3435 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
3433 LLVMValueRef err_val;3436 LLVMValueRef err_val;
3434 if (type_has_bits(child_type)) {3437 if (type_has_bits(child_type)) {
3435 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");3438 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
...@@ -3444,7 +3447,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu...@@ -3444,7 +3447,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
3444 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);3447 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
34453448
3446 LLVMPositionBuilderAtEnd(g->builder, err_block);3449 LLVMPositionBuilderAtEnd(g->builder, err_block);
3447 gen_debug_safety_crash_for_err(g, err_val);3450 gen_safety_crash_for_err(g, err_val);
34483451
3449 LLVMPositionBuilderAtEnd(g->builder, ok_block);3452 LLVMPositionBuilderAtEnd(g->builder, ok_block);
3450 }3453 }
...@@ -3656,7 +3659,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3656,7 +3659,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3656 case IrInstructionIdToPtrType:3659 case IrInstructionIdToPtrType:
3657 case IrInstructionIdPtrTypeChild:3660 case IrInstructionIdPtrTypeChild:
3658 case IrInstructionIdFieldPtr:3661 case IrInstructionIdFieldPtr:
3659 case IrInstructionIdSetDebugSafety:3662 case IrInstructionIdSetCold:
3663 case IrInstructionIdSetRuntimeSafety:
3660 case IrInstructionIdSetFloatMode:3664 case IrInstructionIdSetFloatMode:
3661 case IrInstructionIdArrayType:3665 case IrInstructionIdArrayType:
3662 case IrInstructionIdSliceType:3666 case IrInstructionIdSliceType:
...@@ -5233,7 +5237,8 @@ static void define_builtin_fns(CodeGen *g) {...@@ -5233,7 +5237,8 @@ static void define_builtin_fns(CodeGen *g) {
5233 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);5237 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
5234 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);5238 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
5235 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int5239 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
5236 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);5240 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
5241 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
5237 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);5242 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
5238 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);5243 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
5239 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);5244 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
...@@ -5788,7 +5793,76 @@ static const char *c_int_type_names[] = {...@@ -5788,7 +5793,76 @@ static const char *c_int_type_names[] = {
5788 "unsigned long long",5793 "unsigned long long",
5789};5794};
57905795
5791static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {5796struct GenH {
5797 ZigList<TypeTableEntry *> types_to_declare;
5798};
5799
5800static void prepend_c_type_to_decl_list(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry) {
5801 if (type_entry->gen_h_loop_flag)
5802 return;
5803 type_entry->gen_h_loop_flag = true;
5804
5805 switch (type_entry->id) {
5806 case TypeTableEntryIdInvalid:
5807 case TypeTableEntryIdVar:
5808 case TypeTableEntryIdMetaType:
5809 case TypeTableEntryIdNumLitFloat:
5810 case TypeTableEntryIdNumLitInt:
5811 case TypeTableEntryIdUndefLit:
5812 case TypeTableEntryIdNullLit:
5813 case TypeTableEntryIdNamespace:
5814 case TypeTableEntryIdBlock:
5815 case TypeTableEntryIdBoundFn:
5816 case TypeTableEntryIdArgTuple:
5817 case TypeTableEntryIdErrorUnion:
5818 case TypeTableEntryIdPureError:
5819 zig_unreachable();
5820 case TypeTableEntryIdVoid:
5821 case TypeTableEntryIdUnreachable:
5822 case TypeTableEntryIdBool:
5823 case TypeTableEntryIdInt:
5824 case TypeTableEntryIdFloat:
5825 return;
5826 case TypeTableEntryIdOpaque:
5827 gen_h->types_to_declare.append(type_entry);
5828 return;
5829 case TypeTableEntryIdStruct:
5830 for (uint32_t i = 0; i < type_entry->data.structure.src_field_count; i += 1) {
5831 TypeStructField *field = &type_entry->data.structure.fields[i];
5832 prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
5833 }
5834 gen_h->types_to_declare.append(type_entry);
5835 return;
5836 case TypeTableEntryIdUnion:
5837 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
5838 TypeUnionField *field = &type_entry->data.unionation.fields[i];
5839 prepend_c_type_to_decl_list(g, gen_h, field->type_entry);
5840 }
5841 gen_h->types_to_declare.append(type_entry);
5842 return;
5843 case TypeTableEntryIdEnum:
5844 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.enumeration.tag_int_type);
5845 gen_h->types_to_declare.append(type_entry);
5846 return;
5847 case TypeTableEntryIdPointer:
5848 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.pointer.child_type);
5849 return;
5850 case TypeTableEntryIdArray:
5851 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.array.child_type);
5852 return;
5853 case TypeTableEntryIdMaybe:
5854 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.maybe.child_type);
5855 return;
5856 case TypeTableEntryIdFn:
5857 for (size_t i = 0; i < type_entry->data.fn.fn_type_id.param_count; i += 1) {
5858 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.param_info[i].type);
5859 }
5860 prepend_c_type_to_decl_list(g, gen_h, type_entry->data.fn.fn_type_id.return_type);
5861 return;
5862 }
5863}
5864
5865static void get_c_type(CodeGen *g, GenH *gen_h, TypeTableEntry *type_entry, Buf *out_buf) {
5792 assert(type_entry);5866 assert(type_entry);
57935867
5794 for (size_t i = 0; i < array_length(c_int_type_names); i += 1) {5868 for (size_t i = 0; i < array_length(c_int_type_names); i += 1) {
...@@ -5816,6 +5890,8 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -5816,6 +5890,8 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
5816 return;5890 return;
5817 }5891 }
58185892
5893 prepend_c_type_to_decl_list(g, gen_h, type_entry);
5894
5819 switch (type_entry->id) {5895 switch (type_entry->id) {
5820 case TypeTableEntryIdVoid:5896 case TypeTableEntryIdVoid:
5821 buf_init_from_str(out_buf, "void");5897 buf_init_from_str(out_buf, "void");
...@@ -5856,7 +5932,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -5856,7 +5932,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
5856 {5932 {
5857 Buf child_buf = BUF_INIT;5933 Buf child_buf = BUF_INIT;
5858 TypeTableEntry *child_type = type_entry->data.pointer.child_type;5934 TypeTableEntry *child_type = type_entry->data.pointer.child_type;
5859 get_c_type(g, child_type, &child_buf);5935 get_c_type(g, gen_h, child_type, &child_buf);
58605936
5861 const char *const_str = type_entry->data.pointer.is_const ? "const " : "";5937 const char *const_str = type_entry->data.pointer.is_const ? "const " : "";
5862 buf_resize(out_buf, 0);5938 buf_resize(out_buf, 0);
...@@ -5872,23 +5948,47 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {...@@ -5872,23 +5948,47 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
5872 } else if (child_type->id == TypeTableEntryIdPointer ||5948 } else if (child_type->id == TypeTableEntryIdPointer ||
5873 child_type->id == TypeTableEntryIdFn)5949 child_type->id == TypeTableEntryIdFn)
5874 {5950 {
5875 return get_c_type(g, child_type, out_buf);5951 return get_c_type(g, gen_h, child_type, out_buf);
5876 } else {5952 } else {
5877 zig_unreachable();5953 zig_unreachable();
5878 }5954 }
5879 }5955 }
5880 case TypeTableEntryIdStruct:5956 case TypeTableEntryIdStruct:
5957 {
5958 buf_init_from_str(out_buf, "struct ");
5959 buf_append_buf(out_buf, &type_entry->name);
5960 return;
5961 }
5962 case TypeTableEntryIdUnion:
5963 {
5964 buf_init_from_str(out_buf, "union ");
5965 buf_append_buf(out_buf, &type_entry->name);
5966 return;
5967 }
5968 case TypeTableEntryIdEnum:
5969 {
5970 buf_init_from_str(out_buf, "enum ");
5971 buf_append_buf(out_buf, &type_entry->name);
5972 return;
5973 }
5881 case TypeTableEntryIdOpaque:5974 case TypeTableEntryIdOpaque:
5882 {5975 {
5883 // TODO add to table of structs we need to declare
5884 buf_init_from_buf(out_buf, &type_entry->name);5976 buf_init_from_buf(out_buf, &type_entry->name);
5885 return;5977 return;
5886 }5978 }
5887 case TypeTableEntryIdArray:5979 case TypeTableEntryIdArray:
5980 {
5981 TypeTableEntryArray *array_data = &type_entry->data.array;
5982
5983 Buf *child_buf = buf_alloc();
5984 get_c_type(g, gen_h, array_data->child_type, child_buf);
5985
5986 buf_resize(out_buf, 0);
5987 buf_appendf(out_buf, "%s", buf_ptr(child_buf));
5988 return;
5989 }
5888 case TypeTableEntryIdErrorUnion:5990 case TypeTableEntryIdErrorUnion:
5889 case TypeTableEntryIdPureError:5991 case TypeTableEntryIdPureError:
5890 case TypeTableEntryIdEnum:
5891 case TypeTableEntryIdUnion:
5892 case TypeTableEntryIdFn:5992 case TypeTableEntryIdFn:
5893 zig_panic("TODO implement get_c_type for more types");5993 zig_panic("TODO implement get_c_type for more types");
5894 case TypeTableEntryIdInvalid:5994 case TypeTableEntryIdInvalid:
...@@ -5942,6 +6042,9 @@ static void gen_h_file(CodeGen *g) {...@@ -5942,6 +6042,9 @@ static void gen_h_file(CodeGen *g) {
5942 if (!g->want_h_file)6042 if (!g->want_h_file)
5943 return;6043 return;
59446044
6045 GenH gen_h_data = {0};
6046 GenH *gen_h = &gen_h_data;
6047
5945 codegen_add_time_event(g, "Generate .h");6048 codegen_add_time_event(g, "Generate .h");
59466049
5947 assert(!g->is_test_build);6050 assert(!g->is_test_build);
...@@ -5971,7 +6074,7 @@ static void gen_h_file(CodeGen *g) {...@@ -5971,7 +6074,7 @@ static void gen_h_file(CodeGen *g) {
5971 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;6074 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
59726075
5973 Buf return_type_c = BUF_INIT;6076 Buf return_type_c = BUF_INIT;
5974 get_c_type(g, fn_type_id->return_type, &return_type_c);6077 get_c_type(g, gen_h, fn_type_id->return_type, &return_type_c);
59756078
5976 buf_appendf(&h_buf, "%s %s %s(",6079 buf_appendf(&h_buf, "%s %s %s(",
5977 buf_ptr(export_macro),6080 buf_ptr(export_macro),
...@@ -5987,9 +6090,16 @@ static void gen_h_file(CodeGen *g) {...@@ -5987,9 +6090,16 @@ static void gen_h_file(CodeGen *g) {
59876090
5988 const char *comma_str = (param_i == 0) ? "" : ", ";6091 const char *comma_str = (param_i == 0) ? "" : ", ";
5989 const char *restrict_str = param_info->is_noalias ? "restrict" : "";6092 const char *restrict_str = param_info->is_noalias ? "restrict" : "";
5990 get_c_type(g, param_info->type, &param_type_c);6093 get_c_type(g, gen_h, param_info->type, &param_type_c);
5991 buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),6094
5992 restrict_str, buf_ptr(param_name));6095 if (param_info->type->id == TypeTableEntryIdArray) {
6096 // Arrays decay to pointers
6097 buf_appendf(&h_buf, "%s%s%s %s[]", comma_str, buf_ptr(&param_type_c),
6098 restrict_str, buf_ptr(param_name));
6099 } else {
6100 buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),
6101 restrict_str, buf_ptr(param_name));
6102 }
5993 }6103 }
5994 buf_appendf(&h_buf, ")");6104 buf_appendf(&h_buf, ")");
5995 } else {6105 } else {
...@@ -6027,6 +6137,85 @@ static void gen_h_file(CodeGen *g) {...@@ -6027,6 +6137,85 @@ static void gen_h_file(CodeGen *g) {
6027 fprintf(out_h, "#endif\n");6137 fprintf(out_h, "#endif\n");
6028 fprintf(out_h, "\n");6138 fprintf(out_h, "\n");
60296139
6140 for (size_t type_i = 0; type_i < gen_h->types_to_declare.length; type_i += 1) {
6141 TypeTableEntry *type_entry = gen_h->types_to_declare.at(type_i);
6142 switch (type_entry->id) {
6143 case TypeTableEntryIdInvalid:
6144 case TypeTableEntryIdVar:
6145 case TypeTableEntryIdMetaType:
6146 case TypeTableEntryIdVoid:
6147 case TypeTableEntryIdBool:
6148 case TypeTableEntryIdUnreachable:
6149 case TypeTableEntryIdInt:
6150 case TypeTableEntryIdFloat:
6151 case TypeTableEntryIdPointer:
6152 case TypeTableEntryIdNumLitFloat:
6153 case TypeTableEntryIdNumLitInt:
6154 case TypeTableEntryIdArray:
6155 case TypeTableEntryIdUndefLit:
6156 case TypeTableEntryIdNullLit:
6157 case TypeTableEntryIdErrorUnion:
6158 case TypeTableEntryIdPureError:
6159 case TypeTableEntryIdNamespace:
6160 case TypeTableEntryIdBlock:
6161 case TypeTableEntryIdBoundFn:
6162 case TypeTableEntryIdArgTuple:
6163 case TypeTableEntryIdMaybe:
6164 case TypeTableEntryIdFn:
6165 zig_unreachable();
6166 case TypeTableEntryIdEnum:
6167 assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);
6168 fprintf(out_h, "enum %s {\n", buf_ptr(&type_entry->name));
6169 for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {
6170 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
6171 Buf *value_buf = buf_alloc();
6172 bigint_append_buf(value_buf, &enum_field->value, 10);
6173 fprintf(out_h, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf));
6174 if (field_i != type_entry->data.enumeration.src_field_count - 1) {
6175 fprintf(out_h, ",");
6176 }
6177 fprintf(out_h, "\n");
6178 }
6179 fprintf(out_h, "};\n\n");
6180 break;
6181 case TypeTableEntryIdStruct:
6182 assert(type_entry->data.structure.layout == ContainerLayoutExtern);
6183 fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name));
6184 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
6185 TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
6186
6187 Buf *type_name_buf = buf_alloc();
6188 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
6189
6190 if (struct_field->type_entry->id == TypeTableEntryIdArray) {
6191 fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
6192 buf_ptr(struct_field->name),
6193 struct_field->type_entry->data.array.len);
6194 } else {
6195 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
6196 }
6197
6198 }
6199 fprintf(out_h, "};\n\n");
6200 break;
6201 case TypeTableEntryIdUnion:
6202 assert(type_entry->data.unionation.layout == ContainerLayoutExtern);
6203 fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name));
6204 for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
6205 TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
6206
6207 Buf *type_name_buf = buf_alloc();
6208 get_c_type(g, gen_h, union_field->type_entry, type_name_buf);
6209 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name));
6210 }
6211 fprintf(out_h, "};\n\n");
6212 break;
6213 case TypeTableEntryIdOpaque:
6214 fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name));
6215 break;
6216 }
6217 }
6218
6030 fprintf(out_h, "%s", buf_ptr(&h_buf));6219 fprintf(out_h, "%s", buf_ptr(&h_buf));
60316220
6032 fprintf(out_h, "\n#endif\n");6221 fprintf(out_h, "\n#endif\n");
src/ir.cpp+132-69
...@@ -272,8 +272,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)...@@ -272,8 +272,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)
272 return IrInstructionIdPtrTypeChild;272 return IrInstructionIdPtrTypeChild;
273}273}
274274
275static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {275static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
276 return IrInstructionIdSetDebugSafety;276 return IrInstructionIdSetCold;
277}
278
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) {
280 return IrInstructionIdSetRuntimeSafety;
277}281}
278282
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) {283static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) {
...@@ -1262,15 +1266,22 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN...@@ -1262,15 +1266,22 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN
1262 return &instruction->base;1266 return &instruction->base;
1263}1267}
12641268
1265static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,1269static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {
1266 IrInstruction *scope_value, IrInstruction *debug_safety_on)1270 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node);
1271 instruction->is_cold = is_cold;
1272
1273 ir_ref_instruction(is_cold, irb->current_basic_block);
1274
1275 return &instruction->base;
1276}
1277
1278static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
1279 IrInstruction *safety_on)
1267{1280{
1268 IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, scope, source_node);1281 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node);
1269 instruction->scope_value = scope_value;1282 instruction->safety_on = safety_on;
1270 instruction->debug_safety_on = debug_safety_on;
12711283
1272 ir_ref_instruction(scope_value, irb->current_basic_block);1284 ir_ref_instruction(safety_on, irb->current_basic_block);
1273 ir_ref_instruction(debug_safety_on, irb->current_basic_block);
12741285
1275 return &instruction->base;1286 return &instruction->base;
1276}1287}
...@@ -3065,19 +3076,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo...@@ -3065,19 +3076,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
3065 return arg;3076 return arg;
3066 return ir_build_typeof(irb, scope, node, arg);3077 return ir_build_typeof(irb, scope, node, arg);
3067 }3078 }
3068 case BuiltinFnIdSetDebugSafety:3079 case BuiltinFnIdSetCold:
3069 {3080 {
3070 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);3081 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3071 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);3082 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3072 if (arg0_value == irb->codegen->invalid_instruction)3083 if (arg0_value == irb->codegen->invalid_instruction)
3073 return arg0_value;3084 return arg0_value;
30743085
3075 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);3086 return ir_build_set_cold(irb, scope, node, arg0_value);
3076 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);3087 }
3077 if (arg1_value == irb->codegen->invalid_instruction)3088 case BuiltinFnIdSetRuntimeSafety:
3078 return arg1_value;3089 {
3090 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
3091 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
3092 if (arg0_value == irb->codegen->invalid_instruction)
3093 return arg0_value;
30793094
3080 return ir_build_set_debug_safety(irb, scope, node, arg0_value, arg1_value);3095 return ir_build_set_runtime_safety(irb, scope, node, arg0_value);
3081 }3096 }
3082 case BuiltinFnIdSetFloatMode:3097 case BuiltinFnIdSetFloatMode:
3083 {3098 {
...@@ -4769,7 +4784,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4769,7 +4784,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
4769}4784}
47704785
4771static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,4786static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node,
4772 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *target_value_ptr, IrInstruction *prong_value,4787 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime,
4788 IrInstruction *target_value_ptr, IrInstruction *prong_value,
4773 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)4789 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)
4774{4790{
4775 assert(switch_node->type == NodeTypeSwitchExpr);4791 assert(switch_node->type == NodeTypeSwitchExpr);
...@@ -4786,7 +4802,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit...@@ -4786,7 +4802,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
4786 bool is_shadowable = false;4802 bool is_shadowable = false;
4787 bool is_const = true;4803 bool is_const = true;
4788 VariableTableEntry *var = ir_create_var(irb, var_symbol_node, scope,4804 VariableTableEntry *var = ir_create_var(irb, var_symbol_node, scope,
4789 var_name, is_const, is_const, is_shadowable, is_comptime);4805 var_name, is_const, is_const, is_shadowable, var_is_comptime);
4790 child_scope = var->child_scope;4806 child_scope = var->child_scope;
4791 IrInstruction *var_value;4807 IrInstruction *var_value;
4792 if (prong_value) {4808 if (prong_value) {
...@@ -4827,10 +4843,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4827,10 +4843,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
4827 ZigList<IrInstructionSwitchBrCase> cases = {0};4843 ZigList<IrInstructionSwitchBrCase> cases = {0};
48284844
4829 IrInstruction *is_comptime;4845 IrInstruction *is_comptime;
4846 IrInstruction *var_is_comptime;
4830 if (ir_should_inline(irb->exec, scope)) {4847 if (ir_should_inline(irb->exec, scope)) {
4831 is_comptime = ir_build_const_bool(irb, scope, node, true);4848 is_comptime = ir_build_const_bool(irb, scope, node, true);
4849 var_is_comptime = is_comptime;
4832 } else {4850 } else {
4833 is_comptime = ir_build_test_comptime(irb, scope, node, target_value);4851 is_comptime = ir_build_test_comptime(irb, scope, node, target_value);
4852 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr);
4834 }4853 }
48354854
4836 ZigList<IrInstruction *> incoming_values = {0};4855 ZigList<IrInstruction *> incoming_values = {0};
...@@ -4856,7 +4875,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4856,7 +4875,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
4856 IrBasicBlock *prev_block = irb->current_basic_block;4875 IrBasicBlock *prev_block = irb->current_basic_block;
4857 ir_set_cursor_at_end_and_append_block(irb, else_block);4876 ir_set_cursor_at_end_and_append_block(irb, else_block);
4858 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,4877 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
4859 is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))4878 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
4860 {4879 {
4861 return irb->codegen->invalid_instruction;4880 return irb->codegen->invalid_instruction;
4862 }4881 }
...@@ -4923,7 +4942,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4923,7 +4942,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
49234942
4924 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);4943 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
4925 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,4944 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
4926 is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))4945 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
4927 {4946 {
4928 return irb->codegen->invalid_instruction;4947 return irb->codegen->invalid_instruction;
4929 }4948 }
...@@ -4967,7 +4986,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4967,7 +4986,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
4967 IrBasicBlock *prev_block = irb->current_basic_block;4986 IrBasicBlock *prev_block = irb->current_basic_block;
4968 ir_set_cursor_at_end_and_append_block(irb, prong_block);4987 ir_set_cursor_at_end_and_append_block(irb, prong_block);
4969 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,4988 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
4970 is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))4989 is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
4971 {4990 {
4972 return irb->codegen->invalid_instruction;4991 return irb->codegen->invalid_instruction;
4973 }4992 }
...@@ -4992,7 +5011,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -4992,7 +5011,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
49925011
4993 ir_set_cursor_at_end_and_append_block(irb, end_block);5012 ir_set_cursor_at_end_and_append_block(irb, end_block);
4994 assert(incoming_blocks.length == incoming_values.length);5013 assert(incoming_blocks.length == incoming_values.length);
4995 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);5014 if (incoming_blocks.length == 0) {
5015 return ir_build_const_void(irb, scope, node);
5016 } else {
5017 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
5018 }
4996}5019}
49975020
4998static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {5021static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) {
...@@ -8816,6 +8839,13 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *...@@ -8816,6 +8839,13 @@ static TypeTableEntry *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *
8816 if (op_id == IrBinOpBitShiftLeftLossy) {8839 if (op_id == IrBinOpBitShiftLeftLossy) {
8817 op_id = IrBinOpBitShiftLeftExact;8840 op_id = IrBinOpBitShiftLeftExact;
8818 }8841 }
8842
8843 if (casted_op2->value.data.x_bigint.is_negative) {
8844 Buf *val_buf = buf_alloc();
8845 bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10);
8846 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf)));
8847 return ira->codegen->builtin_types.entry_invalid;
8848 }
8819 } else {8849 } else {
8820 TypeTableEntry *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen,8850 TypeTableEntry *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen,
8821 op1->value.type->data.integral.bit_count - 1);8851 op1->value.type->data.integral.bit_count - 1);
...@@ -9002,7 +9032,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp...@@ -9002,7 +9032,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
9002 int err;9032 int err;
9003 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {9033 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {
9004 if (err == ErrorDivByZero) {9034 if (err == ErrorDivByZero) {
9005 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("division by zero is undefined"));9035 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("division by zero"));
9006 return ira->codegen->builtin_types.entry_invalid;9036 return ira->codegen->builtin_types.entry_invalid;
9007 } else if (err == ErrorOverflow) {9037 } else if (err == ErrorOverflow) {
9008 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow"));9038 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow"));
...@@ -11540,72 +11570,90 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,...@@ -11540,72 +11570,90 @@ static TypeTableEntry *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira,
11540 return ira->codegen->builtin_types.entry_type;11570 return ira->codegen->builtin_types.entry_type;
11541}11571}
1154211572
11543static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,11573static TypeTableEntry *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {
11544 IrInstructionSetDebugSafety *set_debug_safety_instruction)11574 if (ira->new_irb.exec->is_inline) {
11545{11575 // ignore setCold when running functions at compile time
11546 IrInstruction *target_instruction = set_debug_safety_instruction->scope_value->other;11576 ir_build_const_from(ira, &instruction->base);
11547 TypeTableEntry *target_type = target_instruction->value.type;11577 return ira->codegen->builtin_types.entry_void;
11548 if (type_is_invalid(target_type))11578 }
11579
11580 IrInstruction *is_cold_value = instruction->is_cold->other;
11581 bool want_cold;
11582 if (!ir_resolve_bool(ira, is_cold_value, &want_cold))
11549 return ira->codegen->builtin_types.entry_invalid;11583 return ira->codegen->builtin_types.entry_invalid;
11550 ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad);11584
11551 if (!target_val)11585 FnTableEntry *fn_entry = scope_fn_entry(instruction->base.scope);
11586 if (fn_entry == nullptr) {
11587 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function"));
11552 return ira->codegen->builtin_types.entry_invalid;11588 return ira->codegen->builtin_types.entry_invalid;
11589 }
1155311590
11591 if (fn_entry->set_cold_node != nullptr) {
11592 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function"));
11593 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here"));
11594 return ira->codegen->builtin_types.entry_invalid;
11595 }
11596
11597 fn_entry->set_cold_node = instruction->base.source_node;
11598 fn_entry->is_cold = want_cold;
11599
11600 ir_build_const_from(ira, &instruction->base);
11601 return ira->codegen->builtin_types.entry_void;
11602}
11603static TypeTableEntry *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira,
11604 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction)
11605{
11554 if (ira->new_irb.exec->is_inline) {11606 if (ira->new_irb.exec->is_inline) {
11555 // ignore setDebugSafety when running functions at compile time11607 // ignore setRuntimeSafety when running functions at compile time
11556 ir_build_const_from(ira, &set_debug_safety_instruction->base);11608 ir_build_const_from(ira, &set_runtime_safety_instruction->base);
11557 return ira->codegen->builtin_types.entry_void;11609 return ira->codegen->builtin_types.entry_void;
11558 }11610 }
1155911611
11560 bool *safety_off_ptr;11612 bool *safety_off_ptr;
11561 AstNode **safety_set_node_ptr;11613 AstNode **safety_set_node_ptr;
11562 if (target_type->id == TypeTableEntryIdBlock) {11614
11563 ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;11615 Scope *scope = set_runtime_safety_instruction->base.scope;
11564 safety_off_ptr = &block_scope->safety_off;11616 while (scope != nullptr) {
11565 safety_set_node_ptr = &block_scope->safety_set_node;11617 if (scope->id == ScopeIdBlock) {
11566 } else if (target_type->id == TypeTableEntryIdFn) {11618 ScopeBlock *block_scope = (ScopeBlock *)scope;
11567 FnTableEntry *target_fn = target_val->data.x_fn.fn_entry;11619 safety_off_ptr = &block_scope->safety_off;
11568 assert(target_fn->def_scope);11620 safety_set_node_ptr = &block_scope->safety_set_node;
11569 safety_off_ptr = &target_fn->def_scope->safety_off;11621 break;
11570 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;11622 } else if (scope->id == ScopeIdFnDef) {
11571 } else if (target_type->id == TypeTableEntryIdMetaType) {11623 ScopeFnDef *def_scope = (ScopeFnDef *)scope;
11572 ScopeDecls *decls_scope;11624 FnTableEntry *target_fn = def_scope->fn_entry;
11573 TypeTableEntry *type_arg = target_val->data.x_type;11625 assert(target_fn->def_scope != nullptr);
11574 if (type_arg->id == TypeTableEntryIdStruct) {11626 safety_off_ptr = &target_fn->def_scope->safety_off;
11575 decls_scope = type_arg->data.structure.decls_scope;11627 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
11576 } else if (type_arg->id == TypeTableEntryIdEnum) {11628 break;
11577 decls_scope = type_arg->data.enumeration.decls_scope;11629 } else if (scope->id == ScopeIdDecls) {
11578 } else if (type_arg->id == TypeTableEntryIdUnion) {11630 ScopeDecls *decls_scope = (ScopeDecls *)scope;
11579 decls_scope = type_arg->data.unionation.decls_scope;11631 safety_off_ptr = &decls_scope->safety_off;
11632 safety_set_node_ptr = &decls_scope->safety_set_node;
11633 break;
11580 } else {11634 } else {
11581 ir_add_error_node(ira, target_instruction->source_node,11635 scope = scope->parent;
11582 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));11636 continue;
11583 return ira->codegen->builtin_types.entry_invalid;
11584 }11637 }
11585 safety_off_ptr = &decls_scope->safety_off;
11586 safety_set_node_ptr = &decls_scope->safety_set_node;
11587 } else {
11588 ir_add_error_node(ira, target_instruction->source_node,
11589 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));
11590 return ira->codegen->builtin_types.entry_invalid;
11591 }11638 }
11639 assert(scope != nullptr);
1159211640
11593 IrInstruction *debug_safety_on_value = set_debug_safety_instruction->debug_safety_on->other;11641 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->other;
11594 bool want_debug_safety;11642 bool want_runtime_safety;
11595 if (!ir_resolve_bool(ira, debug_safety_on_value, &want_debug_safety))11643 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety))
11596 return ira->codegen->builtin_types.entry_invalid;11644 return ira->codegen->builtin_types.entry_invalid;
1159711645
11598 AstNode *source_node = set_debug_safety_instruction->base.source_node;11646 AstNode *source_node = set_runtime_safety_instruction->base.source_node;
11599 if (*safety_set_node_ptr) {11647 if (*safety_set_node_ptr) {
11600 ErrorMsg *msg = ir_add_error_node(ira, source_node,11648 ErrorMsg *msg = ir_add_error_node(ira, source_node,
11601 buf_sprintf("debug safety set twice for same scope"));11649 buf_sprintf("runtime safety set twice for same scope"));
11602 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));11650 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));
11603 return ira->codegen->builtin_types.entry_invalid;11651 return ira->codegen->builtin_types.entry_invalid;
11604 }11652 }
11605 *safety_set_node_ptr = source_node;11653 *safety_set_node_ptr = source_node;
11606 *safety_off_ptr = !want_debug_safety;11654 *safety_off_ptr = !want_runtime_safety;
1160711655
11608 ir_build_const_from(ira, &set_debug_safety_instruction->base);11656 ir_build_const_from(ira, &set_runtime_safety_instruction->base);
11609 return ira->codegen->builtin_types.entry_void;11657 return ira->codegen->builtin_types.entry_void;
11610}11658}
1161111659
...@@ -12243,11 +12291,18 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,...@@ -12243,11 +12291,18 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
12243 }12291 }
12244 TypeTableEntry *tag_type = target_type->data.unionation.tag_type;12292 TypeTableEntry *tag_type = target_type->data.unionation.tag_type;
12245 assert(tag_type != nullptr);12293 assert(tag_type != nullptr);
12294 assert(tag_type->id == TypeTableEntryIdEnum);
12246 if (pointee_val) {12295 if (pointee_val) {
12247 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);12296 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
12248 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag);12297 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag);
12249 return tag_type;12298 return tag_type;
12250 }12299 }
12300 if (tag_type->data.enumeration.src_field_count == 1) {
12301 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
12302 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0];
12303 bigint_init_bigint(&out_val->data.x_enum_tag, &only_field->value);
12304 return tag_type;
12305 }
1225112306
12252 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,12307 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
12253 switch_target_instruction->base.source_node, target_value_ptr);12308 switch_target_instruction->base.source_node, target_value_ptr);
...@@ -14499,6 +14554,11 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio...@@ -14499,6 +14554,11 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
14499 if (type_is_invalid(msg->value.type))14554 if (type_is_invalid(msg->value.type))
14500 return ira->codegen->builtin_types.entry_invalid;14555 return ira->codegen->builtin_types.entry_invalid;
1450114556
14557 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) {
14558 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time"));
14559 return ira->codegen->builtin_types.entry_invalid;
14560 }
14561
14502 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);14562 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
14503 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);14563 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
14504 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);14564 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
...@@ -15212,8 +15272,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -15212,8 +15272,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
15212 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);15272 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
15213 case IrInstructionIdPtrTypeChild:15273 case IrInstructionIdPtrTypeChild:
15214 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);15274 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
15215 case IrInstructionIdSetDebugSafety:15275 case IrInstructionIdSetCold:
15216 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);15276 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
15277 case IrInstructionIdSetRuntimeSafety:
15278 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
15217 case IrInstructionIdSetFloatMode:15279 case IrInstructionIdSetFloatMode:
15218 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);15280 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
15219 case IrInstructionIdSliceType:15281 case IrInstructionIdSliceType:
...@@ -15448,7 +15510,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -15448,7 +15510,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
15448 case IrInstructionIdCall:15510 case IrInstructionIdCall:
15449 case IrInstructionIdReturn:15511 case IrInstructionIdReturn:
15450 case IrInstructionIdUnreachable:15512 case IrInstructionIdUnreachable:
15451 case IrInstructionIdSetDebugSafety:15513 case IrInstructionIdSetCold:
15514 case IrInstructionIdSetRuntimeSafety:
15452 case IrInstructionIdSetFloatMode:15515 case IrInstructionIdSetFloatMode:
15453 case IrInstructionIdImport:15516 case IrInstructionIdImport:
15454 case IrInstructionIdCompileErr:15517 case IrInstructionIdCompileErr:
src/ir_print.cpp+14-7
...@@ -368,11 +368,15 @@ static void ir_print_union_field_ptr(IrPrint *irp, IrInstructionUnionFieldPtr *i...@@ -368,11 +368,15 @@ static void ir_print_union_field_ptr(IrPrint *irp, IrInstructionUnionFieldPtr *i
368 fprintf(irp->f, ")");368 fprintf(irp->f, ")");
369}369}
370370
371static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {371static void ir_print_set_cold(IrPrint *irp, IrInstructionSetCold *instruction) {
372 fprintf(irp->f, "@setDebugSafety(");372 fprintf(irp->f, "@setCold(");
373 ir_print_other_instruction(irp, instruction->scope_value);373 ir_print_other_instruction(irp, instruction->is_cold);
374 fprintf(irp->f, ", ");374 fprintf(irp->f, ")");
375 ir_print_other_instruction(irp, instruction->debug_safety_on);375}
376
377static void ir_print_set_runtime_safety(IrPrint *irp, IrInstructionSetRuntimeSafety *instruction) {
378 fprintf(irp->f, "@setRuntimeSafety(");
379 ir_print_other_instruction(irp, instruction->safety_on);
376 fprintf(irp->f, ")");380 fprintf(irp->f, ")");
377}381}
378382
...@@ -1081,8 +1085,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1081,8 +1085,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1081 case IrInstructionIdUnionFieldPtr:1085 case IrInstructionIdUnionFieldPtr:
1082 ir_print_union_field_ptr(irp, (IrInstructionUnionFieldPtr *)instruction);1086 ir_print_union_field_ptr(irp, (IrInstructionUnionFieldPtr *)instruction);
1083 break;1087 break;
1084 case IrInstructionIdSetDebugSafety:1088 case IrInstructionIdSetCold:
1085 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);1089 ir_print_set_cold(irp, (IrInstructionSetCold *)instruction);
1090 break;
1091 case IrInstructionIdSetRuntimeSafety:
1092 ir_print_set_runtime_safety(irp, (IrInstructionSetRuntimeSafety *)instruction);
1086 break;1093 break;
1087 case IrInstructionIdSetFloatMode:1094 case IrInstructionIdSetFloatMode:
1088 ir_print_set_float_mode(irp, (IrInstructionSetFloatMode *)instruction);1095 ir_print_set_float_mode(irp, (IrInstructionSetFloatMode *)instruction);
src/main.cpp+1-1
...@@ -462,7 +462,7 @@ int main(int argc, char **argv) {...@@ -462,7 +462,7 @@ int main(int argc, char **argv) {
462 Termination term;462 Termination term;
463 os_spawn_process(buf_ptr(path_to_build_exe), args, &term);463 os_spawn_process(buf_ptr(path_to_build_exe), args, &term);
464 if (term.how != TerminationIdClean || term.code != 0) {464 if (term.how != TerminationIdClean || term.code != 0) {
465 fprintf(stderr, "\nBuild failed. Use the following command to reproduce the failure:\n");465 fprintf(stderr, "\nBuild failed. The following command failed:\n");
466 fprintf(stderr, "%s", buf_ptr(path_to_build_exe));466 fprintf(stderr, "%s", buf_ptr(path_to_build_exe));
467 for (size_t i = 0; i < args.length; i += 1) {467 for (size_t i = 0; i < args.length; i += 1) {
468 fprintf(stderr, " %s", args.at(i));468 fprintf(stderr, " %s", args.at(i));
src/os.cpp+18-11
...@@ -390,17 +390,15 @@ static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,...@@ -390,17 +390,15 @@ static int os_exec_process_posix(const char *exe, ZigList<const char *> &args,
390390
391#if defined(ZIG_OS_WINDOWS)391#if defined(ZIG_OS_WINDOWS)
392392
393/*393//static void win32_panic(const char *str) {
394static void win32_panic(const char *str) {394// DWORD err = GetLastError();
395 DWORD err = GetLastError();395// LPSTR messageBuffer = nullptr;
396 LPSTR messageBuffer = nullptr;396// FormatMessageA(
397 FormatMessageA(397// FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
398 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,398// NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
399 NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);399// zig_panic(str, messageBuffer);
400 zig_panic(str, messageBuffer);400// LocalFree(messageBuffer);
401 LocalFree(messageBuffer);401//}
402}
403*/
404402
405static int os_exec_process_windows(const char *exe, ZigList<const char *> &args,403static int os_exec_process_windows(const char *exe, ZigList<const char *> &args,
406 Termination *term, Buf *out_stderr, Buf *out_stdout)404 Termination *term, Buf *out_stderr, Buf *out_stdout)
...@@ -794,9 +792,18 @@ int os_delete_file(Buf *path) {...@@ -794,9 +792,18 @@ int os_delete_file(Buf *path) {
794}792}
795793
796int os_rename(Buf *src_path, Buf *dest_path) {794int os_rename(Buf *src_path, Buf *dest_path) {
795 if (buf_eql_buf(src_path, dest_path)) {
796 return 0;
797 }
798#if defined(ZIG_OS_WINDOWS)
799 if (!MoveFileExA(buf_ptr(src_path), buf_ptr(dest_path), MOVEFILE_REPLACE_EXISTING)) {
800 return ErrorFileSystem;
801 }
802#else
797 if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {803 if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {
798 return ErrorFileSystem;804 return ErrorFileSystem;
799 }805 }
806#endif
800 return 0;807 return 0;
801}808}
802809
src/parser.cpp+8-27
...@@ -84,11 +84,6 @@ static AstNode *ast_create_node(ParseContext *pc, NodeType type, Token *first_to...@@ -84,11 +84,6 @@ static AstNode *ast_create_node(ParseContext *pc, NodeType type, Token *first_to
84 return node;84 return node;
85}85}
8686
87static AstNode *ast_create_void_type_node(ParseContext *pc, Token *token) {
88 AstNode *node = ast_create_node(pc, NodeTypeSymbol, token);
89 node->data.symbol_expr.symbol = pc->void_buf;
90 return node;
91}
9287
93static void parse_asm_template(ParseContext *pc, AstNode *node) {88static void parse_asm_template(ParseContext *pc, AstNode *node) {
94 Buf *asm_template = node->data.asm_expr.asm_template;89 Buf *asm_template = node->data.asm_expr.asm_template;
...@@ -1495,7 +1490,7 @@ static AstNode *ast_parse_break_expr(ParseContext *pc, size_t *token_index) {...@@ -1495,7 +1490,7 @@ static AstNode *ast_parse_break_expr(ParseContext *pc, size_t *token_index) {
1495}1490}
14961491
1497/*1492/*
1498Defer(body) = option("%") "defer" body1493Defer(body) = ("defer" | "errdefer") body
1499*/1494*/
1500static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {1495static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
1501 Token *token = &pc->tokens->at(*token_index);1496 Token *token = &pc->tokens->at(*token_index);
...@@ -1503,15 +1498,10 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {...@@ -1503,15 +1498,10 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
1503 NodeType node_type;1498 NodeType node_type;
1504 ReturnKind kind;1499 ReturnKind kind;
15051500
1506 if (token->id == TokenIdPercent) {1501 if (token->id == TokenIdKeywordErrdefer) {
1507 Token *next_token = &pc->tokens->at(*token_index + 1);1502 kind = ReturnKindError;
1508 if (next_token->id == TokenIdKeywordDefer) {1503 node_type = NodeTypeDefer;
1509 kind = ReturnKindError;1504 *token_index += 1;
1510 node_type = NodeTypeDefer;
1511 *token_index += 2;
1512 } else {
1513 return nullptr;
1514 }
1515 } else if (token->id == TokenIdKeywordDefer) {1505 } else if (token->id == TokenIdKeywordDefer) {
1516 kind = ReturnKindUnconditional;1506 kind = ReturnKindUnconditional;
1517 node_type = NodeTypeDefer;1507 node_type = NodeTypeDefer;
...@@ -2250,7 +2240,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand...@@ -2250,7 +2240,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
2250}2240}
22512241
2252/*2242/*
2253FnProto = option("coldcc" | "nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") option("-&gt;" TypeExpr)2243FnProto = option("nakedcc" | "stdcallcc" | "extern") "fn" option(Symbol) ParamDeclList option("align" "(" Expression ")") option("section" "(" Expression ")") TypeExpr
2254*/2244*/
2255static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {2245static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
2256 Token *first_token = &pc->tokens->at(*token_index);2246 Token *first_token = &pc->tokens->at(*token_index);
...@@ -2258,11 +2248,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2258,11 +2248,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
22582248
2259 CallingConvention cc;2249 CallingConvention cc;
2260 bool is_extern = false;2250 bool is_extern = false;
2261 if (first_token->id == TokenIdKeywordColdCC) {2251 if (first_token->id == TokenIdKeywordNakedCC) {
2262 *token_index += 1;
2263 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
2264 cc = CallingConventionCold;
2265 } else if (first_token->id == TokenIdKeywordNakedCC) {
2266 *token_index += 1;2252 *token_index += 1;
2267 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);2253 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
2268 cc = CallingConventionNaked;2254 cc = CallingConventionNaked;
...@@ -2329,12 +2315,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m...@@ -2329,12 +2315,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
2329 ast_eat_token(pc, token_index, TokenIdRParen);2315 ast_eat_token(pc, token_index, TokenIdRParen);
2330 next_token = &pc->tokens->at(*token_index);2316 next_token = &pc->tokens->at(*token_index);
2331 }2317 }
2332 if (next_token->id == TokenIdArrow) {2318 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
2333 *token_index += 1;
2334 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, false);
2335 } else {
2336 node->data.fn_proto.return_type = ast_create_void_type_node(pc, next_token);
2337 }
23382319
2339 return node;2320 return node;
2340}2321}
src/tokenizer.cpp+2-2
...@@ -112,13 +112,13 @@ static const struct ZigKeyword zig_keywords[] = {...@@ -112,13 +112,13 @@ static const struct ZigKeyword zig_keywords[] = {
112 {"asm", TokenIdKeywordAsm},112 {"asm", TokenIdKeywordAsm},
113 {"break", TokenIdKeywordBreak},113 {"break", TokenIdKeywordBreak},
114 {"catch", TokenIdKeywordCatch},114 {"catch", TokenIdKeywordCatch},
115 {"coldcc", TokenIdKeywordColdCC},
116 {"comptime", TokenIdKeywordCompTime},115 {"comptime", TokenIdKeywordCompTime},
117 {"const", TokenIdKeywordConst},116 {"const", TokenIdKeywordConst},
118 {"continue", TokenIdKeywordContinue},117 {"continue", TokenIdKeywordContinue},
119 {"defer", TokenIdKeywordDefer},118 {"defer", TokenIdKeywordDefer},
120 {"else", TokenIdKeywordElse},119 {"else", TokenIdKeywordElse},
121 {"enum", TokenIdKeywordEnum},120 {"enum", TokenIdKeywordEnum},
121 {"errdefer", TokenIdKeywordErrdefer},
122 {"error", TokenIdKeywordError},122 {"error", TokenIdKeywordError},
123 {"export", TokenIdKeywordExport},123 {"export", TokenIdKeywordExport},
124 {"extern", TokenIdKeywordExtern},124 {"extern", TokenIdKeywordExtern},
...@@ -1509,13 +1509,13 @@ const char * token_name(TokenId id) {...@@ -1509,13 +1509,13 @@ const char * token_name(TokenId id) {
1509 case TokenIdKeywordAsm: return "asm";1509 case TokenIdKeywordAsm: return "asm";
1510 case TokenIdKeywordBreak: return "break";1510 case TokenIdKeywordBreak: return "break";
1511 case TokenIdKeywordCatch: return "catch";1511 case TokenIdKeywordCatch: return "catch";
1512 case TokenIdKeywordColdCC: return "coldcc";
1513 case TokenIdKeywordCompTime: return "comptime";1512 case TokenIdKeywordCompTime: return "comptime";
1514 case TokenIdKeywordConst: return "const";1513 case TokenIdKeywordConst: return "const";
1515 case TokenIdKeywordContinue: return "continue";1514 case TokenIdKeywordContinue: return "continue";
1516 case TokenIdKeywordDefer: return "defer";1515 case TokenIdKeywordDefer: return "defer";
1517 case TokenIdKeywordElse: return "else";1516 case TokenIdKeywordElse: return "else";
1518 case TokenIdKeywordEnum: return "enum";1517 case TokenIdKeywordEnum: return "enum";
1518 case TokenIdKeywordErrdefer: return "errdefer";
1519 case TokenIdKeywordError: return "error";1519 case TokenIdKeywordError: return "error";
1520 case TokenIdKeywordExport: return "export";1520 case TokenIdKeywordExport: return "export";
1521 case TokenIdKeywordExtern: return "extern";1521 case TokenIdKeywordExtern: return "extern";
src/tokenizer.hpp+1-1
...@@ -51,13 +51,13 @@ enum TokenId {...@@ -51,13 +51,13 @@ enum TokenId {
51 TokenIdKeywordAsm,51 TokenIdKeywordAsm,
52 TokenIdKeywordBreak,52 TokenIdKeywordBreak,
53 TokenIdKeywordCatch,53 TokenIdKeywordCatch,
54 TokenIdKeywordColdCC,
55 TokenIdKeywordCompTime,54 TokenIdKeywordCompTime,
56 TokenIdKeywordConst,55 TokenIdKeywordConst,
57 TokenIdKeywordContinue,56 TokenIdKeywordContinue,
58 TokenIdKeywordDefer,57 TokenIdKeywordDefer,
59 TokenIdKeywordElse,58 TokenIdKeywordElse,
60 TokenIdKeywordEnum,59 TokenIdKeywordEnum,
60 TokenIdKeywordErrdefer,
61 TokenIdKeywordError,61 TokenIdKeywordError,
62 TokenIdKeywordExport,62 TokenIdKeywordExport,
63 TokenIdKeywordExtern,63 TokenIdKeywordExtern,
src/translate_c.cpp+1-1
...@@ -922,7 +922,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou...@@ -922,7 +922,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
922 // void foo(void) -> Foo;922 // void foo(void) -> Foo;
923 // we want to keep the return type AST node.923 // we want to keep the return type AST node.
924 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {924 if (is_c_void_type(proto_node->data.fn_proto.return_type)) {
925 proto_node->data.fn_proto.return_type = nullptr;925 proto_node->data.fn_proto.return_type = trans_create_node_symbol_str(c, "void");
926 }926 }
927 }927 }
928928
std/array_list.zig+16-16
...@@ -4,11 +4,11 @@ const assert = debug.assert;...@@ -4,11 +4,11 @@ const assert = debug.assert;
4const mem = std.mem;4const mem = std.mem;
5const Allocator = mem.Allocator;5const Allocator = mem.Allocator;
66
7pub fn ArrayList(comptime T: type) -> type {7pub fn ArrayList(comptime T: type) type {
8 return AlignedArrayList(T, @alignOf(T));8 return AlignedArrayList(T, @alignOf(T));
9}9}
1010
11pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{11pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
12 return struct {12 return struct {
13 const Self = this;13 const Self = this;
1414
...@@ -20,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{...@@ -20,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
20 allocator: &Allocator,20 allocator: &Allocator,
2121
22 /// Deinitialize with `deinit` or use `toOwnedSlice`.22 /// Deinitialize with `deinit` or use `toOwnedSlice`.
23 pub fn init(allocator: &Allocator) -> Self {23 pub fn init(allocator: &Allocator) Self {
24 return Self {24 return Self {
25 .items = []align(A) T{},25 .items = []align(A) T{},
26 .len = 0,26 .len = 0,
...@@ -28,22 +28,22 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{...@@ -28,22 +28,22 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
28 };28 };
29 }29 }
3030
31 pub fn deinit(l: &Self) {31 pub fn deinit(l: &Self) void {
32 l.allocator.free(l.items);32 l.allocator.free(l.items);
33 }33 }
3434
35 pub fn toSlice(l: &Self) -> []align(A) T {35 pub fn toSlice(l: &Self) []align(A) T {
36 return l.items[0..l.len];36 return l.items[0..l.len];
37 }37 }
3838
39 pub fn toSliceConst(l: &const Self) -> []align(A) const T {39 pub fn toSliceConst(l: &const Self) []align(A) const T {
40 return l.items[0..l.len];40 return l.items[0..l.len];
41 }41 }
4242
43 /// ArrayList takes ownership of the passed in slice. The slice must have been43 /// ArrayList takes ownership of the passed in slice. The slice must have been
44 /// allocated with `allocator`.44 /// allocated with `allocator`.
45 /// Deinitialize with `deinit` or use `toOwnedSlice`.45 /// Deinitialize with `deinit` or use `toOwnedSlice`.
46 pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) -> Self {46 pub fn fromOwnedSlice(allocator: &Allocator, slice: []align(A) T) Self {
47 return Self {47 return Self {
48 .items = slice,48 .items = slice,
49 .len = slice.len,49 .len = slice.len,
...@@ -52,35 +52,35 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{...@@ -52,35 +52,35 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
52 }52 }
5353
54 /// The caller owns the returned memory. ArrayList becomes empty.54 /// The caller owns the returned memory. ArrayList becomes empty.
55 pub fn toOwnedSlice(self: &Self) -> []align(A) T {55 pub fn toOwnedSlice(self: &Self) []align(A) T {
56 const allocator = self.allocator;56 const allocator = self.allocator;
57 const result = allocator.alignedShrink(T, A, self.items, self.len);57 const result = allocator.alignedShrink(T, A, self.items, self.len);
58 *self = init(allocator);58 *self = init(allocator);
59 return result;59 return result;
60 }60 }
6161
62 pub fn append(l: &Self, item: &const T) -> %void {62 pub fn append(l: &Self, item: &const T) %void {
63 const new_item_ptr = try l.addOne();63 const new_item_ptr = try l.addOne();
64 *new_item_ptr = *item;64 *new_item_ptr = *item;
65 }65 }
6666
67 pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void {67 pub fn appendSlice(l: &Self, items: []align(A) const T) %void {
68 try l.ensureCapacity(l.len + items.len);68 try l.ensureCapacity(l.len + items.len);
69 mem.copy(T, l.items[l.len..], items);69 mem.copy(T, l.items[l.len..], items);
70 l.len += items.len;70 l.len += items.len;
71 }71 }
7272
73 pub fn resize(l: &Self, new_len: usize) -> %void {73 pub fn resize(l: &Self, new_len: usize) %void {
74 try l.ensureCapacity(new_len);74 try l.ensureCapacity(new_len);
75 l.len = new_len;75 l.len = new_len;
76 }76 }
7777
78 pub fn shrink(l: &Self, new_len: usize) {78 pub fn shrink(l: &Self, new_len: usize) void {
79 assert(new_len <= l.len);79 assert(new_len <= l.len);
80 l.len = new_len;80 l.len = new_len;
81 }81 }
8282
83 pub fn ensureCapacity(l: &Self, new_capacity: usize) -> %void {83 pub fn ensureCapacity(l: &Self, new_capacity: usize) %void {
84 var better_capacity = l.items.len;84 var better_capacity = l.items.len;
85 if (better_capacity >= new_capacity) return;85 if (better_capacity >= new_capacity) return;
86 while (true) {86 while (true) {
...@@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{...@@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
90 l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);90 l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
91 }91 }
9292
93 pub fn addOne(l: &Self) -> %&T {93 pub fn addOne(l: &Self) %&T {
94 const new_length = l.len + 1;94 const new_length = l.len + 1;
95 try l.ensureCapacity(new_length);95 try l.ensureCapacity(new_length);
96 const result = &l.items[l.len];96 const result = &l.items[l.len];
...@@ -98,12 +98,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{...@@ -98,12 +98,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
98 return result;98 return result;
99 }99 }
100100
101 pub fn pop(self: &Self) -> T {101 pub fn pop(self: &Self) T {
102 self.len -= 1;102 self.len -= 1;
103 return self.items[self.len];103 return self.items[self.len];
104 }104 }
105105
106 pub fn popOrNull(self: &Self) -> ?T {106 pub fn popOrNull(self: &Self) ?T {
107 if (self.len == 0)107 if (self.len == 0)
108 return null;108 return null;
109 return self.pop();109 return self.pop();
std/base64.zig+18-18
...@@ -11,7 +11,7 @@ pub const Base64Encoder = struct {...@@ -11,7 +11,7 @@ pub const Base64Encoder = struct {
11 pad_char: u8,11 pad_char: u8,
1212
13 /// a bunch of assertions, then simply pass the data right through.13 /// a bunch of assertions, then simply pass the data right through.
14 pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64Encoder {14 pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64Encoder {
15 assert(alphabet_chars.len == 64);15 assert(alphabet_chars.len == 64);
16 var char_in_alphabet = []bool{false} ** 256;16 var char_in_alphabet = []bool{false} ** 256;
17 for (alphabet_chars) |c| {17 for (alphabet_chars) |c| {
...@@ -27,12 +27,12 @@ pub const Base64Encoder = struct {...@@ -27,12 +27,12 @@ pub const Base64Encoder = struct {
27 }27 }
2828
29 /// ceil(source_len * 4/3)29 /// ceil(source_len * 4/3)
30 pub fn calcSize(source_len: usize) -> usize {30 pub fn calcSize(source_len: usize) usize {
31 return @divTrunc(source_len + 2, 3) * 4;31 return @divTrunc(source_len + 2, 3) * 4;
32 }32 }
3333
34 /// dest.len must be what you get from ::calcSize.34 /// dest.len must be what you get from ::calcSize.
35 pub fn encode(encoder: &const Base64Encoder, dest: []u8, source: []const u8) {35 pub fn encode(encoder: &const Base64Encoder, dest: []u8, source: []const u8) void {
36 assert(dest.len == Base64Encoder.calcSize(source.len));36 assert(dest.len == Base64Encoder.calcSize(source.len));
3737
38 var i: usize = 0;38 var i: usize = 0;
...@@ -90,7 +90,7 @@ pub const Base64Decoder = struct {...@@ -90,7 +90,7 @@ pub const Base64Decoder = struct {
90 char_in_alphabet: [256]bool,90 char_in_alphabet: [256]bool,
91 pad_char: u8,91 pad_char: u8,
9292
93 pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64Decoder {93 pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64Decoder {
94 assert(alphabet_chars.len == 64);94 assert(alphabet_chars.len == 64);
9595
96 var result = Base64Decoder{96 var result = Base64Decoder{
...@@ -111,7 +111,7 @@ pub const Base64Decoder = struct {...@@ -111,7 +111,7 @@ pub const Base64Decoder = struct {
111 }111 }
112112
113 /// If the encoded buffer is detected to be invalid, returns error.InvalidPadding.113 /// If the encoded buffer is detected to be invalid, returns error.InvalidPadding.
114 pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) -> %usize {114 pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) %usize {
115 if (source.len % 4 != 0) return error.InvalidPadding;115 if (source.len % 4 != 0) return error.InvalidPadding;
116 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);116 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
117 }117 }
...@@ -119,7 +119,7 @@ pub const Base64Decoder = struct {...@@ -119,7 +119,7 @@ pub const Base64Decoder = struct {
119 /// dest.len must be what you get from ::calcSize.119 /// dest.len must be what you get from ::calcSize.
120 /// invalid characters result in error.InvalidCharacter.120 /// invalid characters result in error.InvalidCharacter.
121 /// invalid padding results in error.InvalidPadding.121 /// invalid padding results in error.InvalidPadding.
122 pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) -> %void {122 pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) %void {
123 assert(dest.len == (decoder.calcSize(source) catch unreachable));123 assert(dest.len == (decoder.calcSize(source) catch unreachable));
124 assert(source.len % 4 == 0);124 assert(source.len % 4 == 0);
125125
...@@ -168,7 +168,7 @@ error OutputTooSmall;...@@ -168,7 +168,7 @@ error OutputTooSmall;
168pub const Base64DecoderWithIgnore = struct {168pub const Base64DecoderWithIgnore = struct {
169 decoder: Base64Decoder,169 decoder: Base64Decoder,
170 char_is_ignored: [256]bool,170 char_is_ignored: [256]bool,
171 pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) -> Base64DecoderWithIgnore {171 pub fn init(alphabet_chars: []const u8, pad_char: u8, ignore_chars: []const u8) Base64DecoderWithIgnore {
172 var result = Base64DecoderWithIgnore {172 var result = Base64DecoderWithIgnore {
173 .decoder = Base64Decoder.init(alphabet_chars, pad_char),173 .decoder = Base64Decoder.init(alphabet_chars, pad_char),
174 .char_is_ignored = []bool{false} ** 256,174 .char_is_ignored = []bool{false} ** 256,
...@@ -185,7 +185,7 @@ pub const Base64DecoderWithIgnore = struct {...@@ -185,7 +185,7 @@ pub const Base64DecoderWithIgnore = struct {
185 }185 }
186186
187 /// If no characters end up being ignored or padding, this will be the exact decoded size.187 /// If no characters end up being ignored or padding, this will be the exact decoded size.
188 pub fn calcSizeUpperBound(encoded_len: usize) -> %usize {188 pub fn calcSizeUpperBound(encoded_len: usize) %usize {
189 return @divTrunc(encoded_len, 4) * 3;189 return @divTrunc(encoded_len, 4) * 3;
190 }190 }
191191
...@@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct {...@@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct {
193 /// Invalid padding results in error.InvalidPadding.193 /// Invalid padding results in error.InvalidPadding.
194 /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.194 /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
195 /// Returns the number of bytes writen to dest.195 /// Returns the number of bytes writen to dest.
196 pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) -> %usize {196 pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) %usize {
197 const decoder = &decoder_with_ignore.decoder;197 const decoder = &decoder_with_ignore.decoder;
198198
199 var src_cursor: usize = 0;199 var src_cursor: usize = 0;
...@@ -293,7 +293,7 @@ pub const Base64DecoderUnsafe = struct {...@@ -293,7 +293,7 @@ pub const Base64DecoderUnsafe = struct {
293 char_to_index: [256]u8,293 char_to_index: [256]u8,
294 pad_char: u8,294 pad_char: u8,
295295
296 pub fn init(alphabet_chars: []const u8, pad_char: u8) -> Base64DecoderUnsafe {296 pub fn init(alphabet_chars: []const u8, pad_char: u8) Base64DecoderUnsafe {
297 assert(alphabet_chars.len == 64);297 assert(alphabet_chars.len == 64);
298 var result = Base64DecoderUnsafe {298 var result = Base64DecoderUnsafe {
299 .char_to_index = undefined,299 .char_to_index = undefined,
...@@ -307,13 +307,13 @@ pub const Base64DecoderUnsafe = struct {...@@ -307,13 +307,13 @@ pub const Base64DecoderUnsafe = struct {
307 }307 }
308308
309 /// The source buffer must be valid.309 /// The source buffer must be valid.
310 pub fn calcSize(decoder: &const Base64DecoderUnsafe, source: []const u8) -> usize {310 pub fn calcSize(decoder: &const Base64DecoderUnsafe, source: []const u8) usize {
311 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);311 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
312 }312 }
313313
314 /// dest.len must be what you get from ::calcDecodedSizeExactUnsafe.314 /// dest.len must be what you get from ::calcDecodedSizeExactUnsafe.
315 /// invalid characters or padding will result in undefined values.315 /// invalid characters or padding will result in undefined values.
316 pub fn decode(decoder: &const Base64DecoderUnsafe, dest: []u8, source: []const u8) {316 pub fn decode(decoder: &const Base64DecoderUnsafe, dest: []u8, source: []const u8) void {
317 assert(dest.len == decoder.calcSize(source));317 assert(dest.len == decoder.calcSize(source));
318318
319 var src_index: usize = 0;319 var src_index: usize = 0;
...@@ -359,7 +359,7 @@ pub const Base64DecoderUnsafe = struct {...@@ -359,7 +359,7 @@ pub const Base64DecoderUnsafe = struct {
359 }359 }
360};360};
361361
362fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) -> usize {362fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
363 if (source.len == 0) return 0;363 if (source.len == 0) return 0;
364 var result = @divExact(source.len, 4) * 3;364 var result = @divExact(source.len, 4) * 3;
365 if (source[source.len - 1] == pad_char) {365 if (source[source.len - 1] == pad_char) {
...@@ -378,7 +378,7 @@ test "base64" {...@@ -378,7 +378,7 @@ test "base64" {
378 comptime (testBase64() catch unreachable);378 comptime (testBase64() catch unreachable);
379}379}
380380
381fn testBase64() -> %void {381fn testBase64() %void {
382 try testAllApis("", "");382 try testAllApis("", "");
383 try testAllApis("f", "Zg==");383 try testAllApis("f", "Zg==");
384 try testAllApis("fo", "Zm8=");384 try testAllApis("fo", "Zm8=");
...@@ -412,7 +412,7 @@ fn testBase64() -> %void {...@@ -412,7 +412,7 @@ fn testBase64() -> %void {
412 try testOutputTooSmallError("AAAAAA==");412 try testOutputTooSmallError("AAAAAA==");
413}413}
414414
415fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void {415fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void {
416 // Base64Encoder416 // Base64Encoder
417 {417 {
418 var buffer: [0x100]u8 = undefined;418 var buffer: [0x100]u8 = undefined;
...@@ -449,7 +449,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v...@@ -449,7 +449,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v
449 }449 }
450}450}
451451
452fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %void {452fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %void {
453 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(453 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
454 standard_alphabet_chars, standard_pad_char, " ");454 standard_alphabet_chars, standard_pad_char, " ");
455 var buffer: [0x100]u8 = undefined;455 var buffer: [0x100]u8 = undefined;
...@@ -459,7 +459,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %...@@ -459,7 +459,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %
459}459}
460460
461error ExpectedError;461error ExpectedError;
462fn testError(encoded: []const u8, expected_err: error) -> %void {462fn testError(encoded: []const u8, expected_err: error) %void {
463 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(463 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
464 standard_alphabet_chars, standard_pad_char, " ");464 standard_alphabet_chars, standard_pad_char, " ");
465 var buffer: [0x100]u8 = undefined;465 var buffer: [0x100]u8 = undefined;
...@@ -475,7 +475,7 @@ fn testError(encoded: []const u8, expected_err: error) -> %void {...@@ -475,7 +475,7 @@ fn testError(encoded: []const u8, expected_err: error) -> %void {
475 } else |err| if (err != expected_err) return err;475 } else |err| if (err != expected_err) return err;
476}476}
477477
478fn testOutputTooSmallError(encoded: []const u8) -> %void {478fn testOutputTooSmallError(encoded: []const u8) %void {
479 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(479 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
480 standard_alphabet_chars, standard_pad_char, " ");480 standard_alphabet_chars, standard_pad_char, " ");
481 var buffer: [0x100]u8 = undefined;481 var buffer: [0x100]u8 = undefined;
std/buf_map.zig+12-12
...@@ -9,14 +9,14 @@ pub const BufMap = struct {...@@ -9,14 +9,14 @@ pub const BufMap = struct {
99
10 const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);10 const BufMapHashMap = HashMap([]const u8, []const u8, mem.hash_slice_u8, mem.eql_slice_u8);
1111
12 pub fn init(allocator: &Allocator) -> BufMap {12 pub fn init(allocator: &Allocator) BufMap {
13 var self = BufMap {13 var self = BufMap {
14 .hash_map = BufMapHashMap.init(allocator),14 .hash_map = BufMapHashMap.init(allocator),
15 };15 };
16 return self;16 return self;
17 }17 }
1818
19 pub fn deinit(self: &BufMap) {19 pub fn deinit(self: &BufMap) void {
20 var it = self.hash_map.iterator();20 var it = self.hash_map.iterator();
21 while (true) {21 while (true) {
22 const entry = it.next() ?? break; 22 const entry = it.next() ?? break;
...@@ -27,47 +27,47 @@ pub const BufMap = struct {...@@ -27,47 +27,47 @@ pub const BufMap = struct {
27 self.hash_map.deinit();27 self.hash_map.deinit();
28 }28 }
2929
30 pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void {30 pub fn set(self: &BufMap, key: []const u8, value: []const u8) %void {
31 if (self.hash_map.get(key)) |entry| {31 if (self.hash_map.get(key)) |entry| {
32 const value_copy = try self.copy(value);32 const value_copy = try self.copy(value);
33 %defer self.free(value_copy);33 errdefer self.free(value_copy);
34 _ = try self.hash_map.put(key, value_copy);34 _ = try self.hash_map.put(key, value_copy);
35 self.free(entry.value);35 self.free(entry.value);
36 } else {36 } else {
37 const key_copy = try self.copy(key);37 const key_copy = try self.copy(key);
38 %defer self.free(key_copy);38 errdefer self.free(key_copy);
39 const value_copy = try self.copy(value);39 const value_copy = try self.copy(value);
40 %defer self.free(value_copy);40 errdefer self.free(value_copy);
41 _ = try self.hash_map.put(key_copy, value_copy);41 _ = try self.hash_map.put(key_copy, value_copy);
42 }42 }
43 }43 }
4444
45 pub fn get(self: &BufMap, key: []const u8) -> ?[]const u8 {45 pub fn get(self: &BufMap, key: []const u8) ?[]const u8 {
46 const entry = self.hash_map.get(key) ?? return null;46 const entry = self.hash_map.get(key) ?? return null;
47 return entry.value;47 return entry.value;
48 }48 }
4949
50 pub fn delete(self: &BufMap, key: []const u8) {50 pub fn delete(self: &BufMap, key: []const u8) void {
51 const entry = self.hash_map.remove(key) ?? return;51 const entry = self.hash_map.remove(key) ?? return;
52 self.free(entry.key);52 self.free(entry.key);
53 self.free(entry.value);53 self.free(entry.value);
54 }54 }
5555
56 pub fn count(self: &const BufMap) -> usize {56 pub fn count(self: &const BufMap) usize {
57 return self.hash_map.size;57 return self.hash_map.size;
58 }58 }
5959
60 pub fn iterator(self: &const BufMap) -> BufMapHashMap.Iterator {60 pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
61 return self.hash_map.iterator();61 return self.hash_map.iterator();
62 }62 }
6363
64 fn free(self: &BufMap, value: []const u8) {64 fn free(self: &BufMap, value: []const u8) void {
65 // remove the const65 // remove the const
66 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];66 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
67 self.hash_map.allocator.free(mut_value);67 self.hash_map.allocator.free(mut_value);
68 }68 }
6969
70 fn copy(self: &BufMap, value: []const u8) -> %[]const u8 {70 fn copy(self: &BufMap, value: []const u8) %[]const u8 {
71 const result = try self.hash_map.allocator.alloc(u8, value.len);71 const result = try self.hash_map.allocator.alloc(u8, value.len);
72 mem.copy(u8, result, value);72 mem.copy(u8, result, value);
73 return result;73 return result;
std/buf_set.zig+10-10
...@@ -7,14 +7,14 @@ pub const BufSet = struct {...@@ -7,14 +7,14 @@ pub const BufSet = struct {
77
8 const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);8 const BufSetHashMap = HashMap([]const u8, void, mem.hash_slice_u8, mem.eql_slice_u8);
99
10 pub fn init(a: &Allocator) -> BufSet {10 pub fn init(a: &Allocator) BufSet {
11 var self = BufSet {11 var self = BufSet {
12 .hash_map = BufSetHashMap.init(a),12 .hash_map = BufSetHashMap.init(a),
13 };13 };
14 return self;14 return self;
15 }15 }
1616
17 pub fn deinit(self: &BufSet) {17 pub fn deinit(self: &BufSet) void {
18 var it = self.hash_map.iterator();18 var it = self.hash_map.iterator();
19 while (true) {19 while (true) {
20 const entry = it.next() ?? break; 20 const entry = it.next() ?? break;
...@@ -24,38 +24,38 @@ pub const BufSet = struct {...@@ -24,38 +24,38 @@ pub const BufSet = struct {
24 self.hash_map.deinit();24 self.hash_map.deinit();
25 }25 }
2626
27 pub fn put(self: &BufSet, key: []const u8) -> %void {27 pub fn put(self: &BufSet, key: []const u8) %void {
28 if (self.hash_map.get(key) == null) {28 if (self.hash_map.get(key) == null) {
29 const key_copy = try self.copy(key);29 const key_copy = try self.copy(key);
30 %defer self.free(key_copy);30 errdefer self.free(key_copy);
31 _ = try self.hash_map.put(key_copy, {});31 _ = try self.hash_map.put(key_copy, {});
32 }32 }
33 }33 }
3434
35 pub fn delete(self: &BufSet, key: []const u8) {35 pub fn delete(self: &BufSet, key: []const u8) void {
36 const entry = self.hash_map.remove(key) ?? return;36 const entry = self.hash_map.remove(key) ?? return;
37 self.free(entry.key);37 self.free(entry.key);
38 }38 }
3939
40 pub fn count(self: &const BufSet) -> usize {40 pub fn count(self: &const BufSet) usize {
41 return self.hash_map.size;41 return self.hash_map.size;
42 }42 }
4343
44 pub fn iterator(self: &const BufSet) -> BufSetHashMap.Iterator {44 pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
45 return self.hash_map.iterator();45 return self.hash_map.iterator();
46 }46 }
4747
48 pub fn allocator(self: &const BufSet) -> &Allocator {48 pub fn allocator(self: &const BufSet) &Allocator {
49 return self.hash_map.allocator;49 return self.hash_map.allocator;
50 }50 }
5151
52 fn free(self: &BufSet, value: []const u8) {52 fn free(self: &BufSet, value: []const u8) void {
53 // remove the const53 // remove the const
54 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];54 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
55 self.hash_map.allocator.free(mut_value);55 self.hash_map.allocator.free(mut_value);
56 }56 }
5757
58 fn copy(self: &BufSet, value: []const u8) -> %[]const u8 {58 fn copy(self: &BufSet, value: []const u8) %[]const u8 {
59 const result = try self.hash_map.allocator.alloc(u8, value.len);59 const result = try self.hash_map.allocator.alloc(u8, value.len);
60 mem.copy(u8, result, value);60 mem.copy(u8, result, value);
61 return result;61 return result;
std/buffer.zig+22-22
...@@ -12,14 +12,14 @@ pub const Buffer = struct {...@@ -12,14 +12,14 @@ pub const Buffer = struct {
12 list: ArrayList(u8),12 list: ArrayList(u8),
1313
14 /// Must deinitialize with deinit.14 /// Must deinitialize with deinit.
15 pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {15 pub fn init(allocator: &Allocator, m: []const u8) %Buffer {
16 var self = try initSize(allocator, m.len);16 var self = try initSize(allocator, m.len);
17 mem.copy(u8, self.list.items, m);17 mem.copy(u8, self.list.items, m);
18 return self;18 return self;
19 }19 }
2020
21 /// Must deinitialize with deinit.21 /// Must deinitialize with deinit.
22 pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {22 pub fn initSize(allocator: &Allocator, size: usize) %Buffer {
23 var self = initNull(allocator);23 var self = initNull(allocator);
24 try self.resize(size);24 try self.resize(size);
25 return self;25 return self;
...@@ -30,21 +30,21 @@ pub const Buffer = struct {...@@ -30,21 +30,21 @@ pub const Buffer = struct {
30 /// * ::replaceContents30 /// * ::replaceContents
31 /// * ::replaceContentsBuffer31 /// * ::replaceContentsBuffer
32 /// * ::resize32 /// * ::resize
33 pub fn initNull(allocator: &Allocator) -> Buffer {33 pub fn initNull(allocator: &Allocator) Buffer {
34 return Buffer {34 return Buffer {
35 .list = ArrayList(u8).init(allocator),35 .list = ArrayList(u8).init(allocator),
36 };36 };
37 }37 }
3838
39 /// Must deinitialize with deinit.39 /// Must deinitialize with deinit.
40 pub fn initFromBuffer(buffer: &const Buffer) -> %Buffer {40 pub fn initFromBuffer(buffer: &const Buffer) %Buffer {
41 return Buffer.init(buffer.list.allocator, buffer.toSliceConst());41 return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
42 }42 }
4343
44 /// Buffer takes ownership of the passed in slice. The slice must have been44 /// Buffer takes ownership of the passed in slice. The slice must have been
45 /// allocated with `allocator`.45 /// allocated with `allocator`.
46 /// Must deinitialize with deinit.46 /// Must deinitialize with deinit.
47 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) -> Buffer {47 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {
48 var self = Buffer {48 var self = Buffer {
49 .list = ArrayList(u8).fromOwnedSlice(allocator, slice),49 .list = ArrayList(u8).fromOwnedSlice(allocator, slice),
50 };50 };
...@@ -54,7 +54,7 @@ pub const Buffer = struct {...@@ -54,7 +54,7 @@ pub const Buffer = struct {
5454
55 /// The caller owns the returned memory. The Buffer becomes null and55 /// The caller owns the returned memory. The Buffer becomes null and
56 /// is safe to `deinit`.56 /// is safe to `deinit`.
57 pub fn toOwnedSlice(self: &Buffer) -> []u8 {57 pub fn toOwnedSlice(self: &Buffer) []u8 {
58 const allocator = self.list.allocator;58 const allocator = self.list.allocator;
59 const result = allocator.shrink(u8, self.list.items, self.len());59 const result = allocator.shrink(u8, self.list.items, self.len());
60 *self = initNull(allocator);60 *self = initNull(allocator);
...@@ -62,55 +62,55 @@ pub const Buffer = struct {...@@ -62,55 +62,55 @@ pub const Buffer = struct {
62 }62 }
6363
6464
65 pub fn deinit(self: &Buffer) {65 pub fn deinit(self: &Buffer) void {
66 self.list.deinit();66 self.list.deinit();
67 }67 }
6868
69 pub fn toSlice(self: &Buffer) -> []u8 {69 pub fn toSlice(self: &Buffer) []u8 {
70 return self.list.toSlice()[0..self.len()];70 return self.list.toSlice()[0..self.len()];
71 }71 }
7272
73 pub fn toSliceConst(self: &const Buffer) -> []const u8 {73 pub fn toSliceConst(self: &const Buffer) []const u8 {
74 return self.list.toSliceConst()[0..self.len()];74 return self.list.toSliceConst()[0..self.len()];
75 }75 }
7676
77 pub fn shrink(self: &Buffer, new_len: usize) {77 pub fn shrink(self: &Buffer, new_len: usize) void {
78 assert(new_len <= self.len());78 assert(new_len <= self.len());
79 self.list.shrink(new_len + 1);79 self.list.shrink(new_len + 1);
80 self.list.items[self.len()] = 0;80 self.list.items[self.len()] = 0;
81 }81 }
8282
83 pub fn resize(self: &Buffer, new_len: usize) -> %void {83 pub fn resize(self: &Buffer, new_len: usize) %void {
84 try self.list.resize(new_len + 1);84 try self.list.resize(new_len + 1);
85 self.list.items[self.len()] = 0;85 self.list.items[self.len()] = 0;
86 }86 }
8787
88 pub fn isNull(self: &const Buffer) -> bool {88 pub fn isNull(self: &const Buffer) bool {
89 return self.list.len == 0;89 return self.list.len == 0;
90 }90 }
9191
92 pub fn len(self: &const Buffer) -> usize {92 pub fn len(self: &const Buffer) usize {
93 return self.list.len - 1;93 return self.list.len - 1;
94 }94 }
9595
96 pub fn append(self: &Buffer, m: []const u8) -> %void {96 pub fn append(self: &Buffer, m: []const u8) %void {
97 const old_len = self.len();97 const old_len = self.len();
98 try self.resize(old_len + m.len);98 try self.resize(old_len + m.len);
99 mem.copy(u8, self.list.toSlice()[old_len..], m);99 mem.copy(u8, self.list.toSlice()[old_len..], m);
100 }100 }
101101
102 // TODO: remove, use OutStream for this102 // TODO: remove, use OutStream for this
103 pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) -> %void {103 pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) %void {
104 return fmt.format(self, append, format, args);104 return fmt.format(self, append, format, args);
105 }105 }
106106
107 // TODO: remove, use OutStream for this107 // TODO: remove, use OutStream for this
108 pub fn appendByte(self: &Buffer, byte: u8) -> %void {108 pub fn appendByte(self: &Buffer, byte: u8) %void {
109 return self.appendByteNTimes(byte, 1);109 return self.appendByteNTimes(byte, 1);
110 }110 }
111111
112 // TODO: remove, use OutStream for this112 // TODO: remove, use OutStream for this
113 pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void {113 pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) %void {
114 var prev_size: usize = self.len();114 var prev_size: usize = self.len();
115 const new_size = prev_size + count;115 const new_size = prev_size + count;
116 try self.resize(new_size);116 try self.resize(new_size);
...@@ -121,29 +121,29 @@ pub const Buffer = struct {...@@ -121,29 +121,29 @@ pub const Buffer = struct {
121 }121 }
122 }122 }
123123
124 pub fn eql(self: &const Buffer, m: []const u8) -> bool {124 pub fn eql(self: &const Buffer, m: []const u8) bool {
125 return mem.eql(u8, self.toSliceConst(), m);125 return mem.eql(u8, self.toSliceConst(), m);
126 }126 }
127127
128 pub fn startsWith(self: &const Buffer, m: []const u8) -> bool {128 pub fn startsWith(self: &const Buffer, m: []const u8) bool {
129 if (self.len() < m.len) return false;129 if (self.len() < m.len) return false;
130 return mem.eql(u8, self.list.items[0..m.len], m);130 return mem.eql(u8, self.list.items[0..m.len], m);
131 }131 }
132132
133 pub fn endsWith(self: &const Buffer, m: []const u8) -> bool {133 pub fn endsWith(self: &const Buffer, m: []const u8) bool {
134 const l = self.len();134 const l = self.len();
135 if (l < m.len) return false;135 if (l < m.len) return false;
136 const start = l - m.len;136 const start = l - m.len;
137 return mem.eql(u8, self.list.items[start..l], m);137 return mem.eql(u8, self.list.items[start..l], m);
138 }138 }
139139
140 pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {140 pub fn replaceContents(self: &const Buffer, m: []const u8) %void {
141 try self.resize(m.len);141 try self.resize(m.len);
142 mem.copy(u8, self.list.toSlice(), m);142 mem.copy(u8, self.list.toSlice(), m);
143 }143 }
144144
145 /// For passing to C functions.145 /// For passing to C functions.
146 pub fn ptr(self: &const Buffer) -> &u8 {146 pub fn ptr(self: &const Buffer) &u8 {
147 return self.list.items.ptr;147 return self.list.items.ptr;
148 }148 }
149};149};
std/build.zig+124-124
...@@ -90,7 +90,7 @@ pub const Builder = struct {...@@ -90,7 +90,7 @@ pub const Builder = struct {
90 };90 };
9191
92 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,92 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,
93 cache_root: []const u8) -> Builder93 cache_root: []const u8) Builder
94 {94 {
95 var self = Builder {95 var self = Builder {
96 .zig_exe = zig_exe,96 .zig_exe = zig_exe,
...@@ -136,7 +136,7 @@ pub const Builder = struct {...@@ -136,7 +136,7 @@ pub const Builder = struct {
136 return self;136 return self;
137 }137 }
138138
139 pub fn deinit(self: &Builder) {139 pub fn deinit(self: &Builder) void {
140 self.lib_paths.deinit();140 self.lib_paths.deinit();
141 self.include_paths.deinit();141 self.include_paths.deinit();
142 self.rpaths.deinit();142 self.rpaths.deinit();
...@@ -144,85 +144,85 @@ pub const Builder = struct {...@@ -144,85 +144,85 @@ pub const Builder = struct {
144 self.top_level_steps.deinit();144 self.top_level_steps.deinit();
145 }145 }
146146
147 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {147 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) void {
148 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default148 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default
149 self.lib_dir = os.path.join(self.allocator, self.prefix, "lib") catch unreachable;149 self.lib_dir = os.path.join(self.allocator, self.prefix, "lib") catch unreachable;
150 self.exe_dir = os.path.join(self.allocator, self.prefix, "bin") catch unreachable;150 self.exe_dir = os.path.join(self.allocator, self.prefix, "bin") catch unreachable;
151 }151 }
152152
153 pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {153 pub fn addExecutable(self: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
154 return LibExeObjStep.createExecutable(self, name, root_src);154 return LibExeObjStep.createExecutable(self, name, root_src);
155 }155 }
156156
157 pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep {157 pub fn addObject(self: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
158 return LibExeObjStep.createObject(self, name, root_src);158 return LibExeObjStep.createObject(self, name, root_src);
159 }159 }
160160
161 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,161 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,
162 ver: &const Version) -> &LibExeObjStep162 ver: &const Version) &LibExeObjStep
163 {163 {
164 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);164 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
165 }165 }
166166
167 pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {167 pub fn addStaticLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
168 return LibExeObjStep.createStaticLibrary(self, name, root_src);168 return LibExeObjStep.createStaticLibrary(self, name, root_src);
169 }169 }
170170
171 pub fn addTest(self: &Builder, root_src: []const u8) -> &TestStep {171 pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {
172 const test_step = self.allocator.create(TestStep) catch unreachable;172 const test_step = self.allocator.create(TestStep) catch unreachable;
173 *test_step = TestStep.init(self, root_src);173 *test_step = TestStep.init(self, root_src);
174 return test_step;174 return test_step;
175 }175 }
176176
177 pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {177 pub fn addAssemble(self: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
178 const obj_step = LibExeObjStep.createObject(self, name, null);178 const obj_step = LibExeObjStep.createObject(self, name, null);
179 obj_step.addAssemblyFile(src);179 obj_step.addAssemblyFile(src);
180 return obj_step;180 return obj_step;
181 }181 }
182182
183 pub fn addCStaticLibrary(self: &Builder, name: []const u8) -> &LibExeObjStep {183 pub fn addCStaticLibrary(self: &Builder, name: []const u8) &LibExeObjStep {
184 return LibExeObjStep.createCStaticLibrary(self, name);184 return LibExeObjStep.createCStaticLibrary(self, name);
185 }185 }
186186
187 pub fn addCSharedLibrary(self: &Builder, name: []const u8, ver: &const Version) -> &LibExeObjStep {187 pub fn addCSharedLibrary(self: &Builder, name: []const u8, ver: &const Version) &LibExeObjStep {
188 return LibExeObjStep.createCSharedLibrary(self, name, ver);188 return LibExeObjStep.createCSharedLibrary(self, name, ver);
189 }189 }
190190
191 pub fn addCExecutable(self: &Builder, name: []const u8) -> &LibExeObjStep {191 pub fn addCExecutable(self: &Builder, name: []const u8) &LibExeObjStep {
192 return LibExeObjStep.createCExecutable(self, name);192 return LibExeObjStep.createCExecutable(self, name);
193 }193 }
194194
195 pub fn addCObject(self: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {195 pub fn addCObject(self: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
196 return LibExeObjStep.createCObject(self, name, src);196 return LibExeObjStep.createCObject(self, name, src);
197 }197 }
198198
199 /// ::argv is copied.199 /// ::argv is copied.
200 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,200 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
201 argv: []const []const u8) -> &CommandStep201 argv: []const []const u8) &CommandStep
202 {202 {
203 return CommandStep.create(self, cwd, env_map, argv);203 return CommandStep.create(self, cwd, env_map, argv);
204 }204 }
205205
206 pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) -> &WriteFileStep {206 pub fn addWriteFile(self: &Builder, file_path: []const u8, data: []const u8) &WriteFileStep {
207 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;207 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
208 *write_file_step = WriteFileStep.init(self, file_path, data);208 *write_file_step = WriteFileStep.init(self, file_path, data);
209 return write_file_step;209 return write_file_step;
210 }210 }
211211
212 pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) -> &LogStep {212 pub fn addLog(self: &Builder, comptime format: []const u8, args: ...) &LogStep {
213 const data = self.fmt(format, args);213 const data = self.fmt(format, args);
214 const log_step = self.allocator.create(LogStep) catch unreachable;214 const log_step = self.allocator.create(LogStep) catch unreachable;
215 *log_step = LogStep.init(self, data);215 *log_step = LogStep.init(self, data);
216 return log_step;216 return log_step;
217 }217 }
218218
219 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) -> &RemoveDirStep {219 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {
220 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;220 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
221 *remove_dir_step = RemoveDirStep.init(self, dir_path);221 *remove_dir_step = RemoveDirStep.init(self, dir_path);
222 return remove_dir_step;222 return remove_dir_step;
223 }223 }
224224
225 pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) -> Version {225 pub fn version(self: &const Builder, major: u32, minor: u32, patch: u32) Version {
226 return Version {226 return Version {
227 .major = major,227 .major = major,
228 .minor = minor,228 .minor = minor,
...@@ -230,19 +230,19 @@ pub const Builder = struct {...@@ -230,19 +230,19 @@ pub const Builder = struct {
230 };230 };
231 }231 }
232232
233 pub fn addCIncludePath(self: &Builder, path: []const u8) {233 pub fn addCIncludePath(self: &Builder, path: []const u8) void {
234 self.include_paths.append(path) catch unreachable;234 self.include_paths.append(path) catch unreachable;
235 }235 }
236236
237 pub fn addRPath(self: &Builder, path: []const u8) {237 pub fn addRPath(self: &Builder, path: []const u8) void {
238 self.rpaths.append(path) catch unreachable;238 self.rpaths.append(path) catch unreachable;
239 }239 }
240240
241 pub fn addLibPath(self: &Builder, path: []const u8) {241 pub fn addLibPath(self: &Builder, path: []const u8) void {
242 self.lib_paths.append(path) catch unreachable;242 self.lib_paths.append(path) catch unreachable;
243 }243 }
244244
245 pub fn make(self: &Builder, step_names: []const []const u8) -> %void {245 pub fn make(self: &Builder, step_names: []const []const u8) %void {
246 var wanted_steps = ArrayList(&Step).init(self.allocator);246 var wanted_steps = ArrayList(&Step).init(self.allocator);
247 defer wanted_steps.deinit();247 defer wanted_steps.deinit();
248248
...@@ -260,7 +260,7 @@ pub const Builder = struct {...@@ -260,7 +260,7 @@ pub const Builder = struct {
260 }260 }
261 }261 }
262262
263 pub fn getInstallStep(self: &Builder) -> &Step {263 pub fn getInstallStep(self: &Builder) &Step {
264 if (self.have_install_step)264 if (self.have_install_step)
265 return &self.install_tls.step;265 return &self.install_tls.step;
266266
...@@ -269,7 +269,7 @@ pub const Builder = struct {...@@ -269,7 +269,7 @@ pub const Builder = struct {
269 return &self.install_tls.step;269 return &self.install_tls.step;
270 }270 }
271271
272 pub fn getUninstallStep(self: &Builder) -> &Step {272 pub fn getUninstallStep(self: &Builder) &Step {
273 if (self.have_uninstall_step)273 if (self.have_uninstall_step)
274 return &self.uninstall_tls.step;274 return &self.uninstall_tls.step;
275275
...@@ -278,7 +278,7 @@ pub const Builder = struct {...@@ -278,7 +278,7 @@ pub const Builder = struct {
278 return &self.uninstall_tls.step;278 return &self.uninstall_tls.step;
279 }279 }
280280
281 fn makeUninstall(uninstall_step: &Step) -> %void {281 fn makeUninstall(uninstall_step: &Step) %void {
282 const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);282 const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
283 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);283 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
284284
...@@ -292,7 +292,7 @@ pub const Builder = struct {...@@ -292,7 +292,7 @@ pub const Builder = struct {
292 // TODO remove empty directories292 // TODO remove empty directories
293 }293 }
294294
295 fn makeOneStep(self: &Builder, s: &Step) -> %void {295 fn makeOneStep(self: &Builder, s: &Step) %void {
296 if (s.loop_flag) {296 if (s.loop_flag) {
297 warn("Dependency loop detected:\n {}\n", s.name);297 warn("Dependency loop detected:\n {}\n", s.name);
298 return error.DependencyLoopDetected;298 return error.DependencyLoopDetected;
...@@ -313,7 +313,7 @@ pub const Builder = struct {...@@ -313,7 +313,7 @@ pub const Builder = struct {
313 try s.make();313 try s.make();
314 }314 }
315315
316 fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step {316 fn getTopLevelStepByName(self: &Builder, name: []const u8) %&Step {
317 for (self.top_level_steps.toSliceConst()) |top_level_step| {317 for (self.top_level_steps.toSliceConst()) |top_level_step| {
318 if (mem.eql(u8, top_level_step.step.name, name)) {318 if (mem.eql(u8, top_level_step.step.name, name)) {
319 return &top_level_step.step;319 return &top_level_step.step;
...@@ -323,7 +323,7 @@ pub const Builder = struct {...@@ -323,7 +323,7 @@ pub const Builder = struct {
323 return error.InvalidStepName;323 return error.InvalidStepName;
324 }324 }
325325
326 fn processNixOSEnvVars(self: &Builder) {326 fn processNixOSEnvVars(self: &Builder) void {
327 if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {327 if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
328 var it = mem.split(nix_cflags_compile, " ");328 var it = mem.split(nix_cflags_compile, " ");
329 while (true) {329 while (true) {
...@@ -365,7 +365,7 @@ pub const Builder = struct {...@@ -365,7 +365,7 @@ pub const Builder = struct {
365 }365 }
366 }366 }
367367
368 pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) -> ?T {368 pub fn option(self: &Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
369 const type_id = comptime typeToEnum(T);369 const type_id = comptime typeToEnum(T);
370 const available_option = AvailableOption {370 const available_option = AvailableOption {
371 .name = name,371 .name = name,
...@@ -418,7 +418,7 @@ pub const Builder = struct {...@@ -418,7 +418,7 @@ pub const Builder = struct {
418 }418 }
419 }419 }
420420
421 pub fn step(self: &Builder, name: []const u8, description: []const u8) -> &Step {421 pub fn step(self: &Builder, name: []const u8, description: []const u8) &Step {
422 const step_info = self.allocator.create(TopLevelStep) catch unreachable;422 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
423 *step_info = TopLevelStep {423 *step_info = TopLevelStep {
424 .step = Step.initNoOp(name, self.allocator),424 .step = Step.initNoOp(name, self.allocator),
...@@ -428,7 +428,7 @@ pub const Builder = struct {...@@ -428,7 +428,7 @@ pub const Builder = struct {
428 return &step_info.step;428 return &step_info.step;
429 }429 }
430430
431 pub fn standardReleaseOptions(self: &Builder) -> builtin.Mode {431 pub fn standardReleaseOptions(self: &Builder) builtin.Mode {
432 if (self.release_mode) |mode| return mode;432 if (self.release_mode) |mode| return mode;
433433
434 const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false;434 const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false;
...@@ -449,7 +449,7 @@ pub const Builder = struct {...@@ -449,7 +449,7 @@ pub const Builder = struct {
449 return mode;449 return mode;
450 }450 }
451451
452 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) -> bool {452 pub fn addUserInputOption(self: &Builder, name: []const u8, value: []const u8) bool {
453 if (self.user_input_options.put(name, UserInputOption {453 if (self.user_input_options.put(name, UserInputOption {
454 .name = name,454 .name = name,
455 .value = UserValue { .Scalar = value },455 .value = UserValue { .Scalar = value },
...@@ -486,7 +486,7 @@ pub const Builder = struct {...@@ -486,7 +486,7 @@ pub const Builder = struct {
486 return false;486 return false;
487 }487 }
488488
489 pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool {489 pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {
490 if (self.user_input_options.put(name, UserInputOption {490 if (self.user_input_options.put(name, UserInputOption {
491 .name = name,491 .name = name,
492 .value = UserValue {.Flag = {} },492 .value = UserValue {.Flag = {} },
...@@ -507,7 +507,7 @@ pub const Builder = struct {...@@ -507,7 +507,7 @@ pub const Builder = struct {
507 return false;507 return false;
508 }508 }
509509
510 fn typeToEnum(comptime T: type) -> TypeId {510 fn typeToEnum(comptime T: type) TypeId {
511 return switch (@typeId(T)) {511 return switch (@typeId(T)) {
512 builtin.TypeId.Int => TypeId.Int,512 builtin.TypeId.Int => TypeId.Int,
513 builtin.TypeId.Float => TypeId.Float,513 builtin.TypeId.Float => TypeId.Float,
...@@ -520,11 +520,11 @@ pub const Builder = struct {...@@ -520,11 +520,11 @@ pub const Builder = struct {
520 };520 };
521 }521 }
522522
523 fn markInvalidUserInput(self: &Builder) {523 fn markInvalidUserInput(self: &Builder) void {
524 self.invalid_user_input = true;524 self.invalid_user_input = true;
525 }525 }
526526
527 pub fn typeIdName(id: TypeId) -> []const u8 {527 pub fn typeIdName(id: TypeId) []const u8 {
528 return switch (id) {528 return switch (id) {
529 TypeId.Bool => "bool",529 TypeId.Bool => "bool",
530 TypeId.Int => "int",530 TypeId.Int => "int",
...@@ -534,7 +534,7 @@ pub const Builder = struct {...@@ -534,7 +534,7 @@ pub const Builder = struct {
534 };534 };
535 }535 }
536536
537 pub fn validateUserInputDidItFail(self: &Builder) -> bool {537 pub fn validateUserInputDidItFail(self: &Builder) bool {
538 // make sure all args are used538 // make sure all args are used
539 var it = self.user_input_options.iterator();539 var it = self.user_input_options.iterator();
540 while (true) {540 while (true) {
...@@ -548,11 +548,11 @@ pub const Builder = struct {...@@ -548,11 +548,11 @@ pub const Builder = struct {
548 return self.invalid_user_input;548 return self.invalid_user_input;
549 }549 }
550550
551 fn spawnChild(self: &Builder, argv: []const []const u8) -> %void {551 fn spawnChild(self: &Builder, argv: []const []const u8) %void {
552 return self.spawnChildEnvMap(null, &self.env_map, argv);552 return self.spawnChildEnvMap(null, &self.env_map, argv);
553 }553 }
554554
555 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) {555 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
556 if (cwd) |yes_cwd| warn("cd {} && ", yes_cwd);556 if (cwd) |yes_cwd| warn("cd {} && ", yes_cwd);
557 for (argv) |arg| {557 for (argv) |arg| {
558 warn("{} ", arg);558 warn("{} ", arg);
...@@ -561,7 +561,7 @@ pub const Builder = struct {...@@ -561,7 +561,7 @@ pub const Builder = struct {
561 }561 }
562562
563 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,563 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
564 argv: []const []const u8) -> %void564 argv: []const []const u8) %void
565 {565 {
566 if (self.verbose) {566 if (self.verbose) {
567 printCmd(cwd, argv);567 printCmd(cwd, argv);
...@@ -595,28 +595,28 @@ pub const Builder = struct {...@@ -595,28 +595,28 @@ pub const Builder = struct {
595 }595 }
596 }596 }
597597
598 pub fn makePath(self: &Builder, path: []const u8) -> %void {598 pub fn makePath(self: &Builder, path: []const u8) %void {
599 os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {599 os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
600 warn("Unable to create path {}: {}\n", path, @errorName(err));600 warn("Unable to create path {}: {}\n", path, @errorName(err));
601 return err;601 return err;
602 };602 };
603 }603 }
604604
605 pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) {605 pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) void {
606 self.getInstallStep().dependOn(&self.addInstallArtifact(artifact).step);606 self.getInstallStep().dependOn(&self.addInstallArtifact(artifact).step);
607 }607 }
608608
609 pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) -> &InstallArtifactStep {609 pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) &InstallArtifactStep {
610 return InstallArtifactStep.create(self, artifact);610 return InstallArtifactStep.create(self, artifact);
611 }611 }
612612
613 ///::dest_rel_path is relative to prefix path or it can be an absolute path613 ///::dest_rel_path is relative to prefix path or it can be an absolute path
614 pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) {614 pub fn installFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) void {
615 self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step);615 self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step);
616 }616 }
617617
618 ///::dest_rel_path is relative to prefix path or it can be an absolute path618 ///::dest_rel_path is relative to prefix path or it can be an absolute path
619 pub fn addInstallFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) -> &InstallFileStep {619 pub fn addInstallFile(self: &Builder, src_path: []const u8, dest_rel_path: []const u8) &InstallFileStep {
620 const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;620 const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
621 self.pushInstalledFile(full_dest_path);621 self.pushInstalledFile(full_dest_path);
622622
...@@ -625,16 +625,16 @@ pub const Builder = struct {...@@ -625,16 +625,16 @@ pub const Builder = struct {
625 return install_step;625 return install_step;
626 }626 }
627627
628 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) {628 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) void {
629 _ = self.getUninstallStep();629 _ = self.getUninstallStep();
630 self.installed_files.append(full_path) catch unreachable;630 self.installed_files.append(full_path) catch unreachable;
631 }631 }
632632
633 fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) -> %void {633 fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) %void {
634 return self.copyFileMode(source_path, dest_path, 0o666);634 return self.copyFileMode(source_path, dest_path, 0o666);
635 }635 }
636636
637 fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void {637 fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) %void {
638 if (self.verbose) {638 if (self.verbose) {
639 warn("cp {} {}\n", source_path, dest_path);639 warn("cp {} {}\n", source_path, dest_path);
640 }640 }
...@@ -651,15 +651,15 @@ pub const Builder = struct {...@@ -651,15 +651,15 @@ pub const Builder = struct {
651 };651 };
652 }652 }
653653
654 fn pathFromRoot(self: &Builder, rel_path: []const u8) -> []u8 {654 fn pathFromRoot(self: &Builder, rel_path: []const u8) []u8 {
655 return os.path.resolve(self.allocator, self.build_root, rel_path) catch unreachable;655 return os.path.resolve(self.allocator, self.build_root, rel_path) catch unreachable;
656 }656 }
657657
658 pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) -> []u8 {658 pub fn fmt(self: &Builder, comptime format: []const u8, args: ...) []u8 {
659 return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable;659 return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable;
660 }660 }
661661
662 fn getCCExe(self: &Builder) -> []const u8 {662 fn getCCExe(self: &Builder) []const u8 {
663 if (builtin.environ == builtin.Environ.msvc) {663 if (builtin.environ == builtin.Environ.msvc) {
664 return "cl.exe";664 return "cl.exe";
665 } else {665 } else {
...@@ -672,7 +672,7 @@ pub const Builder = struct {...@@ -672,7 +672,7 @@ pub const Builder = struct {
672 }672 }
673 }673 }
674674
675 pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) -> %[]const u8 {675 pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) %[]const u8 {
676 // TODO report error for ambiguous situations676 // TODO report error for ambiguous situations
677 const exe_extension = (Target { .Native = {}}).exeFileExt();677 const exe_extension = (Target { .Native = {}}).exeFileExt();
678 for (self.search_prefixes.toSliceConst()) |search_prefix| {678 for (self.search_prefixes.toSliceConst()) |search_prefix| {
...@@ -721,7 +721,7 @@ pub const Builder = struct {...@@ -721,7 +721,7 @@ pub const Builder = struct {
721 return error.FileNotFound;721 return error.FileNotFound;
722 }722 }
723723
724 pub fn exec(self: &Builder, argv: []const []const u8) -> %[]u8 {724 pub fn exec(self: &Builder, argv: []const []const u8) %[]u8 {
725 const max_output_size = 100 * 1024;725 const max_output_size = 100 * 1024;
726 const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);726 const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);
727 switch (result.term) {727 switch (result.term) {
...@@ -743,7 +743,7 @@ pub const Builder = struct {...@@ -743,7 +743,7 @@ pub const Builder = struct {
743 }743 }
744 }744 }
745745
746 pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) {746 pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) void {
747 self.search_prefixes.append(search_prefix) catch unreachable;747 self.search_prefixes.append(search_prefix) catch unreachable;
748 }748 }
749};749};
...@@ -764,7 +764,7 @@ pub const Target = union(enum) {...@@ -764,7 +764,7 @@ pub const Target = union(enum) {
764 Native: void,764 Native: void,
765 Cross: CrossTarget,765 Cross: CrossTarget,
766766
767 pub fn oFileExt(self: &const Target) -> []const u8 {767 pub fn oFileExt(self: &const Target) []const u8 {
768 const environ = switch (*self) {768 const environ = switch (*self) {
769 Target.Native => builtin.environ,769 Target.Native => builtin.environ,
770 Target.Cross => |t| t.environ,770 Target.Cross => |t| t.environ,
...@@ -775,42 +775,42 @@ pub const Target = union(enum) {...@@ -775,42 +775,42 @@ pub const Target = union(enum) {
775 };775 };
776 }776 }
777777
778 pub fn exeFileExt(self: &const Target) -> []const u8 {778 pub fn exeFileExt(self: &const Target) []const u8 {
779 return switch (self.getOs()) {779 return switch (self.getOs()) {
780 builtin.Os.windows => ".exe",780 builtin.Os.windows => ".exe",
781 else => "",781 else => "",
782 };782 };
783 }783 }
784784
785 pub fn libFileExt(self: &const Target) -> []const u8 {785 pub fn libFileExt(self: &const Target) []const u8 {
786 return switch (self.getOs()) {786 return switch (self.getOs()) {
787 builtin.Os.windows => ".lib",787 builtin.Os.windows => ".lib",
788 else => ".a",788 else => ".a",
789 };789 };
790 }790 }
791791
792 pub fn getOs(self: &const Target) -> builtin.Os {792 pub fn getOs(self: &const Target) builtin.Os {
793 return switch (*self) {793 return switch (*self) {
794 Target.Native => builtin.os,794 Target.Native => builtin.os,
795 Target.Cross => |t| t.os,795 Target.Cross => |t| t.os,
796 };796 };
797 }797 }
798798
799 pub fn isDarwin(self: &const Target) -> bool {799 pub fn isDarwin(self: &const Target) bool {
800 return switch (self.getOs()) {800 return switch (self.getOs()) {
801 builtin.Os.ios, builtin.Os.macosx => true,801 builtin.Os.ios, builtin.Os.macosx => true,
802 else => false,802 else => false,
803 };803 };
804 }804 }
805805
806 pub fn isWindows(self: &const Target) -> bool {806 pub fn isWindows(self: &const Target) bool {
807 return switch (self.getOs()) {807 return switch (self.getOs()) {
808 builtin.Os.windows => true,808 builtin.Os.windows => true,
809 else => false,809 else => false,
810 };810 };
811 }811 }
812812
813 pub fn wantSharedLibSymLinks(self: &const Target) -> bool {813 pub fn wantSharedLibSymLinks(self: &const Target) bool {
814 return !self.isWindows();814 return !self.isWindows();
815 }815 }
816};816};
...@@ -865,58 +865,58 @@ pub const LibExeObjStep = struct {...@@ -865,58 +865,58 @@ pub const LibExeObjStep = struct {
865 };865 };
866866
867 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,867 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,
868 ver: &const Version) -> &LibExeObjStep868 ver: &const Version) &LibExeObjStep
869 {869 {
870 const self = builder.allocator.create(LibExeObjStep) catch unreachable;870 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
871 *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);871 *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
872 return self;872 return self;
873 }873 }
874874
875 pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) -> &LibExeObjStep {875 pub fn createCSharedLibrary(builder: &Builder, name: []const u8, version: &const Version) &LibExeObjStep {
876 const self = builder.allocator.create(LibExeObjStep) catch unreachable;876 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
877 *self = initC(builder, name, Kind.Lib, version, false);877 *self = initC(builder, name, Kind.Lib, version, false);
878 return self;878 return self;
879 }879 }
880880
881 pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {881 pub fn createStaticLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
882 const self = builder.allocator.create(LibExeObjStep) catch unreachable;882 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
883 *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));883 *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
884 return self;884 return self;
885 }885 }
886886
887 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) -> &LibExeObjStep {887 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {
888 const self = builder.allocator.create(LibExeObjStep) catch unreachable;888 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
889 *self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);889 *self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
890 return self;890 return self;
891 }891 }
892892
893 pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) -> &LibExeObjStep {893 pub fn createObject(builder: &Builder, name: []const u8, root_src: []const u8) &LibExeObjStep {
894 const self = builder.allocator.create(LibExeObjStep) catch unreachable;894 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
895 *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));895 *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
896 return self;896 return self;
897 }897 }
898898
899 pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) -> &LibExeObjStep {899 pub fn createCObject(builder: &Builder, name: []const u8, src: []const u8) &LibExeObjStep {
900 const self = builder.allocator.create(LibExeObjStep) catch unreachable;900 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
901 *self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);901 *self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
902 self.object_src = src;902 self.object_src = src;
903 return self;903 return self;
904 }904 }
905905
906 pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) -> &LibExeObjStep {906 pub fn createExecutable(builder: &Builder, name: []const u8, root_src: ?[]const u8) &LibExeObjStep {
907 const self = builder.allocator.create(LibExeObjStep) catch unreachable;907 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
908 *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));908 *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
909 return self;909 return self;
910 }910 }
911911
912 pub fn createCExecutable(builder: &Builder, name: []const u8) -> &LibExeObjStep {912 pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {
913 const self = builder.allocator.create(LibExeObjStep) catch unreachable;913 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
914 *self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);914 *self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
915 return self;915 return self;
916 }916 }
917917
918 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,918 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,
919 static: bool, ver: &const Version) -> LibExeObjStep919 static: bool, ver: &const Version) LibExeObjStep
920 {920 {
921 var self = LibExeObjStep {921 var self = LibExeObjStep {
922 .strip = false,922 .strip = false,
...@@ -956,7 +956,7 @@ pub const LibExeObjStep = struct {...@@ -956,7 +956,7 @@ pub const LibExeObjStep = struct {
956 return self;956 return self;
957 }957 }
958958
959 fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) -> LibExeObjStep {959 fn initC(builder: &Builder, name: []const u8, kind: Kind, version: &const Version, static: bool) LibExeObjStep {
960 var self = LibExeObjStep {960 var self = LibExeObjStep {
961 .builder = builder,961 .builder = builder,
962 .name = name,962 .name = name,
...@@ -996,7 +996,7 @@ pub const LibExeObjStep = struct {...@@ -996,7 +996,7 @@ pub const LibExeObjStep = struct {
996 return self;996 return self;
997 }997 }
998998
999 fn computeOutFileNames(self: &LibExeObjStep) {999 fn computeOutFileNames(self: &LibExeObjStep) void {
1000 switch (self.kind) {1000 switch (self.kind) {
1001 Kind.Obj => {1001 Kind.Obj => {
1002 self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());1002 self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());
...@@ -1031,7 +1031,7 @@ pub const LibExeObjStep = struct {...@@ -1031,7 +1031,7 @@ pub const LibExeObjStep = struct {
1031 }1031 }
10321032
1033 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,1033 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,
1034 target_environ: builtin.Environ)1034 target_environ: builtin.Environ) void
1035 {1035 {
1036 self.target = Target {1036 self.target = Target {
1037 .Cross = CrossTarget {1037 .Cross = CrossTarget {
...@@ -1044,16 +1044,16 @@ pub const LibExeObjStep = struct {...@@ -1044,16 +1044,16 @@ pub const LibExeObjStep = struct {
1044 }1044 }
10451045
1046 // TODO respect this in the C args1046 // TODO respect this in the C args
1047 pub fn setLinkerScriptPath(self: &LibExeObjStep, path: []const u8) {1047 pub fn setLinkerScriptPath(self: &LibExeObjStep, path: []const u8) void {
1048 self.linker_script = path;1048 self.linker_script = path;
1049 }1049 }
10501050
1051 pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) {1051 pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) void {
1052 assert(self.target.isDarwin());1052 assert(self.target.isDarwin());
1053 self.frameworks.put(framework_name) catch unreachable;1053 self.frameworks.put(framework_name) catch unreachable;
1054 }1054 }
10551055
1056 pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) {1056 pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) void {
1057 assert(self.kind != Kind.Obj);1057 assert(self.kind != Kind.Obj);
1058 assert(lib.kind == Kind.Lib);1058 assert(lib.kind == Kind.Lib);
10591059
...@@ -1074,26 +1074,26 @@ pub const LibExeObjStep = struct {...@@ -1074,26 +1074,26 @@ pub const LibExeObjStep = struct {
1074 }1074 }
1075 }1075 }
10761076
1077 pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) {1077 pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) void {
1078 assert(self.kind != Kind.Obj);1078 assert(self.kind != Kind.Obj);
1079 self.link_libs.put(name) catch unreachable;1079 self.link_libs.put(name) catch unreachable;
1080 }1080 }
10811081
1082 pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) {1082 pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) void {
1083 assert(self.kind != Kind.Obj);1083 assert(self.kind != Kind.Obj);
1084 assert(!self.is_zig);1084 assert(!self.is_zig);
1085 self.source_files.append(file) catch unreachable;1085 self.source_files.append(file) catch unreachable;
1086 }1086 }
10871087
1088 pub fn setVerboseLink(self: &LibExeObjStep, value: bool) {1088 pub fn setVerboseLink(self: &LibExeObjStep, value: bool) void {
1089 self.verbose_link = value;1089 self.verbose_link = value;
1090 }1090 }
10911091
1092 pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) {1092 pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) void {
1093 self.build_mode = mode;1093 self.build_mode = mode;
1094 }1094 }
10951095
1096 pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) {1096 pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) void {
1097 self.output_path = file_path;1097 self.output_path = file_path;
10981098
1099 // catch a common mistake1099 // catch a common mistake
...@@ -1102,14 +1102,14 @@ pub const LibExeObjStep = struct {...@@ -1102,14 +1102,14 @@ pub const LibExeObjStep = struct {
1102 }1102 }
1103 }1103 }
11041104
1105 pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 {1105 pub fn getOutputPath(self: &LibExeObjStep) []const u8 {
1106 return if (self.output_path) |output_path|1106 return if (self.output_path) |output_path|
1107 output_path1107 output_path
1108 else1108 else
1109 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;1109 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;
1110 }1110 }
11111111
1112 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) {1112 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {
1113 self.output_h_path = file_path;1113 self.output_h_path = file_path;
11141114
1115 // catch a common mistake1115 // catch a common mistake
...@@ -1118,24 +1118,24 @@ pub const LibExeObjStep = struct {...@@ -1118,24 +1118,24 @@ pub const LibExeObjStep = struct {
1118 }1118 }
1119 }1119 }
11201120
1121 pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 {1121 pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {
1122 return if (self.output_h_path) |output_h_path|1122 return if (self.output_h_path) |output_h_path|
1123 output_h_path1123 output_h_path
1124 else1124 else
1125 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;1125 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;
1126 }1126 }
11271127
1128 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) {1128 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {
1129 self.assembly_files.append(path) catch unreachable;1129 self.assembly_files.append(path) catch unreachable;
1130 }1130 }
11311131
1132 pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) {1132 pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) void {
1133 assert(self.kind != Kind.Obj);1133 assert(self.kind != Kind.Obj);
11341134
1135 self.object_files.append(path) catch unreachable;1135 self.object_files.append(path) catch unreachable;
1136 }1136 }
11371137
1138 pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) {1138 pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) void {
1139 assert(obj.kind == Kind.Obj);1139 assert(obj.kind == Kind.Obj);
1140 assert(self.kind != Kind.Obj);1140 assert(self.kind != Kind.Obj);
11411141
...@@ -1152,15 +1152,15 @@ pub const LibExeObjStep = struct {...@@ -1152,15 +1152,15 @@ pub const LibExeObjStep = struct {
1152 self.include_dirs.append(self.builder.cache_root) catch unreachable;1152 self.include_dirs.append(self.builder.cache_root) catch unreachable;
1153 }1153 }
11541154
1155 pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) {1155 pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) void {
1156 self.include_dirs.append(path) catch unreachable;1156 self.include_dirs.append(path) catch unreachable;
1157 }1157 }
11581158
1159 pub fn addLibPath(self: &LibExeObjStep, path: []const u8) {1159 pub fn addLibPath(self: &LibExeObjStep, path: []const u8) void {
1160 self.lib_paths.append(path) catch unreachable;1160 self.lib_paths.append(path) catch unreachable;
1161 }1161 }
11621162
1163 pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) {1163 pub fn addPackagePath(self: &LibExeObjStep, name: []const u8, pkg_index_path: []const u8) void {
1164 assert(self.is_zig);1164 assert(self.is_zig);
11651165
1166 self.packages.append(Pkg {1166 self.packages.append(Pkg {
...@@ -1169,23 +1169,23 @@ pub const LibExeObjStep = struct {...@@ -1169,23 +1169,23 @@ pub const LibExeObjStep = struct {
1169 }) catch unreachable;1169 }) catch unreachable;
1170 }1170 }
11711171
1172 pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) {1172 pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) void {
1173 for (flags) |flag| {1173 for (flags) |flag| {
1174 self.cflags.append(flag) catch unreachable;1174 self.cflags.append(flag) catch unreachable;
1175 }1175 }
1176 }1176 }
11771177
1178 pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) {1178 pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) void {
1179 assert(!self.is_zig);1179 assert(!self.is_zig);
1180 self.disable_libc = disable;1180 self.disable_libc = disable;
1181 }1181 }
11821182
1183 fn make(step: &Step) -> %void {1183 fn make(step: &Step) %void {
1184 const self = @fieldParentPtr(LibExeObjStep, "step", step);1184 const self = @fieldParentPtr(LibExeObjStep, "step", step);
1185 return if (self.is_zig) self.makeZig() else self.makeC();1185 return if (self.is_zig) self.makeZig() else self.makeC();
1186 }1186 }
11871187
1188 fn makeZig(self: &LibExeObjStep) -> %void {1188 fn makeZig(self: &LibExeObjStep) %void {
1189 const builder = self.builder;1189 const builder = self.builder;
11901190
1191 assert(self.is_zig);1191 assert(self.is_zig);
...@@ -1351,7 +1351,7 @@ pub const LibExeObjStep = struct {...@@ -1351,7 +1351,7 @@ pub const LibExeObjStep = struct {
1351 }1351 }
1352 }1352 }
13531353
1354 fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) {1354 fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) void {
1355 if (!self.strip) {1355 if (!self.strip) {
1356 args.append("-g") catch unreachable;1356 args.append("-g") catch unreachable;
1357 }1357 }
...@@ -1396,7 +1396,7 @@ pub const LibExeObjStep = struct {...@@ -1396,7 +1396,7 @@ pub const LibExeObjStep = struct {
1396 }1396 }
1397 }1397 }
13981398
1399 fn makeC(self: &LibExeObjStep) -> %void {1399 fn makeC(self: &LibExeObjStep) %void {
1400 const builder = self.builder;1400 const builder = self.builder;
14011401
1402 const cc = builder.getCCExe();1402 const cc = builder.getCCExe();
...@@ -1635,7 +1635,7 @@ pub const TestStep = struct {...@@ -1635,7 +1635,7 @@ pub const TestStep = struct {
1635 target: Target,1635 target: Target,
1636 exec_cmd_args: ?[]const ?[]const u8,1636 exec_cmd_args: ?[]const ?[]const u8,
16371637
1638 pub fn init(builder: &Builder, root_src: []const u8) -> TestStep {1638 pub fn init(builder: &Builder, root_src: []const u8) TestStep {
1639 const step_name = builder.fmt("test {}", root_src);1639 const step_name = builder.fmt("test {}", root_src);
1640 return TestStep {1640 return TestStep {
1641 .step = Step.init(step_name, builder.allocator, make),1641 .step = Step.init(step_name, builder.allocator, make),
...@@ -1651,28 +1651,28 @@ pub const TestStep = struct {...@@ -1651,28 +1651,28 @@ pub const TestStep = struct {
1651 };1651 };
1652 }1652 }
16531653
1654 pub fn setVerbose(self: &TestStep, value: bool) {1654 pub fn setVerbose(self: &TestStep, value: bool) void {
1655 self.verbose = value;1655 self.verbose = value;
1656 }1656 }
16571657
1658 pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) {1658 pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) void {
1659 self.build_mode = mode;1659 self.build_mode = mode;
1660 }1660 }
16611661
1662 pub fn linkSystemLibrary(self: &TestStep, name: []const u8) {1662 pub fn linkSystemLibrary(self: &TestStep, name: []const u8) void {
1663 self.link_libs.put(name) catch unreachable;1663 self.link_libs.put(name) catch unreachable;
1664 }1664 }
16651665
1666 pub fn setNamePrefix(self: &TestStep, text: []const u8) {1666 pub fn setNamePrefix(self: &TestStep, text: []const u8) void {
1667 self.name_prefix = text;1667 self.name_prefix = text;
1668 }1668 }
16691669
1670 pub fn setFilter(self: &TestStep, text: ?[]const u8) {1670 pub fn setFilter(self: &TestStep, text: ?[]const u8) void {
1671 self.filter = text;1671 self.filter = text;
1672 }1672 }
16731673
1674 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,1674 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,
1675 target_environ: builtin.Environ)1675 target_environ: builtin.Environ) void
1676 {1676 {
1677 self.target = Target {1677 self.target = Target {
1678 .Cross = CrossTarget {1678 .Cross = CrossTarget {
...@@ -1683,11 +1683,11 @@ pub const TestStep = struct {...@@ -1683,11 +1683,11 @@ pub const TestStep = struct {
1683 };1683 };
1684 }1684 }
16851685
1686 pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) {1686 pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) void {
1687 self.exec_cmd_args = args;1687 self.exec_cmd_args = args;
1688 }1688 }
16891689
1690 fn make(step: &Step) -> %void {1690 fn make(step: &Step) %void {
1691 const self = @fieldParentPtr(TestStep, "step", step);1691 const self = @fieldParentPtr(TestStep, "step", step);
1692 const builder = self.builder;1692 const builder = self.builder;
16931693
...@@ -1781,7 +1781,7 @@ pub const CommandStep = struct {...@@ -1781,7 +1781,7 @@ pub const CommandStep = struct {
17811781
1782 /// ::argv is copied.1782 /// ::argv is copied.
1783 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,1783 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
1784 argv: []const []const u8) -> &CommandStep1784 argv: []const []const u8) &CommandStep
1785 {1785 {
1786 const self = builder.allocator.create(CommandStep) catch unreachable;1786 const self = builder.allocator.create(CommandStep) catch unreachable;
1787 *self = CommandStep {1787 *self = CommandStep {
...@@ -1796,7 +1796,7 @@ pub const CommandStep = struct {...@@ -1796,7 +1796,7 @@ pub const CommandStep = struct {
1796 return self;1796 return self;
1797 }1797 }
17981798
1799 fn make(step: &Step) -> %void {1799 fn make(step: &Step) %void {
1800 const self = @fieldParentPtr(CommandStep, "step", step);1800 const self = @fieldParentPtr(CommandStep, "step", step);
18011801
1802 const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;1802 const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
...@@ -1812,7 +1812,7 @@ const InstallArtifactStep = struct {...@@ -1812,7 +1812,7 @@ const InstallArtifactStep = struct {
18121812
1813 const Self = this;1813 const Self = this;
18141814
1815 pub fn create(builder: &Builder, artifact: &LibExeObjStep) -> &Self {1815 pub fn create(builder: &Builder, artifact: &LibExeObjStep) &Self {
1816 const self = builder.allocator.create(Self) catch unreachable;1816 const self = builder.allocator.create(Self) catch unreachable;
1817 const dest_dir = switch (artifact.kind) {1817 const dest_dir = switch (artifact.kind) {
1818 LibExeObjStep.Kind.Obj => unreachable,1818 LibExeObjStep.Kind.Obj => unreachable,
...@@ -1836,7 +1836,7 @@ const InstallArtifactStep = struct {...@@ -1836,7 +1836,7 @@ const InstallArtifactStep = struct {
1836 return self;1836 return self;
1837 }1837 }
18381838
1839 fn make(step: &Step) -> %void {1839 fn make(step: &Step) %void {
1840 const self = @fieldParentPtr(Self, "step", step);1840 const self = @fieldParentPtr(Self, "step", step);
1841 const builder = self.builder;1841 const builder = self.builder;
18421842
...@@ -1859,7 +1859,7 @@ pub const InstallFileStep = struct {...@@ -1859,7 +1859,7 @@ pub const InstallFileStep = struct {
1859 src_path: []const u8,1859 src_path: []const u8,
1860 dest_path: []const u8,1860 dest_path: []const u8,
18611861
1862 pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) -> InstallFileStep {1862 pub fn init(builder: &Builder, src_path: []const u8, dest_path: []const u8) InstallFileStep {
1863 return InstallFileStep {1863 return InstallFileStep {
1864 .builder = builder,1864 .builder = builder,
1865 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),1865 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
...@@ -1868,7 +1868,7 @@ pub const InstallFileStep = struct {...@@ -1868,7 +1868,7 @@ pub const InstallFileStep = struct {
1868 };1868 };
1869 }1869 }
18701870
1871 fn make(step: &Step) -> %void {1871 fn make(step: &Step) %void {
1872 const self = @fieldParentPtr(InstallFileStep, "step", step);1872 const self = @fieldParentPtr(InstallFileStep, "step", step);
1873 try self.builder.copyFile(self.src_path, self.dest_path);1873 try self.builder.copyFile(self.src_path, self.dest_path);
1874 }1874 }
...@@ -1880,7 +1880,7 @@ pub const WriteFileStep = struct {...@@ -1880,7 +1880,7 @@ pub const WriteFileStep = struct {
1880 file_path: []const u8,1880 file_path: []const u8,
1881 data: []const u8,1881 data: []const u8,
18821882
1883 pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) -> WriteFileStep {1883 pub fn init(builder: &Builder, file_path: []const u8, data: []const u8) WriteFileStep {
1884 return WriteFileStep {1884 return WriteFileStep {
1885 .builder = builder,1885 .builder = builder,
1886 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),1886 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
...@@ -1889,7 +1889,7 @@ pub const WriteFileStep = struct {...@@ -1889,7 +1889,7 @@ pub const WriteFileStep = struct {
1889 };1889 };
1890 }1890 }
18911891
1892 fn make(step: &Step) -> %void {1892 fn make(step: &Step) %void {
1893 const self = @fieldParentPtr(WriteFileStep, "step", step);1893 const self = @fieldParentPtr(WriteFileStep, "step", step);
1894 const full_path = self.builder.pathFromRoot(self.file_path);1894 const full_path = self.builder.pathFromRoot(self.file_path);
1895 const full_path_dir = os.path.dirname(full_path);1895 const full_path_dir = os.path.dirname(full_path);
...@@ -1909,7 +1909,7 @@ pub const LogStep = struct {...@@ -1909,7 +1909,7 @@ pub const LogStep = struct {
1909 builder: &Builder,1909 builder: &Builder,
1910 data: []const u8,1910 data: []const u8,
19111911
1912 pub fn init(builder: &Builder, data: []const u8) -> LogStep {1912 pub fn init(builder: &Builder, data: []const u8) LogStep {
1913 return LogStep {1913 return LogStep {
1914 .builder = builder,1914 .builder = builder,
1915 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),1915 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
...@@ -1917,7 +1917,7 @@ pub const LogStep = struct {...@@ -1917,7 +1917,7 @@ pub const LogStep = struct {
1917 };1917 };
1918 }1918 }
19191919
1920 fn make(step: &Step) -> %void {1920 fn make(step: &Step) %void {
1921 const self = @fieldParentPtr(LogStep, "step", step);1921 const self = @fieldParentPtr(LogStep, "step", step);
1922 warn("{}", self.data);1922 warn("{}", self.data);
1923 }1923 }
...@@ -1928,7 +1928,7 @@ pub const RemoveDirStep = struct {...@@ -1928,7 +1928,7 @@ pub const RemoveDirStep = struct {
1928 builder: &Builder,1928 builder: &Builder,
1929 dir_path: []const u8,1929 dir_path: []const u8,
19301930
1931 pub fn init(builder: &Builder, dir_path: []const u8) -> RemoveDirStep {1931 pub fn init(builder: &Builder, dir_path: []const u8) RemoveDirStep {
1932 return RemoveDirStep {1932 return RemoveDirStep {
1933 .builder = builder,1933 .builder = builder,
1934 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),1934 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
...@@ -1936,7 +1936,7 @@ pub const RemoveDirStep = struct {...@@ -1936,7 +1936,7 @@ pub const RemoveDirStep = struct {
1936 };1936 };
1937 }1937 }
19381938
1939 fn make(step: &Step) -> %void {1939 fn make(step: &Step) %void {
1940 const self = @fieldParentPtr(RemoveDirStep, "step", step);1940 const self = @fieldParentPtr(RemoveDirStep, "step", step);
19411941
1942 const full_path = self.builder.pathFromRoot(self.dir_path);1942 const full_path = self.builder.pathFromRoot(self.dir_path);
...@@ -1949,12 +1949,12 @@ pub const RemoveDirStep = struct {...@@ -1949,12 +1949,12 @@ pub const RemoveDirStep = struct {
19491949
1950pub const Step = struct {1950pub const Step = struct {
1951 name: []const u8,1951 name: []const u8,
1952 makeFn: fn(self: &Step) -> %void,1952 makeFn: fn(self: &Step) %void,
1953 dependencies: ArrayList(&Step),1953 dependencies: ArrayList(&Step),
1954 loop_flag: bool,1954 loop_flag: bool,
1955 done_flag: bool,1955 done_flag: bool,
19561956
1957 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)->%void) -> Step {1957 pub fn init(name: []const u8, allocator: &Allocator, makeFn: fn (&Step)%void) Step {
1958 return Step {1958 return Step {
1959 .name = name,1959 .name = name,
1960 .makeFn = makeFn,1960 .makeFn = makeFn,
...@@ -1963,11 +1963,11 @@ pub const Step = struct {...@@ -1963,11 +1963,11 @@ pub const Step = struct {
1963 .done_flag = false,1963 .done_flag = false,
1964 };1964 };
1965 }1965 }
1966 pub fn initNoOp(name: []const u8, allocator: &Allocator) -> Step {1966 pub fn initNoOp(name: []const u8, allocator: &Allocator) Step {
1967 return init(name, allocator, makeNoOp);1967 return init(name, allocator, makeNoOp);
1968 }1968 }
19691969
1970 pub fn make(self: &Step) -> %void {1970 pub fn make(self: &Step) %void {
1971 if (self.done_flag)1971 if (self.done_flag)
1972 return;1972 return;
19731973
...@@ -1975,15 +1975,15 @@ pub const Step = struct {...@@ -1975,15 +1975,15 @@ pub const Step = struct {
1975 self.done_flag = true;1975 self.done_flag = true;
1976 }1976 }
19771977
1978 pub fn dependOn(self: &Step, other: &Step) {1978 pub fn dependOn(self: &Step, other: &Step) void {
1979 self.dependencies.append(other) catch unreachable;1979 self.dependencies.append(other) catch unreachable;
1980 }1980 }
19811981
1982 fn makeNoOp(self: &Step) -> %void {}1982 fn makeNoOp(self: &Step) %void {}
1983};1983};
19841984
1985fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,1985fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,
1986 filename_name_only: []const u8) -> %void1986 filename_name_only: []const u8) %void
1987{1987{
1988 const out_dir = os.path.dirname(output_path);1988 const out_dir = os.path.dirname(output_path);
1989 const out_basename = os.path.basename(output_path);1989 const out_basename = os.path.basename(output_path);
std/c/darwin.zig+3-3
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1extern "c" fn __error() -> &c_int;1extern "c" fn __error() &c_int;
2pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) -> c_int;2pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) c_int;
33
44
5pub use @import("../os/darwin_errno.zig");5pub use @import("../os/darwin_errno.zig");
...@@ -41,7 +41,7 @@ pub const sigset_t = u32;...@@ -41,7 +41,7 @@ pub const sigset_t = u32;
4141
42/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.42/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
43pub const Sigaction = extern struct {43pub const Sigaction = extern struct {
44 handler: extern fn(c_int),44 handler: extern fn(c_int)void,
45 sa_mask: sigset_t,45 sa_mask: sigset_t,
46 sa_flags: c_int,46 sa_flags: c_int,
47};47};
std/c/index.zig+37-37
...@@ -9,43 +9,43 @@ pub use switch(builtin.os) {...@@ -9,43 +9,43 @@ pub use switch(builtin.os) {
9};9};
10const empty_import = @import("../empty.zig");10const empty_import = @import("../empty.zig");
1111
12pub extern "c" fn abort() -> noreturn;12pub extern "c" fn abort() noreturn;
13pub extern "c" fn exit(code: c_int) -> noreturn;13pub extern "c" fn exit(code: c_int) noreturn;
14pub extern "c" fn isatty(fd: c_int) -> c_int;14pub extern "c" fn isatty(fd: c_int) c_int;
15pub extern "c" fn close(fd: c_int) -> c_int;15pub extern "c" fn close(fd: c_int) c_int;
16pub extern "c" fn fstat(fd: c_int, buf: &Stat) -> c_int;16pub extern "c" fn fstat(fd: c_int, buf: &Stat) c_int;
17pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: &Stat) -> c_int;17pub extern "c" fn @"fstat$INODE64"(fd: c_int, buf: &Stat) c_int;
18pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) -> isize;18pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) isize;
19pub extern "c" fn open(path: &const u8, oflag: c_int, ...) -> c_int;19pub extern "c" fn open(path: &const u8, oflag: c_int, ...) c_int;
20pub extern "c" fn raise(sig: c_int) -> c_int;20pub extern "c" fn raise(sig: c_int) c_int;
21pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) -> isize;21pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) isize;
22pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) -> c_int;22pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) c_int;
23pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) -> c_int;23pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) c_int;
24pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,24pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
25 fd: c_int, offset: isize) -> ?&c_void;25 fd: c_int, offset: isize) ?&c_void;
26pub extern "c" fn munmap(addr: &c_void, len: usize) -> c_int;26pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;
27pub extern "c" fn unlink(path: &const u8) -> c_int;27pub extern "c" fn unlink(path: &const u8) c_int;
28pub extern "c" fn getcwd(buf: &u8, size: usize) -> ?&u8;28pub extern "c" fn getcwd(buf: &u8, size: usize) ?&u8;
29pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) -> c_int;29pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) c_int;
30pub extern "c" fn fork() -> c_int;30pub extern "c" fn fork() c_int;
31pub extern "c" fn pipe(fds: &c_int) -> c_int;31pub extern "c" fn pipe(fds: &c_int) c_int;
32pub extern "c" fn mkdir(path: &const u8, mode: c_uint) -> c_int;32pub extern "c" fn mkdir(path: &const u8, mode: c_uint) c_int;
33pub extern "c" fn symlink(existing: &const u8, new: &const u8) -> c_int;33pub extern "c" fn symlink(existing: &const u8, new: &const u8) c_int;
34pub extern "c" fn rename(old: &const u8, new: &const u8) -> c_int;34pub extern "c" fn rename(old: &const u8, new: &const u8) c_int;
35pub extern "c" fn chdir(path: &const u8) -> c_int;35pub extern "c" fn chdir(path: &const u8) c_int;
36pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,36pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
37 envp: &const ?&const u8) -> c_int;37 envp: &const ?&const u8) c_int;
38pub extern "c" fn dup(fd: c_int) -> c_int;38pub extern "c" fn dup(fd: c_int) c_int;
39pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int;39pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) c_int;
40pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) -> isize;40pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) isize;
41pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) -> ?&u8;41pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) ?&u8;
42pub extern "c" fn sigprocmask(how: c_int, noalias set: &const sigset_t, noalias oset: ?&sigset_t) -> c_int;42pub extern "c" fn sigprocmask(how: c_int, noalias set: &const sigset_t, noalias oset: ?&sigset_t) c_int;
43pub extern "c" fn sigaction(sig: c_int, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> c_int;43pub extern "c" fn sigaction(sig: c_int, noalias act: &const Sigaction, noalias oact: ?&Sigaction) c_int;
44pub extern "c" fn nanosleep(rqtp: &const timespec, rmtp: ?&timespec) -> c_int;44pub extern "c" fn nanosleep(rqtp: &const timespec, rmtp: ?&timespec) c_int;
45pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) -> c_int;45pub extern "c" fn setreuid(ruid: c_uint, euid: c_uint) c_int;
46pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) -> c_int;46pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
4747
48pub extern "c" fn malloc(usize) -> ?&c_void;48pub extern "c" fn malloc(usize) ?&c_void;
49pub extern "c" fn realloc(&c_void, usize) -> ?&c_void;49pub extern "c" fn realloc(&c_void, usize) ?&c_void;
50pub extern "c" fn free(&c_void);50pub extern "c" fn free(&c_void) void;
51pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) -> c_int;51pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) c_int;
std/c/linux.zig+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub use @import("../os/linux_errno.zig");1pub use @import("../os/linux_errno.zig");
22
3pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) -> c_int;3pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) c_int;
4extern "c" fn __errno_location() -> &c_int;4extern "c" fn __errno_location() &c_int;
5pub const _errno = __errno_location;5pub const _errno = __errno_location;
std/c/windows.zig+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1pub extern "c" fn _errno() -> &c_int;1pub extern "c" fn _errno() &c_int;
std/crypto/blake2.zig+15-15
...@@ -9,7 +9,7 @@ const RoundParam = struct {...@@ -9,7 +9,7 @@ const RoundParam = struct {
9 a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,9 a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,
10};10};
1111
12fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam {12fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) RoundParam {
13 return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };13 return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };
14}14}
1515
...@@ -19,7 +19,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam...@@ -19,7 +19,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam
19pub const Blake2s224 = Blake2s(224);19pub const Blake2s224 = Blake2s(224);
20pub const Blake2s256 = Blake2s(256);20pub const Blake2s256 = Blake2s(256);
2121
22fn Blake2s(comptime out_len: usize) -> type { return struct {22fn Blake2s(comptime out_len: usize) type { return struct {
23 const Self = this;23 const Self = this;
24 const block_size = 64;24 const block_size = 64;
25 const digest_size = out_len / 8;25 const digest_size = out_len / 8;
...@@ -48,7 +48,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {...@@ -48,7 +48,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
48 buf: [64]u8,48 buf: [64]u8,
49 buf_len: u8,49 buf_len: u8,
5050
51 pub fn init() -> Self {51 pub fn init() Self {
52 debug.assert(8 <= out_len and out_len <= 512);52 debug.assert(8 <= out_len and out_len <= 512);
5353
54 var s: Self = undefined;54 var s: Self = undefined;
...@@ -56,7 +56,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {...@@ -56,7 +56,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
56 return s;56 return s;
57 }57 }
5858
59 pub fn reset(d: &Self) {59 pub fn reset(d: &Self) void {
60 mem.copy(u32, d.h[0..], iv[0..]);60 mem.copy(u32, d.h[0..], iv[0..]);
6161
62 // No key plus default parameters62 // No key plus default parameters
...@@ -65,13 +65,13 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {...@@ -65,13 +65,13 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
65 d.buf_len = 0;65 d.buf_len = 0;
66 }66 }
6767
68 pub fn hash(b: []const u8, out: []u8) {68 pub fn hash(b: []const u8, out: []u8) void {
69 var d = Self.init();69 var d = Self.init();
70 d.update(b);70 d.update(b);
71 d.final(out);71 d.final(out);
72 }72 }
7373
74 pub fn update(d: &Self, b: []const u8) {74 pub fn update(d: &Self, b: []const u8) void {
75 var off: usize = 0;75 var off: usize = 0;
7676
77 // Partial buffer exists from previous update. Copy into buffer then hash.77 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {...@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
94 d.buf_len += u8(b[off..].len);94 d.buf_len += u8(b[off..].len);
95 }95 }
9696
97 pub fn final(d: &Self, out: []u8) {97 pub fn final(d: &Self, out: []u8) void {
98 debug.assert(out.len >= out_len / 8);98 debug.assert(out.len >= out_len / 8);
9999
100 mem.set(u8, d.buf[d.buf_len..], 0);100 mem.set(u8, d.buf[d.buf_len..], 0);
...@@ -108,7 +108,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {...@@ -108,7 +108,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
108 }108 }
109 }109 }
110110
111 fn round(d: &Self, b: []const u8, last: bool) {111 fn round(d: &Self, b: []const u8, last: bool) void {
112 debug.assert(b.len == 64);112 debug.assert(b.len == 64);
113113
114 var m: [16]u32 = undefined;114 var m: [16]u32 = undefined;
...@@ -236,7 +236,7 @@ test "blake2s256 streaming" {...@@ -236,7 +236,7 @@ test "blake2s256 streaming" {
236pub const Blake2b384 = Blake2b(384);236pub const Blake2b384 = Blake2b(384);
237pub const Blake2b512 = Blake2b(512);237pub const Blake2b512 = Blake2b(512);
238238
239fn Blake2b(comptime out_len: usize) -> type { return struct {239fn Blake2b(comptime out_len: usize) type { return struct {
240 const Self = this;240 const Self = this;
241 const block_size = 128;241 const block_size = 128;
242 const digest_size = out_len / 8;242 const digest_size = out_len / 8;
...@@ -269,7 +269,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {...@@ -269,7 +269,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
269 buf: [128]u8,269 buf: [128]u8,
270 buf_len: u8,270 buf_len: u8,
271271
272 pub fn init() -> Self {272 pub fn init() Self {
273 debug.assert(8 <= out_len and out_len <= 512);273 debug.assert(8 <= out_len and out_len <= 512);
274274
275 var s: Self = undefined;275 var s: Self = undefined;
...@@ -277,7 +277,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {...@@ -277,7 +277,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
277 return s;277 return s;
278 }278 }
279279
280 pub fn reset(d: &Self) {280 pub fn reset(d: &Self) void {
281 mem.copy(u64, d.h[0..], iv[0..]);281 mem.copy(u64, d.h[0..], iv[0..]);
282282
283 // No key plus default parameters283 // No key plus default parameters
...@@ -286,13 +286,13 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {...@@ -286,13 +286,13 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
286 d.buf_len = 0;286 d.buf_len = 0;
287 }287 }
288288
289 pub fn hash(b: []const u8, out: []u8) {289 pub fn hash(b: []const u8, out: []u8) void {
290 var d = Self.init();290 var d = Self.init();
291 d.update(b);291 d.update(b);
292 d.final(out);292 d.final(out);
293 }293 }
294294
295 pub fn update(d: &Self, b: []const u8) {295 pub fn update(d: &Self, b: []const u8) void {
296 var off: usize = 0;296 var off: usize = 0;
297297
298 // Partial buffer exists from previous update. Copy into buffer then hash.298 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -315,7 +315,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {...@@ -315,7 +315,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
315 d.buf_len += u8(b[off..].len);315 d.buf_len += u8(b[off..].len);
316 }316 }
317317
318 pub fn final(d: &Self, out: []u8) {318 pub fn final(d: &Self, out: []u8) void {
319 mem.set(u8, d.buf[d.buf_len..], 0);319 mem.set(u8, d.buf[d.buf_len..], 0);
320 d.t += d.buf_len;320 d.t += d.buf_len;
321 d.round(d.buf[0..], true);321 d.round(d.buf[0..], true);
...@@ -327,7 +327,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {...@@ -327,7 +327,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
327 }327 }
328 }328 }
329329
330 fn round(d: &Self, b: []const u8, last: bool) {330 fn round(d: &Self, b: []const u8, last: bool) void {
331 debug.assert(b.len == 128);331 debug.assert(b.len == 128);
332332
333 var m: [16]u64 = undefined;333 var m: [16]u64 = undefined;
std/crypto/md5.zig+7-7
...@@ -10,7 +10,7 @@ const RoundParam = struct {...@@ -10,7 +10,7 @@ const RoundParam = struct {
10 k: usize, s: u32, t: u3210 k: usize, s: u32, t: u32
11};11};
1212
13fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) -> RoundParam {13fn Rp(a: usize, b: usize, c: usize, d: usize, k: usize, s: u32, t: u32) RoundParam {
14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };
15}15}
1616
...@@ -25,13 +25,13 @@ pub const Md5 = struct {...@@ -25,13 +25,13 @@ pub const Md5 = struct {
25 buf_len: u8,25 buf_len: u8,
26 total_len: u64,26 total_len: u64,
2727
28 pub fn init() -> Self {28 pub fn init() Self {
29 var d: Self = undefined;29 var d: Self = undefined;
30 d.reset();30 d.reset();
31 return d;31 return d;
32 }32 }
3333
34 pub fn reset(d: &Self) {34 pub fn reset(d: &Self) void {
35 d.s[0] = 0x67452301;35 d.s[0] = 0x67452301;
36 d.s[1] = 0xEFCDAB89;36 d.s[1] = 0xEFCDAB89;
37 d.s[2] = 0x98BADCFE;37 d.s[2] = 0x98BADCFE;
...@@ -40,13 +40,13 @@ pub const Md5 = struct {...@@ -40,13 +40,13 @@ pub const Md5 = struct {
40 d.total_len = 0;40 d.total_len = 0;
41 }41 }
4242
43 pub fn hash(b: []const u8, out: []u8) {43 pub fn hash(b: []const u8, out: []u8) void {
44 var d = Md5.init();44 var d = Md5.init();
45 d.update(b);45 d.update(b);
46 d.final(out);46 d.final(out);
47 }47 }
4848
49 pub fn update(d: &Self, b: []const u8) {49 pub fn update(d: &Self, b: []const u8) void {
50 var off: usize = 0;50 var off: usize = 0;
5151
52 // Partial buffer exists from previous update. Copy into buffer then hash.52 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -71,7 +71,7 @@ pub const Md5 = struct {...@@ -71,7 +71,7 @@ pub const Md5 = struct {
71 d.total_len +%= b.len;71 d.total_len +%= b.len;
72 }72 }
7373
74 pub fn final(d: &Self, out: []u8) {74 pub fn final(d: &Self, out: []u8) void {
75 debug.assert(out.len >= 16);75 debug.assert(out.len >= 16);
7676
77 // The buffer here will never be completely full.77 // The buffer here will never be completely full.
...@@ -103,7 +103,7 @@ pub const Md5 = struct {...@@ -103,7 +103,7 @@ pub const Md5 = struct {
103 }103 }
104 }104 }
105105
106 fn round(d: &Self, b: []const u8) {106 fn round(d: &Self, b: []const u8) void {
107 debug.assert(b.len == 64);107 debug.assert(b.len == 64);
108108
109 var s: [16]u32 = undefined;109 var s: [16]u32 = undefined;
std/crypto/sha1.zig+7-7
...@@ -10,7 +10,7 @@ const RoundParam = struct {...@@ -10,7 +10,7 @@ const RoundParam = struct {
10 a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,10 a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,
11};11};
1212
13fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) -> RoundParam {13fn Rp(a: usize, b: usize, c: usize, d: usize, e: usize, i: u32) RoundParam {
14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };14 return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };
15}15}
1616
...@@ -25,13 +25,13 @@ pub const Sha1 = struct {...@@ -25,13 +25,13 @@ pub const Sha1 = struct {
25 buf_len: u8,25 buf_len: u8,
26 total_len: u64,26 total_len: u64,
2727
28 pub fn init() -> Self {28 pub fn init() Self {
29 var d: Self = undefined;29 var d: Self = undefined;
30 d.reset();30 d.reset();
31 return d;31 return d;
32 }32 }
3333
34 pub fn reset(d: &Self) {34 pub fn reset(d: &Self) void {
35 d.s[0] = 0x67452301;35 d.s[0] = 0x67452301;
36 d.s[1] = 0xEFCDAB89;36 d.s[1] = 0xEFCDAB89;
37 d.s[2] = 0x98BADCFE;37 d.s[2] = 0x98BADCFE;
...@@ -41,13 +41,13 @@ pub const Sha1 = struct {...@@ -41,13 +41,13 @@ pub const Sha1 = struct {
41 d.total_len = 0;41 d.total_len = 0;
42 }42 }
4343
44 pub fn hash(b: []const u8, out: []u8) {44 pub fn hash(b: []const u8, out: []u8) void {
45 var d = Sha1.init();45 var d = Sha1.init();
46 d.update(b);46 d.update(b);
47 d.final(out);47 d.final(out);
48 }48 }
4949
50 pub fn update(d: &Self, b: []const u8) {50 pub fn update(d: &Self, b: []const u8) void {
51 var off: usize = 0;51 var off: usize = 0;
5252
53 // Partial buffer exists from previous update. Copy into buffer then hash.53 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -71,7 +71,7 @@ pub const Sha1 = struct {...@@ -71,7 +71,7 @@ pub const Sha1 = struct {
71 d.total_len += b.len;71 d.total_len += b.len;
72 }72 }
7373
74 pub fn final(d: &Self, out: []u8) {74 pub fn final(d: &Self, out: []u8) void {
75 debug.assert(out.len >= 20);75 debug.assert(out.len >= 20);
7676
77 // The buffer here will never be completely full.77 // The buffer here will never be completely full.
...@@ -103,7 +103,7 @@ pub const Sha1 = struct {...@@ -103,7 +103,7 @@ pub const Sha1 = struct {
103 }103 }
104 }104 }
105105
106 fn round(d: &Self, b: []const u8) {106 fn round(d: &Self, b: []const u8) void {
107 debug.assert(b.len == 64);107 debug.assert(b.len == 64);
108108
109 var s: [16]u32 = undefined;109 var s: [16]u32 = undefined;
std/crypto/sha2.zig+16-16
...@@ -13,7 +13,7 @@ const RoundParam256 = struct {...@@ -13,7 +13,7 @@ const RoundParam256 = struct {
13 i: usize, k: u32,13 i: usize, k: u32,
14};14};
1515
16fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) -> RoundParam256 {16fn Rp256(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u32) RoundParam256 {
17 return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };17 return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
18}18}
1919
...@@ -56,7 +56,7 @@ const Sha256Params = Sha2Params32 {...@@ -56,7 +56,7 @@ const Sha256Params = Sha2Params32 {
56pub const Sha224 = Sha2_32(Sha224Params);56pub const Sha224 = Sha2_32(Sha224Params);
57pub const Sha256 = Sha2_32(Sha256Params);57pub const Sha256 = Sha2_32(Sha256Params);
5858
59fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {59fn Sha2_32(comptime params: Sha2Params32) type { return struct {
60 const Self = this;60 const Self = this;
61 const block_size = 64;61 const block_size = 64;
62 const digest_size = params.out_len / 8;62 const digest_size = params.out_len / 8;
...@@ -67,13 +67,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {...@@ -67,13 +67,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
67 buf_len: u8,67 buf_len: u8,
68 total_len: u64,68 total_len: u64,
6969
70 pub fn init() -> Self {70 pub fn init() Self {
71 var d: Self = undefined;71 var d: Self = undefined;
72 d.reset();72 d.reset();
73 return d;73 return d;
74 }74 }
7575
76 pub fn reset(d: &Self) {76 pub fn reset(d: &Self) void {
77 d.s[0] = params.iv0;77 d.s[0] = params.iv0;
78 d.s[1] = params.iv1;78 d.s[1] = params.iv1;
79 d.s[2] = params.iv2;79 d.s[2] = params.iv2;
...@@ -86,13 +86,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {...@@ -86,13 +86,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
86 d.total_len = 0;86 d.total_len = 0;
87 }87 }
8888
89 pub fn hash(b: []const u8, out: []u8) {89 pub fn hash(b: []const u8, out: []u8) void {
90 var d = Self.init();90 var d = Self.init();
91 d.update(b);91 d.update(b);
92 d.final(out);92 d.final(out);
93 }93 }
9494
95 pub fn update(d: &Self, b: []const u8) {95 pub fn update(d: &Self, b: []const u8) void {
96 var off: usize = 0;96 var off: usize = 0;
9797
98 // Partial buffer exists from previous update. Copy into buffer then hash.98 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {...@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
116 d.total_len += b.len;116 d.total_len += b.len;
117 }117 }
118118
119 pub fn final(d: &Self, out: []u8) {119 pub fn final(d: &Self, out: []u8) void {
120 debug.assert(out.len >= params.out_len / 8);120 debug.assert(out.len >= params.out_len / 8);
121121
122 // The buffer here will never be completely full.122 // The buffer here will never be completely full.
...@@ -151,7 +151,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {...@@ -151,7 +151,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
151 }151 }
152 }152 }
153153
154 fn round(d: &Self, b: []const u8) {154 fn round(d: &Self, b: []const u8) void {
155 debug.assert(b.len == 64);155 debug.assert(b.len == 64);
156156
157 var s: [64]u32 = undefined;157 var s: [64]u32 = undefined;
...@@ -329,7 +329,7 @@ const RoundParam512 = struct {...@@ -329,7 +329,7 @@ const RoundParam512 = struct {
329 i: usize, k: u64,329 i: usize, k: u64,
330};330};
331331
332fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) -> RoundParam512 {332fn Rp512(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize, g: usize, h: usize, i: usize, k: u64) RoundParam512 {
333 return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };333 return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
334}334}
335335
...@@ -372,7 +372,7 @@ const Sha512Params = Sha2Params64 {...@@ -372,7 +372,7 @@ const Sha512Params = Sha2Params64 {
372pub const Sha384 = Sha2_64(Sha384Params);372pub const Sha384 = Sha2_64(Sha384Params);
373pub const Sha512 = Sha2_64(Sha512Params);373pub const Sha512 = Sha2_64(Sha512Params);
374374
375fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {375fn Sha2_64(comptime params: Sha2Params64) type { return struct {
376 const Self = this;376 const Self = this;
377 const block_size = 128;377 const block_size = 128;
378 const digest_size = params.out_len / 8;378 const digest_size = params.out_len / 8;
...@@ -383,13 +383,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {...@@ -383,13 +383,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
383 buf_len: u8,383 buf_len: u8,
384 total_len: u128,384 total_len: u128,
385385
386 pub fn init() -> Self {386 pub fn init() Self {
387 var d: Self = undefined;387 var d: Self = undefined;
388 d.reset();388 d.reset();
389 return d;389 return d;
390 }390 }
391391
392 pub fn reset(d: &Self) {392 pub fn reset(d: &Self) void {
393 d.s[0] = params.iv0;393 d.s[0] = params.iv0;
394 d.s[1] = params.iv1;394 d.s[1] = params.iv1;
395 d.s[2] = params.iv2;395 d.s[2] = params.iv2;
...@@ -402,13 +402,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {...@@ -402,13 +402,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
402 d.total_len = 0;402 d.total_len = 0;
403 }403 }
404404
405 pub fn hash(b: []const u8, out: []u8) {405 pub fn hash(b: []const u8, out: []u8) void {
406 var d = Self.init();406 var d = Self.init();
407 d.update(b);407 d.update(b);
408 d.final(out);408 d.final(out);
409 }409 }
410410
411 pub fn update(d: &Self, b: []const u8) {411 pub fn update(d: &Self, b: []const u8) void {
412 var off: usize = 0;412 var off: usize = 0;
413413
414 // Partial buffer exists from previous update. Copy into buffer then hash.414 // Partial buffer exists from previous update. Copy into buffer then hash.
...@@ -432,7 +432,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {...@@ -432,7 +432,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
432 d.total_len += b.len;432 d.total_len += b.len;
433 }433 }
434434
435 pub fn final(d: &Self, out: []u8) {435 pub fn final(d: &Self, out: []u8) void {
436 debug.assert(out.len >= params.out_len / 8);436 debug.assert(out.len >= params.out_len / 8);
437437
438 // The buffer here will never be completely full.438 // The buffer here will never be completely full.
...@@ -467,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {...@@ -467,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
467 }467 }
468 }468 }
469469
470 fn round(d: &Self, b: []const u8) {470 fn round(d: &Self, b: []const u8) void {
471 debug.assert(b.len == 128);471 debug.assert(b.len == 128);
472472
473 var s: [80]u64 = undefined;473 var s: [80]u64 = undefined;
std/crypto/sha3.zig+7-7
...@@ -10,7 +10,7 @@ pub const Sha3_256 = Keccak(256, 0x06);...@@ -10,7 +10,7 @@ pub const Sha3_256 = Keccak(256, 0x06);
10pub const Sha3_384 = Keccak(384, 0x06);10pub const Sha3_384 = Keccak(384, 0x06);
11pub const Sha3_512 = Keccak(512, 0x06);11pub const Sha3_512 = Keccak(512, 0x06);
1212
13fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {13fn Keccak(comptime bits: usize, comptime delim: u8) type { return struct {
14 const Self = this;14 const Self = this;
15 const block_size = 200;15 const block_size = 200;
16 const digest_size = bits / 8;16 const digest_size = bits / 8;
...@@ -19,25 +19,25 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {...@@ -19,25 +19,25 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
19 offset: usize,19 offset: usize,
20 rate: usize,20 rate: usize,
2121
22 pub fn init() -> Self {22 pub fn init() Self {
23 var d: Self = undefined;23 var d: Self = undefined;
24 d.reset();24 d.reset();
25 return d;25 return d;
26 }26 }
2727
28 pub fn reset(d: &Self) {28 pub fn reset(d: &Self) void {
29 mem.set(u8, d.s[0..], 0);29 mem.set(u8, d.s[0..], 0);
30 d.offset = 0;30 d.offset = 0;
31 d.rate = 200 - (bits / 4);31 d.rate = 200 - (bits / 4);
32 }32 }
3333
34 pub fn hash(b: []const u8, out: []u8) {34 pub fn hash(b: []const u8, out: []u8) void {
35 var d = Self.init();35 var d = Self.init();
36 d.update(b);36 d.update(b);
37 d.final(out);37 d.final(out);
38 }38 }
3939
40 pub fn update(d: &Self, b: []const u8) {40 pub fn update(d: &Self, b: []const u8) void {
41 var ip: usize = 0;41 var ip: usize = 0;
42 var len = b.len;42 var len = b.len;
43 var rate = d.rate - d.offset;43 var rate = d.rate - d.offset;
...@@ -62,7 +62,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {...@@ -62,7 +62,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
62 d.offset = offset + len;62 d.offset = offset + len;
63 }63 }
6464
65 pub fn final(d: &Self, out: []u8) {65 pub fn final(d: &Self, out: []u8) void {
66 // padding66 // padding
67 d.s[d.offset] ^= delim;67 d.s[d.offset] ^= delim;
68 d.s[d.rate - 1] ^= 0x80;68 d.s[d.rate - 1] ^= 0x80;
...@@ -109,7 +109,7 @@ const M5 = []const usize {...@@ -109,7 +109,7 @@ const M5 = []const usize {
109 0, 1, 2, 3, 4, 0, 1, 2, 3, 4109 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
110};110};
111111
112fn keccak_f(comptime F: usize, d: []u8) {112fn keccak_f(comptime F: usize, d: []u8) void {
113 debug.assert(d.len == F / 8);113 debug.assert(d.len == F / 8);
114114
115 const B = F / 25;115 const B = F / 25;
std/crypto/test.zig+2-2
...@@ -3,7 +3,7 @@ const mem = @import("../mem.zig");...@@ -3,7 +3,7 @@ const mem = @import("../mem.zig");
3const fmt = @import("../fmt/index.zig");3const fmt = @import("../fmt/index.zig");
44
5// Hash using the specified hasher `H` asserting `expected == H(input)`.5// Hash using the specified hasher `H` asserting `expected == H(input)`.
6pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) {6pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, input: []const u8) void {
7 var h: [expected.len / 2]u8 = undefined;7 var h: [expected.len / 2]u8 = undefined;
8 Hasher.hash(input, h[0..]);8 Hasher.hash(input, h[0..]);
99
...@@ -11,7 +11,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu...@@ -11,7 +11,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu
11}11}
1212
13// Assert `expected` == `input` where `input` is a bytestring.13// Assert `expected` == `input` where `input` is a bytestring.
14pub fn assertEqual(comptime expected: []const u8, input: []const u8) {14pub fn assertEqual(comptime expected: []const u8, input: []const u8) void {
15 var expected_bytes: [expected.len / 2]u8 = undefined;15 var expected_bytes: [expected.len / 2]u8 = undefined;
16 for (expected_bytes) |*r, i| {16 for (expected_bytes) |*r, i| {
17 *r = fmt.parseInt(u8, expected[2*i .. 2*i+2], 16) catch unreachable;17 *r = fmt.parseInt(u8, expected[2*i .. 2*i+2], 16) catch unreachable;
std/crypto/throughput_test.zig+1-1
...@@ -18,7 +18,7 @@ const c = @cImport({...@@ -18,7 +18,7 @@ const c = @cImport({
1818
19const Mb = 1024 * 1024;19const Mb = 1024 * 1024;
2020
21pub fn main() -> %void {21pub fn main() %void {
22 var stdout_file = try std.io.getStdOut();22 var stdout_file = try std.io.getStdOut();
23 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);23 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
24 const stdout = &stdout_out_stream.stream;24 const stdout = &stdout_out_stream.stream;
std/cstr.zig+9-9
...@@ -3,13 +3,13 @@ const debug = std.debug;...@@ -3,13 +3,13 @@ const debug = std.debug;
3const mem = std.mem;3const mem = std.mem;
4const assert = debug.assert;4const assert = debug.assert;
55
6pub fn len(ptr: &const u8) -> usize {6pub fn len(ptr: &const u8) usize {
7 var count: usize = 0;7 var count: usize = 0;
8 while (ptr[count] != 0) : (count += 1) {}8 while (ptr[count] != 0) : (count += 1) {}
9 return count;9 return count;
10}10}
1111
12pub fn cmp(a: &const u8, b: &const u8) -> i8 {12pub fn cmp(a: &const u8, b: &const u8) i8 {
13 var index: usize = 0;13 var index: usize = 0;
14 while (a[index] == b[index] and a[index] != 0) : (index += 1) {}14 while (a[index] == b[index] and a[index] != 0) : (index += 1) {}
15 if (a[index] > b[index]) {15 if (a[index] > b[index]) {
...@@ -21,11 +21,11 @@ pub fn cmp(a: &const u8, b: &const u8) -> i8 {...@@ -21,11 +21,11 @@ pub fn cmp(a: &const u8, b: &const u8) -> i8 {
21 }21 }
22}22}
2323
24pub fn toSliceConst(str: &const u8) -> []const u8 {24pub fn toSliceConst(str: &const u8) []const u8 {
25 return str[0..len(str)];25 return str[0..len(str)];
26}26}
2727
28pub fn toSlice(str: &u8) -> []u8 {28pub fn toSlice(str: &u8) []u8 {
29 return str[0..len(str)];29 return str[0..len(str)];
30}30}
3131
...@@ -34,7 +34,7 @@ test "cstr fns" {...@@ -34,7 +34,7 @@ test "cstr fns" {
34 testCStrFnsImpl();34 testCStrFnsImpl();
35}35}
3636
37fn testCStrFnsImpl() {37fn testCStrFnsImpl() void {
38 assert(cmp(c"aoeu", c"aoez") == -1);38 assert(cmp(c"aoeu", c"aoez") == -1);
39 assert(len(c"123456789") == 9);39 assert(len(c"123456789") == 9);
40}40}
...@@ -42,7 +42,7 @@ fn testCStrFnsImpl() {...@@ -42,7 +42,7 @@ fn testCStrFnsImpl() {
42/// Returns a mutable slice with exactly the same size which is guaranteed to42/// Returns a mutable slice with exactly the same size which is guaranteed to
43/// have a null byte after it.43/// have a null byte after it.
44/// Caller owns the returned memory.44/// Caller owns the returned memory.
45pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {45pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) %[]u8 {
46 const result = try allocator.alloc(u8, slice.len + 1);46 const result = try allocator.alloc(u8, slice.len + 1);
47 mem.copy(u8, result, slice);47 mem.copy(u8, result, slice);
48 result[slice.len] = 0;48 result[slice.len] = 0;
...@@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {...@@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {
5656
57 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator57 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator
58 /// Caller must deinit result58 /// Caller must deinit result
59 pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) -> %NullTerminated2DArray {59 pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) %NullTerminated2DArray {
60 var new_len: usize = 1; // 1 for the list null60 var new_len: usize = 1; // 1 for the list null
61 var byte_count: usize = 0;61 var byte_count: usize = 0;
62 for (slices) |slice| {62 for (slices) |slice| {
...@@ -71,7 +71,7 @@ pub const NullTerminated2DArray = struct {...@@ -71,7 +71,7 @@ pub const NullTerminated2DArray = struct {
71 byte_count += index_size;71 byte_count += index_size;
7272
73 const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);73 const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
74 %defer allocator.free(buf);74 errdefer allocator.free(buf);
7575
76 var write_index = index_size;76 var write_index = index_size;
77 const index_buf = ([]?&u8)(buf);77 const index_buf = ([]?&u8)(buf);
...@@ -96,7 +96,7 @@ pub const NullTerminated2DArray = struct {...@@ -96,7 +96,7 @@ pub const NullTerminated2DArray = struct {
96 };96 };
97 }97 }
9898
99 pub fn deinit(self: &NullTerminated2DArray) {99 pub fn deinit(self: &NullTerminated2DArray) void {
100 const buf = @ptrCast(&u8, self.ptr);100 const buf = @ptrCast(&u8, self.ptr);
101 self.allocator.free(buf[0..self.byte_count]);101 self.allocator.free(buf[0..self.byte_count]);
102 }102 }
std/debug/failing_allocator.zig+4-4
...@@ -12,7 +12,7 @@ pub const FailingAllocator = struct {...@@ -12,7 +12,7 @@ pub const FailingAllocator = struct {
12 freed_bytes: usize,12 freed_bytes: usize,
13 deallocations: usize,13 deallocations: usize,
1414
15 pub fn init(allocator: &mem.Allocator, fail_index: usize) -> FailingAllocator {15 pub fn init(allocator: &mem.Allocator, fail_index: usize) FailingAllocator {
16 return FailingAllocator {16 return FailingAllocator {
17 .internal_allocator = allocator,17 .internal_allocator = allocator,
18 .fail_index = fail_index,18 .fail_index = fail_index,
...@@ -28,7 +28,7 @@ pub const FailingAllocator = struct {...@@ -28,7 +28,7 @@ pub const FailingAllocator = struct {
28 };28 };
29 }29 }
3030
31 fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 {31 fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) %[]u8 {
32 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);32 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
33 if (self.index == self.fail_index) {33 if (self.index == self.fail_index) {
34 return error.OutOfMemory;34 return error.OutOfMemory;
...@@ -39,7 +39,7 @@ pub const FailingAllocator = struct {...@@ -39,7 +39,7 @@ pub const FailingAllocator = struct {
39 return result;39 return result;
40 }40 }
4141
42 fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {42 fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
43 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);43 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
44 if (new_size <= old_mem.len) {44 if (new_size <= old_mem.len) {
45 self.freed_bytes += old_mem.len - new_size;45 self.freed_bytes += old_mem.len - new_size;
...@@ -55,7 +55,7 @@ pub const FailingAllocator = struct {...@@ -55,7 +55,7 @@ pub const FailingAllocator = struct {
55 return result;55 return result;
56 }56 }
5757
58 fn free(allocator: &mem.Allocator, bytes: []u8) {58 fn free(allocator: &mem.Allocator, bytes: []u8) void {
59 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);59 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
60 self.freed_bytes += bytes.len;60 self.freed_bytes += bytes.len;
61 self.deallocations += 1;61 self.deallocations += 1;
std/debug/index.zig+51-51
...@@ -25,11 +25,11 @@ error TodoSupportCOFFDebugInfo;...@@ -25,11 +25,11 @@ error TodoSupportCOFFDebugInfo;
25var stderr_file: io.File = undefined;25var stderr_file: io.File = undefined;
26var stderr_file_out_stream: io.FileOutStream = undefined;26var stderr_file_out_stream: io.FileOutStream = undefined;
27var stderr_stream: ?&io.OutStream = null;27var stderr_stream: ?&io.OutStream = null;
28pub fn warn(comptime fmt: []const u8, args: ...) {28pub fn warn(comptime fmt: []const u8, args: ...) void {
29 const stderr = getStderrStream() catch return;29 const stderr = getStderrStream() catch return;
30 stderr.print(fmt, args) catch return;30 stderr.print(fmt, args) catch return;
31}31}
32fn getStderrStream() -> %&io.OutStream {32fn getStderrStream() %&io.OutStream {
33 if (stderr_stream) |st| {33 if (stderr_stream) |st| {
34 return st;34 return st;
35 } else {35 } else {
...@@ -42,7 +42,7 @@ fn getStderrStream() -> %&io.OutStream {...@@ -42,7 +42,7 @@ fn getStderrStream() -> %&io.OutStream {
42}42}
4343
44var self_debug_info: ?&ElfStackTrace = null;44var self_debug_info: ?&ElfStackTrace = null;
45pub fn getSelfDebugInfo() -> %&ElfStackTrace {45pub fn getSelfDebugInfo() %&ElfStackTrace {
46 if (self_debug_info) |info| {46 if (self_debug_info) |info| {
47 return info;47 return info;
48 } else {48 } else {
...@@ -53,7 +53,7 @@ pub fn getSelfDebugInfo() -> %&ElfStackTrace {...@@ -53,7 +53,7 @@ pub fn getSelfDebugInfo() -> %&ElfStackTrace {
53}53}
5454
55/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.55/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
56pub fn dumpCurrentStackTrace() {56pub fn dumpCurrentStackTrace() void {
57 const stderr = getStderrStream() catch return;57 const stderr = getStderrStream() catch return;
58 const debug_info = getSelfDebugInfo() catch |err| {58 const debug_info = getSelfDebugInfo() catch |err| {
59 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;59 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
...@@ -67,7 +67,7 @@ pub fn dumpCurrentStackTrace() {...@@ -67,7 +67,7 @@ pub fn dumpCurrentStackTrace() {
67}67}
6868
69/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.69/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
70pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {70pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) void {
71 const stderr = getStderrStream() catch return;71 const stderr = getStderrStream() catch return;
72 const debug_info = getSelfDebugInfo() catch |err| {72 const debug_info = getSelfDebugInfo() catch |err| {
73 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;73 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
...@@ -85,7 +85,7 @@ pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {...@@ -85,7 +85,7 @@ pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {
85/// generated, and the `unreachable` statement triggers a panic.85/// generated, and the `unreachable` statement triggers a panic.
86/// In ReleaseFast and ReleaseSmall modes, calls to this function can be86/// In ReleaseFast and ReleaseSmall modes, calls to this function can be
87/// optimized away.87/// optimized away.
88pub fn assert(ok: bool) {88pub fn assert(ok: bool) void {
89 if (!ok) {89 if (!ok) {
90 // In ReleaseFast test mode, we still want assert(false) to crash, so90 // In ReleaseFast test mode, we still want assert(false) to crash, so
91 // we insert an explicit call to @panic instead of unreachable.91 // we insert an explicit call to @panic instead of unreachable.
...@@ -100,7 +100,7 @@ pub fn assert(ok: bool) {...@@ -100,7 +100,7 @@ pub fn assert(ok: bool) {
100100
101/// Call this function when you want to panic if the condition is not true.101/// Call this function when you want to panic if the condition is not true.
102/// If `ok` is `false`, this function will panic in every release mode.102/// If `ok` is `false`, this function will panic in every release mode.
103pub fn assertOrPanic(ok: bool) {103pub fn assertOrPanic(ok: bool) void {
104 if (!ok) {104 if (!ok) {
105 @panic("assertion failure");105 @panic("assertion failure");
106 }106 }
...@@ -108,7 +108,7 @@ pub fn assertOrPanic(ok: bool) {...@@ -108,7 +108,7 @@ pub fn assertOrPanic(ok: bool) {
108108
109var panicking = false;109var panicking = false;
110/// This is the default panic implementation.110/// This is the default panic implementation.
111pub fn panic(comptime format: []const u8, args: ...) -> noreturn {111pub fn panic(comptime format: []const u8, args: ...) noreturn {
112 // TODO an intrinsic that labels this as unlikely to be reached112 // TODO an intrinsic that labels this as unlikely to be reached
113113
114 // TODO114 // TODO
...@@ -130,7 +130,7 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {...@@ -130,7 +130,7 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
130 os.abort();130 os.abort();
131}131}
132132
133pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) -> noreturn {133pub fn panicWithTrace(trace: &const builtin.StackTrace, comptime format: []const u8, args: ...) noreturn {
134 if (panicking) {134 if (panicking) {
135 os.abort();135 os.abort();
136 } else {136 } else {
...@@ -153,7 +153,7 @@ error PathNotFound;...@@ -153,7 +153,7 @@ error PathNotFound;
153error InvalidDebugInfo;153error InvalidDebugInfo;
154154
155pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,155pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,
156 debug_info: &ElfStackTrace, tty_color: bool) -> %void156 debug_info: &ElfStackTrace, tty_color: bool) %void
157{157{
158 var frame_index: usize = undefined;158 var frame_index: usize = undefined;
159 var frames_left: usize = undefined;159 var frames_left: usize = undefined;
...@@ -175,7 +175,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O...@@ -175,7 +175,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O
175}175}
176176
177pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,177pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,
178 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) -> %void178 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) %void
179{179{
180 var ignored_count: usize = 0;180 var ignored_count: usize = 0;
181181
...@@ -191,7 +191,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat...@@ -191,7 +191,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat
191 }191 }
192}192}
193193
194fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) -> %void {194fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) %void {
195 if (builtin.os == builtin.Os.windows) {195 if (builtin.os == builtin.Os.windows) {
196 return error.UnsupportedDebugInfo;196 return error.UnsupportedDebugInfo;
197 }197 }
...@@ -232,7 +232,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a...@@ -232,7 +232,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
232 }232 }
233}233}
234234
235pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {235pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {
236 switch (builtin.object_format) {236 switch (builtin.object_format) {
237 builtin.ObjectFormat.elf => {237 builtin.ObjectFormat.elf => {
238 const st = try allocator.create(ElfStackTrace);238 const st = try allocator.create(ElfStackTrace);
...@@ -248,10 +248,10 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {...@@ -248,10 +248,10 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
248 .compile_unit_list = ArrayList(CompileUnit).init(allocator),248 .compile_unit_list = ArrayList(CompileUnit).init(allocator),
249 };249 };
250 st.self_exe_file = try os.openSelfExe();250 st.self_exe_file = try os.openSelfExe();
251 %defer st.self_exe_file.close();251 errdefer st.self_exe_file.close();
252252
253 try st.elf.openFile(allocator, &st.self_exe_file);253 try st.elf.openFile(allocator, &st.self_exe_file);
254 %defer st.elf.close();254 errdefer st.elf.close();
255255
256 st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;256 st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
257 st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;257 st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
...@@ -276,7 +276,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {...@@ -276,7 +276,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
276 }276 }
277}277}
278278
279fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void {279fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) %void {
280 var f = try io.File.openRead(line_info.file_name, allocator);280 var f = try io.File.openRead(line_info.file_name, allocator);
281 defer f.close();281 defer f.close();
282 // TODO fstat and make sure that the file has the correct size282 // TODO fstat and make sure that the file has the correct size
...@@ -320,17 +320,17 @@ pub const ElfStackTrace = struct {...@@ -320,17 +320,17 @@ pub const ElfStackTrace = struct {
320 abbrev_table_list: ArrayList(AbbrevTableHeader),320 abbrev_table_list: ArrayList(AbbrevTableHeader),
321 compile_unit_list: ArrayList(CompileUnit),321 compile_unit_list: ArrayList(CompileUnit),
322322
323 pub fn allocator(self: &const ElfStackTrace) -> &mem.Allocator {323 pub fn allocator(self: &const ElfStackTrace) &mem.Allocator {
324 return self.abbrev_table_list.allocator;324 return self.abbrev_table_list.allocator;
325 }325 }
326326
327 pub fn readString(self: &ElfStackTrace) -> %[]u8 {327 pub fn readString(self: &ElfStackTrace) %[]u8 {
328 var in_file_stream = io.FileInStream.init(&self.self_exe_file);328 var in_file_stream = io.FileInStream.init(&self.self_exe_file);
329 const in_stream = &in_file_stream.stream;329 const in_stream = &in_file_stream.stream;
330 return readStringRaw(self.allocator(), in_stream);330 return readStringRaw(self.allocator(), in_stream);
331 }331 }
332332
333 pub fn close(self: &ElfStackTrace) {333 pub fn close(self: &ElfStackTrace) void {
334 self.self_exe_file.close();334 self.self_exe_file.close();
335 self.elf.close();335 self.elf.close();
336 }336 }
...@@ -387,7 +387,7 @@ const Constant = struct {...@@ -387,7 +387,7 @@ const Constant = struct {
387 payload: []u8,387 payload: []u8,
388 signed: bool,388 signed: bool,
389389
390 fn asUnsignedLe(self: &const Constant) -> %u64 {390 fn asUnsignedLe(self: &const Constant) %u64 {
391 if (self.payload.len > @sizeOf(u64))391 if (self.payload.len > @sizeOf(u64))
392 return error.InvalidDebugInfo;392 return error.InvalidDebugInfo;
393 if (self.signed)393 if (self.signed)
...@@ -406,7 +406,7 @@ const Die = struct {...@@ -406,7 +406,7 @@ const Die = struct {
406 value: FormValue,406 value: FormValue,
407 };407 };
408408
409 fn getAttr(self: &const Die, id: u64) -> ?&const FormValue {409 fn getAttr(self: &const Die, id: u64) ?&const FormValue {
410 for (self.attrs.toSliceConst()) |*attr| {410 for (self.attrs.toSliceConst()) |*attr| {
411 if (attr.id == id)411 if (attr.id == id)
412 return &attr.value;412 return &attr.value;
...@@ -414,7 +414,7 @@ const Die = struct {...@@ -414,7 +414,7 @@ const Die = struct {
414 return null;414 return null;
415 }415 }
416416
417 fn getAttrAddr(self: &const Die, id: u64) -> %u64 {417 fn getAttrAddr(self: &const Die, id: u64) %u64 {
418 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;418 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
419 return switch (*form_value) {419 return switch (*form_value) {
420 FormValue.Address => |value| value,420 FormValue.Address => |value| value,
...@@ -422,7 +422,7 @@ const Die = struct {...@@ -422,7 +422,7 @@ const Die = struct {
422 };422 };
423 }423 }
424424
425 fn getAttrSecOffset(self: &const Die, id: u64) -> %u64 {425 fn getAttrSecOffset(self: &const Die, id: u64) %u64 {
426 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;426 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
427 return switch (*form_value) {427 return switch (*form_value) {
428 FormValue.Const => |value| value.asUnsignedLe(),428 FormValue.Const => |value| value.asUnsignedLe(),
...@@ -431,7 +431,7 @@ const Die = struct {...@@ -431,7 +431,7 @@ const Die = struct {
431 };431 };
432 }432 }
433433
434 fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {434 fn getAttrUnsignedLe(self: &const Die, id: u64) %u64 {
435 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;435 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
436 return switch (*form_value) {436 return switch (*form_value) {
437 FormValue.Const => |value| value.asUnsignedLe(),437 FormValue.Const => |value| value.asUnsignedLe(),
...@@ -439,7 +439,7 @@ const Die = struct {...@@ -439,7 +439,7 @@ const Die = struct {
439 };439 };
440 }440 }
441441
442 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {442 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) %[]u8 {
443 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;443 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
444 return switch (*form_value) {444 return switch (*form_value) {
445 FormValue.String => |value| value,445 FormValue.String => |value| value,
...@@ -462,7 +462,7 @@ const LineInfo = struct {...@@ -462,7 +462,7 @@ const LineInfo = struct {
462 file_name: []u8,462 file_name: []u8,
463 allocator: &mem.Allocator,463 allocator: &mem.Allocator,
464464
465 fn deinit(self: &const LineInfo) {465 fn deinit(self: &const LineInfo) void {
466 self.allocator.free(self.file_name);466 self.allocator.free(self.file_name);
467 }467 }
468};468};
...@@ -489,7 +489,7 @@ const LineNumberProgram = struct {...@@ -489,7 +489,7 @@ const LineNumberProgram = struct {
489 prev_end_sequence: bool,489 prev_end_sequence: bool,
490490
491 pub fn init(is_stmt: bool, include_dirs: []const []const u8,491 pub fn init(is_stmt: bool, include_dirs: []const []const u8,
492 file_entries: &ArrayList(FileEntry), target_address: usize) -> LineNumberProgram492 file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram
493 {493 {
494 return LineNumberProgram {494 return LineNumberProgram {
495 .address = 0,495 .address = 0,
...@@ -512,7 +512,7 @@ const LineNumberProgram = struct {...@@ -512,7 +512,7 @@ const LineNumberProgram = struct {
512 };512 };
513 }513 }
514514
515 pub fn checkLineMatch(self: &LineNumberProgram) -> %?LineInfo {515 pub fn checkLineMatch(self: &LineNumberProgram) %?LineInfo {
516 if (self.target_address >= self.prev_address and self.target_address < self.address) {516 if (self.target_address >= self.prev_address and self.target_address < self.address) {
517 const file_entry = if (self.prev_file == 0) {517 const file_entry = if (self.prev_file == 0) {
518 return error.MissingDebugInfo;518 return error.MissingDebugInfo;
...@@ -524,7 +524,7 @@ const LineNumberProgram = struct {...@@ -524,7 +524,7 @@ const LineNumberProgram = struct {
524 return error.InvalidDebugInfo;524 return error.InvalidDebugInfo;
525 } else self.include_dirs[file_entry.dir_index];525 } else self.include_dirs[file_entry.dir_index];
526 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);526 const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
527 %defer self.file_entries.allocator.free(file_name);527 errdefer self.file_entries.allocator.free(file_name);
528 return LineInfo {528 return LineInfo {
529 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,529 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
530 .column = self.prev_column,530 .column = self.prev_column,
...@@ -544,7 +544,7 @@ const LineNumberProgram = struct {...@@ -544,7 +544,7 @@ const LineNumberProgram = struct {
544 }544 }
545};545};
546546
547fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {547fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {
548 var buf = ArrayList(u8).init(allocator);548 var buf = ArrayList(u8).init(allocator);
549 while (true) {549 while (true) {
550 const byte = try in_stream.readByte();550 const byte = try in_stream.readByte();
...@@ -555,58 +555,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {...@@ -555,58 +555,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
555 return buf.toSlice();555 return buf.toSlice();
556}556}
557557
558fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 {558fn getString(st: &ElfStackTrace, offset: u64) %[]u8 {
559 const pos = st.debug_str.offset + offset;559 const pos = st.debug_str.offset + offset;
560 try st.self_exe_file.seekTo(pos);560 try st.self_exe_file.seekTo(pos);
561 return st.readString();561 return st.readString();
562}562}
563563
564fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 {564fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %[]u8 {
565 const buf = try global_allocator.alloc(u8, size);565 const buf = try global_allocator.alloc(u8, size);
566 %defer global_allocator.free(buf);566 errdefer global_allocator.free(buf);
567 if ((try in_stream.read(buf)) < size) return error.EndOfFile;567 if ((try in_stream.read(buf)) < size) return error.EndOfFile;
568 return buf;568 return buf;
569}569}
570570
571fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {571fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
572 const buf = try readAllocBytes(allocator, in_stream, size);572 const buf = try readAllocBytes(allocator, in_stream, size);
573 return FormValue { .Block = buf };573 return FormValue { .Block = buf };
574}574}
575575
576fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {576fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
577 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);577 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
578 return parseFormValueBlockLen(allocator, in_stream, block_len);578 return parseFormValueBlockLen(allocator, in_stream, block_len);
579}579}
580580
581fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {581fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) %FormValue {
582 return FormValue { .Const = Constant {582 return FormValue { .Const = Constant {
583 .signed = signed,583 .signed = signed,
584 .payload = try readAllocBytes(allocator, in_stream, size),584 .payload = try readAllocBytes(allocator, in_stream, size),
585 }};585 }};
586}586}
587587
588fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {588fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) %u64 {
589 return if (is_64) try in_stream.readIntLe(u64)589 return if (is_64) try in_stream.readIntLe(u64)
590 else u64(try in_stream.readIntLe(u32)) ;590 else u64(try in_stream.readIntLe(u32)) ;
591}591}
592592
593fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {593fn parseFormValueTargetAddrSize(in_stream: &io.InStream) %u64 {
594 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))594 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))
595 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)595 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
596 else unreachable;596 else unreachable;
597}597}
598598
599fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {599fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) %FormValue {
600 const buf = try readAllocBytes(allocator, in_stream, size);600 const buf = try readAllocBytes(allocator, in_stream, size);
601 return FormValue { .Ref = buf };601 return FormValue { .Ref = buf };
602}602}
603603
604fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue {604fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) %FormValue {
605 const block_len = try in_stream.readIntLe(T);605 const block_len = try in_stream.readIntLe(T);
606 return parseFormValueRefLen(allocator, in_stream, block_len);606 return parseFormValueRefLen(allocator, in_stream, block_len);
607}607}
608608
609fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue {609fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) %FormValue {
610 return switch (form_id) {610 return switch (form_id) {
611 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },611 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },
612 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),612 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
...@@ -656,7 +656,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u...@@ -656,7 +656,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
656 };656 };
657}657}
658658
659fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {659fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {
660 const in_file = &st.self_exe_file;660 const in_file = &st.self_exe_file;
661 var in_file_stream = io.FileInStream.init(in_file);661 var in_file_stream = io.FileInStream.init(in_file);
662 const in_stream = &in_file_stream.stream;662 const in_stream = &in_file_stream.stream;
...@@ -688,7 +688,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {...@@ -688,7 +688,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
688688
689/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,689/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
690/// seeks in the stream and parses it.690/// seeks in the stream and parses it.
691fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable {691fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) %&const AbbrevTable {
692 for (st.abbrev_table_list.toSlice()) |*header| {692 for (st.abbrev_table_list.toSlice()) |*header| {
693 if (header.offset == abbrev_offset) {693 if (header.offset == abbrev_offset) {
694 return &header.table;694 return &header.table;
...@@ -702,7 +702,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable...@@ -702,7 +702,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable
702 return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;702 return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;
703}703}
704704
705fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&const AbbrevTableEntry {705fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {
706 for (abbrev_table.toSliceConst()) |*table_entry| {706 for (abbrev_table.toSliceConst()) |*table_entry| {
707 if (table_entry.abbrev_code == abbrev_code)707 if (table_entry.abbrev_code == abbrev_code)
708 return table_entry;708 return table_entry;
...@@ -710,7 +710,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&...@@ -710,7 +710,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&
710 return null;710 return null;
711}711}
712712
713fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -> %Die {713fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) %Die {
714 const in_file = &st.self_exe_file;714 const in_file = &st.self_exe_file;
715 var in_file_stream = io.FileInStream.init(in_file);715 var in_file_stream = io.FileInStream.init(in_file);
716 const in_stream = &in_file_stream.stream;716 const in_stream = &in_file_stream.stream;
...@@ -732,7 +732,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -...@@ -732,7 +732,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -
732 return result;732 return result;
733}733}
734734
735fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo {735fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) %LineInfo {
736 const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);736 const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);
737737
738 const in_file = &st.self_exe_file;738 const in_file = &st.self_exe_file;
...@@ -910,7 +910,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe...@@ -910,7 +910,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
910 return error.MissingDebugInfo;910 return error.MissingDebugInfo;
911}911}
912912
913fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {913fn scanAllCompileUnits(st: &ElfStackTrace) %void {
914 const debug_info_end = st.debug_info.offset + st.debug_info.size;914 const debug_info_end = st.debug_info.offset + st.debug_info.size;
915 var this_unit_offset = st.debug_info.offset;915 var this_unit_offset = st.debug_info.offset;
916 var cu_index: usize = 0;916 var cu_index: usize = 0;
...@@ -986,7 +986,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {...@@ -986,7 +986,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
986 }986 }
987}987}
988988
989fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUnit {989fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit {
990 var in_file_stream = io.FileInStream.init(&st.self_exe_file);990 var in_file_stream = io.FileInStream.init(&st.self_exe_file);
991 const in_stream = &in_file_stream.stream;991 const in_stream = &in_file_stream.stream;
992 for (st.compile_unit_list.toSlice()) |*compile_unit| {992 for (st.compile_unit_list.toSlice()) |*compile_unit| {
...@@ -1022,7 +1022,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn...@@ -1022,7 +1022,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
1022 return error.MissingDebugInfo;1022 return error.MissingDebugInfo;
1023}1023}
10241024
1025fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {1025fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {
1026 const first_32_bits = try in_stream.readIntLe(u32);1026 const first_32_bits = try in_stream.readIntLe(u32);
1027 *is_64 = (first_32_bits == 0xffffffff);1027 *is_64 = (first_32_bits == 0xffffffff);
1028 if (*is_64) {1028 if (*is_64) {
...@@ -1033,7 +1033,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {...@@ -1033,7 +1033,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
1033 }1033 }
1034}1034}
10351035
1036fn readULeb128(in_stream: &io.InStream) -> %u64 {1036fn readULeb128(in_stream: &io.InStream) %u64 {
1037 var result: u64 = 0;1037 var result: u64 = 0;
1038 var shift: usize = 0;1038 var shift: usize = 0;
10391039
...@@ -1054,7 +1054,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 {...@@ -1054,7 +1054,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 {
1054 }1054 }
1055}1055}
10561056
1057fn readILeb128(in_stream: &io.InStream) -> %i64 {1057fn readILeb128(in_stream: &io.InStream) %i64 {
1058 var result: i64 = 0;1058 var result: i64 = 0;
1059 var shift: usize = 0;1059 var shift: usize = 0;
10601060
std/elf.zig+6-6
...@@ -81,14 +81,14 @@ pub const Elf = struct {...@@ -81,14 +81,14 @@ pub const Elf = struct {
81 prealloc_file: io.File,81 prealloc_file: io.File,
8282
83 /// Call close when done.83 /// Call close when done.
84 pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void {84 pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) %void {
85 try elf.prealloc_file.open(path);85 try elf.prealloc_file.open(path);
86 try elf.openFile(allocator, &elf.prealloc_file);86 try elf.openFile(allocator, &elf.prealloc_file);
87 elf.auto_close_stream = true;87 elf.auto_close_stream = true;
88 }88 }
8989
90 /// Call close when done.90 /// Call close when done.
91 pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) -> %void {91 pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) %void {
92 elf.allocator = allocator;92 elf.allocator = allocator;
93 elf.in_file = file;93 elf.in_file = file;
94 elf.auto_close_stream = false;94 elf.auto_close_stream = false;
...@@ -183,7 +183,7 @@ pub const Elf = struct {...@@ -183,7 +183,7 @@ pub const Elf = struct {
183 try elf.in_file.seekTo(elf.section_header_offset);183 try elf.in_file.seekTo(elf.section_header_offset);
184184
185 elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count);185 elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count);
186 %defer elf.allocator.free(elf.section_headers);186 errdefer elf.allocator.free(elf.section_headers);
187187
188 if (elf.is_64) {188 if (elf.is_64) {
189 if (sh_entry_size != 64) return error.InvalidFormat;189 if (sh_entry_size != 64) return error.InvalidFormat;
...@@ -232,14 +232,14 @@ pub const Elf = struct {...@@ -232,14 +232,14 @@ pub const Elf = struct {
232 }232 }
233 }233 }
234234
235 pub fn close(elf: &Elf) {235 pub fn close(elf: &Elf) void {
236 elf.allocator.free(elf.section_headers);236 elf.allocator.free(elf.section_headers);
237237
238 if (elf.auto_close_stream)238 if (elf.auto_close_stream)
239 elf.in_file.close();239 elf.in_file.close();
240 }240 }
241241
242 pub fn findSection(elf: &Elf, name: []const u8) -> %?&SectionHeader {242 pub fn findSection(elf: &Elf, name: []const u8) %?&SectionHeader {
243 var file_stream = io.FileInStream.init(elf.in_file);243 var file_stream = io.FileInStream.init(elf.in_file);
244 const in = &file_stream.stream;244 const in = &file_stream.stream;
245245
...@@ -263,7 +263,7 @@ pub const Elf = struct {...@@ -263,7 +263,7 @@ pub const Elf = struct {
263 return null;263 return null;
264 }264 }
265265
266 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {266 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) %void {
267 try elf.in_file.seekTo(elf_section.offset);267 try elf.in_file.seekTo(elf_section.offset);
268 }268 }
269};269};
std/endian.zig+4-4
...@@ -1,19 +1,19 @@...@@ -1,19 +1,19 @@
1const mem = @import("mem.zig");1const mem = @import("mem.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn swapIfLe(comptime T: type, x: T) -> T {4pub fn swapIfLe(comptime T: type, x: T) T {
5 return swapIf(builtin.Endian.Little, T, x);5 return swapIf(builtin.Endian.Little, T, x);
6}6}
77
8pub fn swapIfBe(comptime T: type, x: T) -> T {8pub fn swapIfBe(comptime T: type, x: T) T {
9 return swapIf(builtin.Endian.Big, T, x);9 return swapIf(builtin.Endian.Big, T, x);
10}10}
1111
12pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) -> T {12pub fn swapIf(endian: builtin.Endian, comptime T: type, x: T) T {
13 return if (builtin.endian == endian) swap(T, x) else x;13 return if (builtin.endian == endian) swap(T, x) else x;
14}14}
1515
16pub fn swap(comptime T: type, x: T) -> T {16pub fn swap(comptime T: type, x: T) T {
17 var buf: [@sizeOf(T)]u8 = undefined;17 var buf: [@sizeOf(T)]u8 = undefined;
18 mem.writeInt(buf[0..], x, builtin.Endian.Little);18 mem.writeInt(buf[0..], x, builtin.Endian.Little);
19 return mem.readInt(buf, T, builtin.Endian.Big);19 return mem.readInt(buf, T, builtin.Endian.Big);
std/fmt/errol/enum3.zig+1-1
...@@ -438,7 +438,7 @@ const Slab = struct {...@@ -438,7 +438,7 @@ const Slab = struct {
438 exp: i32,438 exp: i32,
439};439};
440440
441fn slab(str: []const u8, exp: i32) -> Slab {441fn slab(str: []const u8, exp: i32) Slab {
442 return Slab {442 return Slab {
443 .str = str,443 .str = str,
444 .exp = exp,444 .exp = exp,
std/fmt/errol/index.zig+16-16
...@@ -13,7 +13,7 @@ pub const FloatDecimal = struct {...@@ -13,7 +13,7 @@ pub const FloatDecimal = struct {
13};13};
1414
15/// Corrected Errol3 double to ASCII conversion.15/// Corrected Errol3 double to ASCII conversion.
16pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {16pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
17 const bits = @bitCast(u64, value);17 const bits = @bitCast(u64, value);
18 const i = tableLowerBound(bits);18 const i = tableLowerBound(bits);
19 if (i < enum3.len and enum3[i] == bits) {19 if (i < enum3.len and enum3[i] == bits) {
...@@ -30,7 +30,7 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {...@@ -30,7 +30,7 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
30}30}
3131
32/// Uncorrected Errol3 double to ASCII conversion.32/// Uncorrected Errol3 double to ASCII conversion.
33fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {33fn errol3u(val: f64, buffer: []u8) FloatDecimal {
34 // check if in integer or fixed range34 // check if in integer or fixed range
3535
36 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {36 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
...@@ -133,7 +133,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {...@@ -133,7 +133,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
133 };133 };
134}134}
135135
136fn tableLowerBound(k: u64) -> usize {136fn tableLowerBound(k: u64) usize {
137 var i = enum3.len;137 var i = enum3.len;
138 var j: usize = 0;138 var j: usize = 0;
139139
...@@ -153,7 +153,7 @@ fn tableLowerBound(k: u64) -> usize {...@@ -153,7 +153,7 @@ fn tableLowerBound(k: u64) -> usize {
153/// @in: The HP number.153/// @in: The HP number.
154/// @val: The double.154/// @val: The double.
155/// &returns: The HP number.155/// &returns: The HP number.
156fn hpProd(in: &const HP, val: f64) -> HP {156fn hpProd(in: &const HP, val: f64) HP {
157 var hi: f64 = undefined;157 var hi: f64 = undefined;
158 var lo: f64 = undefined;158 var lo: f64 = undefined;
159 split(in.val, &hi, &lo);159 split(in.val, &hi, &lo);
...@@ -175,12 +175,12 @@ fn hpProd(in: &const HP, val: f64) -> HP {...@@ -175,12 +175,12 @@ fn hpProd(in: &const HP, val: f64) -> HP {
175/// @val: The double.175/// @val: The double.
176/// @hi: The high bits.176/// @hi: The high bits.
177/// @lo: The low bits.177/// @lo: The low bits.
178fn split(val: f64, hi: &f64, lo: &f64) {178fn split(val: f64, hi: &f64, lo: &f64) void {
179 *hi = gethi(val);179 *hi = gethi(val);
180 *lo = val - *hi;180 *lo = val - *hi;
181}181}
182182
183fn gethi(in: f64) -> f64 {183fn gethi(in: f64) f64 {
184 const bits = @bitCast(u64, in);184 const bits = @bitCast(u64, in);
185 const new_bits = bits & 0xFFFFFFFFF8000000;185 const new_bits = bits & 0xFFFFFFFFF8000000;
186 return @bitCast(f64, new_bits);186 return @bitCast(f64, new_bits);
...@@ -188,7 +188,7 @@ fn gethi(in: f64) -> f64 {...@@ -188,7 +188,7 @@ fn gethi(in: f64) -> f64 {
188188
189/// Normalize the number by factoring in the error.189/// Normalize the number by factoring in the error.
190/// @hp: The float pair.190/// @hp: The float pair.
191fn hpNormalize(hp: &HP) {191fn hpNormalize(hp: &HP) void {
192 const val = hp.val;192 const val = hp.val;
193193
194 hp.val += hp.off;194 hp.val += hp.off;
...@@ -197,7 +197,7 @@ fn hpNormalize(hp: &HP) {...@@ -197,7 +197,7 @@ fn hpNormalize(hp: &HP) {
197197
198/// Divide the high-precision number by ten.198/// Divide the high-precision number by ten.
199/// @hp: The high-precision number199/// @hp: The high-precision number
200fn hpDiv10(hp: &HP) {200fn hpDiv10(hp: &HP) void {
201 var val = hp.val;201 var val = hp.val;
202202
203 hp.val /= 10.0;203 hp.val /= 10.0;
...@@ -213,7 +213,7 @@ fn hpDiv10(hp: &HP) {...@@ -213,7 +213,7 @@ fn hpDiv10(hp: &HP) {
213213
214/// Multiply the high-precision number by ten.214/// Multiply the high-precision number by ten.
215/// @hp: The high-precision number215/// @hp: The high-precision number
216fn hpMul10(hp: &HP) {216fn hpMul10(hp: &HP) void {
217 const val = hp.val;217 const val = hp.val;
218218
219 hp.val *= 10.0;219 hp.val *= 10.0;
...@@ -233,7 +233,7 @@ fn hpMul10(hp: &HP) {...@@ -233,7 +233,7 @@ fn hpMul10(hp: &HP) {
233/// @val: The val.233/// @val: The val.
234/// @buf: The output buffer.234/// @buf: The output buffer.
235/// &return: The exponent.235/// &return: The exponent.
236fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {236fn errolInt(val: f64, buffer: []u8) FloatDecimal {
237 const pow19 = u128(1e19);237 const pow19 = u128(1e19);
238238
239 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));239 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
...@@ -291,7 +291,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {...@@ -291,7 +291,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
291/// @val: The val.291/// @val: The val.
292/// @buf: The output buffer.292/// @buf: The output buffer.
293/// &return: The exponent.293/// &return: The exponent.
294fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {294fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
295 assert((val >= 16.0) and (val < 9.007199254740992e15));295 assert((val >= 16.0) and (val < 9.007199254740992e15));
296296
297 const u = u64(val);297 const u = u64(val);
...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {...@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
347 };347 };
348}348}
349349
350fn fpnext(val: f64) -> f64 {350fn fpnext(val: f64) f64 {
351 return @bitCast(f64, @bitCast(u64, val) +% 1);351 return @bitCast(f64, @bitCast(u64, val) +% 1);
352}352}
353353
354fn fpprev(val: f64) -> f64 {354fn fpprev(val: f64) f64 {
355 return @bitCast(f64, @bitCast(u64, val) -% 1);355 return @bitCast(f64, @bitCast(u64, val) -% 1);
356}356}
357357
...@@ -373,7 +373,7 @@ pub const c_digits_lut = []u8 {...@@ -373,7 +373,7 @@ pub const c_digits_lut = []u8 {
373 '9', '8', '9', '9',373 '9', '8', '9', '9',
374};374};
375375
376fn u64toa(value_param: u64, buffer: []u8) -> usize {376fn u64toa(value_param: u64, buffer: []u8) usize {
377 var value = value_param;377 var value = value_param;
378 const kTen8: u64 = 100000000;378 const kTen8: u64 = 100000000;
379 const kTen9: u64 = kTen8 * 10;379 const kTen9: u64 = kTen8 * 10;
...@@ -606,7 +606,7 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {...@@ -606,7 +606,7 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
606 return buf_index;606 return buf_index;
607}607}
608608
609fn fpeint(from: f64) -> u128 {609fn fpeint(from: f64) u128 {
610 const bits = @bitCast(u64, from);610 const bits = @bitCast(u64, from);
611 assert((bits & ((1 << 52) - 1)) == 0);611 assert((bits & ((1 << 52) - 1)) == 0);
612612
...@@ -621,7 +621,7 @@ fn fpeint(from: f64) -> u128 {...@@ -621,7 +621,7 @@ fn fpeint(from: f64) -> u128 {
621/// @a: Integer a.621/// @a: Integer a.
622/// @b: Integer b.622/// @b: Integer b.
623/// &returns: An index within [0, 19).623/// &returns: An index within [0, 19).
624fn mismatch10(a: u64, b: u64) -> i32 {624fn mismatch10(a: u64, b: u64) i32 {
625 const pow10 = 10000000000;625 const pow10 = 10000000000;
626 const af = a / pow10;626 const af = a / pow10;
627 const bf = b / pow10;627 const bf = b / pow10;
std/fmt/index.zig+23-23
...@@ -24,8 +24,8 @@ const State = enum { // TODO put inside format function and make sure the name a...@@ -24,8 +24,8 @@ const State = enum { // TODO put inside format function and make sure the name a
24/// Renders fmt string with args, calling output with slices of bytes.24/// Renders fmt string with args, calling output with slices of bytes.
25/// If `output` returns an error, the error is returned from `format` and25/// If `output` returns an error, the error is returned from `format` and
26/// `output` is not called again.26/// `output` is not called again.
27pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,27pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
28 comptime fmt: []const u8, args: ...) -> %void28 comptime fmt: []const u8, args: ...) %void
29{29{
30 comptime var start_index = 0;30 comptime var start_index = 0;
31 comptime var state = State.Start;31 comptime var state = State.Start;
...@@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,...@@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
191 }191 }
192}192}
193193
194pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {194pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
195 const T = @typeOf(value);195 const T = @typeOf(value);
196 switch (@typeId(T)) {196 switch (@typeId(T)) {
197 builtin.TypeId.Int => {197 builtin.TypeId.Int => {
...@@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons...@@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
240 }240 }
241}241}
242242
243pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {243pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
244 return output(context, (&c)[0..1]);244 return output(context, (&c)[0..1]);
245}245}
246246
247pub fn formatBuf(buf: []const u8, width: usize,247pub fn formatBuf(buf: []const u8, width: usize,
248 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void248 context: var, output: fn(@typeOf(context), []const u8)%void) %void
249{249{
250 try output(context, buf);250 try output(context, buf);
251251
...@@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,...@@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
256 }256 }
257}257}
258258
259pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {259pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
260 var x = f64(value);260 var x = f64(value);
261261
262 // Errol doesn't handle these special cases.262 // Errol doesn't handle these special cases.
...@@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons...@@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
294 }294 }
295}295}
296296
297pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {297pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
298 var x = f64(value);298 var x = f64(value);
299299
300 // Errol doesn't handle these special cases.300 // Errol doesn't handle these special cases.
...@@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn...@@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
336336
337337
338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
339 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void339 context: var, output: fn(@typeOf(context), []const u8)%void) %void
340{340{
341 if (@typeOf(value).is_signed) {341 if (@typeOf(value).is_signed) {
342 return formatIntSigned(value, base, uppercase, width, context, output);342 return formatIntSigned(value, base, uppercase, width, context, output);
...@@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,...@@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
346}346}
347347
348fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,348fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
349 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void349 context: var, output: fn(@typeOf(context), []const u8)%void) %void
350{350{
351 const uint = @IntType(false, @typeOf(value).bit_count);351 const uint = @IntType(false, @typeOf(value).bit_count);
352 if (value < 0) {352 if (value < 0) {
...@@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
367}367}
368368
369fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,369fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
370 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void370 context: var, output: fn(@typeOf(context), []const u8)%void) %void
371{371{
372 // max_int_digits accounts for the minus sign. when printing an unsigned372 // max_int_digits accounts for the minus sign. when printing an unsigned
373 // number we don't need to do that.373 // number we don't need to do that.
...@@ -405,7 +405,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,...@@ -405,7 +405,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
405 }405 }
406}406}
407407
408pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> usize {408pub fn formatIntBuf(out_buf: []u8, value: var, base: u8, uppercase: bool, width: usize) usize {
409 var context = FormatIntBuf {409 var context = FormatIntBuf {
410 .out_buf = out_buf,410 .out_buf = out_buf,
411 .index = 0,411 .index = 0,
...@@ -417,12 +417,12 @@ const FormatIntBuf = struct {...@@ -417,12 +417,12 @@ const FormatIntBuf = struct {
417 out_buf: []u8,417 out_buf: []u8,
418 index: usize,418 index: usize,
419};419};
420fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) -> %void {420fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) %void {
421 mem.copy(u8, context.out_buf[context.index..], bytes);421 mem.copy(u8, context.out_buf[context.index..], bytes);
422 context.index += bytes.len;422 context.index += bytes.len;
423}423}
424424
425pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T {425pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) %T {
426 if (!T.is_signed)426 if (!T.is_signed)
427 return parseUnsigned(T, buf, radix);427 return parseUnsigned(T, buf, radix);
428 if (buf.len == 0)428 if (buf.len == 0)
...@@ -446,7 +446,7 @@ test "fmt.parseInt" {...@@ -446,7 +446,7 @@ test "fmt.parseInt" {
446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
447}447}
448448
449pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {449pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
450 var x: T = 0;450 var x: T = 0;
451451
452 for (buf) |c| {452 for (buf) |c| {
...@@ -459,7 +459,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {...@@ -459,7 +459,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
459}459}
460460
461error InvalidChar;461error InvalidChar;
462fn charToDigit(c: u8, radix: u8) -> %u8 {462fn charToDigit(c: u8, radix: u8) %u8 {
463 const value = switch (c) {463 const value = switch (c) {
464 '0' ... '9' => c - '0',464 '0' ... '9' => c - '0',
465 'A' ... 'Z' => c - 'A' + 10,465 'A' ... 'Z' => c - 'A' + 10,
...@@ -473,7 +473,7 @@ fn charToDigit(c: u8, radix: u8) -> %u8 {...@@ -473,7 +473,7 @@ fn charToDigit(c: u8, radix: u8) -> %u8 {
473 return value;473 return value;
474}474}
475475
476fn digitToChar(digit: u8, uppercase: bool) -> u8 {476fn digitToChar(digit: u8, uppercase: bool) u8 {
477 return switch (digit) {477 return switch (digit) {
478 0 ... 9 => digit + '0',478 0 ... 9 => digit + '0',
479 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),479 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
...@@ -486,19 +486,19 @@ const BufPrintContext = struct {...@@ -486,19 +486,19 @@ const BufPrintContext = struct {
486};486};
487487
488error BufferTooSmall;488error BufferTooSmall;
489fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void {489fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) %void {
490 if (context.remaining.len < bytes.len) return error.BufferTooSmall;490 if (context.remaining.len < bytes.len) return error.BufferTooSmall;
491 mem.copy(u8, context.remaining, bytes);491 mem.copy(u8, context.remaining, bytes);
492 context.remaining = context.remaining[bytes.len..];492 context.remaining = context.remaining[bytes.len..];
493}493}
494494
495pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 {495pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) %[]u8 {
496 var context = BufPrintContext { .remaining = buf, };496 var context = BufPrintContext { .remaining = buf, };
497 try format(&context, bufPrintWrite, fmt, args);497 try format(&context, bufPrintWrite, fmt, args);
498 return buf[0..buf.len - context.remaining.len];498 return buf[0..buf.len - context.remaining.len];
499}499}
500500
501pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) -> %[]u8 {501pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) %[]u8 {
502 var size: usize = 0;502 var size: usize = 0;
503 // Cannot fail because `countSize` cannot fail.503 // Cannot fail because `countSize` cannot fail.
504 format(&size, countSize, fmt, args) catch unreachable;504 format(&size, countSize, fmt, args) catch unreachable;
...@@ -506,7 +506,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ......@@ -506,7 +506,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...
506 return bufPrint(buf, fmt, args);506 return bufPrint(buf, fmt, args);
507}507}
508508
509fn countSize(size: &usize, bytes: []const u8) -> %void {509fn countSize(size: &usize, bytes: []const u8) %void {
510 *size += bytes.len;510 *size += bytes.len;
511}511}
512512
...@@ -528,7 +528,7 @@ test "buf print int" {...@@ -528,7 +528,7 @@ test "buf print int" {
528 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));528 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
529}529}
530530
531fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) -> []u8 {531fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: usize) []u8 {
532 return buf[0..formatIntBuf(buf, value, base, uppercase, width)];532 return buf[0..formatIntBuf(buf, value, base, uppercase, width)];
533}533}
534534
...@@ -644,7 +644,7 @@ test "fmt.format" {...@@ -644,7 +644,7 @@ test "fmt.format" {
644 }644 }
645}645}
646646
647pub fn trim(buf: []const u8) -> []const u8 {647pub fn trim(buf: []const u8) []const u8 {
648 var start: usize = 0;648 var start: usize = 0;
649 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) { }649 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) { }
650650
...@@ -671,7 +671,7 @@ test "fmt.trim" {...@@ -671,7 +671,7 @@ test "fmt.trim" {
671 assert(mem.eql(u8, "abc", trim("abc ")));671 assert(mem.eql(u8, "abc", trim("abc ")));
672}672}
673673
674pub fn isWhiteSpace(byte: u8) -> bool {674pub fn isWhiteSpace(byte: u8) bool {
675 return switch (byte) {675 return switch (byte) {
676 ' ', '\t', '\n', '\r' => true,676 ' ', '\t', '\n', '\r' => true,
677 else => false,677 else => false,
std/hash_map.zig+18-18
...@@ -10,8 +10,8 @@ const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;...@@ -10,8 +10,8 @@ const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
10const debug_u32 = if (want_modification_safety) u32 else void;10const debug_u32 = if (want_modification_safety) u32 else void;
1111
12pub fn HashMap(comptime K: type, comptime V: type,12pub fn HashMap(comptime K: type, comptime V: type,
13 comptime hash: fn(key: K)->u32,13 comptime hash: fn(key: K)u32,
14 comptime eql: fn(a: K, b: K)->bool) -> type14 comptime eql: fn(a: K, b: K)bool) type
15{15{
16 return struct {16 return struct {
17 entries: []Entry,17 entries: []Entry,
...@@ -39,7 +39,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -39,7 +39,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
39 // used to detect concurrent modification39 // used to detect concurrent modification
40 initial_modification_count: debug_u32,40 initial_modification_count: debug_u32,
4141
42 pub fn next(it: &Iterator) -> ?&Entry {42 pub fn next(it: &Iterator) ?&Entry {
43 if (want_modification_safety) {43 if (want_modification_safety) {
44 assert(it.initial_modification_count == it.hm.modification_count); // concurrent modification44 assert(it.initial_modification_count == it.hm.modification_count); // concurrent modification
45 }45 }
...@@ -56,7 +56,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -56,7 +56,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
56 }56 }
57 };57 };
5858
59 pub fn init(allocator: &Allocator) -> Self {59 pub fn init(allocator: &Allocator) Self {
60 return Self {60 return Self {
61 .entries = []Entry{},61 .entries = []Entry{},
62 .allocator = allocator,62 .allocator = allocator,
...@@ -66,11 +66,11 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -66,11 +66,11 @@ pub fn HashMap(comptime K: type, comptime V: type,
66 };66 };
67 }67 }
6868
69 pub fn deinit(hm: &Self) {69 pub fn deinit(hm: &Self) void {
70 hm.allocator.free(hm.entries);70 hm.allocator.free(hm.entries);
71 }71 }
7272
73 pub fn clear(hm: &Self) {73 pub fn clear(hm: &Self) void {
74 for (hm.entries) |*entry| {74 for (hm.entries) |*entry| {
75 entry.used = false;75 entry.used = false;
76 }76 }
...@@ -80,7 +80,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -80,7 +80,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
80 }80 }
8181
82 /// Returns the value that was already there.82 /// Returns the value that was already there.
83 pub fn put(hm: &Self, key: K, value: &const V) -> %?V {83 pub fn put(hm: &Self, key: K, value: &const V) %?V {
84 if (hm.entries.len == 0) {84 if (hm.entries.len == 0) {
85 try hm.initCapacity(16);85 try hm.initCapacity(16);
86 }86 }
...@@ -102,18 +102,18 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -102,18 +102,18 @@ pub fn HashMap(comptime K: type, comptime V: type,
102 return hm.internalPut(key, value);102 return hm.internalPut(key, value);
103 }103 }
104104
105 pub fn get(hm: &Self, key: K) -> ?&Entry {105 pub fn get(hm: &Self, key: K) ?&Entry {
106 if (hm.entries.len == 0) {106 if (hm.entries.len == 0) {
107 return null;107 return null;
108 }108 }
109 return hm.internalGet(key);109 return hm.internalGet(key);
110 }110 }
111111
112 pub fn contains(hm: &Self, key: K) -> bool {112 pub fn contains(hm: &Self, key: K) bool {
113 return hm.get(key) != null;113 return hm.get(key) != null;
114 }114 }
115115
116 pub fn remove(hm: &Self, key: K) -> ?&Entry {116 pub fn remove(hm: &Self, key: K) ?&Entry {
117 hm.incrementModificationCount();117 hm.incrementModificationCount();
118 const start_index = hm.keyToIndex(key);118 const start_index = hm.keyToIndex(key);
119 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {119 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
...@@ -142,7 +142,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -142,7 +142,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
142 return null;142 return null;
143 }143 }
144144
145 pub fn iterator(hm: &const Self) -> Iterator {145 pub fn iterator(hm: &const Self) Iterator {
146 return Iterator {146 return Iterator {
147 .hm = hm,147 .hm = hm,
148 .count = 0,148 .count = 0,
...@@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
151 };151 };
152 }152 }
153153
154 fn initCapacity(hm: &Self, capacity: usize) -> %void {154 fn initCapacity(hm: &Self, capacity: usize) %void {
155 hm.entries = try hm.allocator.alloc(Entry, capacity);155 hm.entries = try hm.allocator.alloc(Entry, capacity);
156 hm.size = 0;156 hm.size = 0;
157 hm.max_distance_from_start_index = 0;157 hm.max_distance_from_start_index = 0;
...@@ -160,14 +160,14 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -160,14 +160,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
160 }160 }
161 }161 }
162162
163 fn incrementModificationCount(hm: &Self) {163 fn incrementModificationCount(hm: &Self) void {
164 if (want_modification_safety) {164 if (want_modification_safety) {
165 hm.modification_count +%= 1;165 hm.modification_count +%= 1;
166 }166 }
167 }167 }
168168
169 /// Returns the value that was already there.169 /// Returns the value that was already there.
170 fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) -> ?V {170 fn internalPut(hm: &Self, orig_key: K, orig_value: &const V) ?V {
171 var key = orig_key;171 var key = orig_key;
172 var value = *orig_value;172 var value = *orig_value;
173 const start_index = hm.keyToIndex(key);173 const start_index = hm.keyToIndex(key);
...@@ -217,7 +217,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -217,7 +217,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
217 unreachable; // put into a full map217 unreachable; // put into a full map
218 }218 }
219219
220 fn internalGet(hm: &Self, key: K) -> ?&Entry {220 fn internalGet(hm: &Self, key: K) ?&Entry {
221 const start_index = hm.keyToIndex(key);221 const start_index = hm.keyToIndex(key);
222 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {222 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
223 const index = (start_index + roll_over) % hm.entries.len;223 const index = (start_index + roll_over) % hm.entries.len;
...@@ -229,7 +229,7 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -229,7 +229,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
229 return null;229 return null;
230 }230 }
231231
232 fn keyToIndex(hm: &Self, key: K) -> usize {232 fn keyToIndex(hm: &Self, key: K) usize {
233 return usize(hash(key)) % hm.entries.len;233 return usize(hash(key)) % hm.entries.len;
234 }234 }
235 };235 };
...@@ -254,10 +254,10 @@ test "basicHashMapTest" {...@@ -254,10 +254,10 @@ test "basicHashMapTest" {
254 assert(map.get(2) == null);254 assert(map.get(2) == null);
255}255}
256256
257fn hash_i32(x: i32) -> u32 {257fn hash_i32(x: i32) u32 {
258 return @bitCast(u32, x);258 return @bitCast(u32, x);
259}259}
260260
261fn eql_i32(a: i32, b: i32) -> bool {261fn eql_i32(a: i32, b: i32) bool {
262 return a == b;262 return a == b;
263}263}
std/heap.zig+10-10
...@@ -18,14 +18,14 @@ var c_allocator_state = Allocator {...@@ -18,14 +18,14 @@ var c_allocator_state = Allocator {
18 .freeFn = cFree,18 .freeFn = cFree,
19};19};
2020
21fn cAlloc(self: &Allocator, n: usize, alignment: u29) -> %[]u8 {21fn cAlloc(self: &Allocator, n: usize, alignment: u29) %[]u8 {
22 return if (c.malloc(usize(n))) |buf|22 return if (c.malloc(usize(n))) |buf|
23 @ptrCast(&u8, buf)[0..n]23 @ptrCast(&u8, buf)[0..n]
24 else24 else
25 error.OutOfMemory;25 error.OutOfMemory;
26}26}
2727
28fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {28fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
29 const old_ptr = @ptrCast(&c_void, old_mem.ptr);29 const old_ptr = @ptrCast(&c_void, old_mem.ptr);
30 if (c.realloc(old_ptr, new_size)) |buf| {30 if (c.realloc(old_ptr, new_size)) |buf| {
31 return @ptrCast(&u8, buf)[0..new_size];31 return @ptrCast(&u8, buf)[0..new_size];
...@@ -36,7 +36,7 @@ fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ->...@@ -36,7 +36,7 @@ fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ->
36 }36 }
37}37}
3838
39fn cFree(self: &Allocator, old_mem: []u8) {39fn cFree(self: &Allocator, old_mem: []u8) void {
40 const old_ptr = @ptrCast(&c_void, old_mem.ptr);40 const old_ptr = @ptrCast(&c_void, old_mem.ptr);
41 c.free(old_ptr);41 c.free(old_ptr);
42}42}
...@@ -47,7 +47,7 @@ pub const IncrementingAllocator = struct {...@@ -47,7 +47,7 @@ pub const IncrementingAllocator = struct {
47 end_index: usize,47 end_index: usize,
48 heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,48 heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,
4949
50 fn init(capacity: usize) -> %IncrementingAllocator {50 fn init(capacity: usize) %IncrementingAllocator {
51 switch (builtin.os) {51 switch (builtin.os) {
52 Os.linux, Os.macosx, Os.ios => {52 Os.linux, Os.macosx, Os.ios => {
53 const p = os.posix;53 const p = os.posix;
...@@ -85,7 +85,7 @@ pub const IncrementingAllocator = struct {...@@ -85,7 +85,7 @@ pub const IncrementingAllocator = struct {
85 }85 }
86 }86 }
8787
88 fn deinit(self: &IncrementingAllocator) {88 fn deinit(self: &IncrementingAllocator) void {
89 switch (builtin.os) {89 switch (builtin.os) {
90 Os.linux, Os.macosx, Os.ios => {90 Os.linux, Os.macosx, Os.ios => {
91 _ = os.posix.munmap(self.bytes.ptr, self.bytes.len);91 _ = os.posix.munmap(self.bytes.ptr, self.bytes.len);
...@@ -97,15 +97,15 @@ pub const IncrementingAllocator = struct {...@@ -97,15 +97,15 @@ pub const IncrementingAllocator = struct {
97 }97 }
98 }98 }
9999
100 fn reset(self: &IncrementingAllocator) {100 fn reset(self: &IncrementingAllocator) void {
101 self.end_index = 0;101 self.end_index = 0;
102 }102 }
103103
104 fn bytesLeft(self: &const IncrementingAllocator) -> usize {104 fn bytesLeft(self: &const IncrementingAllocator) usize {
105 return self.bytes.len - self.end_index;105 return self.bytes.len - self.end_index;
106 }106 }
107107
108 fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 {108 fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
109 const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);109 const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
110 const addr = @ptrToInt(&self.bytes[self.end_index]);110 const addr = @ptrToInt(&self.bytes[self.end_index]);
111 const rem = @rem(addr, alignment);111 const rem = @rem(addr, alignment);
...@@ -120,7 +120,7 @@ pub const IncrementingAllocator = struct {...@@ -120,7 +120,7 @@ pub const IncrementingAllocator = struct {
120 return result;120 return result;
121 }121 }
122122
123 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {123 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
124 if (new_size <= old_mem.len) {124 if (new_size <= old_mem.len) {
125 return old_mem[0..new_size];125 return old_mem[0..new_size];
126 } else {126 } else {
...@@ -130,7 +130,7 @@ pub const IncrementingAllocator = struct {...@@ -130,7 +130,7 @@ pub const IncrementingAllocator = struct {
130 }130 }
131 }131 }
132132
133 fn free(allocator: &Allocator, bytes: []u8) {133 fn free(allocator: &Allocator, bytes: []u8) void {
134 // Do nothing. That's the point of an incrementing allocator.134 // Do nothing. That's the point of an incrementing allocator.
135 }135 }
136};136};
std/io.zig+91-51
...@@ -48,8 +48,9 @@ error PathNotFound;...@@ -48,8 +48,9 @@ error PathNotFound;
48error OutOfMemory;48error OutOfMemory;
49error Unseekable;49error Unseekable;
50error EndOfFile;50error EndOfFile;
51error FilePosLargerThanPointerRange;
5152
52pub fn getStdErr() -> %File {53pub fn getStdErr() %File {
53 const handle = if (is_windows)54 const handle = if (is_windows)
54 try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)55 try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
55 else if (is_posix)56 else if (is_posix)
...@@ -59,7 +60,7 @@ pub fn getStdErr() -> %File {...@@ -59,7 +60,7 @@ pub fn getStdErr() -> %File {
59 return File.openHandle(handle);60 return File.openHandle(handle);
60}61}
6162
62pub fn getStdOut() -> %File {63pub fn getStdOut() %File {
63 const handle = if (is_windows)64 const handle = if (is_windows)
64 try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)65 try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
65 else if (is_posix)66 else if (is_posix)
...@@ -69,7 +70,7 @@ pub fn getStdOut() -> %File {...@@ -69,7 +70,7 @@ pub fn getStdOut() -> %File {
69 return File.openHandle(handle);70 return File.openHandle(handle);
70}71}
7172
72pub fn getStdIn() -> %File {73pub fn getStdIn() %File {
73 const handle = if (is_windows)74 const handle = if (is_windows)
74 try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)75 try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
75 else if (is_posix)76 else if (is_posix)
...@@ -84,7 +85,7 @@ pub const FileInStream = struct {...@@ -84,7 +85,7 @@ pub const FileInStream = struct {
84 file: &File,85 file: &File,
85 stream: InStream,86 stream: InStream,
8687
87 pub fn init(file: &File) -> FileInStream {88 pub fn init(file: &File) FileInStream {
88 return FileInStream {89 return FileInStream {
89 .file = file,90 .file = file,
90 .stream = InStream {91 .stream = InStream {
...@@ -93,7 +94,7 @@ pub const FileInStream = struct {...@@ -93,7 +94,7 @@ pub const FileInStream = struct {
93 };94 };
94 }95 }
9596
96 fn readFn(in_stream: &InStream, buffer: []u8) -> %usize {97 fn readFn(in_stream: &InStream, buffer: []u8) %usize {
97 const self = @fieldParentPtr(FileInStream, "stream", in_stream);98 const self = @fieldParentPtr(FileInStream, "stream", in_stream);
98 return self.file.read(buffer);99 return self.file.read(buffer);
99 }100 }
...@@ -104,7 +105,7 @@ pub const FileOutStream = struct {...@@ -104,7 +105,7 @@ pub const FileOutStream = struct {
104 file: &File,105 file: &File,
105 stream: OutStream,106 stream: OutStream,
106107
107 pub fn init(file: &File) -> FileOutStream {108 pub fn init(file: &File) FileOutStream {
108 return FileOutStream {109 return FileOutStream {
109 .file = file,110 .file = file,
110 .stream = OutStream {111 .stream = OutStream {
...@@ -113,7 +114,7 @@ pub const FileOutStream = struct {...@@ -113,7 +114,7 @@ pub const FileOutStream = struct {
113 };114 };
114 }115 }
115116
116 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {117 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
117 const self = @fieldParentPtr(FileOutStream, "stream", out_stream);118 const self = @fieldParentPtr(FileOutStream, "stream", out_stream);
118 return self.file.write(bytes);119 return self.file.write(bytes);
119 }120 }
...@@ -128,7 +129,7 @@ pub const File = struct {...@@ -128,7 +129,7 @@ pub const File = struct {
128 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.129 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
129 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.130 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
130 /// Call close to clean up.131 /// Call close to clean up.
131 pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File {132 pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) %File {
132 if (is_posix) {133 if (is_posix) {
133 const flags = system.O_LARGEFILE|system.O_RDONLY;134 const flags = system.O_LARGEFILE|system.O_RDONLY;
134 const fd = try os.posixOpen(path, flags, 0, allocator);135 const fd = try os.posixOpen(path, flags, 0, allocator);
...@@ -143,7 +144,7 @@ pub const File = struct {...@@ -143,7 +144,7 @@ pub const File = struct {
143 }144 }
144145
145 /// Calls `openWriteMode` with 0o666 for the mode.146 /// Calls `openWriteMode` with 0o666 for the mode.
146 pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) -> %File {147 pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) %File {
147 return openWriteMode(path, 0o666, allocator);148 return openWriteMode(path, 0o666, allocator);
148149
149 }150 }
...@@ -153,7 +154,7 @@ pub const File = struct {...@@ -153,7 +154,7 @@ pub const File = struct {
153 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.154 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
154 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.155 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
155 /// Call close to clean up.156 /// Call close to clean up.
156 pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File {157 pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) %File {
157 if (is_posix) {158 if (is_posix) {
158 const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;159 const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;
159 const fd = try os.posixOpen(path, flags, mode, allocator);160 const fd = try os.posixOpen(path, flags, mode, allocator);
...@@ -169,7 +170,7 @@ pub const File = struct {...@@ -169,7 +170,7 @@ pub const File = struct {
169170
170 }171 }
171172
172 pub fn openHandle(handle: os.FileHandle) -> File {173 pub fn openHandle(handle: os.FileHandle) File {
173 return File {174 return File {
174 .handle = handle,175 .handle = handle,
175 };176 };
...@@ -178,17 +179,17 @@ pub const File = struct {...@@ -178,17 +179,17 @@ pub const File = struct {
178179
179 /// Upon success, the stream is in an uninitialized state. To continue using it,180 /// Upon success, the stream is in an uninitialized state. To continue using it,
180 /// you must use the open() function.181 /// you must use the open() function.
181 pub fn close(self: &File) {182 pub fn close(self: &File) void {
182 os.close(self.handle);183 os.close(self.handle);
183 self.handle = undefined;184 self.handle = undefined;
184 }185 }
185186
186 /// Calls `os.isTty` on `self.handle`.187 /// Calls `os.isTty` on `self.handle`.
187 pub fn isTty(self: &File) -> bool {188 pub fn isTty(self: &File) bool {
188 return os.isTty(self.handle);189 return os.isTty(self.handle);
189 }190 }
190191
191 pub fn seekForward(self: &File, amount: isize) -> %void {192 pub fn seekForward(self: &File, amount: isize) %void {
192 switch (builtin.os) {193 switch (builtin.os) {
193 Os.linux, Os.macosx, Os.ios => {194 Os.linux, Os.macosx, Os.ios => {
194 const result = system.lseek(self.handle, amount, system.SEEK_CUR);195 const result = system.lseek(self.handle, amount, system.SEEK_CUR);
...@@ -204,14 +205,24 @@ pub const File = struct {...@@ -204,14 +205,24 @@ pub const File = struct {
204 };205 };
205 }206 }
206 },207 },
208 Os.windows => {
209 if (system.SetFilePointerEx(self.handle, amount, null, system.FILE_CURRENT) == 0) {
210 const err = system.GetLastError();
211 return switch (err) {
212 system.ERROR.INVALID_PARAMETER => error.BadFd,
213 else => os.unexpectedErrorWindows(err),
214 };
215 }
216 },
207 else => @compileError("unsupported OS"),217 else => @compileError("unsupported OS"),
208 }218 }
209 }219 }
210220
211 pub fn seekTo(self: &File, pos: usize) -> %void {221 pub fn seekTo(self: &File, pos: usize) %void {
212 switch (builtin.os) {222 switch (builtin.os) {
213 Os.linux, Os.macosx, Os.ios => {223 Os.linux, Os.macosx, Os.ios => {
214 const result = system.lseek(self.handle, @bitCast(isize, pos), system.SEEK_SET);224 const ipos = try math.cast(isize, pos);
225 const result = system.lseek(self.handle, ipos, system.SEEK_SET);
215 const err = system.getErrno(result);226 const err = system.getErrno(result);
216 if (err > 0) {227 if (err > 0) {
217 return switch (err) {228 return switch (err) {
...@@ -224,11 +235,21 @@ pub const File = struct {...@@ -224,11 +235,21 @@ pub const File = struct {
224 };235 };
225 }236 }
226 },237 },
238 Os.windows => {
239 const ipos = try math.cast(isize, pos);
240 if (system.SetFilePointerEx(self.handle, ipos, null, system.FILE_BEGIN) == 0) {
241 const err = system.GetLastError();
242 return switch (err) {
243 system.ERROR.INVALID_PARAMETER => error.BadFd,
244 else => os.unexpectedErrorWindows(err),
245 };
246 }
247 },
227 else => @compileError("unsupported OS: " ++ @tagName(builtin.os)),248 else => @compileError("unsupported OS: " ++ @tagName(builtin.os)),
228 }249 }
229 }250 }
230251
231 pub fn getPos(self: &File) -> %usize {252 pub fn getPos(self: &File) %usize {
232 switch (builtin.os) {253 switch (builtin.os) {
233 Os.linux, Os.macosx, Os.ios => {254 Os.linux, Os.macosx, Os.ios => {
234 const result = system.lseek(self.handle, 0, system.SEEK_CUR);255 const result = system.lseek(self.handle, 0, system.SEEK_CUR);
...@@ -245,11 +266,30 @@ pub const File = struct {...@@ -245,11 +266,30 @@ pub const File = struct {
245 }266 }
246 return result;267 return result;
247 },268 },
269 Os.windows => {
270 var pos : system.LARGE_INTEGER = undefined;
271 if (system.SetFilePointerEx(self.handle, 0, &pos, system.FILE_CURRENT) == 0) {
272 const err = system.GetLastError();
273 return switch (err) {
274 system.ERROR.INVALID_PARAMETER => error.BadFd,
275 else => os.unexpectedErrorWindows(err),
276 };
277 }
278
279 assert(pos >= 0);
280 if (@sizeOf(@typeOf(pos)) > @sizeOf(usize)) {
281 if (pos > @maxValue(usize)) {
282 return error.FilePosLargerThanPointerRange;
283 }
284 }
285
286 return usize(pos);
287 },
248 else => @compileError("unsupported OS"),288 else => @compileError("unsupported OS"),
249 }289 }
250 }290 }
251291
252 pub fn getEndPos(self: &File) -> %usize {292 pub fn getEndPos(self: &File) %usize {
253 if (is_posix) {293 if (is_posix) {
254 var stat: system.Stat = undefined;294 var stat: system.Stat = undefined;
255 const err = system.getErrno(system.fstat(self.handle, &stat));295 const err = system.getErrno(system.fstat(self.handle, &stat));
...@@ -278,7 +318,7 @@ pub const File = struct {...@@ -278,7 +318,7 @@ pub const File = struct {
278 }318 }
279 }319 }
280320
281 pub fn read(self: &File, buffer: []u8) -> %usize {321 pub fn read(self: &File, buffer: []u8) %usize {
282 if (is_posix) {322 if (is_posix) {
283 var index: usize = 0;323 var index: usize = 0;
284 while (index < buffer.len) {324 while (index < buffer.len) {
...@@ -320,7 +360,7 @@ pub const File = struct {...@@ -320,7 +360,7 @@ pub const File = struct {
320 }360 }
321 }361 }
322362
323 fn write(self: &File, bytes: []const u8) -> %void {363 fn write(self: &File, bytes: []const u8) %void {
324 if (is_posix) {364 if (is_posix) {
325 try os.posixWrite(self.handle, bytes);365 try os.posixWrite(self.handle, bytes);
326 } else if (is_windows) {366 } else if (is_windows) {
...@@ -338,12 +378,12 @@ pub const InStream = struct {...@@ -338,12 +378,12 @@ pub const InStream = struct {
338 /// Return the number of bytes read. If the number read is smaller than buf.len, it378 /// Return the number of bytes read. If the number read is smaller than buf.len, it
339 /// means the stream reached the end. Reaching the end of a stream is not an error379 /// means the stream reached the end. Reaching the end of a stream is not an error
340 /// condition.380 /// condition.
341 readFn: fn(self: &InStream, buffer: []u8) -> %usize,381 readFn: fn(self: &InStream, buffer: []u8) %usize,
342382
343 /// Replaces `buffer` contents by reading from the stream until it is finished.383 /// Replaces `buffer` contents by reading from the stream until it is finished.
344 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and384 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
345 /// the contents read from the stream are lost.385 /// the contents read from the stream are lost.
346 pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void {386 pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) %void {
347 try buffer.resize(0);387 try buffer.resize(0);
348388
349 var actual_buf_len: usize = 0;389 var actual_buf_len: usize = 0;
...@@ -368,7 +408,7 @@ pub const InStream = struct {...@@ -368,7 +408,7 @@ pub const InStream = struct {
368 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.408 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.
369 /// Caller owns returned memory.409 /// Caller owns returned memory.
370 /// If this function returns an error, the contents from the stream read so far are lost.410 /// If this function returns an error, the contents from the stream read so far are lost.
371 pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) -> %[]u8 {411 pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) %[]u8 {
372 var buf = Buffer.initNull(allocator);412 var buf = Buffer.initNull(allocator);
373 defer buf.deinit();413 defer buf.deinit();
374414
...@@ -380,7 +420,7 @@ pub const InStream = struct {...@@ -380,7 +420,7 @@ pub const InStream = struct {
380 /// Does not include the delimiter in the result.420 /// Does not include the delimiter in the result.
381 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents421 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
382 /// read from the stream so far are lost.422 /// read from the stream so far are lost.
383 pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void {423 pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) %void {
384 try buf.resize(0);424 try buf.resize(0);
385425
386 while (true) {426 while (true) {
...@@ -403,7 +443,7 @@ pub const InStream = struct {...@@ -403,7 +443,7 @@ pub const InStream = struct {
403 /// Caller owns returned memory.443 /// Caller owns returned memory.
404 /// If this function returns an error, the contents from the stream read so far are lost.444 /// If this function returns an error, the contents from the stream read so far are lost.
405 pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,445 pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,
406 delimiter: u8, max_size: usize) -> %[]u8446 delimiter: u8, max_size: usize) %[]u8
407 {447 {
408 var buf = Buffer.initNull(allocator);448 var buf = Buffer.initNull(allocator);
409 defer buf.deinit();449 defer buf.deinit();
...@@ -415,43 +455,43 @@ pub const InStream = struct {...@@ -415,43 +455,43 @@ pub const InStream = struct {
415 /// Returns the number of bytes read. If the number read is smaller than buf.len, it455 /// Returns the number of bytes read. If the number read is smaller than buf.len, it
416 /// means the stream reached the end. Reaching the end of a stream is not an error456 /// means the stream reached the end. Reaching the end of a stream is not an error
417 /// condition.457 /// condition.
418 pub fn read(self: &InStream, buffer: []u8) -> %usize {458 pub fn read(self: &InStream, buffer: []u8) %usize {
419 return self.readFn(self, buffer);459 return self.readFn(self, buffer);
420 }460 }
421461
422 /// Same as `read` but end of stream returns `error.EndOfStream`.462 /// Same as `read` but end of stream returns `error.EndOfStream`.
423 pub fn readNoEof(self: &InStream, buf: []u8) -> %void {463 pub fn readNoEof(self: &InStream, buf: []u8) %void {
424 const amt_read = try self.read(buf);464 const amt_read = try self.read(buf);
425 if (amt_read < buf.len) return error.EndOfStream;465 if (amt_read < buf.len) return error.EndOfStream;
426 }466 }
427467
428 /// Reads 1 byte from the stream or returns `error.EndOfStream`.468 /// Reads 1 byte from the stream or returns `error.EndOfStream`.
429 pub fn readByte(self: &InStream) -> %u8 {469 pub fn readByte(self: &InStream) %u8 {
430 var result: [1]u8 = undefined;470 var result: [1]u8 = undefined;
431 try self.readNoEof(result[0..]);471 try self.readNoEof(result[0..]);
432 return result[0];472 return result[0];
433 }473 }
434474
435 /// Same as `readByte` except the returned byte is signed.475 /// Same as `readByte` except the returned byte is signed.
436 pub fn readByteSigned(self: &InStream) -> %i8 {476 pub fn readByteSigned(self: &InStream) %i8 {
437 return @bitCast(i8, try self.readByte());477 return @bitCast(i8, try self.readByte());
438 }478 }
439479
440 pub fn readIntLe(self: &InStream, comptime T: type) -> %T {480 pub fn readIntLe(self: &InStream, comptime T: type) %T {
441 return self.readInt(builtin.Endian.Little, T);481 return self.readInt(builtin.Endian.Little, T);
442 }482 }
443483
444 pub fn readIntBe(self: &InStream, comptime T: type) -> %T {484 pub fn readIntBe(self: &InStream, comptime T: type) %T {
445 return self.readInt(builtin.Endian.Big, T);485 return self.readInt(builtin.Endian.Big, T);
446 }486 }
447487
448 pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T {488 pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) %T {
449 var bytes: [@sizeOf(T)]u8 = undefined;489 var bytes: [@sizeOf(T)]u8 = undefined;
450 try self.readNoEof(bytes[0..]);490 try self.readNoEof(bytes[0..]);
451 return mem.readInt(bytes, T, endian);491 return mem.readInt(bytes, T, endian);
452 }492 }
453493
454 pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) -> %T {494 pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) %T {
455 assert(size <= @sizeOf(T));495 assert(size <= @sizeOf(T));
456 assert(size <= 8);496 assert(size <= 8);
457 var input_buf: [8]u8 = undefined;497 var input_buf: [8]u8 = undefined;
...@@ -464,22 +504,22 @@ pub const InStream = struct {...@@ -464,22 +504,22 @@ pub const InStream = struct {
464};504};
465505
466pub const OutStream = struct {506pub const OutStream = struct {
467 writeFn: fn(self: &OutStream, bytes: []const u8) -> %void,507 writeFn: fn(self: &OutStream, bytes: []const u8) %void,
468508
469 pub fn print(self: &OutStream, comptime format: []const u8, args: ...) -> %void {509 pub fn print(self: &OutStream, comptime format: []const u8, args: ...) %void {
470 return std.fmt.format(self, self.writeFn, format, args);510 return std.fmt.format(self, self.writeFn, format, args);
471 }511 }
472512
473 pub fn write(self: &OutStream, bytes: []const u8) -> %void {513 pub fn write(self: &OutStream, bytes: []const u8) %void {
474 return self.writeFn(self, bytes);514 return self.writeFn(self, bytes);
475 }515 }
476516
477 pub fn writeByte(self: &OutStream, byte: u8) -> %void {517 pub fn writeByte(self: &OutStream, byte: u8) %void {
478 const slice = (&byte)[0..1];518 const slice = (&byte)[0..1];
479 return self.writeFn(self, slice);519 return self.writeFn(self, slice);
480 }520 }
481521
482 pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) -> %void {522 pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) %void {
483 const slice = (&byte)[0..1];523 const slice = (&byte)[0..1];
484 var i: usize = 0;524 var i: usize = 0;
485 while (i < n) : (i += 1) {525 while (i < n) : (i += 1) {
...@@ -492,25 +532,25 @@ pub const OutStream = struct {...@@ -492,25 +532,25 @@ pub const OutStream = struct {
492/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed532/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed
493/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.533/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.
494/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.534/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
495pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void {535pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) %void {
496 var file = try File.openWrite(path, allocator);536 var file = try File.openWrite(path, allocator);
497 defer file.close();537 defer file.close();
498 try file.write(data);538 try file.write(data);
499}539}
500540
501/// On success, caller owns returned buffer.541/// On success, caller owns returned buffer.
502pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 {542pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) %[]u8 {
503 return readFileAllocExtra(path, allocator, 0);543 return readFileAllocExtra(path, allocator, 0);
504}544}
505/// On success, caller owns returned buffer.545/// On success, caller owns returned buffer.
506/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.546/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.
507pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 {547pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) %[]u8 {
508 var file = try File.openRead(path, allocator);548 var file = try File.openRead(path, allocator);
509 defer file.close();549 defer file.close();
510550
511 const size = try file.getEndPos();551 const size = try file.getEndPos();
512 const buf = try allocator.alloc(u8, size + extra_len);552 const buf = try allocator.alloc(u8, size + extra_len);
513 %defer allocator.free(buf);553 errdefer allocator.free(buf);
514554
515 var adapter = FileInStream.init(&file);555 var adapter = FileInStream.init(&file);
516 try adapter.stream.readNoEof(buf[0..size]);556 try adapter.stream.readNoEof(buf[0..size]);
...@@ -519,7 +559,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len...@@ -519,7 +559,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len
519559
520pub const BufferedInStream = BufferedInStreamCustom(os.page_size);560pub const BufferedInStream = BufferedInStreamCustom(os.page_size);
521561
522pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {562pub fn BufferedInStreamCustom(comptime buffer_size: usize) type {
523 return struct {563 return struct {
524 const Self = this;564 const Self = this;
525565
...@@ -531,7 +571,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {...@@ -531,7 +571,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
531 start_index: usize,571 start_index: usize,
532 end_index: usize,572 end_index: usize,
533573
534 pub fn init(unbuffered_in_stream: &InStream) -> Self {574 pub fn init(unbuffered_in_stream: &InStream) Self {
535 return Self {575 return Self {
536 .unbuffered_in_stream = unbuffered_in_stream,576 .unbuffered_in_stream = unbuffered_in_stream,
537 .buffer = undefined,577 .buffer = undefined,
...@@ -549,7 +589,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {...@@ -549,7 +589,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
549 };589 };
550 }590 }
551591
552 fn readFn(in_stream: &InStream, dest: []u8) -> %usize {592 fn readFn(in_stream: &InStream, dest: []u8) %usize {
553 const self = @fieldParentPtr(Self, "stream", in_stream);593 const self = @fieldParentPtr(Self, "stream", in_stream);
554594
555 var dest_index: usize = 0;595 var dest_index: usize = 0;
...@@ -590,7 +630,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {...@@ -590,7 +630,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
590630
591pub const BufferedOutStream = BufferedOutStreamCustom(os.page_size);631pub const BufferedOutStream = BufferedOutStreamCustom(os.page_size);
592632
593pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {633pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
594 return struct {634 return struct {
595 const Self = this;635 const Self = this;
596636
...@@ -601,7 +641,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {...@@ -601,7 +641,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
601 buffer: [buffer_size]u8,641 buffer: [buffer_size]u8,
602 index: usize,642 index: usize,
603643
604 pub fn init(unbuffered_out_stream: &OutStream) -> Self {644 pub fn init(unbuffered_out_stream: &OutStream) Self {
605 return Self {645 return Self {
606 .unbuffered_out_stream = unbuffered_out_stream,646 .unbuffered_out_stream = unbuffered_out_stream,
607 .buffer = undefined,647 .buffer = undefined,
...@@ -612,7 +652,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {...@@ -612,7 +652,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
612 };652 };
613 }653 }
614654
615 pub fn flush(self: &Self) -> %void {655 pub fn flush(self: &Self) %void {
616 if (self.index == 0)656 if (self.index == 0)
617 return;657 return;
618658
...@@ -620,7 +660,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {...@@ -620,7 +660,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
620 self.index = 0;660 self.index = 0;
621 }661 }
622662
623 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {663 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
624 const self = @fieldParentPtr(Self, "stream", out_stream);664 const self = @fieldParentPtr(Self, "stream", out_stream);
625665
626 if (bytes.len >= self.buffer.len) {666 if (bytes.len >= self.buffer.len) {
...@@ -649,7 +689,7 @@ pub const BufferOutStream = struct {...@@ -649,7 +689,7 @@ pub const BufferOutStream = struct {
649 buffer: &Buffer,689 buffer: &Buffer,
650 stream: OutStream,690 stream: OutStream,
651691
652 pub fn init(buffer: &Buffer) -> BufferOutStream {692 pub fn init(buffer: &Buffer) BufferOutStream {
653 return BufferOutStream {693 return BufferOutStream {
654 .buffer = buffer,694 .buffer = buffer,
655 .stream = OutStream {695 .stream = OutStream {
...@@ -658,7 +698,7 @@ pub const BufferOutStream = struct {...@@ -658,7 +698,7 @@ pub const BufferOutStream = struct {
658 };698 };
659 }699 }
660700
661 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {701 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
662 const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);702 const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);
663 return self.buffer.append(bytes);703 return self.buffer.append(bytes);
664 }704 }
std/linked_list.zig+18-18
...@@ -5,17 +5,17 @@ const mem = std.mem;...@@ -5,17 +5,17 @@ const mem = std.mem;
5const Allocator = mem.Allocator;5const Allocator = mem.Allocator;
66
7/// Generic non-intrusive doubly linked list.7/// Generic non-intrusive doubly linked list.
8pub fn LinkedList(comptime T: type) -> type {8pub fn LinkedList(comptime T: type) type {
9 return BaseLinkedList(T, void, "");9 return BaseLinkedList(T, void, "");
10}10}
1111
12/// Generic intrusive doubly linked list.12/// Generic intrusive doubly linked list.
13pub fn IntrusiveLinkedList(comptime ParentType: type, comptime field_name: []const u8) -> type {13pub fn IntrusiveLinkedList(comptime ParentType: type, comptime field_name: []const u8) type {
14 return BaseLinkedList(void, ParentType, field_name);14 return BaseLinkedList(void, ParentType, field_name);
15}15}
1616
17/// Generic doubly linked list.17/// Generic doubly linked list.
18fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_name: []const u8) -> type {18fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_name: []const u8) type {
19 return struct {19 return struct {
20 const Self = this;20 const Self = this;
2121
...@@ -25,7 +25,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -25,7 +25,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
25 next: ?&Node,25 next: ?&Node,
26 data: T,26 data: T,
2727
28 pub fn init(value: &const T) -> Node {28 pub fn init(value: &const T) Node {
29 return Node {29 return Node {
30 .prev = null,30 .prev = null,
31 .next = null,31 .next = null,
...@@ -33,12 +33,12 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -33,12 +33,12 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
33 };33 };
34 }34 }
3535
36 pub fn initIntrusive() -> Node {36 pub fn initIntrusive() Node {
37 // TODO: when #678 is solved this can become `init`.37 // TODO: when #678 is solved this can become `init`.
38 return Node.init({});38 return Node.init({});
39 }39 }
4040
41 pub fn toData(node: &Node) -> &ParentType {41 pub fn toData(node: &Node) &ParentType {
42 comptime assert(isIntrusive());42 comptime assert(isIntrusive());
43 return @fieldParentPtr(ParentType, field_name, node);43 return @fieldParentPtr(ParentType, field_name, node);
44 }44 }
...@@ -52,7 +52,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -52,7 +52,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
52 ///52 ///
53 /// Returns:53 /// Returns:
54 /// An empty linked list.54 /// An empty linked list.
55 pub fn init() -> Self {55 pub fn init() Self {
56 return Self {56 return Self {
57 .first = null,57 .first = null,
58 .last = null,58 .last = null,
...@@ -60,7 +60,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -60,7 +60,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
60 };60 };
61 }61 }
6262
63 fn isIntrusive() -> bool {63 fn isIntrusive() bool {
64 return ParentType != void or field_name.len != 0;64 return ParentType != void or field_name.len != 0;
65 }65 }
6666
...@@ -69,7 +69,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -69,7 +69,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
69 /// Arguments:69 /// Arguments:
70 /// node: Pointer to a node in the list.70 /// node: Pointer to a node in the list.
71 /// new_node: Pointer to the new node to insert.71 /// new_node: Pointer to the new node to insert.
72 pub fn insertAfter(list: &Self, node: &Node, new_node: &Node) {72 pub fn insertAfter(list: &Self, node: &Node, new_node: &Node) void {
73 new_node.prev = node;73 new_node.prev = node;
74 if (node.next) |next_node| {74 if (node.next) |next_node| {
75 // Intermediate node.75 // Intermediate node.
...@@ -90,7 +90,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -90,7 +90,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
90 /// Arguments:90 /// Arguments:
91 /// node: Pointer to a node in the list.91 /// node: Pointer to a node in the list.
92 /// new_node: Pointer to the new node to insert.92 /// new_node: Pointer to the new node to insert.
93 pub fn insertBefore(list: &Self, node: &Node, new_node: &Node) {93 pub fn insertBefore(list: &Self, node: &Node, new_node: &Node) void {
94 new_node.next = node;94 new_node.next = node;
95 if (node.prev) |prev_node| {95 if (node.prev) |prev_node| {
96 // Intermediate node.96 // Intermediate node.
...@@ -110,7 +110,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -110,7 +110,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
110 ///110 ///
111 /// Arguments:111 /// Arguments:
112 /// new_node: Pointer to the new node to insert.112 /// new_node: Pointer to the new node to insert.
113 pub fn append(list: &Self, new_node: &Node) {113 pub fn append(list: &Self, new_node: &Node) void {
114 if (list.last) |last| {114 if (list.last) |last| {
115 // Insert after last.115 // Insert after last.
116 list.insertAfter(last, new_node);116 list.insertAfter(last, new_node);
...@@ -124,7 +124,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -124,7 +124,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
124 ///124 ///
125 /// Arguments:125 /// Arguments:
126 /// new_node: Pointer to the new node to insert.126 /// new_node: Pointer to the new node to insert.
127 pub fn prepend(list: &Self, new_node: &Node) {127 pub fn prepend(list: &Self, new_node: &Node) void {
128 if (list.first) |first| {128 if (list.first) |first| {
129 // Insert before first.129 // Insert before first.
130 list.insertBefore(first, new_node);130 list.insertBefore(first, new_node);
...@@ -143,7 +143,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -143,7 +143,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
143 ///143 ///
144 /// Arguments:144 /// Arguments:
145 /// node: Pointer to the node to be removed.145 /// node: Pointer to the node to be removed.
146 pub fn remove(list: &Self, node: &Node) {146 pub fn remove(list: &Self, node: &Node) void {
147 if (node.prev) |prev_node| {147 if (node.prev) |prev_node| {
148 // Intermediate node.148 // Intermediate node.
149 prev_node.next = node.next;149 prev_node.next = node.next;
...@@ -167,7 +167,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -167,7 +167,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
167 ///167 ///
168 /// Returns:168 /// Returns:
169 /// A pointer to the last node in the list.169 /// A pointer to the last node in the list.
170 pub fn pop(list: &Self) -> ?&Node {170 pub fn pop(list: &Self) ?&Node {
171 const last = list.last ?? return null;171 const last = list.last ?? return null;
172 list.remove(last);172 list.remove(last);
173 return last;173 return last;
...@@ -177,7 +177,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -177,7 +177,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
177 ///177 ///
178 /// Returns:178 /// Returns:
179 /// A pointer to the first node in the list.179 /// A pointer to the first node in the list.
180 pub fn popFirst(list: &Self) -> ?&Node {180 pub fn popFirst(list: &Self) ?&Node {
181 const first = list.first ?? return null;181 const first = list.first ?? return null;
182 list.remove(first);182 list.remove(first);
183 return first;183 return first;
...@@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
190 ///190 ///
191 /// Returns:191 /// Returns:
192 /// A pointer to the new node.192 /// A pointer to the new node.
193 pub fn allocateNode(list: &Self, allocator: &Allocator) -> %&Node {193 pub fn allocateNode(list: &Self, allocator: &Allocator) %&Node {
194 comptime assert(!isIntrusive());194 comptime assert(!isIntrusive());
195 return allocator.create(Node);195 return allocator.create(Node);
196 }196 }
...@@ -200,7 +200,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -200,7 +200,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
200 /// Arguments:200 /// Arguments:
201 /// node: Pointer to the node to deallocate.201 /// node: Pointer to the node to deallocate.
202 /// allocator: Dynamic memory allocator.202 /// allocator: Dynamic memory allocator.
203 pub fn destroyNode(list: &Self, node: &Node, allocator: &Allocator) {203 pub fn destroyNode(list: &Self, node: &Node, allocator: &Allocator) void {
204 comptime assert(!isIntrusive());204 comptime assert(!isIntrusive());
205 allocator.destroy(node);205 allocator.destroy(node);
206 }206 }
...@@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na...@@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
213 ///213 ///
214 /// Returns:214 /// Returns:
215 /// A pointer to the new node.215 /// A pointer to the new node.
216 pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node {216 pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) %&Node {
217 comptime assert(!isIntrusive());217 comptime assert(!isIntrusive());
218 var node = try list.allocateNode(allocator);218 var node = try list.allocateNode(allocator);
219 *node = Node.init(data);219 *node = Node.init(data);
std/math/acos.zig+5-5
...@@ -6,7 +6,7 @@ const std = @import("../index.zig");...@@ -6,7 +6,7 @@ const std = @import("../index.zig");
6const math = std.math;6const math = std.math;
7const assert = std.debug.assert;7const assert = std.debug.assert;
88
9pub fn acos(x: var) -> @typeOf(x) {9pub fn acos(x: var) @typeOf(x) {
10 const T = @typeOf(x);10 const T = @typeOf(x);
11 return switch (T) {11 return switch (T) {
12 f32 => acos32(x),12 f32 => acos32(x),
...@@ -15,7 +15,7 @@ pub fn acos(x: var) -> @typeOf(x) {...@@ -15,7 +15,7 @@ pub fn acos(x: var) -> @typeOf(x) {
15 };15 };
16}16}
1717
18fn r32(z: f32) -> f32 {18fn r32(z: f32) f32 {
19 const pS0 = 1.6666586697e-01;19 const pS0 = 1.6666586697e-01;
20 const pS1 = -4.2743422091e-02;20 const pS1 = -4.2743422091e-02;
21 const pS2 = -8.6563630030e-03;21 const pS2 = -8.6563630030e-03;
...@@ -26,7 +26,7 @@ fn r32(z: f32) -> f32 {...@@ -26,7 +26,7 @@ fn r32(z: f32) -> f32 {
26 return p / q;26 return p / q;
27}27}
2828
29fn acos32(x: f32) -> f32 {29fn acos32(x: f32) f32 {
30 const pio2_hi = 1.5707962513e+00;30 const pio2_hi = 1.5707962513e+00;
31 const pio2_lo = 7.5497894159e-08;31 const pio2_lo = 7.5497894159e-08;
3232
...@@ -73,7 +73,7 @@ fn acos32(x: f32) -> f32 {...@@ -73,7 +73,7 @@ fn acos32(x: f32) -> f32 {
73 return 2 * (df + w);73 return 2 * (df + w);
74}74}
7575
76fn r64(z: f64) -> f64 {76fn r64(z: f64) f64 {
77 const pS0: f64 = 1.66666666666666657415e-01;77 const pS0: f64 = 1.66666666666666657415e-01;
78 const pS1: f64 = -3.25565818622400915405e-01;78 const pS1: f64 = -3.25565818622400915405e-01;
79 const pS2: f64 = 2.01212532134862925881e-01;79 const pS2: f64 = 2.01212532134862925881e-01;
...@@ -90,7 +90,7 @@ fn r64(z: f64) -> f64 {...@@ -90,7 +90,7 @@ fn r64(z: f64) -> f64 {
90 return p / q;90 return p / q;
91}91}
9292
93fn acos64(x: f64) -> f64 {93fn acos64(x: f64) f64 {
94 const pio2_hi: f64 = 1.57079632679489655800e+00;94 const pio2_hi: f64 = 1.57079632679489655800e+00;
95 const pio2_lo: f64 = 6.12323399573676603587e-17;95 const pio2_lo: f64 = 6.12323399573676603587e-17;
9696
std/math/acosh.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn acosh(x: var) -> @typeOf(x) {11pub fn acosh(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => acosh32(x),14 f32 => acosh32(x),
...@@ -18,7 +18,7 @@ pub fn acosh(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn acosh(x: var) -> @typeOf(x) {
18}18}
1919
20// acosh(x) = log(x + sqrt(x * x - 1))20// acosh(x) = log(x + sqrt(x * x - 1))
21fn acosh32(x: f32) -> f32 {21fn acosh32(x: f32) f32 {
22 const u = @bitCast(u32, x);22 const u = @bitCast(u32, x);
23 const i = u & 0x7FFFFFFF;23 const i = u & 0x7FFFFFFF;
2424
...@@ -36,7 +36,7 @@ fn acosh32(x: f32) -> f32 {...@@ -36,7 +36,7 @@ fn acosh32(x: f32) -> f32 {
36 }36 }
37}37}
3838
39fn acosh64(x: f64) -> f64 {39fn acosh64(x: f64) f64 {
40 const u = @bitCast(u64, x);40 const u = @bitCast(u64, x);
41 const e = (u >> 52) & 0x7FF;41 const e = (u >> 52) & 0x7FF;
4242
std/math/asin.zig+5-5
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10pub fn asin(x: var) -> @typeOf(x) {10pub fn asin(x: var) @typeOf(x) {
11 const T = @typeOf(x);11 const T = @typeOf(x);
12 return switch (T) {12 return switch (T) {
13 f32 => asin32(x),13 f32 => asin32(x),
...@@ -16,7 +16,7 @@ pub fn asin(x: var) -> @typeOf(x) {...@@ -16,7 +16,7 @@ pub fn asin(x: var) -> @typeOf(x) {
16 };16 };
17}17}
1818
19fn r32(z: f32) -> f32 {19fn r32(z: f32) f32 {
20 const pS0 = 1.6666586697e-01;20 const pS0 = 1.6666586697e-01;
21 const pS1 = -4.2743422091e-02;21 const pS1 = -4.2743422091e-02;
22 const pS2 = -8.6563630030e-03;22 const pS2 = -8.6563630030e-03;
...@@ -27,7 +27,7 @@ fn r32(z: f32) -> f32 {...@@ -27,7 +27,7 @@ fn r32(z: f32) -> f32 {
27 return p / q;27 return p / q;
28}28}
2929
30fn asin32(x: f32) -> f32 {30fn asin32(x: f32) f32 {
31 const pio2 = 1.570796326794896558e+00;31 const pio2 = 1.570796326794896558e+00;
3232
33 const hx: u32 = @bitCast(u32, x);33 const hx: u32 = @bitCast(u32, x);
...@@ -65,7 +65,7 @@ fn asin32(x: f32) -> f32 {...@@ -65,7 +65,7 @@ fn asin32(x: f32) -> f32 {
65 }65 }
66}66}
6767
68fn r64(z: f64) -> f64 {68fn r64(z: f64) f64 {
69 const pS0: f64 = 1.66666666666666657415e-01;69 const pS0: f64 = 1.66666666666666657415e-01;
70 const pS1: f64 = -3.25565818622400915405e-01;70 const pS1: f64 = -3.25565818622400915405e-01;
71 const pS2: f64 = 2.01212532134862925881e-01;71 const pS2: f64 = 2.01212532134862925881e-01;
...@@ -82,7 +82,7 @@ fn r64(z: f64) -> f64 {...@@ -82,7 +82,7 @@ fn r64(z: f64) -> f64 {
82 return p / q;82 return p / q;
83}83}
8484
85fn asin64(x: f64) -> f64 {85fn asin64(x: f64) f64 {
86 const pio2_hi: f64 = 1.57079632679489655800e+00;86 const pio2_hi: f64 = 1.57079632679489655800e+00;
87 const pio2_lo: f64 = 6.12323399573676603587e-17;87 const pio2_lo: f64 = 6.12323399573676603587e-17;
8888
std/math/asinh.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn asinh(x: var) -> @typeOf(x) {11pub fn asinh(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => asinh32(x),14 f32 => asinh32(x),
...@@ -18,7 +18,7 @@ pub fn asinh(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn asinh(x: var) -> @typeOf(x) {
18}18}
1919
20// asinh(x) = sign(x) * log(|x| + sqrt(x * x + 1)) ~= x - x^3/6 + o(x^5)20// asinh(x) = sign(x) * log(|x| + sqrt(x * x + 1)) ~= x - x^3/6 + o(x^5)
21fn asinh32(x: f32) -> f32 {21fn asinh32(x: f32) f32 {
22 const u = @bitCast(u32, x);22 const u = @bitCast(u32, x);
23 const i = u & 0x7FFFFFFF;23 const i = u & 0x7FFFFFFF;
24 const s = i >> 31;24 const s = i >> 31;
...@@ -50,7 +50,7 @@ fn asinh32(x: f32) -> f32 {...@@ -50,7 +50,7 @@ fn asinh32(x: f32) -> f32 {
50 return if (s != 0) -rx else rx;50 return if (s != 0) -rx else rx;
51}51}
5252
53fn asinh64(x: f64) -> f64 {53fn asinh64(x: f64) f64 {
54 const u = @bitCast(u64, x);54 const u = @bitCast(u64, x);
55 const e = (u >> 52) & 0x7FF;55 const e = (u >> 52) & 0x7FF;
56 const s = u >> 63;56 const s = u >> 63;
std/math/atan.zig+3-3
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10pub fn atan(x: var) -> @typeOf(x) {10pub fn atan(x: var) @typeOf(x) {
11 const T = @typeOf(x);11 const T = @typeOf(x);
12 return switch (T) {12 return switch (T) {
13 f32 => atan32(x),13 f32 => atan32(x),
...@@ -16,7 +16,7 @@ pub fn atan(x: var) -> @typeOf(x) {...@@ -16,7 +16,7 @@ pub fn atan(x: var) -> @typeOf(x) {
16 };16 };
17}17}
1818
19fn atan32(x_: f32) -> f32 {19fn atan32(x_: f32) f32 {
20 const atanhi = []const f32 {20 const atanhi = []const f32 {
21 4.6364760399e-01, // atan(0.5)hi21 4.6364760399e-01, // atan(0.5)hi
22 7.8539812565e-01, // atan(1.0)hi22 7.8539812565e-01, // atan(1.0)hi
...@@ -108,7 +108,7 @@ fn atan32(x_: f32) -> f32 {...@@ -108,7 +108,7 @@ fn atan32(x_: f32) -> f32 {
108 }108 }
109}109}
110110
111fn atan64(x_: f64) -> f64 {111fn atan64(x_: f64) f64 {
112 const atanhi = []const f64 {112 const atanhi = []const f64 {
113 4.63647609000806093515e-01, // atan(0.5)hi113 4.63647609000806093515e-01, // atan(0.5)hi
114 7.85398163397448278999e-01, // atan(1.0)hi114 7.85398163397448278999e-01, // atan(1.0)hi
std/math/atan2.zig+3-3
...@@ -22,7 +22,7 @@ const std = @import("../index.zig");...@@ -22,7 +22,7 @@ const std = @import("../index.zig");
22const math = std.math;22const math = std.math;
23const assert = std.debug.assert;23const assert = std.debug.assert;
2424
25fn atan2(comptime T: type, x: T, y: T) -> T {25fn atan2(comptime T: type, x: T, y: T) T {
26 return switch (T) {26 return switch (T) {
27 f32 => atan2_32(x, y),27 f32 => atan2_32(x, y),
28 f64 => atan2_64(x, y),28 f64 => atan2_64(x, y),
...@@ -30,7 +30,7 @@ fn atan2(comptime T: type, x: T, y: T) -> T {...@@ -30,7 +30,7 @@ fn atan2(comptime T: type, x: T, y: T) -> T {
30 };30 };
31}31}
3232
33fn atan2_32(y: f32, x: f32) -> f32 {33fn atan2_32(y: f32, x: f32) f32 {
34 const pi: f32 = 3.1415927410e+00;34 const pi: f32 = 3.1415927410e+00;
35 const pi_lo: f32 = -8.7422776573e-08;35 const pi_lo: f32 = -8.7422776573e-08;
3636
...@@ -115,7 +115,7 @@ fn atan2_32(y: f32, x: f32) -> f32 {...@@ -115,7 +115,7 @@ fn atan2_32(y: f32, x: f32) -> f32 {
115 }115 }
116}116}
117117
118fn atan2_64(y: f64, x: f64) -> f64 {118fn atan2_64(y: f64, x: f64) f64 {
119 const pi: f64 = 3.1415926535897931160E+00;119 const pi: f64 = 3.1415926535897931160E+00;
120 const pi_lo: f64 = 1.2246467991473531772E-16;120 const pi_lo: f64 = 1.2246467991473531772E-16;
121121
std/math/atanh.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn atanh(x: var) -> @typeOf(x) {11pub fn atanh(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => atanh_32(x),14 f32 => atanh_32(x),
...@@ -18,7 +18,7 @@ pub fn atanh(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn atanh(x: var) -> @typeOf(x) {
18}18}
1919
20// atanh(x) = log((1 + x) / (1 - x)) / 2 = log1p(2x / (1 - x)) / 2 ~= x + x^3 / 3 + o(x^5)20// atanh(x) = log((1 + x) / (1 - x)) / 2 = log1p(2x / (1 - x)) / 2 ~= x + x^3 / 3 + o(x^5)
21fn atanh_32(x: f32) -> f32 {21fn atanh_32(x: f32) f32 {
22 const u = @bitCast(u32, x);22 const u = @bitCast(u32, x);
23 const i = u & 0x7FFFFFFF;23 const i = u & 0x7FFFFFFF;
24 const s = u >> 31;24 const s = u >> 31;
...@@ -47,7 +47,7 @@ fn atanh_32(x: f32) -> f32 {...@@ -47,7 +47,7 @@ fn atanh_32(x: f32) -> f32 {
47 return if (s != 0) -y else y;47 return if (s != 0) -y else y;
48}48}
4949
50fn atanh_64(x: f64) -> f64 {50fn atanh_64(x: f64) f64 {
51 const u = @bitCast(u64, x);51 const u = @bitCast(u64, x);
52 const e = (u >> 52) & 0x7FF;52 const e = (u >> 52) & 0x7FF;
53 const s = u >> 63;53 const s = u >> 63;
std/math/cbrt.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn cbrt(x: var) -> @typeOf(x) {11pub fn cbrt(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => cbrt32(x),14 f32 => cbrt32(x),
...@@ -17,7 +17,7 @@ pub fn cbrt(x: var) -> @typeOf(x) {...@@ -17,7 +17,7 @@ pub fn cbrt(x: var) -> @typeOf(x) {
17 };17 };
18}18}
1919
20fn cbrt32(x: f32) -> f32 {20fn cbrt32(x: f32) f32 {
21 const B1: u32 = 709958130; // (127 - 127.0 / 3 - 0.03306235651) * 2^2321 const B1: u32 = 709958130; // (127 - 127.0 / 3 - 0.03306235651) * 2^23
22 const B2: u32 = 642849266; // (127 - 127.0 / 3 - 24 / 3 - 0.03306235651) * 2^2322 const B2: u32 = 642849266; // (127 - 127.0 / 3 - 24 / 3 - 0.03306235651) * 2^23
2323
...@@ -57,7 +57,7 @@ fn cbrt32(x: f32) -> f32 {...@@ -57,7 +57,7 @@ fn cbrt32(x: f32) -> f32 {
57 return f32(t);57 return f32(t);
58}58}
5959
60fn cbrt64(x: f64) -> f64 {60fn cbrt64(x: f64) f64 {
61 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^2061 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
62 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^2062 const B2: u32 = 696219795; // (1023 - 1023 / 3 - 54 / 3 - 0.03306235651 * 2^20
6363
std/math/ceil.zig+3-3
...@@ -9,7 +9,7 @@ const std = @import("../index.zig");...@@ -9,7 +9,7 @@ const std = @import("../index.zig");
9const math = std.math;9const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
1111
12pub fn ceil(x: var) -> @typeOf(x) {12pub fn ceil(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => ceil32(x),15 f32 => ceil32(x),
...@@ -18,7 +18,7 @@ pub fn ceil(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn ceil(x: var) -> @typeOf(x) {
18 };18 };
19}19}
2020
21fn ceil32(x: f32) -> f32 {21fn ceil32(x: f32) f32 {
22 var u = @bitCast(u32, x);22 var u = @bitCast(u32, x);
23 var e = i32((u >> 23) & 0xFF) - 0x7F;23 var e = i32((u >> 23) & 0xFF) - 0x7F;
24 var m: u32 = undefined;24 var m: u32 = undefined;
...@@ -51,7 +51,7 @@ fn ceil32(x: f32) -> f32 {...@@ -51,7 +51,7 @@ fn ceil32(x: f32) -> f32 {
51 }51 }
52}52}
5353
54fn ceil64(x: f64) -> f64 {54fn ceil64(x: f64) f64 {
55 const u = @bitCast(u64, x);55 const u = @bitCast(u64, x);
56 const e = (u >> 52) & 0x7FF;56 const e = (u >> 52) & 0x7FF;
57 var y: f64 = undefined;57 var y: f64 = undefined;
std/math/copysign.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn copysign(comptime T: type, x: T, y: T) -> T {5pub fn copysign(comptime T: type, x: T, y: T) T {
6 return switch (T) {6 return switch (T) {
7 f32 => copysign32(x, y),7 f32 => copysign32(x, y),
8 f64 => copysign64(x, y),8 f64 => copysign64(x, y),
...@@ -10,7 +10,7 @@ pub fn copysign(comptime T: type, x: T, y: T) -> T {...@@ -10,7 +10,7 @@ pub fn copysign(comptime T: type, x: T, y: T) -> T {
10 };10 };
11}11}
1212
13fn copysign32(x: f32, y: f32) -> f32 {13fn copysign32(x: f32, y: f32) f32 {
14 const ux = @bitCast(u32, x);14 const ux = @bitCast(u32, x);
15 const uy = @bitCast(u32, y);15 const uy = @bitCast(u32, y);
1616
...@@ -19,7 +19,7 @@ fn copysign32(x: f32, y: f32) -> f32 {...@@ -19,7 +19,7 @@ fn copysign32(x: f32, y: f32) -> f32 {
19 return @bitCast(f32, h1 | h2);19 return @bitCast(f32, h1 | h2);
20}20}
2121
22fn copysign64(x: f64, y: f64) -> f64 {22fn copysign64(x: f64, y: f64) f64 {
23 const ux = @bitCast(u64, x);23 const ux = @bitCast(u64, x);
24 const uy = @bitCast(u64, y);24 const uy = @bitCast(u64, y);
2525
std/math/cos.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn cos(x: var) -> @typeOf(x) {11pub fn cos(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => cos32(x),14 f32 => cos32(x),
...@@ -36,7 +36,7 @@ const C5 = 4.16666666666665929218E-2;...@@ -36,7 +36,7 @@ const C5 = 4.16666666666665929218E-2;
36// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.36// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
37//37//
38// This may have slight differences on some edge cases and may need to replaced if so.38// This may have slight differences on some edge cases and may need to replaced if so.
39fn cos32(x_: f32) -> f32 {39fn cos32(x_: f32) f32 {
40 @setFloatMode(this, @import("builtin").FloatMode.Strict);40 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4141
42 const pi4a = 7.85398125648498535156e-1;42 const pi4a = 7.85398125648498535156e-1;
...@@ -89,7 +89,7 @@ fn cos32(x_: f32) -> f32 {...@@ -89,7 +89,7 @@ fn cos32(x_: f32) -> f32 {
89 }89 }
90}90}
9191
92fn cos64(x_: f64) -> f64 {92fn cos64(x_: f64) f64 {
93 const pi4a = 7.85398125648498535156e-1;93 const pi4a = 7.85398125648498535156e-1;
94 const pi4b = 3.77489470793079817668E-8;94 const pi4b = 3.77489470793079817668E-8;
95 const pi4c = 2.69515142907905952645E-15;95 const pi4c = 2.69515142907905952645E-15;
std/math/cosh.zig+3-3
...@@ -10,7 +10,7 @@ const math = std.math;...@@ -10,7 +10,7 @@ const math = std.math;
10const expo2 = @import("expo2.zig").expo2;10const expo2 = @import("expo2.zig").expo2;
11const assert = std.debug.assert;11const assert = std.debug.assert;
1212
13pub fn cosh(x: var) -> @typeOf(x) {13pub fn cosh(x: var) @typeOf(x) {
14 const T = @typeOf(x);14 const T = @typeOf(x);
15 return switch (T) {15 return switch (T) {
16 f32 => cosh32(x),16 f32 => cosh32(x),
...@@ -22,7 +22,7 @@ pub fn cosh(x: var) -> @typeOf(x) {...@@ -22,7 +22,7 @@ pub fn cosh(x: var) -> @typeOf(x) {
22// cosh(x) = (exp(x) + 1 / exp(x)) / 222// cosh(x) = (exp(x) + 1 / exp(x)) / 2
23// = 1 + 0.5 * (exp(x) - 1) * (exp(x) - 1) / exp(x)23// = 1 + 0.5 * (exp(x) - 1) * (exp(x) - 1) / exp(x)
24// = 1 + (x * x) / 2 + o(x^4)24// = 1 + (x * x) / 2 + o(x^4)
25fn cosh32(x: f32) -> f32 {25fn cosh32(x: f32) f32 {
26 const u = @bitCast(u32, x);26 const u = @bitCast(u32, x);
27 const ux = u & 0x7FFFFFFF;27 const ux = u & 0x7FFFFFFF;
28 const ax = @bitCast(f32, ux);28 const ax = @bitCast(f32, ux);
...@@ -47,7 +47,7 @@ fn cosh32(x: f32) -> f32 {...@@ -47,7 +47,7 @@ fn cosh32(x: f32) -> f32 {
47 return expo2(ax);47 return expo2(ax);
48}48}
4949
50fn cosh64(x: f64) -> f64 {50fn cosh64(x: f64) f64 {
51 const u = @bitCast(u64, x);51 const u = @bitCast(u64, x);
52 const w = u32(u >> 32);52 const w = u32(u >> 32);
53 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));53 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
std/math/exp.zig+3-3
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10pub fn exp(x: var) -> @typeOf(x) {10pub fn exp(x: var) @typeOf(x) {
11 const T = @typeOf(x);11 const T = @typeOf(x);
12 return switch (T) {12 return switch (T) {
13 f32 => exp32(x),13 f32 => exp32(x),
...@@ -16,7 +16,7 @@ pub fn exp(x: var) -> @typeOf(x) {...@@ -16,7 +16,7 @@ pub fn exp(x: var) -> @typeOf(x) {
16 };16 };
17}17}
1818
19fn exp32(x_: f32) -> f32 {19fn exp32(x_: f32) f32 {
20 const half = []f32 { 0.5, -0.5 };20 const half = []f32 { 0.5, -0.5 };
21 const ln2hi = 6.9314575195e-1;21 const ln2hi = 6.9314575195e-1;
22 const ln2lo = 1.4286067653e-6;22 const ln2lo = 1.4286067653e-6;
...@@ -93,7 +93,7 @@ fn exp32(x_: f32) -> f32 {...@@ -93,7 +93,7 @@ fn exp32(x_: f32) -> f32 {
93 }93 }
94}94}
9595
96fn exp64(x_: f64) -> f64 {96fn exp64(x_: f64) f64 {
97 const half = []const f64 { 0.5, -0.5 };97 const half = []const f64 { 0.5, -0.5 };
98 const ln2hi: f64 = 6.93147180369123816490e-01;98 const ln2hi: f64 = 6.93147180369123816490e-01;
99 const ln2lo: f64 = 1.90821492927058770002e-10;99 const ln2lo: f64 = 1.90821492927058770002e-10;
std/math/exp2.zig+3-3
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10pub fn exp2(x: var) -> @typeOf(x) {10pub fn exp2(x: var) @typeOf(x) {
11 const T = @typeOf(x);11 const T = @typeOf(x);
12 return switch (T) {12 return switch (T) {
13 f32 => exp2_32(x),13 f32 => exp2_32(x),
...@@ -35,7 +35,7 @@ const exp2ft = []const f64 {...@@ -35,7 +35,7 @@ const exp2ft = []const f64 {
35 0x1.5ab07dd485429p+0,35 0x1.5ab07dd485429p+0,
36};36};
3737
38fn exp2_32(x: f32) -> f32 {38fn exp2_32(x: f32) f32 {
39 @setFloatMode(this, @import("builtin").FloatMode.Strict);39 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4040
41 const tblsiz = u32(exp2ft.len);41 const tblsiz = u32(exp2ft.len);
...@@ -352,7 +352,7 @@ const exp2dt = []f64 {...@@ -352,7 +352,7 @@ const exp2dt = []f64 {
352 0x1.690f4b19e9471p+0, -0x1.9780p-45,352 0x1.690f4b19e9471p+0, -0x1.9780p-45,
353};353};
354354
355fn exp2_64(x: f64) -> f64 {355fn exp2_64(x: f64) f64 {
356 @setFloatMode(this, @import("builtin").FloatMode.Strict);356 @setFloatMode(this, @import("builtin").FloatMode.Strict);
357357
358 const tblsiz = u32(exp2dt.len / 2);358 const tblsiz = u32(exp2dt.len / 2);
std/math/expm1.zig+3-3
...@@ -9,7 +9,7 @@ const std = @import("../index.zig");...@@ -9,7 +9,7 @@ const std = @import("../index.zig");
9const math = std.math;9const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
1111
12pub fn expm1(x: var) -> @typeOf(x) {12pub fn expm1(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => expm1_32(x),15 f32 => expm1_32(x),
...@@ -18,7 +18,7 @@ pub fn expm1(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn expm1(x: var) -> @typeOf(x) {
18 };18 };
19}19}
2020
21fn expm1_32(x_: f32) -> f32 {21fn expm1_32(x_: f32) f32 {
22 @setFloatMode(this, builtin.FloatMode.Strict);22 @setFloatMode(this, builtin.FloatMode.Strict);
23 const o_threshold: f32 = 8.8721679688e+01;23 const o_threshold: f32 = 8.8721679688e+01;
24 const ln2_hi: f32 = 6.9313812256e-01;24 const ln2_hi: f32 = 6.9313812256e-01;
...@@ -145,7 +145,7 @@ fn expm1_32(x_: f32) -> f32 {...@@ -145,7 +145,7 @@ fn expm1_32(x_: f32) -> f32 {
145 }145 }
146}146}
147147
148fn expm1_64(x_: f64) -> f64 {148fn expm1_64(x_: f64) f64 {
149 @setFloatMode(this, builtin.FloatMode.Strict);149 @setFloatMode(this, builtin.FloatMode.Strict);
150 const o_threshold: f64 = 7.09782712893383973096e+02;150 const o_threshold: f64 = 7.09782712893383973096e+02;
151 const ln2_hi: f64 = 6.93147180369123816490e-01;151 const ln2_hi: f64 = 6.93147180369123816490e-01;
std/math/expo2.zig+3-3
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const math = @import("index.zig");1const math = @import("index.zig");
22
3pub fn expo2(x: var) -> @typeOf(x) {3pub fn expo2(x: var) @typeOf(x) {
4 const T = @typeOf(x);4 const T = @typeOf(x);
5 return switch (T) {5 return switch (T) {
6 f32 => expo2f(x),6 f32 => expo2f(x),
...@@ -9,7 +9,7 @@ pub fn expo2(x: var) -> @typeOf(x) {...@@ -9,7 +9,7 @@ pub fn expo2(x: var) -> @typeOf(x) {
9 };9 };
10}10}
1111
12fn expo2f(x: f32) -> f32 {12fn expo2f(x: f32) f32 {
13 const k: u32 = 235;13 const k: u32 = 235;
14 const kln2 = 0x1.45C778p+7;14 const kln2 = 0x1.45C778p+7;
1515
...@@ -18,7 +18,7 @@ fn expo2f(x: f32) -> f32 {...@@ -18,7 +18,7 @@ fn expo2f(x: f32) -> f32 {
18 return math.exp(x - kln2) * scale * scale;18 return math.exp(x - kln2) * scale * scale;
19}19}
2020
21fn expo2d(x: f64) -> f64 {21fn expo2d(x: f64) f64 {
22 const k: u32 = 2043;22 const k: u32 = 2043;
23 const kln2 = 0x1.62066151ADD8BP+10;23 const kln2 = 0x1.62066151ADD8BP+10;
2424
std/math/fabs.zig+3-3
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10pub fn fabs(x: var) -> @typeOf(x) {10pub fn fabs(x: var) @typeOf(x) {
11 const T = @typeOf(x);11 const T = @typeOf(x);
12 return switch (T) {12 return switch (T) {
13 f32 => fabs32(x),13 f32 => fabs32(x),
...@@ -16,13 +16,13 @@ pub fn fabs(x: var) -> @typeOf(x) {...@@ -16,13 +16,13 @@ pub fn fabs(x: var) -> @typeOf(x) {
16 };16 };
17}17}
1818
19fn fabs32(x: f32) -> f32 {19fn fabs32(x: f32) f32 {
20 var u = @bitCast(u32, x);20 var u = @bitCast(u32, x);
21 u &= 0x7FFFFFFF;21 u &= 0x7FFFFFFF;
22 return @bitCast(f32, u);22 return @bitCast(f32, u);
23}23}
2424
25fn fabs64(x: f64) -> f64 {25fn fabs64(x: f64) f64 {
26 var u = @bitCast(u64, x);26 var u = @bitCast(u64, x);
27 u &= @maxValue(u64) >> 1;27 u &= @maxValue(u64) >> 1;
28 return @bitCast(f64, u);28 return @bitCast(f64, u);
std/math/floor.zig+3-3
...@@ -9,7 +9,7 @@ const assert = std.debug.assert;...@@ -9,7 +9,7 @@ const assert = std.debug.assert;
9const std = @import("../index.zig");9const std = @import("../index.zig");
10const math = std.math;10const math = std.math;
1111
12pub fn floor(x: var) -> @typeOf(x) {12pub fn floor(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => floor32(x),15 f32 => floor32(x),
...@@ -18,7 +18,7 @@ pub fn floor(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn floor(x: var) -> @typeOf(x) {
18 };18 };
19}19}
2020
21fn floor32(x: f32) -> f32 {21fn floor32(x: f32) f32 {
22 var u = @bitCast(u32, x);22 var u = @bitCast(u32, x);
23 const e = i32((u >> 23) & 0xFF) - 0x7F;23 const e = i32((u >> 23) & 0xFF) - 0x7F;
24 var m: u32 = undefined;24 var m: u32 = undefined;
...@@ -52,7 +52,7 @@ fn floor32(x: f32) -> f32 {...@@ -52,7 +52,7 @@ fn floor32(x: f32) -> f32 {
52 }52 }
53}53}
5454
55fn floor64(x: f64) -> f64 {55fn floor64(x: f64) f64 {
56 const u = @bitCast(u64, x);56 const u = @bitCast(u64, x);
57 const e = (u >> 52) & 0x7FF;57 const e = (u >> 52) & 0x7FF;
58 var y: f64 = undefined;58 var y: f64 = undefined;
std/math/fma.zig+7-7
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {5pub fn fma(comptime T: type, x: T, y: T, z: T) T {
6 return switch (T) {6 return switch (T) {
7 f32 => fma32(x, y, z),7 f32 => fma32(x, y, z),
8 f64 => fma64(x, y ,z),8 f64 => fma64(x, y ,z),
...@@ -10,7 +10,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {...@@ -10,7 +10,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
10 };10 };
11}11}
1212
13fn fma32(x: f32, y: f32, z: f32) -> f32 {13fn fma32(x: f32, y: f32, z: f32) f32 {
14 const xy = f64(x) * y;14 const xy = f64(x) * y;
15 const xy_z = xy + z;15 const xy_z = xy + z;
16 const u = @bitCast(u64, xy_z);16 const u = @bitCast(u64, xy_z);
...@@ -24,7 +24,7 @@ fn fma32(x: f32, y: f32, z: f32) -> f32 {...@@ -24,7 +24,7 @@ fn fma32(x: f32, y: f32, z: f32) -> f32 {
24 }24 }
25}25}
2626
27fn fma64(x: f64, y: f64, z: f64) -> f64 {27fn fma64(x: f64, y: f64, z: f64) f64 {
28 if (!math.isFinite(x) or !math.isFinite(y)) {28 if (!math.isFinite(x) or !math.isFinite(y)) {
29 return x * y + z;29 return x * y + z;
30 }30 }
...@@ -73,7 +73,7 @@ fn fma64(x: f64, y: f64, z: f64) -> f64 {...@@ -73,7 +73,7 @@ fn fma64(x: f64, y: f64, z: f64) -> f64 {
7373
74const dd = struct { hi: f64, lo: f64, };74const dd = struct { hi: f64, lo: f64, };
7575
76fn dd_add(a: f64, b: f64) -> dd {76fn dd_add(a: f64, b: f64) dd {
77 var ret: dd = undefined;77 var ret: dd = undefined;
78 ret.hi = a + b;78 ret.hi = a + b;
79 const s = ret.hi - a;79 const s = ret.hi - a;
...@@ -81,7 +81,7 @@ fn dd_add(a: f64, b: f64) -> dd {...@@ -81,7 +81,7 @@ fn dd_add(a: f64, b: f64) -> dd {
81 return ret;81 return ret;
82}82}
8383
84fn dd_mul(a: f64, b: f64) -> dd {84fn dd_mul(a: f64, b: f64) dd {
85 var ret: dd = undefined;85 var ret: dd = undefined;
86 const split: f64 = 0x1.0p27 + 1.0;86 const split: f64 = 0x1.0p27 + 1.0;
8787
...@@ -103,7 +103,7 @@ fn dd_mul(a: f64, b: f64) -> dd {...@@ -103,7 +103,7 @@ fn dd_mul(a: f64, b: f64) -> dd {
103 return ret;103 return ret;
104}104}
105105
106fn add_adjusted(a: f64, b: f64) -> f64 {106fn add_adjusted(a: f64, b: f64) f64 {
107 var sum = dd_add(a, b);107 var sum = dd_add(a, b);
108 if (sum.lo != 0) {108 if (sum.lo != 0) {
109 var uhii = @bitCast(u64, sum.hi);109 var uhii = @bitCast(u64, sum.hi);
...@@ -117,7 +117,7 @@ fn add_adjusted(a: f64, b: f64) -> f64 {...@@ -117,7 +117,7 @@ fn add_adjusted(a: f64, b: f64) -> f64 {
117 return sum.hi;117 return sum.hi;
118}118}
119119
120fn add_and_denorm(a: f64, b: f64, scale: i32) -> f64 {120fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
121 var sum = dd_add(a, b);121 var sum = dd_add(a, b);
122 if (sum.lo != 0) {122 if (sum.lo != 0) {
123 var uhii = @bitCast(u64, sum.hi);123 var uhii = @bitCast(u64, sum.hi);
std/math/frexp.zig+4-4
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11fn frexp_result(comptime T: type) -> type {11fn frexp_result(comptime T: type) type {
12 return struct {12 return struct {
13 significand: T,13 significand: T,
14 exponent: i32,14 exponent: i32,
...@@ -17,7 +17,7 @@ fn frexp_result(comptime T: type) -> type {...@@ -17,7 +17,7 @@ fn frexp_result(comptime T: type) -> type {
17pub const frexp32_result = frexp_result(f32);17pub const frexp32_result = frexp_result(f32);
18pub const frexp64_result = frexp_result(f64);18pub const frexp64_result = frexp_result(f64);
1919
20pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {20pub fn frexp(x: var) frexp_result(@typeOf(x)) {
21 const T = @typeOf(x);21 const T = @typeOf(x);
22 return switch (T) {22 return switch (T) {
23 f32 => frexp32(x),23 f32 => frexp32(x),
...@@ -26,7 +26,7 @@ pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {...@@ -26,7 +26,7 @@ pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {
26 };26 };
27}27}
2828
29fn frexp32(x: f32) -> frexp32_result {29fn frexp32(x: f32) frexp32_result {
30 var result: frexp32_result = undefined;30 var result: frexp32_result = undefined;
3131
32 var y = @bitCast(u32, x);32 var y = @bitCast(u32, x);
...@@ -63,7 +63,7 @@ fn frexp32(x: f32) -> frexp32_result {...@@ -63,7 +63,7 @@ fn frexp32(x: f32) -> frexp32_result {
63 return result;63 return result;
64}64}
6565
66fn frexp64(x: f64) -> frexp64_result {66fn frexp64(x: f64) frexp64_result {
67 var result: frexp64_result = undefined;67 var result: frexp64_result = undefined;
6868
69 var y = @bitCast(u64, x);69 var y = @bitCast(u64, x);
std/math/hypot.zig+4-4
...@@ -9,7 +9,7 @@ const std = @import("../index.zig");...@@ -9,7 +9,7 @@ const std = @import("../index.zig");
9const math = std.math;9const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
1111
12pub fn hypot(comptime T: type, x: T, y: T) -> T {12pub fn hypot(comptime T: type, x: T, y: T) T {
13 return switch (T) {13 return switch (T) {
14 f32 => hypot32(x, y),14 f32 => hypot32(x, y),
15 f64 => hypot64(x, y),15 f64 => hypot64(x, y),
...@@ -17,7 +17,7 @@ pub fn hypot(comptime T: type, x: T, y: T) -> T {...@@ -17,7 +17,7 @@ pub fn hypot(comptime T: type, x: T, y: T) -> T {
17 };17 };
18}18}
1919
20fn hypot32(x: f32, y: f32) -> f32 {20fn hypot32(x: f32, y: f32) f32 {
21 var ux = @bitCast(u32, x);21 var ux = @bitCast(u32, x);
22 var uy = @bitCast(u32, y);22 var uy = @bitCast(u32, y);
2323
...@@ -52,7 +52,7 @@ fn hypot32(x: f32, y: f32) -> f32 {...@@ -52,7 +52,7 @@ fn hypot32(x: f32, y: f32) -> f32 {
52 return z * math.sqrt(f32(f64(x) * x + f64(y) * y));52 return z * math.sqrt(f32(f64(x) * x + f64(y) * y));
53}53}
5454
55fn sq(hi: &f64, lo: &f64, x: f64) {55fn sq(hi: &f64, lo: &f64, x: f64) void {
56 const split: f64 = 0x1.0p27 + 1.0;56 const split: f64 = 0x1.0p27 + 1.0;
57 const xc = x * split;57 const xc = x * split;
58 const xh = x - xc + xc;58 const xh = x - xc + xc;
...@@ -61,7 +61,7 @@ fn sq(hi: &f64, lo: &f64, x: f64) {...@@ -61,7 +61,7 @@ fn sq(hi: &f64, lo: &f64, x: f64) {
61 *lo = xh * xh - *hi + 2 * xh * xl + xl * xl;61 *lo = xh * xh - *hi + 2 * xh * xl + xl * xl;
62}62}
6363
64fn hypot64(x: f64, y: f64) -> f64 {64fn hypot64(x: f64, y: f64) f64 {
65 var ux = @bitCast(u64, x);65 var ux = @bitCast(u64, x);
66 var uy = @bitCast(u64, y);66 var uy = @bitCast(u64, y);
6767
std/math/ilogb.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn ilogb(x: var) -> i32 {11pub fn ilogb(x: var) i32 {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => ilogb32(x),14 f32 => ilogb32(x),
...@@ -21,7 +21,7 @@ pub fn ilogb(x: var) -> i32 {...@@ -21,7 +21,7 @@ pub fn ilogb(x: var) -> i32 {
21const fp_ilogbnan = -1 - i32(@maxValue(u32) >> 1);21const fp_ilogbnan = -1 - i32(@maxValue(u32) >> 1);
22const fp_ilogb0 = fp_ilogbnan;22const fp_ilogb0 = fp_ilogbnan;
2323
24fn ilogb32(x: f32) -> i32 {24fn ilogb32(x: f32) i32 {
25 var u = @bitCast(u32, x);25 var u = @bitCast(u32, x);
26 var e = i32((u >> 23) & 0xFF);26 var e = i32((u >> 23) & 0xFF);
2727
...@@ -57,7 +57,7 @@ fn ilogb32(x: f32) -> i32 {...@@ -57,7 +57,7 @@ fn ilogb32(x: f32) -> i32 {
57 return e - 0x7F;57 return e - 0x7F;
58}58}
5959
60fn ilogb64(x: f64) -> i32 {60fn ilogb64(x: f64) i32 {
61 var u = @bitCast(u64, x);61 var u = @bitCast(u64, x);
62 var e = i32((u >> 52) & 0x7FF);62 var e = i32((u >> 52) & 0x7FF);
6363
std/math/index.zig+43-43
...@@ -35,13 +35,13 @@ pub const nan = @import("nan.zig").nan;...@@ -35,13 +35,13 @@ pub const nan = @import("nan.zig").nan;
35pub const snan = @import("nan.zig").snan;35pub const snan = @import("nan.zig").snan;
36pub const inf = @import("inf.zig").inf;36pub const inf = @import("inf.zig").inf;
3737
38pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) -> bool {38pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool {
39 assert(@typeId(T) == TypeId.Float);39 assert(@typeId(T) == TypeId.Float);
40 return fabs(x - y) < epsilon;40 return fabs(x - y) < epsilon;
41}41}
4242
43// TODO: Hide the following in an internal module.43// TODO: Hide the following in an internal module.
44pub fn forceEval(value: var) {44pub fn forceEval(value: var) void {
45 const T = @typeOf(value);45 const T = @typeOf(value);
46 switch (T) {46 switch (T) {
47 f32 => {47 f32 => {
...@@ -60,23 +60,23 @@ pub fn forceEval(value: var) {...@@ -60,23 +60,23 @@ pub fn forceEval(value: var) {
60 }60 }
61}61}
6262
63pub fn raiseInvalid() {63pub fn raiseInvalid() void {
64 // Raise INVALID fpu exception64 // Raise INVALID fpu exception
65}65}
6666
67pub fn raiseUnderflow() {67pub fn raiseUnderflow() void {
68 // Raise UNDERFLOW fpu exception68 // Raise UNDERFLOW fpu exception
69}69}
7070
71pub fn raiseOverflow() {71pub fn raiseOverflow() void {
72 // Raise OVERFLOW fpu exception72 // Raise OVERFLOW fpu exception
73}73}
7474
75pub fn raiseInexact() {75pub fn raiseInexact() void {
76 // Raise INEXACT fpu exception76 // Raise INEXACT fpu exception
77}77}
7878
79pub fn raiseDivByZero() {79pub fn raiseDivByZero() void {
80 // Raise INEXACT fpu exception80 // Raise INEXACT fpu exception
81}81}
8282
...@@ -175,7 +175,7 @@ test "math" {...@@ -175,7 +175,7 @@ test "math" {
175}175}
176176
177177
178pub fn min(x: var, y: var) -> @typeOf(x + y) {178pub fn min(x: var, y: var) @typeOf(x + y) {
179 return if (x < y) x else y;179 return if (x < y) x else y;
180}180}
181181
...@@ -183,7 +183,7 @@ test "math.min" {...@@ -183,7 +183,7 @@ test "math.min" {
183 assert(min(i32(-1), i32(2)) == -1);183 assert(min(i32(-1), i32(2)) == -1);
184}184}
185185
186pub fn max(x: var, y: var) -> @typeOf(x + y) {186pub fn max(x: var, y: var) @typeOf(x + y) {
187 return if (x > y) x else y;187 return if (x > y) x else y;
188}188}
189189
...@@ -192,36 +192,36 @@ test "math.max" {...@@ -192,36 +192,36 @@ test "math.max" {
192}192}
193193
194error Overflow;194error Overflow;
195pub fn mul(comptime T: type, a: T, b: T) -> %T {195pub fn mul(comptime T: type, a: T, b: T) %T {
196 var answer: T = undefined;196 var answer: T = undefined;
197 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;197 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
198}198}
199199
200error Overflow;200error Overflow;
201pub fn add(comptime T: type, a: T, b: T) -> %T {201pub fn add(comptime T: type, a: T, b: T) %T {
202 var answer: T = undefined;202 var answer: T = undefined;
203 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;203 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
204}204}
205205
206error Overflow;206error Overflow;
207pub fn sub(comptime T: type, a: T, b: T) -> %T {207pub fn sub(comptime T: type, a: T, b: T) %T {
208 var answer: T = undefined;208 var answer: T = undefined;
209 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;209 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
210}210}
211211
212pub fn negate(x: var) -> %@typeOf(x) {212pub fn negate(x: var) %@typeOf(x) {
213 return sub(@typeOf(x), 0, x);213 return sub(@typeOf(x), 0, x);
214}214}
215215
216error Overflow;216error Overflow;
217pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) -> %T {217pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) %T {
218 var answer: T = undefined;218 var answer: T = undefined;
219 return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;219 return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
220}220}
221221
222/// Shifts left. Overflowed bits are truncated.222/// Shifts left. Overflowed bits are truncated.
223/// A negative shift amount results in a right shift.223/// A negative shift amount results in a right shift.
224pub fn shl(comptime T: type, a: T, shift_amt: var) -> T {224pub fn shl(comptime T: type, a: T, shift_amt: var) T {
225 const abs_shift_amt = absCast(shift_amt);225 const abs_shift_amt = absCast(shift_amt);
226 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);226 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
227227
...@@ -245,7 +245,7 @@ test "math.shl" {...@@ -245,7 +245,7 @@ test "math.shl" {
245245
246/// Shifts right. Overflowed bits are truncated.246/// Shifts right. Overflowed bits are truncated.
247/// A negative shift amount results in a lefft shift.247/// A negative shift amount results in a lefft shift.
248pub fn shr(comptime T: type, a: T, shift_amt: var) -> T {248pub fn shr(comptime T: type, a: T, shift_amt: var) T {
249 const abs_shift_amt = absCast(shift_amt);249 const abs_shift_amt = absCast(shift_amt);
250 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);250 const casted_shift_amt = if (abs_shift_amt >= T.bit_count) return 0 else Log2Int(T)(abs_shift_amt);
251251
...@@ -269,7 +269,7 @@ test "math.shr" {...@@ -269,7 +269,7 @@ test "math.shr" {
269269
270/// Rotates right. Only unsigned values can be rotated.270/// Rotates right. Only unsigned values can be rotated.
271/// Negative shift values results in shift modulo the bit count.271/// Negative shift values results in shift modulo the bit count.
272pub fn rotr(comptime T: type, x: T, r: var) -> T {272pub fn rotr(comptime T: type, x: T, r: var) T {
273 if (T.is_signed) {273 if (T.is_signed) {
274 @compileError("cannot rotate signed integer");274 @compileError("cannot rotate signed integer");
275 } else {275 } else {
...@@ -288,7 +288,7 @@ test "math.rotr" {...@@ -288,7 +288,7 @@ test "math.rotr" {
288288
289/// Rotates left. Only unsigned values can be rotated.289/// Rotates left. Only unsigned values can be rotated.
290/// Negative shift values results in shift modulo the bit count.290/// Negative shift values results in shift modulo the bit count.
291pub fn rotl(comptime T: type, x: T, r: var) -> T {291pub fn rotl(comptime T: type, x: T, r: var) T {
292 if (T.is_signed) {292 if (T.is_signed) {
293 @compileError("cannot rotate signed integer");293 @compileError("cannot rotate signed integer");
294 } else {294 } else {
...@@ -306,7 +306,7 @@ test "math.rotl" {...@@ -306,7 +306,7 @@ test "math.rotl" {
306}306}
307307
308308
309pub fn Log2Int(comptime T: type) -> type {309pub fn Log2Int(comptime T: type) type {
310 return @IntType(false, log2(T.bit_count));310 return @IntType(false, log2(T.bit_count));
311}311}
312312
...@@ -315,7 +315,7 @@ test "math overflow functions" {...@@ -315,7 +315,7 @@ test "math overflow functions" {
315 comptime testOverflow();315 comptime testOverflow();
316}316}
317317
318fn testOverflow() {318fn testOverflow() void {
319 assert((mul(i32, 3, 4) catch unreachable) == 12);319 assert((mul(i32, 3, 4) catch unreachable) == 12);
320 assert((add(i32, 3, 4) catch unreachable) == 7);320 assert((add(i32, 3, 4) catch unreachable) == 7);
321 assert((sub(i32, 3, 4) catch unreachable) == -1);321 assert((sub(i32, 3, 4) catch unreachable) == -1);
...@@ -324,14 +324,14 @@ fn testOverflow() {...@@ -324,14 +324,14 @@ fn testOverflow() {
324324
325325
326error Overflow;326error Overflow;
327pub fn absInt(x: var) -> %@typeOf(x) {327pub fn absInt(x: var) %@typeOf(x) {
328 const T = @typeOf(x);328 const T = @typeOf(x);
329 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt329 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
330 comptime assert(T.is_signed); // must pass a signed integer to absInt330 comptime assert(T.is_signed); // must pass a signed integer to absInt
331 if (x == @minValue(@typeOf(x)))331 if (x == @minValue(@typeOf(x)))
332 return error.Overflow;332 return error.Overflow;
333 {333 {
334 @setDebugSafety(this, false);334 @setRuntimeSafety(false);
335 return if (x < 0) -x else x;335 return if (x < 0) -x else x;
336 }336 }
337}337}
...@@ -340,7 +340,7 @@ test "math.absInt" {...@@ -340,7 +340,7 @@ test "math.absInt" {
340 testAbsInt();340 testAbsInt();
341 comptime testAbsInt();341 comptime testAbsInt();
342}342}
343fn testAbsInt() {343fn testAbsInt() void {
344 assert((absInt(i32(-10)) catch unreachable) == 10);344 assert((absInt(i32(-10)) catch unreachable) == 10);
345 assert((absInt(i32(10)) catch unreachable) == 10);345 assert((absInt(i32(10)) catch unreachable) == 10);
346}346}
...@@ -349,8 +349,8 @@ pub const absFloat = @import("fabs.zig").fabs;...@@ -349,8 +349,8 @@ pub const absFloat = @import("fabs.zig").fabs;
349349
350error DivisionByZero;350error DivisionByZero;
351error Overflow;351error Overflow;
352pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {352pub fn divTrunc(comptime T: type, numerator: T, denominator: T) %T {
353 @setDebugSafety(this, false);353 @setRuntimeSafety(false);
354 if (denominator == 0)354 if (denominator == 0)
355 return error.DivisionByZero;355 return error.DivisionByZero;
356 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)356 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
...@@ -362,7 +362,7 @@ test "math.divTrunc" {...@@ -362,7 +362,7 @@ test "math.divTrunc" {
362 testDivTrunc();362 testDivTrunc();
363 comptime testDivTrunc();363 comptime testDivTrunc();
364}364}
365fn testDivTrunc() {365fn testDivTrunc() void {
366 assert((divTrunc(i32, 5, 3) catch unreachable) == 1);366 assert((divTrunc(i32, 5, 3) catch unreachable) == 1);
367 assert((divTrunc(i32, -5, 3) catch unreachable) == -1);367 assert((divTrunc(i32, -5, 3) catch unreachable) == -1);
368 if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);368 if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
...@@ -374,8 +374,8 @@ fn testDivTrunc() {...@@ -374,8 +374,8 @@ fn testDivTrunc() {
374374
375error DivisionByZero;375error DivisionByZero;
376error Overflow;376error Overflow;
377pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {377pub fn divFloor(comptime T: type, numerator: T, denominator: T) %T {
378 @setDebugSafety(this, false);378 @setRuntimeSafety(false);
379 if (denominator == 0)379 if (denominator == 0)
380 return error.DivisionByZero;380 return error.DivisionByZero;
381 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)381 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
...@@ -387,7 +387,7 @@ test "math.divFloor" {...@@ -387,7 +387,7 @@ test "math.divFloor" {
387 testDivFloor();387 testDivFloor();
388 comptime testDivFloor();388 comptime testDivFloor();
389}389}
390fn testDivFloor() {390fn testDivFloor() void {
391 assert((divFloor(i32, 5, 3) catch unreachable) == 1);391 assert((divFloor(i32, 5, 3) catch unreachable) == 1);
392 assert((divFloor(i32, -5, 3) catch unreachable) == -2);392 assert((divFloor(i32, -5, 3) catch unreachable) == -2);
393 if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);393 if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
...@@ -400,8 +400,8 @@ fn testDivFloor() {...@@ -400,8 +400,8 @@ fn testDivFloor() {
400error DivisionByZero;400error DivisionByZero;
401error Overflow;401error Overflow;
402error UnexpectedRemainder;402error UnexpectedRemainder;
403pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {403pub fn divExact(comptime T: type, numerator: T, denominator: T) %T {
404 @setDebugSafety(this, false);404 @setRuntimeSafety(false);
405 if (denominator == 0)405 if (denominator == 0)
406 return error.DivisionByZero;406 return error.DivisionByZero;
407 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)407 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
...@@ -416,7 +416,7 @@ test "math.divExact" {...@@ -416,7 +416,7 @@ test "math.divExact" {
416 testDivExact();416 testDivExact();
417 comptime testDivExact();417 comptime testDivExact();
418}418}
419fn testDivExact() {419fn testDivExact() void {
420 assert((divExact(i32, 10, 5) catch unreachable) == 2);420 assert((divExact(i32, 10, 5) catch unreachable) == 2);
421 assert((divExact(i32, -10, 5) catch unreachable) == -2);421 assert((divExact(i32, -10, 5) catch unreachable) == -2);
422 if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);422 if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
...@@ -430,8 +430,8 @@ fn testDivExact() {...@@ -430,8 +430,8 @@ fn testDivExact() {
430430
431error DivisionByZero;431error DivisionByZero;
432error NegativeDenominator;432error NegativeDenominator;
433pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {433pub fn mod(comptime T: type, numerator: T, denominator: T) %T {
434 @setDebugSafety(this, false);434 @setRuntimeSafety(false);
435 if (denominator == 0)435 if (denominator == 0)
436 return error.DivisionByZero;436 return error.DivisionByZero;
437 if (denominator < 0)437 if (denominator < 0)
...@@ -443,7 +443,7 @@ test "math.mod" {...@@ -443,7 +443,7 @@ test "math.mod" {
443 testMod();443 testMod();
444 comptime testMod();444 comptime testMod();
445}445}
446fn testMod() {446fn testMod() void {
447 assert((mod(i32, -5, 3) catch unreachable) == 1);447 assert((mod(i32, -5, 3) catch unreachable) == 1);
448 assert((mod(i32, 5, 3) catch unreachable) == 2);448 assert((mod(i32, 5, 3) catch unreachable) == 2);
449 if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);449 if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
...@@ -457,8 +457,8 @@ fn testMod() {...@@ -457,8 +457,8 @@ fn testMod() {
457457
458error DivisionByZero;458error DivisionByZero;
459error NegativeDenominator;459error NegativeDenominator;
460pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {460pub fn rem(comptime T: type, numerator: T, denominator: T) %T {
461 @setDebugSafety(this, false);461 @setRuntimeSafety(false);
462 if (denominator == 0)462 if (denominator == 0)
463 return error.DivisionByZero;463 return error.DivisionByZero;
464 if (denominator < 0)464 if (denominator < 0)
...@@ -470,7 +470,7 @@ test "math.rem" {...@@ -470,7 +470,7 @@ test "math.rem" {
470 testRem();470 testRem();
471 comptime testRem();471 comptime testRem();
472}472}
473fn testRem() {473fn testRem() void {
474 assert((rem(i32, -5, 3) catch unreachable) == -2);474 assert((rem(i32, -5, 3) catch unreachable) == -2);
475 assert((rem(i32, 5, 3) catch unreachable) == 2);475 assert((rem(i32, 5, 3) catch unreachable) == 2);
476 if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);476 if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
...@@ -484,7 +484,7 @@ fn testRem() {...@@ -484,7 +484,7 @@ fn testRem() {
484484
485/// Returns the absolute value of the integer parameter.485/// Returns the absolute value of the integer parameter.
486/// Result is an unsigned integer.486/// Result is an unsigned integer.
487pub fn absCast(x: var) -> @IntType(false, @typeOf(x).bit_count) {487pub fn absCast(x: var) @IntType(false, @typeOf(x).bit_count) {
488 const uint = @IntType(false, @typeOf(x).bit_count);488 const uint = @IntType(false, @typeOf(x).bit_count);
489 if (x >= 0)489 if (x >= 0)
490 return uint(x);490 return uint(x);
...@@ -506,7 +506,7 @@ test "math.absCast" {...@@ -506,7 +506,7 @@ test "math.absCast" {
506/// Returns the negation of the integer parameter.506/// Returns the negation of the integer parameter.
507/// Result is a signed integer.507/// Result is a signed integer.
508error Overflow;508error Overflow;
509pub fn negateCast(x: var) -> %@IntType(true, @typeOf(x).bit_count) {509pub fn negateCast(x: var) %@IntType(true, @typeOf(x).bit_count) {
510 if (@typeOf(x).is_signed)510 if (@typeOf(x).is_signed)
511 return negate(x);511 return negate(x);
512512
...@@ -533,7 +533,7 @@ test "math.negateCast" {...@@ -533,7 +533,7 @@ test "math.negateCast" {
533/// Cast an integer to a different integer type. If the value doesn't fit, 533/// Cast an integer to a different integer type. If the value doesn't fit,
534/// return an error.534/// return an error.
535error Overflow;535error Overflow;
536pub fn cast(comptime T: type, x: var) -> %T {536pub fn cast(comptime T: type, x: var) %T {
537 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer537 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
538 if (x > @maxValue(T)) {538 if (x > @maxValue(T)) {
539 return error.Overflow;539 return error.Overflow;
...@@ -542,7 +542,7 @@ pub fn cast(comptime T: type, x: var) -> %T {...@@ -542,7 +542,7 @@ pub fn cast(comptime T: type, x: var) -> %T {
542 }542 }
543}543}
544544
545pub fn floorPowerOfTwo(comptime T: type, value: T) -> T {545pub fn floorPowerOfTwo(comptime T: type, value: T) T {
546 var x = value;546 var x = value;
547547
548 comptime var i = 1;548 comptime var i = 1;
...@@ -558,7 +558,7 @@ test "math.floorPowerOfTwo" {...@@ -558,7 +558,7 @@ test "math.floorPowerOfTwo" {
558 comptime testFloorPowerOfTwo();558 comptime testFloorPowerOfTwo();
559}559}
560560
561fn testFloorPowerOfTwo() {561fn testFloorPowerOfTwo() void {
562 assert(floorPowerOfTwo(u32, 63) == 32);562 assert(floorPowerOfTwo(u32, 63) == 32);
563 assert(floorPowerOfTwo(u32, 64) == 64);563 assert(floorPowerOfTwo(u32, 64) == 64);
564 assert(floorPowerOfTwo(u32, 65) == 64);564 assert(floorPowerOfTwo(u32, 65) == 64);
std/math/inf.zig+1-1
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn inf(comptime T: type) -> T {5pub fn inf(comptime T: type) T {
6 return switch (T) {6 return switch (T) {
7 f32 => @bitCast(f32, math.inf_u32),7 f32 => @bitCast(f32, math.inf_u32),
8 f64 => @bitCast(f64, math.inf_u64),8 f64 => @bitCast(f64, math.inf_u64),
std/math/isfinite.zig+1-1
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn isFinite(x: var) -> bool {5pub fn isFinite(x: var) bool {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 switch (T) {7 switch (T) {
8 f32 => {8 f32 => {
std/math/isinf.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn isInf(x: var) -> bool {5pub fn isInf(x: var) bool {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 switch (T) {7 switch (T) {
8 f32 => {8 f32 => {
...@@ -19,7 +19,7 @@ pub fn isInf(x: var) -> bool {...@@ -19,7 +19,7 @@ pub fn isInf(x: var) -> bool {
19 }19 }
20}20}
2121
22pub fn isPositiveInf(x: var) -> bool {22pub fn isPositiveInf(x: var) bool {
23 const T = @typeOf(x);23 const T = @typeOf(x);
24 switch (T) {24 switch (T) {
25 f32 => {25 f32 => {
...@@ -34,7 +34,7 @@ pub fn isPositiveInf(x: var) -> bool {...@@ -34,7 +34,7 @@ pub fn isPositiveInf(x: var) -> bool {
34 }34 }
35}35}
3636
37pub fn isNegativeInf(x: var) -> bool {37pub fn isNegativeInf(x: var) bool {
38 const T = @typeOf(x);38 const T = @typeOf(x);
39 switch (T) {39 switch (T) {
40 f32 => {40 f32 => {
std/math/isnan.zig+2-2
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn isNan(x: var) -> bool {5pub fn isNan(x: var) bool {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 switch (T) {7 switch (T) {
8 f32 => {8 f32 => {
...@@ -21,7 +21,7 @@ pub fn isNan(x: var) -> bool {...@@ -21,7 +21,7 @@ pub fn isNan(x: var) -> bool {
2121
22// Note: A signalling nan is identical to a standard right now by may have a different bit22// Note: A signalling nan is identical to a standard right now by may have a different bit
23// representation in the future when required.23// representation in the future when required.
24pub fn isSignalNan(x: var) -> bool {24pub fn isSignalNan(x: var) bool {
25 return isNan(x);25 return isNan(x);
26}26}
2727
std/math/isnormal.zig+1-1
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn isNormal(x: var) -> bool {5pub fn isNormal(x: var) bool {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 switch (T) {7 switch (T) {
8 f32 => {8 f32 => {
std/math/ln.zig+3-3
...@@ -11,7 +11,7 @@ const assert = std.debug.assert;...@@ -11,7 +11,7 @@ const assert = std.debug.assert;
11const builtin = @import("builtin");11const builtin = @import("builtin");
12const TypeId = builtin.TypeId;12const TypeId = builtin.TypeId;
1313
14pub fn ln(x: var) -> @typeOf(x) {14pub fn ln(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.FloatLiteral => {
...@@ -34,7 +34,7 @@ pub fn ln(x: var) -> @typeOf(x) {...@@ -34,7 +34,7 @@ pub fn ln(x: var) -> @typeOf(x) {
34 }34 }
35}35}
3636
37pub fn ln_32(x_: f32) -> f32 {37pub fn ln_32(x_: f32) f32 {
38 @setFloatMode(this, @import("builtin").FloatMode.Strict);38 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3939
40 const ln2_hi: f32 = 6.9313812256e-01;40 const ln2_hi: f32 = 6.9313812256e-01;
...@@ -88,7 +88,7 @@ pub fn ln_32(x_: f32) -> f32 {...@@ -88,7 +88,7 @@ pub fn ln_32(x_: f32) -> f32 {
88 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;88 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
89}89}
9090
91pub fn ln_64(x_: f64) -> f64 {91pub fn ln_64(x_: f64) f64 {
92 const ln2_hi: f64 = 6.93147180369123816490e-01;92 const ln2_hi: f64 = 6.93147180369123816490e-01;
93 const ln2_lo: f64 = 1.90821492927058770002e-10;93 const ln2_lo: f64 = 1.90821492927058770002e-10;
94 const Lg1: f64 = 6.666666666666735130e-01;94 const Lg1: f64 = 6.666666666666735130e-01;
std/math/log.zig+1-1
...@@ -4,7 +4,7 @@ const builtin = @import("builtin");...@@ -4,7 +4,7 @@ const builtin = @import("builtin");
4const TypeId = builtin.TypeId;4const TypeId = builtin.TypeId;
5const assert = std.debug.assert;5const assert = std.debug.assert;
66
7pub fn log(comptime T: type, base: T, x: T) -> T {7pub fn log(comptime T: type, base: T, x: T) T {
8 if (base == 2) {8 if (base == 2) {
9 return math.log2(x);9 return math.log2(x);
10 } else if (base == 10) {10 } else if (base == 10) {
std/math/log10.zig+3-3
...@@ -11,7 +11,7 @@ const assert = std.debug.assert;...@@ -11,7 +11,7 @@ const assert = std.debug.assert;
11const builtin = @import("builtin");11const builtin = @import("builtin");
12const TypeId = builtin.TypeId;12const TypeId = builtin.TypeId;
1313
14pub fn log10(x: var) -> @typeOf(x) {14pub fn log10(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.FloatLiteral => {
...@@ -34,7 +34,7 @@ pub fn log10(x: var) -> @typeOf(x) {...@@ -34,7 +34,7 @@ pub fn log10(x: var) -> @typeOf(x) {
34 }34 }
35}35}
3636
37pub fn log10_32(x_: f32) -> f32 {37pub fn log10_32(x_: f32) f32 {
38 const ivln10hi: f32 = 4.3432617188e-01;38 const ivln10hi: f32 = 4.3432617188e-01;
39 const ivln10lo: f32 = -3.1689971365e-05;39 const ivln10lo: f32 = -3.1689971365e-05;
40 const log10_2hi: f32 = 3.0102920532e-01;40 const log10_2hi: f32 = 3.0102920532e-01;
...@@ -94,7 +94,7 @@ pub fn log10_32(x_: f32) -> f32 {...@@ -94,7 +94,7 @@ pub fn log10_32(x_: f32) -> f32 {
94 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;94 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
95}95}
9696
97pub fn log10_64(x_: f64) -> f64 {97pub fn log10_64(x_: f64) f64 {
98 const ivln10hi: f64 = 4.34294481878168880939e-01;98 const ivln10hi: f64 = 4.34294481878168880939e-01;
99 const ivln10lo: f64 = 2.50829467116452752298e-11;99 const ivln10lo: f64 = 2.50829467116452752298e-11;
100 const log10_2hi: f64 = 3.01029995663611771306e-01;100 const log10_2hi: f64 = 3.01029995663611771306e-01;
std/math/log1p.zig+3-3
...@@ -10,7 +10,7 @@ const std = @import("../index.zig");...@@ -10,7 +10,7 @@ const std = @import("../index.zig");
10const math = std.math;10const math = std.math;
11const assert = std.debug.assert;11const assert = std.debug.assert;
1212
13pub fn log1p(x: var) -> @typeOf(x) {13pub fn log1p(x: var) @typeOf(x) {
14 const T = @typeOf(x);14 const T = @typeOf(x);
15 return switch (T) {15 return switch (T) {
16 f32 => log1p_32(x),16 f32 => log1p_32(x),
...@@ -19,7 +19,7 @@ pub fn log1p(x: var) -> @typeOf(x) {...@@ -19,7 +19,7 @@ pub fn log1p(x: var) -> @typeOf(x) {
19 };19 };
20}20}
2121
22fn log1p_32(x: f32) -> f32 {22fn log1p_32(x: f32) f32 {
23 const ln2_hi = 6.9313812256e-01;23 const ln2_hi = 6.9313812256e-01;
24 const ln2_lo = 9.0580006145e-06;24 const ln2_lo = 9.0580006145e-06;
25 const Lg1: f32 = 0xaaaaaa.0p-24;25 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -95,7 +95,7 @@ fn log1p_32(x: f32) -> f32 {...@@ -95,7 +95,7 @@ fn log1p_32(x: f32) -> f32 {
95 return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;95 return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
96}96}
9797
98fn log1p_64(x: f64) -> f64 {98fn log1p_64(x: f64) f64 {
99 const ln2_hi: f64 = 6.93147180369123816490e-01;99 const ln2_hi: f64 = 6.93147180369123816490e-01;
100 const ln2_lo: f64 = 1.90821492927058770002e-10;100 const ln2_lo: f64 = 1.90821492927058770002e-10;
101 const Lg1: f64 = 6.666666666666735130e-01;101 const Lg1: f64 = 6.666666666666735130e-01;
std/math/log2.zig+4-4
...@@ -11,7 +11,7 @@ const assert = std.debug.assert;...@@ -11,7 +11,7 @@ const assert = std.debug.assert;
11const builtin = @import("builtin");11const builtin = @import("builtin");
12const TypeId = builtin.TypeId;12const TypeId = builtin.TypeId;
1313
14pub fn log2(x: var) -> @typeOf(x) {14pub fn log2(x: var) @typeOf(x) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.FloatLiteral => {
...@@ -37,12 +37,12 @@ pub fn log2(x: var) -> @typeOf(x) {...@@ -37,12 +37,12 @@ pub fn log2(x: var) -> @typeOf(x) {
37 }37 }
38}38}
3939
40pub fn log2_int(comptime T: type, x: T) -> T {40pub fn log2_int(comptime T: type, x: T) T {
41 assert(x != 0);41 assert(x != 0);
42 return T.bit_count - 1 - T(@clz(x));42 return T.bit_count - 1 - T(@clz(x));
43}43}
4444
45pub fn log2_32(x_: f32) -> f32 {45pub fn log2_32(x_: f32) f32 {
46 const ivln2hi: f32 = 1.4428710938e+00;46 const ivln2hi: f32 = 1.4428710938e+00;
47 const ivln2lo: f32 = -1.7605285393e-04;47 const ivln2lo: f32 = -1.7605285393e-04;
48 const Lg1: f32 = 0xaaaaaa.0p-24;48 const Lg1: f32 = 0xaaaaaa.0p-24;
...@@ -98,7 +98,7 @@ pub fn log2_32(x_: f32) -> f32 {...@@ -98,7 +98,7 @@ pub fn log2_32(x_: f32) -> f32 {
98 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);98 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);
99}99}
100100
101pub fn log2_64(x_: f64) -> f64 {101pub fn log2_64(x_: f64) f64 {
102 const ivln2hi: f64 = 1.44269504072144627571e+00;102 const ivln2hi: f64 = 1.44269504072144627571e+00;
103 const ivln2lo: f64 = 1.67517131648865118353e-10;103 const ivln2lo: f64 = 1.67517131648865118353e-10;
104 const Lg1: f64 = 6.666666666666735130e-01;104 const Lg1: f64 = 6.666666666666735130e-01;
std/math/modf.zig+4-4
...@@ -7,7 +7,7 @@ const std = @import("../index.zig");...@@ -7,7 +7,7 @@ const std = @import("../index.zig");
7const math = std.math;7const math = std.math;
8const assert = std.debug.assert;8const assert = std.debug.assert;
99
10fn modf_result(comptime T: type) -> type {10fn modf_result(comptime T: type) type {
11 return struct {11 return struct {
12 fpart: T,12 fpart: T,
13 ipart: T,13 ipart: T,
...@@ -16,7 +16,7 @@ fn modf_result(comptime T: type) -> type {...@@ -16,7 +16,7 @@ fn modf_result(comptime T: type) -> type {
16pub const modf32_result = modf_result(f32);16pub const modf32_result = modf_result(f32);
17pub const modf64_result = modf_result(f64);17pub const modf64_result = modf_result(f64);
1818
19pub fn modf(x: var) -> modf_result(@typeOf(x)) {19pub fn modf(x: var) modf_result(@typeOf(x)) {
20 const T = @typeOf(x);20 const T = @typeOf(x);
21 return switch (T) {21 return switch (T) {
22 f32 => modf32(x),22 f32 => modf32(x),
...@@ -25,7 +25,7 @@ pub fn modf(x: var) -> modf_result(@typeOf(x)) {...@@ -25,7 +25,7 @@ pub fn modf(x: var) -> modf_result(@typeOf(x)) {
25 };25 };
26}26}
2727
28fn modf32(x: f32) -> modf32_result {28fn modf32(x: f32) modf32_result {
29 var result: modf32_result = undefined;29 var result: modf32_result = undefined;
3030
31 const u = @bitCast(u32, x);31 const u = @bitCast(u32, x);
...@@ -70,7 +70,7 @@ fn modf32(x: f32) -> modf32_result {...@@ -70,7 +70,7 @@ fn modf32(x: f32) -> modf32_result {
70 return result;70 return result;
71}71}
7272
73fn modf64(x: f64) -> modf64_result {73fn modf64(x: f64) modf64_result {
74 var result: modf64_result = undefined;74 var result: modf64_result = undefined;
7575
76 const u = @bitCast(u64, x);76 const u = @bitCast(u64, x);
std/math/nan.zig+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const math = @import("index.zig");1const math = @import("index.zig");
22
3pub fn nan(comptime T: type) -> T {3pub fn nan(comptime T: type) T {
4 return switch (T) {4 return switch (T) {
5 f32 => @bitCast(f32, math.nan_u32),5 f32 => @bitCast(f32, math.nan_u32),
6 f64 => @bitCast(f64, math.nan_u64),6 f64 => @bitCast(f64, math.nan_u64),
...@@ -10,7 +10,7 @@ pub fn nan(comptime T: type) -> T {...@@ -10,7 +10,7 @@ pub fn nan(comptime T: type) -> T {
1010
11// Note: A signalling nan is identical to a standard right now by may have a different bit11// Note: A signalling nan is identical to a standard right now by may have a different bit
12// representation in the future when required.12// representation in the future when required.
13pub fn snan(comptime T: type) -> T {13pub fn snan(comptime T: type) T {
14 return switch (T) {14 return switch (T) {
15 f32 => @bitCast(f32, math.nan_u32),15 f32 => @bitCast(f32, math.nan_u32),
16 f64 => @bitCast(f64, math.nan_u64),16 f64 => @bitCast(f64, math.nan_u64),
std/math/pow.zig+2-2
...@@ -27,7 +27,7 @@ const math = std.math;...@@ -27,7 +27,7 @@ const math = std.math;
27const assert = std.debug.assert;27const assert = std.debug.assert;
2828
29// This implementation is taken from the go stlib, musl is a bit more complex.29// This implementation is taken from the go stlib, musl is a bit more complex.
30pub fn pow(comptime T: type, x: T, y: T) -> T {30pub fn pow(comptime T: type, x: T, y: T) T {
3131
32 @setFloatMode(this, @import("builtin").FloatMode.Strict);32 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3333
...@@ -170,7 +170,7 @@ pub fn pow(comptime T: type, x: T, y: T) -> T {...@@ -170,7 +170,7 @@ pub fn pow(comptime T: type, x: T, y: T) -> T {
170 return math.scalbn(a1, ae);170 return math.scalbn(a1, ae);
171}171}
172172
173fn isOddInteger(x: f64) -> bool {173fn isOddInteger(x: f64) bool {
174 const r = math.modf(x);174 const r = math.modf(x);
175 return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;175 return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;
176}176}
std/math/round.zig+3-3
...@@ -9,7 +9,7 @@ const assert = std.debug.assert;...@@ -9,7 +9,7 @@ const assert = std.debug.assert;
9const std = @import("../index.zig");9const std = @import("../index.zig");
10const math = std.math;10const math = std.math;
1111
12pub fn round(x: var) -> @typeOf(x) {12pub fn round(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => round32(x),15 f32 => round32(x),
...@@ -18,7 +18,7 @@ pub fn round(x: var) -> @typeOf(x) {...@@ -18,7 +18,7 @@ pub fn round(x: var) -> @typeOf(x) {
18 };18 };
19}19}
2020
21fn round32(x_: f32) -> f32 {21fn round32(x_: f32) f32 {
22 var x = x_;22 var x = x_;
23 const u = @bitCast(u32, x);23 const u = @bitCast(u32, x);
24 const e = (u >> 23) & 0xFF;24 const e = (u >> 23) & 0xFF;
...@@ -55,7 +55,7 @@ fn round32(x_: f32) -> f32 {...@@ -55,7 +55,7 @@ fn round32(x_: f32) -> f32 {
55 }55 }
56}56}
5757
58fn round64(x_: f64) -> f64 {58fn round64(x_: f64) f64 {
59 var x = x_;59 var x = x_;
60 const u = @bitCast(u64, x);60 const u = @bitCast(u64, x);
61 const e = (u >> 52) & 0x7FF;61 const e = (u >> 52) & 0x7FF;
std/math/scalbn.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn scalbn(x: var, n: i32) -> @typeOf(x) {5pub fn scalbn(x: var, n: i32) @typeOf(x) {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 return switch (T) {7 return switch (T) {
8 f32 => scalbn32(x, n),8 f32 => scalbn32(x, n),
...@@ -11,7 +11,7 @@ pub fn scalbn(x: var, n: i32) -> @typeOf(x) {...@@ -11,7 +11,7 @@ pub fn scalbn(x: var, n: i32) -> @typeOf(x) {
11 };11 };
12}12}
1313
14fn scalbn32(x: f32, n_: i32) -> f32 {14fn scalbn32(x: f32, n_: i32) f32 {
15 var y = x;15 var y = x;
16 var n = n_;16 var n = n_;
1717
...@@ -41,7 +41,7 @@ fn scalbn32(x: f32, n_: i32) -> f32 {...@@ -41,7 +41,7 @@ fn scalbn32(x: f32, n_: i32) -> f32 {
41 return y * @bitCast(f32, u);41 return y * @bitCast(f32, u);
42}42}
4343
44fn scalbn64(x: f64, n_: i32) -> f64 {44fn scalbn64(x: f64, n_: i32) f64 {
45 var y = x;45 var y = x;
46 var n = n_;46 var n = n_;
4747
std/math/signbit.zig+3-3
...@@ -2,7 +2,7 @@ const std = @import("../index.zig");...@@ -2,7 +2,7 @@ const std = @import("../index.zig");
2const math = std.math;2const math = std.math;
3const assert = std.debug.assert;3const assert = std.debug.assert;
44
5pub fn signbit(x: var) -> bool {5pub fn signbit(x: var) bool {
6 const T = @typeOf(x);6 const T = @typeOf(x);
7 return switch (T) {7 return switch (T) {
8 f32 => signbit32(x),8 f32 => signbit32(x),
...@@ -11,12 +11,12 @@ pub fn signbit(x: var) -> bool {...@@ -11,12 +11,12 @@ pub fn signbit(x: var) -> bool {
11 };11 };
12}12}
1313
14fn signbit32(x: f32) -> bool {14fn signbit32(x: f32) bool {
15 const bits = @bitCast(u32, x);15 const bits = @bitCast(u32, x);
16 return bits >> 31 != 0;16 return bits >> 31 != 0;
17}17}
1818
19fn signbit64(x: f64) -> bool {19fn signbit64(x: f64) bool {
20 const bits = @bitCast(u64, x);20 const bits = @bitCast(u64, x);
21 return bits >> 63 != 0;21 return bits >> 63 != 0;
22}22}
std/math/sin.zig+3-3
...@@ -9,7 +9,7 @@ const std = @import("../index.zig");...@@ -9,7 +9,7 @@ const std = @import("../index.zig");
9const math = std.math;9const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
1111
12pub fn sin(x: var) -> @typeOf(x) {12pub fn sin(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => sin32(x),15 f32 => sin32(x),
...@@ -37,7 +37,7 @@ const C5 = 4.16666666666665929218E-2;...@@ -37,7 +37,7 @@ const C5 = 4.16666666666665929218E-2;
37// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.37// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
38//38//
39// This may have slight differences on some edge cases and may need to replaced if so.39// This may have slight differences on some edge cases and may need to replaced if so.
40fn sin32(x_: f32) -> f32 {40fn sin32(x_: f32) f32 {
41 @setFloatMode(this, @import("builtin").FloatMode.Strict);41 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4242
43 const pi4a = 7.85398125648498535156e-1;43 const pi4a = 7.85398125648498535156e-1;
...@@ -91,7 +91,7 @@ fn sin32(x_: f32) -> f32 {...@@ -91,7 +91,7 @@ fn sin32(x_: f32) -> f32 {
91 }91 }
92}92}
9393
94fn sin64(x_: f64) -> f64 {94fn sin64(x_: f64) f64 {
95 const pi4a = 7.85398125648498535156e-1;95 const pi4a = 7.85398125648498535156e-1;
96 const pi4b = 3.77489470793079817668E-8;96 const pi4b = 3.77489470793079817668E-8;
97 const pi4c = 2.69515142907905952645E-15;97 const pi4c = 2.69515142907905952645E-15;
std/math/sinh.zig+3-3
...@@ -10,7 +10,7 @@ const math = std.math;...@@ -10,7 +10,7 @@ const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
11const expo2 = @import("expo2.zig").expo2;11const expo2 = @import("expo2.zig").expo2;
1212
13pub fn sinh(x: var) -> @typeOf(x) {13pub fn sinh(x: var) @typeOf(x) {
14 const T = @typeOf(x);14 const T = @typeOf(x);
15 return switch (T) {15 return switch (T) {
16 f32 => sinh32(x),16 f32 => sinh32(x),
...@@ -22,7 +22,7 @@ pub fn sinh(x: var) -> @typeOf(x) {...@@ -22,7 +22,7 @@ pub fn sinh(x: var) -> @typeOf(x) {
22// sinh(x) = (exp(x) - 1 / exp(x)) / 222// sinh(x) = (exp(x) - 1 / exp(x)) / 2
23// = (exp(x) - 1 + (exp(x) - 1) / exp(x)) / 223// = (exp(x) - 1 + (exp(x) - 1) / exp(x)) / 2
24// = x + x^3 / 6 + o(x^5)24// = x + x^3 / 6 + o(x^5)
25fn sinh32(x: f32) -> f32 {25fn sinh32(x: f32) f32 {
26 const u = @bitCast(u32, x);26 const u = @bitCast(u32, x);
27 const ux = u & 0x7FFFFFFF;27 const ux = u & 0x7FFFFFFF;
28 const ax = @bitCast(f32, ux);28 const ax = @bitCast(f32, ux);
...@@ -53,7 +53,7 @@ fn sinh32(x: f32) -> f32 {...@@ -53,7 +53,7 @@ fn sinh32(x: f32) -> f32 {
53 return 2 * h * expo2(ax);53 return 2 * h * expo2(ax);
54}54}
5555
56fn sinh64(x: f64) -> f64 {56fn sinh64(x: f64) f64 {
57 @setFloatMode(this, @import("builtin").FloatMode.Strict);57 @setFloatMode(this, @import("builtin").FloatMode.Strict);
5858
59 const u = @bitCast(u64, x);59 const u = @bitCast(u64, x);
std/math/sqrt.zig+4-4
...@@ -11,7 +11,7 @@ const assert = std.debug.assert;...@@ -11,7 +11,7 @@ const assert = std.debug.assert;
11const builtin = @import("builtin");11const builtin = @import("builtin");
12const TypeId = builtin.TypeId;12const TypeId = builtin.TypeId;
1313
14pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {14pub fn sqrt(x: var) (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @typeOf(x).bit_count / 2) else @typeOf(x)) {
15 const T = @typeOf(x);15 const T = @typeOf(x);
16 switch (@typeId(T)) {16 switch (@typeId(T)) {
17 TypeId.FloatLiteral => {17 TypeId.FloatLiteral => {
...@@ -50,7 +50,7 @@ pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @...@@ -50,7 +50,7 @@ pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @
50 }50 }
51}51}
5252
53fn sqrt32(x: f32) -> f32 {53fn sqrt32(x: f32) f32 {
54 const tiny: f32 = 1.0e-30;54 const tiny: f32 = 1.0e-30;
55 const sign: i32 = @bitCast(i32, u32(0x80000000));55 const sign: i32 = @bitCast(i32, u32(0x80000000));
56 var ix: i32 = @bitCast(i32, x);56 var ix: i32 = @bitCast(i32, x);
...@@ -129,7 +129,7 @@ fn sqrt32(x: f32) -> f32 {...@@ -129,7 +129,7 @@ fn sqrt32(x: f32) -> f32 {
129// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound129// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
130// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are130// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
131// potentially some edge cases remaining that are not handled in the same way.131// potentially some edge cases remaining that are not handled in the same way.
132fn sqrt64(x: f64) -> f64 {132fn sqrt64(x: f64) f64 {
133 const tiny: f64 = 1.0e-300;133 const tiny: f64 = 1.0e-300;
134 const sign: u32 = 0x80000000;134 const sign: u32 = 0x80000000;
135 const u = @bitCast(u64, x);135 const u = @bitCast(u64, x);
...@@ -308,7 +308,7 @@ test "math.sqrt64.special" {...@@ -308,7 +308,7 @@ test "math.sqrt64.special" {
308 assert(math.isNan(sqrt64(math.nan(f64))));308 assert(math.isNan(sqrt64(math.nan(f64))));
309}309}
310310
311fn sqrt_int(comptime T: type, value: T) -> @IntType(false, T.bit_count / 2) {311fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
312 var op = value;312 var op = value;
313 var res: T = 0;313 var res: T = 0;
314 var one: T = 1 << (T.bit_count - 2);314 var one: T = 1 << (T.bit_count - 2);
std/math/tan.zig+3-3
...@@ -9,7 +9,7 @@ const std = @import("../index.zig");...@@ -9,7 +9,7 @@ const std = @import("../index.zig");
9const math = std.math;9const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
1111
12pub fn tan(x: var) -> @typeOf(x) {12pub fn tan(x: var) @typeOf(x) {
13 const T = @typeOf(x);13 const T = @typeOf(x);
14 return switch (T) {14 return switch (T) {
15 f32 => tan32(x),15 f32 => tan32(x),
...@@ -30,7 +30,7 @@ const Tq4 = -5.38695755929454629881E7;...@@ -30,7 +30,7 @@ const Tq4 = -5.38695755929454629881E7;
30// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.30// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
31//31//
32// This may have slight differences on some edge cases and may need to replaced if so.32// This may have slight differences on some edge cases and may need to replaced if so.
33fn tan32(x_: f32) -> f32 {33fn tan32(x_: f32) f32 {
34 @setFloatMode(this, @import("builtin").FloatMode.Strict);34 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3535
36 const pi4a = 7.85398125648498535156e-1;36 const pi4a = 7.85398125648498535156e-1;
...@@ -81,7 +81,7 @@ fn tan32(x_: f32) -> f32 {...@@ -81,7 +81,7 @@ fn tan32(x_: f32) -> f32 {
81 return r;81 return r;
82}82}
8383
84fn tan64(x_: f64) -> f64 {84fn tan64(x_: f64) f64 {
85 const pi4a = 7.85398125648498535156e-1;85 const pi4a = 7.85398125648498535156e-1;
86 const pi4b = 3.77489470793079817668E-8;86 const pi4b = 3.77489470793079817668E-8;
87 const pi4c = 2.69515142907905952645E-15;87 const pi4c = 2.69515142907905952645E-15;
std/math/tanh.zig+3-3
...@@ -10,7 +10,7 @@ const math = std.math;...@@ -10,7 +10,7 @@ const math = std.math;
10const assert = std.debug.assert;10const assert = std.debug.assert;
11const expo2 = @import("expo2.zig").expo2;11const expo2 = @import("expo2.zig").expo2;
1212
13pub fn tanh(x: var) -> @typeOf(x) {13pub fn tanh(x: var) @typeOf(x) {
14 const T = @typeOf(x);14 const T = @typeOf(x);
15 return switch (T) {15 return switch (T) {
16 f32 => tanh32(x),16 f32 => tanh32(x),
...@@ -22,7 +22,7 @@ pub fn tanh(x: var) -> @typeOf(x) {...@@ -22,7 +22,7 @@ pub fn tanh(x: var) -> @typeOf(x) {
22// tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))22// tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
23// = (exp(2x) - 1) / (exp(2x) - 1 + 2)23// = (exp(2x) - 1) / (exp(2x) - 1 + 2)
24// = (1 - exp(-2x)) / (exp(-2x) - 1 + 2)24// = (1 - exp(-2x)) / (exp(-2x) - 1 + 2)
25fn tanh32(x: f32) -> f32 {25fn tanh32(x: f32) f32 {
26 const u = @bitCast(u32, x);26 const u = @bitCast(u32, x);
27 const ux = u & 0x7FFFFFFF;27 const ux = u & 0x7FFFFFFF;
28 const ax = @bitCast(f32, ux);28 const ax = @bitCast(f32, ux);
...@@ -66,7 +66,7 @@ fn tanh32(x: f32) -> f32 {...@@ -66,7 +66,7 @@ fn tanh32(x: f32) -> f32 {
66 }66 }
67}67}
6868
69fn tanh64(x: f64) -> f64 {69fn tanh64(x: f64) f64 {
70 const u = @bitCast(u64, x);70 const u = @bitCast(u64, x);
71 const w = u32(u >> 32);71 const w = u32(u >> 32);
72 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));72 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
std/math/trunc.zig+3-3
...@@ -8,7 +8,7 @@ const std = @import("../index.zig");...@@ -8,7 +8,7 @@ const std = @import("../index.zig");
8const math = std.math;8const math = std.math;
9const assert = std.debug.assert;9const assert = std.debug.assert;
1010
11pub fn trunc(x: var) -> @typeOf(x) {11pub fn trunc(x: var) @typeOf(x) {
12 const T = @typeOf(x);12 const T = @typeOf(x);
13 return switch (T) {13 return switch (T) {
14 f32 => trunc32(x),14 f32 => trunc32(x),
...@@ -17,7 +17,7 @@ pub fn trunc(x: var) -> @typeOf(x) {...@@ -17,7 +17,7 @@ pub fn trunc(x: var) -> @typeOf(x) {
17 };17 };
18}18}
1919
20fn trunc32(x: f32) -> f32 {20fn trunc32(x: f32) f32 {
21 const u = @bitCast(u32, x);21 const u = @bitCast(u32, x);
22 var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9;22 var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9;
23 var m: u32 = undefined;23 var m: u32 = undefined;
...@@ -38,7 +38,7 @@ fn trunc32(x: f32) -> f32 {...@@ -38,7 +38,7 @@ fn trunc32(x: f32) -> f32 {
38 }38 }
39}39}
4040
41fn trunc64(x: f64) -> f64 {41fn trunc64(x: f64) f64 {
42 const u = @bitCast(u64, x);42 const u = @bitCast(u64, x);
43 var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12;43 var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12;
44 var m: u64 = undefined;44 var m: u64 = undefined;
std/math/x86_64/sqrt.zig+2-2
...@@ -1,4 +1,4 @@...@@ -1,4 +1,4 @@
1pub fn sqrt32(x: f32) -> f32 {1pub fn sqrt32(x: f32) f32 {
2 return asm (2 return asm (
3 \\sqrtss %%xmm0, %%xmm03 \\sqrtss %%xmm0, %%xmm0
4 : [ret] "={xmm0}" (-> f32)4 : [ret] "={xmm0}" (-> f32)
...@@ -6,7 +6,7 @@ pub fn sqrt32(x: f32) -> f32 {...@@ -6,7 +6,7 @@ pub fn sqrt32(x: f32) -> f32 {
6 );6 );
7}7}
88
9pub fn sqrt64(x: f64) -> f64 {9pub fn sqrt64(x: f64) f64 {
10 return asm (10 return asm (
11 \\sqrtsd %%xmm0, %%xmm011 \\sqrtsd %%xmm0, %%xmm0
12 : [ret] "={xmm0}" (-> f64)12 : [ret] "={xmm0}" (-> f64)
std/mem.zig+50-50
...@@ -10,7 +10,7 @@ pub const Allocator = struct {...@@ -10,7 +10,7 @@ pub const Allocator = struct {
10 /// Allocate byte_count bytes and return them in a slice, with the10 /// Allocate byte_count bytes and return them in a slice, with the
11 /// slice's pointer aligned at least to alignment bytes.11 /// slice's pointer aligned at least to alignment bytes.
12 /// The returned newly allocated memory is undefined.12 /// The returned newly allocated memory is undefined.
13 allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) -> %[]u8,13 allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) %[]u8,
1414
15 /// If `new_byte_count > old_mem.len`:15 /// If `new_byte_count > old_mem.len`:
16 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.16 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
...@@ -21,26 +21,26 @@ pub const Allocator = struct {...@@ -21,26 +21,26 @@ pub const Allocator = struct {
21 /// * alignment <= alignment of old_mem.ptr21 /// * alignment <= alignment of old_mem.ptr
22 ///22 ///
23 /// The returned newly allocated memory is undefined.23 /// The returned newly allocated memory is undefined.
24 reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) -> %[]u8,24 reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) %[]u8,
2525
26 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`26 /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
27 freeFn: fn (self: &Allocator, old_mem: []u8),27 freeFn: fn (self: &Allocator, old_mem: []u8) void,
2828
29 fn create(self: &Allocator, comptime T: type) -> %&T {29 fn create(self: &Allocator, comptime T: type) %&T {
30 const slice = try self.alloc(T, 1);30 const slice = try self.alloc(T, 1);
31 return &slice[0];31 return &slice[0];
32 }32 }
3333
34 fn destroy(self: &Allocator, ptr: var) {34 fn destroy(self: &Allocator, ptr: var) void {
35 self.free(ptr[0..1]);35 self.free(ptr[0..1]);
36 }36 }
3737
38 fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {38 fn alloc(self: &Allocator, comptime T: type, n: usize) %[]T {
39 return self.alignedAlloc(T, @alignOf(T), n);39 return self.alignedAlloc(T, @alignOf(T), n);
40 }40 }
4141
42 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,42 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
43 n: usize) -> %[]align(alignment) T43 n: usize) %[]align(alignment) T
44 {44 {
45 const byte_count = try math.mul(usize, @sizeOf(T), n);45 const byte_count = try math.mul(usize, @sizeOf(T), n);
46 const byte_slice = try self.allocFn(self, byte_count, alignment);46 const byte_slice = try self.allocFn(self, byte_count, alignment);
...@@ -51,12 +51,12 @@ pub const Allocator = struct {...@@ -51,12 +51,12 @@ pub const Allocator = struct {
51 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));51 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
52 }52 }
5353
54 fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) -> %[]T {54 fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) %[]T {
55 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);55 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
56 }56 }
5757
58 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,58 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,
59 old_mem: []align(alignment) T, n: usize) -> %[]align(alignment) T59 old_mem: []align(alignment) T, n: usize) %[]align(alignment) T
60 {60 {
61 if (old_mem.len == 0) {61 if (old_mem.len == 0) {
62 return self.alloc(T, n);62 return self.alloc(T, n);
...@@ -75,12 +75,12 @@ pub const Allocator = struct {...@@ -75,12 +75,12 @@ pub const Allocator = struct {
75 /// Reallocate, but `n` must be less than or equal to `old_mem.len`.75 /// Reallocate, but `n` must be less than or equal to `old_mem.len`.
76 /// Unlike `realloc`, this function cannot fail.76 /// Unlike `realloc`, this function cannot fail.
77 /// Shrinking to 0 is the same as calling `free`.77 /// Shrinking to 0 is the same as calling `free`.
78 fn shrink(self: &Allocator, comptime T: type, old_mem: []T, n: usize) -> []T {78 fn shrink(self: &Allocator, comptime T: type, old_mem: []T, n: usize) []T {
79 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);79 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
80 }80 }
8181
82 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29,82 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29,
83 old_mem: []align(alignment) T, n: usize) -> []align(alignment) T83 old_mem: []align(alignment) T, n: usize) []align(alignment) T
84 {84 {
85 if (n == 0) {85 if (n == 0) {
86 self.free(old_mem);86 self.free(old_mem);
...@@ -97,7 +97,7 @@ pub const Allocator = struct {...@@ -97,7 +97,7 @@ pub const Allocator = struct {
97 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));97 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
98 }98 }
9999
100 fn free(self: &Allocator, memory: var) {100 fn free(self: &Allocator, memory: var) void {
101 const bytes = ([]const u8)(memory);101 const bytes = ([]const u8)(memory);
102 if (bytes.len == 0)102 if (bytes.len == 0)
103 return;103 return;
...@@ -111,7 +111,7 @@ pub const FixedBufferAllocator = struct {...@@ -111,7 +111,7 @@ pub const FixedBufferAllocator = struct {
111 end_index: usize,111 end_index: usize,
112 buffer: []u8,112 buffer: []u8,
113113
114 pub fn init(buffer: []u8) -> FixedBufferAllocator {114 pub fn init(buffer: []u8) FixedBufferAllocator {
115 return FixedBufferAllocator {115 return FixedBufferAllocator {
116 .allocator = Allocator {116 .allocator = Allocator {
117 .allocFn = alloc,117 .allocFn = alloc,
...@@ -123,7 +123,7 @@ pub const FixedBufferAllocator = struct {...@@ -123,7 +123,7 @@ pub const FixedBufferAllocator = struct {
123 };123 };
124 }124 }
125125
126 fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 {126 fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
127 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);127 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
128 const addr = @ptrToInt(&self.buffer[self.end_index]);128 const addr = @ptrToInt(&self.buffer[self.end_index]);
129 const rem = @rem(addr, alignment);129 const rem = @rem(addr, alignment);
...@@ -138,7 +138,7 @@ pub const FixedBufferAllocator = struct {...@@ -138,7 +138,7 @@ pub const FixedBufferAllocator = struct {
138 return result;138 return result;
139 }139 }
140140
141 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) -> %[]u8 {141 fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
142 if (new_size <= old_mem.len) {142 if (new_size <= old_mem.len) {
143 return old_mem[0..new_size];143 return old_mem[0..new_size];
144 } else {144 } else {
...@@ -148,27 +148,27 @@ pub const FixedBufferAllocator = struct {...@@ -148,27 +148,27 @@ pub const FixedBufferAllocator = struct {
148 }148 }
149 }149 }
150150
151 fn free(allocator: &Allocator, bytes: []u8) { }151 fn free(allocator: &Allocator, bytes: []u8) void { }
152};152};
153153
154154
155/// Copy all of source into dest at position 0.155/// Copy all of source into dest at position 0.
156/// dest.len must be >= source.len.156/// dest.len must be >= source.len.
157pub fn copy(comptime T: type, dest: []T, source: []const T) {157pub fn copy(comptime T: type, dest: []T, source: []const T) void {
158 // TODO instead of manually doing this check for the whole array158 // TODO instead of manually doing this check for the whole array
159 // and turning off debug safety, the compiler should detect loops like159 // and turning off runtime safety, the compiler should detect loops like
160 // this and automatically omit safety checks for loops160 // this and automatically omit safety checks for loops
161 @setDebugSafety(this, false);161 @setRuntimeSafety(false);
162 assert(dest.len >= source.len);162 assert(dest.len >= source.len);
163 for (source) |s, i| dest[i] = s;163 for (source) |s, i| dest[i] = s;
164}164}
165165
166pub fn set(comptime T: type, dest: []T, value: T) {166pub fn set(comptime T: type, dest: []T, value: T) void {
167 for (dest) |*d| *d = value;167 for (dest) |*d| *d = value;
168}168}
169169
170/// Returns true if lhs < rhs, false otherwise170/// Returns true if lhs < rhs, false otherwise
171pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) -> bool {171pub fn lessThan(comptime T: type, lhs: []const T, rhs: []const T) bool {
172 const n = math.min(lhs.len, rhs.len);172 const n = math.min(lhs.len, rhs.len);
173 var i: usize = 0;173 var i: usize = 0;
174 while (i < n) : (i += 1) {174 while (i < n) : (i += 1) {
...@@ -188,7 +188,7 @@ test "mem.lessThan" {...@@ -188,7 +188,7 @@ test "mem.lessThan" {
188}188}
189189
190/// Compares two slices and returns whether they are equal.190/// Compares two slices and returns whether they are equal.
191pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool {191pub fn eql(comptime T: type, a: []const T, b: []const T) bool {
192 if (a.len != b.len) return false;192 if (a.len != b.len) return false;
193 for (a) |item, index| {193 for (a) |item, index| {
194 if (b[index] != item) return false;194 if (b[index] != item) return false;
...@@ -197,14 +197,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool {...@@ -197,14 +197,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool {
197}197}
198198
199/// Copies ::m to newly allocated memory. Caller is responsible to free it.199/// Copies ::m to newly allocated memory. Caller is responsible to free it.
200pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T {200pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) %[]T {
201 const new_buf = try allocator.alloc(T, m.len);201 const new_buf = try allocator.alloc(T, m.len);
202 copy(T, new_buf, m);202 copy(T, new_buf, m);
203 return new_buf;203 return new_buf;
204}204}
205205
206/// Remove values from the beginning and end of a slice.206/// Remove values from the beginning and end of a slice.
207pub fn trim(comptime T: type, slice: []const T, values_to_strip: []const T) -> []const T {207pub fn trim(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
208 var begin: usize = 0;208 var begin: usize = 0;
209 var end: usize = slice.len;209 var end: usize = slice.len;
210 while (begin < end and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}210 while (begin < end and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
...@@ -218,11 +218,11 @@ test "mem.trim" {...@@ -218,11 +218,11 @@ test "mem.trim" {
218}218}
219219
220/// Linear search for the index of a scalar value inside a slice.220/// Linear search for the index of a scalar value inside a slice.
221pub fn indexOfScalar(comptime T: type, slice: []const T, value: T) -> ?usize {221pub fn indexOfScalar(comptime T: type, slice: []const T, value: T) ?usize {
222 return indexOfScalarPos(T, slice, 0, value);222 return indexOfScalarPos(T, slice, 0, value);
223}223}
224224
225pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) -> ?usize {225pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize, value: T) ?usize {
226 var i: usize = start_index;226 var i: usize = start_index;
227 while (i < slice.len) : (i += 1) {227 while (i < slice.len) : (i += 1) {
228 if (slice[i] == value)228 if (slice[i] == value)
...@@ -231,11 +231,11 @@ pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize,...@@ -231,11 +231,11 @@ pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize,
231 return null;231 return null;
232}232}
233233
234pub fn indexOfAny(comptime T: type, slice: []const T, values: []const T) -> ?usize {234pub fn indexOfAny(comptime T: type, slice: []const T, values: []const T) ?usize {
235 return indexOfAnyPos(T, slice, 0, values);235 return indexOfAnyPos(T, slice, 0, values);
236}236}
237237
238pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, values: []const T) -> ?usize {238pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, values: []const T) ?usize {
239 var i: usize = start_index;239 var i: usize = start_index;
240 while (i < slice.len) : (i += 1) {240 while (i < slice.len) : (i += 1) {
241 for (values) |value| {241 for (values) |value| {
...@@ -246,12 +246,12 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val...@@ -246,12 +246,12 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val
246 return null;246 return null;
247}247}
248248
249pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) -> ?usize {249pub fn indexOf(comptime T: type, haystack: []const T, needle: []const T) ?usize {
250 return indexOfPos(T, haystack, 0, needle);250 return indexOfPos(T, haystack, 0, needle);
251}251}
252252
253// TODO boyer-moore algorithm253// TODO boyer-moore algorithm
254pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) -> ?usize {254pub fn indexOfPos(comptime T: type, haystack: []const T, start_index: usize, needle: []const T) ?usize {
255 if (needle.len > haystack.len)255 if (needle.len > haystack.len)
256 return null;256 return null;
257257
...@@ -275,7 +275,7 @@ test "mem.indexOf" {...@@ -275,7 +275,7 @@ test "mem.indexOf" {
275/// T specifies the return type, which must be large enough to store275/// T specifies the return type, which must be large enough to store
276/// the result.276/// the result.
277/// See also ::readIntBE or ::readIntLE.277/// See also ::readIntBE or ::readIntLE.
278pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) -> T {278pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) T {
279 if (T.bit_count == 8) {279 if (T.bit_count == 8) {
280 return bytes[0];280 return bytes[0];
281 }281 }
...@@ -298,7 +298,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) -> T...@@ -298,7 +298,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) -> T
298298
299/// Reads a big-endian int of type T from bytes.299/// Reads a big-endian int of type T from bytes.
300/// bytes.len must be exactly @sizeOf(T).300/// bytes.len must be exactly @sizeOf(T).
301pub fn readIntBE(comptime T: type, bytes: []const u8) -> T {301pub fn readIntBE(comptime T: type, bytes: []const u8) T {
302 if (T.is_signed) {302 if (T.is_signed) {
303 return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes));303 return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes));
304 }304 }
...@@ -312,7 +312,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) -> T {...@@ -312,7 +312,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) -> T {
312312
313/// Reads a little-endian int of type T from bytes.313/// Reads a little-endian int of type T from bytes.
314/// bytes.len must be exactly @sizeOf(T).314/// bytes.len must be exactly @sizeOf(T).
315pub fn readIntLE(comptime T: type, bytes: []const u8) -> T {315pub fn readIntLE(comptime T: type, bytes: []const u8) T {
316 if (T.is_signed) {316 if (T.is_signed) {
317 return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes));317 return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes));
318 }318 }
...@@ -327,7 +327,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) -> T {...@@ -327,7 +327,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) -> T {
327/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes327/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
328/// to fill the entire buffer provided.328/// to fill the entire buffer provided.
329/// value must be an integer.329/// value must be an integer.
330pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) {330pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) void {
331 const uint = @IntType(false, @typeOf(value).bit_count);331 const uint = @IntType(false, @typeOf(value).bit_count);
332 var bits = @truncate(uint, value);332 var bits = @truncate(uint, value);
333 switch (endian) {333 switch (endian) {
...@@ -351,7 +351,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) {...@@ -351,7 +351,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) {
351}351}
352352
353353
354pub fn hash_slice_u8(k: []const u8) -> u32 {354pub fn hash_slice_u8(k: []const u8) u32 {
355 // FNV 32-bit hash355 // FNV 32-bit hash
356 var h: u32 = 2166136261;356 var h: u32 = 2166136261;
357 for (k) |b| {357 for (k) |b| {
...@@ -360,7 +360,7 @@ pub fn hash_slice_u8(k: []const u8) -> u32 {...@@ -360,7 +360,7 @@ pub fn hash_slice_u8(k: []const u8) -> u32 {
360 return h;360 return h;
361}361}
362362
363pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {363pub fn eql_slice_u8(a: []const u8, b: []const u8) bool {
364 return eql(u8, a, b);364 return eql(u8, a, b);
365}365}
366366
...@@ -368,7 +368,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {...@@ -368,7 +368,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {
368/// any of the bytes in `split_bytes`.368/// any of the bytes in `split_bytes`.
369/// split(" abc def ghi ", " ")369/// split(" abc def ghi ", " ")
370/// Will return slices for "abc", "def", "ghi", null, in that order.370/// Will return slices for "abc", "def", "ghi", null, in that order.
371pub fn split(buffer: []const u8, split_bytes: []const u8) -> SplitIterator {371pub fn split(buffer: []const u8, split_bytes: []const u8) SplitIterator {
372 return SplitIterator {372 return SplitIterator {
373 .index = 0,373 .index = 0,
374 .buffer = buffer,374 .buffer = buffer,
...@@ -384,7 +384,7 @@ test "mem.split" {...@@ -384,7 +384,7 @@ test "mem.split" {
384 assert(it.next() == null);384 assert(it.next() == null);
385}385}
386386
387pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) -> bool {387pub fn startsWith(comptime T: type, haystack: []const T, needle: []const T) bool {
388 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);388 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);
389}389}
390390
...@@ -393,7 +393,7 @@ const SplitIterator = struct {...@@ -393,7 +393,7 @@ const SplitIterator = struct {
393 split_bytes: []const u8, 393 split_bytes: []const u8,
394 index: usize,394 index: usize,
395395
396 pub fn next(self: &SplitIterator) -> ?[]const u8 {396 pub fn next(self: &SplitIterator) ?[]const u8 {
397 // move to beginning of token397 // move to beginning of token
398 while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}398 while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
399 const start = self.index;399 const start = self.index;
...@@ -409,14 +409,14 @@ const SplitIterator = struct {...@@ -409,14 +409,14 @@ const SplitIterator = struct {
409 }409 }
410410
411 /// Returns a slice of the remaining bytes. Does not affect iterator state.411 /// Returns a slice of the remaining bytes. Does not affect iterator state.
412 pub fn rest(self: &const SplitIterator) -> []const u8 {412 pub fn rest(self: &const SplitIterator) []const u8 {
413 // move to beginning of token413 // move to beginning of token
414 var index: usize = self.index;414 var index: usize = self.index;
415 while (index < self.buffer.len and self.isSplitByte(self.buffer[index])) : (index += 1) {}415 while (index < self.buffer.len and self.isSplitByte(self.buffer[index])) : (index += 1) {}
416 return self.buffer[index..];416 return self.buffer[index..];
417 }417 }
418418
419 fn isSplitByte(self: &const SplitIterator, byte: u8) -> bool {419 fn isSplitByte(self: &const SplitIterator, byte: u8) bool {
420 for (self.split_bytes) |split_byte| {420 for (self.split_bytes) |split_byte| {
421 if (byte == split_byte) {421 if (byte == split_byte) {
422 return true;422 return true;
...@@ -428,7 +428,7 @@ const SplitIterator = struct {...@@ -428,7 +428,7 @@ const SplitIterator = struct {
428428
429/// Naively combines a series of strings with a separator.429/// Naively combines a series of strings with a separator.
430/// Allocates memory for the result, which must be freed by the caller.430/// Allocates memory for the result, which must be freed by the caller.
431pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {431pub fn join(allocator: &Allocator, sep: u8, strings: ...) %[]u8 {
432 comptime assert(strings.len >= 1);432 comptime assert(strings.len >= 1);
433 var total_strings_len: usize = strings.len; // 1 sep per string433 var total_strings_len: usize = strings.len; // 1 sep per string
434 {434 {
...@@ -440,7 +440,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {...@@ -440,7 +440,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
440 }440 }
441441
442 const buf = try allocator.alloc(u8, total_strings_len);442 const buf = try allocator.alloc(u8, total_strings_len);
443 %defer allocator.free(buf);443 errdefer allocator.free(buf);
444444
445 var buf_index: usize = 0;445 var buf_index: usize = 0;
446 comptime var string_i = 0;446 comptime var string_i = 0;
...@@ -474,7 +474,7 @@ test "testReadInt" {...@@ -474,7 +474,7 @@ test "testReadInt" {
474 testReadIntImpl();474 testReadIntImpl();
475 comptime testReadIntImpl();475 comptime testReadIntImpl();
476}476}
477fn testReadIntImpl() {477fn testReadIntImpl() void {
478 {478 {
479 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };479 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };
480 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);480 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
...@@ -507,7 +507,7 @@ test "testWriteInt" {...@@ -507,7 +507,7 @@ test "testWriteInt" {
507 testWriteIntImpl();507 testWriteIntImpl();
508 comptime testWriteIntImpl();508 comptime testWriteIntImpl();
509}509}
510fn testWriteIntImpl() {510fn testWriteIntImpl() void {
511 var bytes: [4]u8 = undefined;511 var bytes: [4]u8 = undefined;
512512
513 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);513 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
...@@ -524,7 +524,7 @@ fn testWriteIntImpl() {...@@ -524,7 +524,7 @@ fn testWriteIntImpl() {
524}524}
525525
526526
527pub fn min(comptime T: type, slice: []const T) -> T {527pub fn min(comptime T: type, slice: []const T) T {
528 var best = slice[0];528 var best = slice[0];
529 for (slice[1..]) |item| {529 for (slice[1..]) |item| {
530 best = math.min(best, item);530 best = math.min(best, item);
...@@ -536,7 +536,7 @@ test "mem.min" {...@@ -536,7 +536,7 @@ test "mem.min" {
536 assert(min(u8, "abcdefg") == 'a');536 assert(min(u8, "abcdefg") == 'a');
537}537}
538538
539pub fn max(comptime T: type, slice: []const T) -> T {539pub fn max(comptime T: type, slice: []const T) T {
540 var best = slice[0];540 var best = slice[0];
541 for (slice[1..]) |item| {541 for (slice[1..]) |item| {
542 best = math.max(best, item);542 best = math.max(best, item);
...@@ -548,14 +548,14 @@ test "mem.max" {...@@ -548,14 +548,14 @@ test "mem.max" {
548 assert(max(u8, "abcdefg") == 'g');548 assert(max(u8, "abcdefg") == 'g');
549}549}
550550
551pub fn swap(comptime T: type, a: &T, b: &T) {551pub fn swap(comptime T: type, a: &T, b: &T) void {
552 const tmp = *a;552 const tmp = *a;
553 *a = *b;553 *a = *b;
554 *b = tmp;554 *b = tmp;
555}555}
556556
557/// In-place order reversal of a slice557/// In-place order reversal of a slice
558pub fn reverse(comptime T: type, items: []T) {558pub fn reverse(comptime T: type, items: []T) void {
559 var i: usize = 0;559 var i: usize = 0;
560 const end = items.len / 2;560 const end = items.len / 2;
561 while (i < end) : (i += 1) {561 while (i < end) : (i += 1) {
...@@ -572,7 +572,7 @@ test "std.mem.reverse" {...@@ -572,7 +572,7 @@ test "std.mem.reverse" {
572572
573/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)573/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
574/// Assumes 0 <= amount <= items.len574/// Assumes 0 <= amount <= items.len
575pub fn rotate(comptime T: type, items: []T, amount: usize) {575pub fn rotate(comptime T: type, items: []T, amount: usize) void {
576 reverse(T, items[0..amount]);576 reverse(T, items[0..amount]);
577 reverse(T, items[amount..]);577 reverse(T, items[amount..]);
578 reverse(T, items);578 reverse(T, items);
std/net.zig+10-10
...@@ -17,7 +17,7 @@ error BadFd;...@@ -17,7 +17,7 @@ error BadFd;
17const Connection = struct {17const Connection = struct {
18 socket_fd: i32,18 socket_fd: i32,
1919
20 pub fn send(c: Connection, buf: []const u8) -> %usize {20 pub fn send(c: Connection, buf: []const u8) %usize {
21 const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);21 const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
22 const send_err = linux.getErrno(send_ret);22 const send_err = linux.getErrno(send_ret);
23 switch (send_err) {23 switch (send_err) {
...@@ -31,7 +31,7 @@ const Connection = struct {...@@ -31,7 +31,7 @@ const Connection = struct {
31 }31 }
32 }32 }
3333
34 pub fn recv(c: Connection, buf: []u8) -> %[]u8 {34 pub fn recv(c: Connection, buf: []u8) %[]u8 {
35 const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);35 const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
36 const recv_err = linux.getErrno(recv_ret);36 const recv_err = linux.getErrno(recv_ret);
37 switch (recv_err) {37 switch (recv_err) {
...@@ -48,7 +48,7 @@ const Connection = struct {...@@ -48,7 +48,7 @@ const Connection = struct {
48 }48 }
49 }49 }
5050
51 pub fn close(c: Connection) -> %void {51 pub fn close(c: Connection) %void {
52 switch (linux.getErrno(linux.close(c.socket_fd))) {52 switch (linux.getErrno(linux.close(c.socket_fd))) {
53 0 => return,53 0 => return,
54 linux.EBADF => unreachable,54 linux.EBADF => unreachable,
...@@ -66,7 +66,7 @@ const Address = struct {...@@ -66,7 +66,7 @@ const Address = struct {
66 sort_key: i32,66 sort_key: i32,
67};67};
6868
69pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {69pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
70 if (hostname.len == 0) {70 if (hostname.len == 0) {
7171
72 unreachable; // TODO72 unreachable; // TODO
...@@ -75,7 +75,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {...@@ -75,7 +75,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
75 unreachable; // TODO75 unreachable; // TODO
76}76}
7777
78pub fn connectAddr(addr: &Address, port: u16) -> %Connection {78pub fn connectAddr(addr: &Address, port: u16) %Connection {
79 const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);79 const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);
80 const socket_err = linux.getErrno(socket_ret);80 const socket_err = linux.getErrno(socket_ret);
81 if (socket_err > 0) {81 if (socket_err > 0) {
...@@ -118,7 +118,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {...@@ -118,7 +118,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
118 };118 };
119}119}
120120
121pub fn connect(hostname: []const u8, port: u16) -> %Connection {121pub fn connect(hostname: []const u8, port: u16) %Connection {
122 var addrs_buf: [1]Address = undefined;122 var addrs_buf: [1]Address = undefined;
123 const addrs_slice = try lookup(hostname, addrs_buf[0..]);123 const addrs_slice = try lookup(hostname, addrs_buf[0..]);
124 const main_addr = &addrs_slice[0];124 const main_addr = &addrs_slice[0];
...@@ -128,12 +128,12 @@ pub fn connect(hostname: []const u8, port: u16) -> %Connection {...@@ -128,12 +128,12 @@ pub fn connect(hostname: []const u8, port: u16) -> %Connection {
128128
129error InvalidIpLiteral;129error InvalidIpLiteral;
130130
131pub fn parseIpLiteral(buf: []const u8) -> %Address {131pub fn parseIpLiteral(buf: []const u8) %Address {
132132
133 return error.InvalidIpLiteral;133 return error.InvalidIpLiteral;
134}134}
135135
136fn hexDigit(c: u8) -> u8 {136fn hexDigit(c: u8) u8 {
137 // TODO use switch with range137 // TODO use switch with range
138 if ('0' <= c and c <= '9') {138 if ('0' <= c and c <= '9') {
139 return c - '0';139 return c - '0';
...@@ -151,7 +151,7 @@ error Overflow;...@@ -151,7 +151,7 @@ error Overflow;
151error JunkAtEnd;151error JunkAtEnd;
152error Incomplete;152error Incomplete;
153153
154fn parseIp6(buf: []const u8) -> %Address {154fn parseIp6(buf: []const u8) %Address {
155 var result: Address = undefined;155 var result: Address = undefined;
156 result.family = linux.AF_INET6;156 result.family = linux.AF_INET6;
157 result.scope_id = 0;157 result.scope_id = 0;
...@@ -232,7 +232,7 @@ fn parseIp6(buf: []const u8) -> %Address {...@@ -232,7 +232,7 @@ fn parseIp6(buf: []const u8) -> %Address {
232 return error.Incomplete;232 return error.Incomplete;
233}233}
234234
235fn parseIp4(buf: []const u8) -> %u32 {235fn parseIp4(buf: []const u8) %u32 {
236 var result: u32 = undefined;236 var result: u32 = undefined;
237 const out_ptr = ([]u8)((&result)[0..1]);237 const out_ptr = ([]u8)((&result)[0..1]);
238238
std/os/child_process.zig+49-49
...@@ -37,7 +37,7 @@ pub const ChildProcess = struct {...@@ -37,7 +37,7 @@ pub const ChildProcess = struct {
37 pub argv: []const []const u8,37 pub argv: []const []const u8,
3838
39 /// Possibly called from a signal handler. Must set this before calling `spawn`.39 /// Possibly called from a signal handler. Must set this before calling `spawn`.
40 pub onTerm: ?fn(&ChildProcess),40 pub onTerm: ?fn(&ChildProcess)void,
4141
42 /// Leave as null to use the current env map using the supplied allocator.42 /// Leave as null to use the current env map using the supplied allocator.
43 pub env_map: ?&const BufMap,43 pub env_map: ?&const BufMap,
...@@ -74,9 +74,9 @@ pub const ChildProcess = struct {...@@ -74,9 +74,9 @@ pub const ChildProcess = struct {
7474
75 /// First argument in argv is the executable.75 /// First argument in argv is the executable.
76 /// On success must call deinit.76 /// On success must call deinit.
77 pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess {77 pub fn init(argv: []const []const u8, allocator: &mem.Allocator) %&ChildProcess {
78 const child = try allocator.create(ChildProcess);78 const child = try allocator.create(ChildProcess);
79 %defer allocator.destroy(child);79 errdefer allocator.destroy(child);
8080
81 *child = ChildProcess {81 *child = ChildProcess {
82 .allocator = allocator,82 .allocator = allocator,
...@@ -103,7 +103,7 @@ pub const ChildProcess = struct {...@@ -103,7 +103,7 @@ pub const ChildProcess = struct {
103 return child;103 return child;
104 }104 }
105105
106 pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void {106 pub fn setUserName(self: &ChildProcess, name: []const u8) %void {
107 const user_info = try os.getUserInfo(name);107 const user_info = try os.getUserInfo(name);
108 self.uid = user_info.uid;108 self.uid = user_info.uid;
109 self.gid = user_info.gid;109 self.gid = user_info.gid;
...@@ -111,7 +111,7 @@ pub const ChildProcess = struct {...@@ -111,7 +111,7 @@ pub const ChildProcess = struct {
111111
112 /// onTerm can be called before `spawn` returns.112 /// onTerm can be called before `spawn` returns.
113 /// On success must call `kill` or `wait`.113 /// On success must call `kill` or `wait`.
114 pub fn spawn(self: &ChildProcess) -> %void {114 pub fn spawn(self: &ChildProcess) %void {
115 if (is_windows) {115 if (is_windows) {
116 return self.spawnWindows();116 return self.spawnWindows();
117 } else {117 } else {
...@@ -119,13 +119,13 @@ pub const ChildProcess = struct {...@@ -119,13 +119,13 @@ pub const ChildProcess = struct {
119 }119 }
120 }120 }
121121
122 pub fn spawnAndWait(self: &ChildProcess) -> %Term {122 pub fn spawnAndWait(self: &ChildProcess) %Term {
123 try self.spawn();123 try self.spawn();
124 return self.wait();124 return self.wait();
125 }125 }
126126
127 /// Forcibly terminates child process and then cleans up all resources.127 /// Forcibly terminates child process and then cleans up all resources.
128 pub fn kill(self: &ChildProcess) -> %Term {128 pub fn kill(self: &ChildProcess) %Term {
129 if (is_windows) {129 if (is_windows) {
130 return self.killWindows(1);130 return self.killWindows(1);
131 } else {131 } else {
...@@ -133,7 +133,7 @@ pub const ChildProcess = struct {...@@ -133,7 +133,7 @@ pub const ChildProcess = struct {
133 }133 }
134 }134 }
135135
136 pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) -> %Term {136 pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) %Term {
137 if (self.term) |term| {137 if (self.term) |term| {
138 self.cleanupStreams();138 self.cleanupStreams();
139 return term;139 return term;
...@@ -149,7 +149,7 @@ pub const ChildProcess = struct {...@@ -149,7 +149,7 @@ pub const ChildProcess = struct {
149 return ??self.term;149 return ??self.term;
150 }150 }
151151
152 pub fn killPosix(self: &ChildProcess) -> %Term {152 pub fn killPosix(self: &ChildProcess) %Term {
153 block_SIGCHLD();153 block_SIGCHLD();
154 defer restore_SIGCHLD();154 defer restore_SIGCHLD();
155155
...@@ -172,7 +172,7 @@ pub const ChildProcess = struct {...@@ -172,7 +172,7 @@ pub const ChildProcess = struct {
172 }172 }
173173
174 /// Blocks until child process terminates and then cleans up all resources.174 /// Blocks until child process terminates and then cleans up all resources.
175 pub fn wait(self: &ChildProcess) -> %Term {175 pub fn wait(self: &ChildProcess) %Term {
176 if (is_windows) {176 if (is_windows) {
177 return self.waitWindows();177 return self.waitWindows();
178 } else {178 } else {
...@@ -189,7 +189,7 @@ pub const ChildProcess = struct {...@@ -189,7 +189,7 @@ pub const ChildProcess = struct {
189 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.189 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
190 /// If it succeeds, the caller owns result.stdout and result.stderr memory.190 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
191 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8,191 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8,
192 env_map: ?&const BufMap, max_output_size: usize) -> %ExecResult192 env_map: ?&const BufMap, max_output_size: usize) %ExecResult
193 {193 {
194 const child = try ChildProcess.init(argv, allocator);194 const child = try ChildProcess.init(argv, allocator);
195 defer child.deinit();195 defer child.deinit();
...@@ -220,7 +220,7 @@ pub const ChildProcess = struct {...@@ -220,7 +220,7 @@ pub const ChildProcess = struct {
220 };220 };
221 }221 }
222222
223 fn waitWindows(self: &ChildProcess) -> %Term {223 fn waitWindows(self: &ChildProcess) %Term {
224 if (self.term) |term| {224 if (self.term) |term| {
225 self.cleanupStreams();225 self.cleanupStreams();
226 return term;226 return term;
...@@ -230,7 +230,7 @@ pub const ChildProcess = struct {...@@ -230,7 +230,7 @@ pub const ChildProcess = struct {
230 return ??self.term;230 return ??self.term;
231 }231 }
232232
233 fn waitPosix(self: &ChildProcess) -> %Term {233 fn waitPosix(self: &ChildProcess) %Term {
234 block_SIGCHLD();234 block_SIGCHLD();
235 defer restore_SIGCHLD();235 defer restore_SIGCHLD();
236236
...@@ -243,11 +243,11 @@ pub const ChildProcess = struct {...@@ -243,11 +243,11 @@ pub const ChildProcess = struct {
243 return ??self.term;243 return ??self.term;
244 }244 }
245245
246 pub fn deinit(self: &ChildProcess) {246 pub fn deinit(self: &ChildProcess) void {
247 self.allocator.destroy(self);247 self.allocator.destroy(self);
248 }248 }
249249
250 fn waitUnwrappedWindows(self: &ChildProcess) -> %void {250 fn waitUnwrappedWindows(self: &ChildProcess) %void {
251 const result = os.windowsWaitSingle(self.handle, windows.INFINITE);251 const result = os.windowsWaitSingle(self.handle, windows.INFINITE);
252252
253 self.term = (%Term)(x: {253 self.term = (%Term)(x: {
...@@ -265,7 +265,7 @@ pub const ChildProcess = struct {...@@ -265,7 +265,7 @@ pub const ChildProcess = struct {
265 return result;265 return result;
266 }266 }
267267
268 fn waitUnwrapped(self: &ChildProcess) {268 fn waitUnwrapped(self: &ChildProcess) void {
269 var status: i32 = undefined;269 var status: i32 = undefined;
270 while (true) {270 while (true) {
271 const err = posix.getErrno(posix.waitpid(self.pid, &status, 0));271 const err = posix.getErrno(posix.waitpid(self.pid, &status, 0));
...@@ -281,7 +281,7 @@ pub const ChildProcess = struct {...@@ -281,7 +281,7 @@ pub const ChildProcess = struct {
281 }281 }
282 }282 }
283283
284 fn handleWaitResult(self: &ChildProcess, status: i32) {284 fn handleWaitResult(self: &ChildProcess, status: i32) void {
285 self.term = self.cleanupAfterWait(status);285 self.term = self.cleanupAfterWait(status);
286286
287 if (self.onTerm) |onTerm| {287 if (self.onTerm) |onTerm| {
...@@ -289,13 +289,13 @@ pub const ChildProcess = struct {...@@ -289,13 +289,13 @@ pub const ChildProcess = struct {
289 }289 }
290 }290 }
291291
292 fn cleanupStreams(self: &ChildProcess) {292 fn cleanupStreams(self: &ChildProcess) void {
293 if (self.stdin) |*stdin| { stdin.close(); self.stdin = null; }293 if (self.stdin) |*stdin| { stdin.close(); self.stdin = null; }
294 if (self.stdout) |*stdout| { stdout.close(); self.stdout = null; }294 if (self.stdout) |*stdout| { stdout.close(); self.stdout = null; }
295 if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }295 if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }
296 }296 }
297297
298 fn cleanupAfterWait(self: &ChildProcess, status: i32) -> %Term {298 fn cleanupAfterWait(self: &ChildProcess, status: i32) %Term {
299 children_nodes.remove(&self.llnode);299 children_nodes.remove(&self.llnode);
300300
301 defer {301 defer {
...@@ -319,7 +319,7 @@ pub const ChildProcess = struct {...@@ -319,7 +319,7 @@ pub const ChildProcess = struct {
319 return statusToTerm(status);319 return statusToTerm(status);
320 }320 }
321321
322 fn statusToTerm(status: i32) -> Term {322 fn statusToTerm(status: i32) Term {
323 return if (posix.WIFEXITED(status))323 return if (posix.WIFEXITED(status))
324 Term { .Exited = posix.WEXITSTATUS(status) }324 Term { .Exited = posix.WEXITSTATUS(status) }
325 else if (posix.WIFSIGNALED(status))325 else if (posix.WIFSIGNALED(status))
...@@ -331,18 +331,18 @@ pub const ChildProcess = struct {...@@ -331,18 +331,18 @@ pub const ChildProcess = struct {
331 ;331 ;
332 }332 }
333333
334 fn spawnPosix(self: &ChildProcess) -> %void {334 fn spawnPosix(self: &ChildProcess) %void {
335 // TODO atomically set a flag saying that we already did this335 // TODO atomically set a flag saying that we already did this
336 install_SIGCHLD_handler();336 install_SIGCHLD_handler();
337337
338 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;338 const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;
339 %defer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); };339 errdefer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); };
340340
341 const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;341 const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;
342 %defer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); };342 errdefer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); };
343343
344 const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;344 const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;
345 %defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };345 errdefer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };
346346
347 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);347 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
348 const dev_null_fd = if (any_ignore)348 const dev_null_fd = if (any_ignore)
...@@ -367,7 +367,7 @@ pub const ChildProcess = struct {...@@ -367,7 +367,7 @@ pub const ChildProcess = struct {
367 // This pipe is used to communicate errors between the time of fork367 // This pipe is used to communicate errors between the time of fork
368 // and execve from the child process to the parent process.368 // and execve from the child process to the parent process.
369 const err_pipe = try makePipe();369 const err_pipe = try makePipe();
370 %defer destroyPipe(err_pipe);370 errdefer destroyPipe(err_pipe);
371371
372 block_SIGCHLD();372 block_SIGCHLD();
373 const pid_result = posix.fork();373 const pid_result = posix.fork();
...@@ -440,7 +440,7 @@ pub const ChildProcess = struct {...@@ -440,7 +440,7 @@ pub const ChildProcess = struct {
440 if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }440 if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }
441 }441 }
442442
443 fn spawnWindows(self: &ChildProcess) -> %void {443 fn spawnWindows(self: &ChildProcess) %void {
444 const saAttr = windows.SECURITY_ATTRIBUTES {444 const saAttr = windows.SECURITY_ATTRIBUTES {
445 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),445 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
446 .bInheritHandle = windows.TRUE,446 .bInheritHandle = windows.TRUE,
...@@ -479,7 +479,7 @@ pub const ChildProcess = struct {...@@ -479,7 +479,7 @@ pub const ChildProcess = struct {
479 g_hChildStd_IN_Rd = null;479 g_hChildStd_IN_Rd = null;
480 },480 },
481 }481 }
482 %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr); };482 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_IN_Rd, g_hChildStd_IN_Wr); };
483483
484 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;484 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;
485 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;485 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
...@@ -497,7 +497,7 @@ pub const ChildProcess = struct {...@@ -497,7 +497,7 @@ pub const ChildProcess = struct {
497 g_hChildStd_OUT_Wr = null;497 g_hChildStd_OUT_Wr = null;
498 },498 },
499 }499 }
500 %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr); };500 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_OUT_Rd, g_hChildStd_OUT_Wr); };
501501
502 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;502 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;
503 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;503 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
...@@ -515,7 +515,7 @@ pub const ChildProcess = struct {...@@ -515,7 +515,7 @@ pub const ChildProcess = struct {
515 g_hChildStd_ERR_Wr = null;515 g_hChildStd_ERR_Wr = null;
516 },516 },
517 }517 }
518 %defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); };518 errdefer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); };
519519
520 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);520 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
521 defer self.allocator.free(cmd_line);521 defer self.allocator.free(cmd_line);
...@@ -623,7 +623,7 @@ pub const ChildProcess = struct {...@@ -623,7 +623,7 @@ pub const ChildProcess = struct {
623 if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }623 if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }
624 }624 }
625625
626 fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) -> %void {626 fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) %void {
627 switch (stdio) {627 switch (stdio) {
628 StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),628 StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
629 StdIo.Close => os.close(std_fileno),629 StdIo.Close => os.close(std_fileno),
...@@ -635,7 +635,7 @@ pub const ChildProcess = struct {...@@ -635,7 +635,7 @@ pub const ChildProcess = struct {
635};635};
636636
637fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8,637fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8,
638 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) -> %void638 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) %void
639{639{
640 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0,640 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0,
641 @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0)641 @ptrCast(?&c_void, envp_ptr), cwd_ptr, lpStartupInfo, lpProcessInformation) == 0)
...@@ -655,7 +655,7 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?...@@ -655,7 +655,7 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?
655655
656/// Caller must dealloc.656/// Caller must dealloc.
657/// Guarantees a null byte at result[result.len].657/// Guarantees a null byte at result[result.len].
658fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 {658fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) %[]u8 {
659 var buf = try Buffer.initSize(allocator, 0);659 var buf = try Buffer.initSize(allocator, 0);
660 defer buf.deinit();660 defer buf.deinit();
661661
...@@ -690,7 +690,7 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)...@@ -690,7 +690,7 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)
690 return buf.toOwnedSlice();690 return buf.toOwnedSlice();
691}691}
692692
693fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {693fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
694 if (rd) |h| os.close(h);694 if (rd) |h| os.close(h);
695 if (wr) |h| os.close(h);695 if (wr) |h| os.close(h);
696}696}
...@@ -700,7 +700,7 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {...@@ -700,7 +700,7 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {
700// a namespace field lookup700// a namespace field lookup
701const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;701const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
702702
703fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {703fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
704 if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {704 if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {
705 const err = windows.GetLastError();705 const err = windows.GetLastError();
706 return switch (err) {706 return switch (err) {
...@@ -709,7 +709,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR...@@ -709,7 +709,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR
709 }709 }
710}710}
711711
712fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) -> %void {712fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) %void {
713 if (windows.SetHandleInformation(h, mask, flags) == 0) {713 if (windows.SetHandleInformation(h, mask, flags) == 0) {
714 const err = windows.GetLastError();714 const err = windows.GetLastError();
715 return switch (err) {715 return switch (err) {
...@@ -718,27 +718,27 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D...@@ -718,27 +718,27 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
718 }718 }
719}719}
720720
721fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {721fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
722 var rd_h: windows.HANDLE = undefined;722 var rd_h: windows.HANDLE = undefined;
723 var wr_h: windows.HANDLE = undefined;723 var wr_h: windows.HANDLE = undefined;
724 try windowsMakePipe(&rd_h, &wr_h, sattr);724 try windowsMakePipe(&rd_h, &wr_h, sattr);
725 %defer windowsDestroyPipe(rd_h, wr_h);725 errdefer windowsDestroyPipe(rd_h, wr_h);
726 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);726 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
727 *rd = rd_h;727 *rd = rd_h;
728 *wr = wr_h;728 *wr = wr_h;
729}729}
730730
731fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {731fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
732 var rd_h: windows.HANDLE = undefined;732 var rd_h: windows.HANDLE = undefined;
733 var wr_h: windows.HANDLE = undefined;733 var wr_h: windows.HANDLE = undefined;
734 try windowsMakePipe(&rd_h, &wr_h, sattr);734 try windowsMakePipe(&rd_h, &wr_h, sattr);
735 %defer windowsDestroyPipe(rd_h, wr_h);735 errdefer windowsDestroyPipe(rd_h, wr_h);
736 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);736 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
737 *rd = rd_h;737 *rd = rd_h;
738 *wr = wr_h;738 *wr = wr_h;
739}739}
740740
741fn makePipe() -> %[2]i32 {741fn makePipe() %[2]i32 {
742 var fds: [2]i32 = undefined;742 var fds: [2]i32 = undefined;
743 const err = posix.getErrno(posix.pipe(&fds));743 const err = posix.getErrno(posix.pipe(&fds));
744 if (err > 0) {744 if (err > 0) {
...@@ -750,33 +750,33 @@ fn makePipe() -> %[2]i32 {...@@ -750,33 +750,33 @@ fn makePipe() -> %[2]i32 {
750 return fds;750 return fds;
751}751}
752752
753fn destroyPipe(pipe: &const [2]i32) {753fn destroyPipe(pipe: &const [2]i32) void {
754 os.close((*pipe)[0]);754 os.close((*pipe)[0]);
755 os.close((*pipe)[1]);755 os.close((*pipe)[1]);
756}756}
757757
758// Child of fork calls this to report an error to the fork parent.758// Child of fork calls this to report an error to the fork parent.
759// Then the child exits.759// Then the child exits.
760fn forkChildErrReport(fd: i32, err: error) -> noreturn {760fn forkChildErrReport(fd: i32, err: error) noreturn {
761 _ = writeIntFd(fd, ErrInt(err));761 _ = writeIntFd(fd, ErrInt(err));
762 posix.exit(1);762 posix.exit(1);
763}763}
764764
765const ErrInt = @IntType(false, @sizeOf(error) * 8);765const ErrInt = @IntType(false, @sizeOf(error) * 8);
766766
767fn writeIntFd(fd: i32, value: ErrInt) -> %void {767fn writeIntFd(fd: i32, value: ErrInt) %void {
768 var bytes: [@sizeOf(ErrInt)]u8 = undefined;768 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
769 mem.writeInt(bytes[0..], value, builtin.endian);769 mem.writeInt(bytes[0..], value, builtin.endian);
770 os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;770 os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;
771}771}
772772
773fn readIntFd(fd: i32) -> %ErrInt {773fn readIntFd(fd: i32) %ErrInt {
774 var bytes: [@sizeOf(ErrInt)]u8 = undefined;774 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
775 os.posixRead(fd, bytes[0..]) catch return error.SystemResources;775 os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
776 return mem.readInt(bytes[0..], ErrInt, builtin.endian);776 return mem.readInt(bytes[0..], ErrInt, builtin.endian);
777}777}
778778
779extern fn sigchld_handler(_: i32) {779extern fn sigchld_handler(_: i32) void {
780 while (true) {780 while (true) {
781 var status: i32 = undefined;781 var status: i32 = undefined;
782 const pid_result = posix.waitpid(-1, &status, posix.WNOHANG);782 const pid_result = posix.waitpid(-1, &status, posix.WNOHANG);
...@@ -794,7 +794,7 @@ extern fn sigchld_handler(_: i32) {...@@ -794,7 +794,7 @@ extern fn sigchld_handler(_: i32) {
794 }794 }
795}795}
796796
797fn handleTerm(pid: i32, status: i32) {797fn handleTerm(pid: i32, status: i32) void {
798 var it = children_nodes.first;798 var it = children_nodes.first;
799 while (it) |node| : (it = node.next) {799 while (it) |node| : (it = node.next) {
800 if (node.data.pid == pid) {800 if (node.data.pid == pid) {
...@@ -810,12 +810,12 @@ const sigchld_set = x: {...@@ -810,12 +810,12 @@ const sigchld_set = x: {
810 break :x signal_set;810 break :x signal_set;
811};811};
812812
813fn block_SIGCHLD() {813fn block_SIGCHLD() void {
814 const err = posix.getErrno(posix.sigprocmask(posix.SIG_BLOCK, &sigchld_set, null));814 const err = posix.getErrno(posix.sigprocmask(posix.SIG_BLOCK, &sigchld_set, null));
815 assert(err == 0);815 assert(err == 0);
816}816}
817817
818fn restore_SIGCHLD() {818fn restore_SIGCHLD() void {
819 const err = posix.getErrno(posix.sigprocmask(posix.SIG_UNBLOCK, &sigchld_set, null));819 const err = posix.getErrno(posix.sigprocmask(posix.SIG_UNBLOCK, &sigchld_set, null));
820 assert(err == 0);820 assert(err == 0);
821}821}
...@@ -826,7 +826,7 @@ const sigchld_action = posix.Sigaction {...@@ -826,7 +826,7 @@ const sigchld_action = posix.Sigaction {
826 .flags = posix.SA_RESTART | posix.SA_NOCLDSTOP,826 .flags = posix.SA_RESTART | posix.SA_NOCLDSTOP,
827};827};
828828
829fn install_SIGCHLD_handler() {829fn install_SIGCHLD_handler() void {
830 const err = posix.getErrno(posix.sigaction(posix.SIGCHLD, &sigchld_action, null));830 const err = posix.getErrno(posix.sigaction(posix.SIGCHLD, &sigchld_action, null));
831 assert(err == 0);831 assert(err == 0);
832}832}
std/os/darwin.zig+44-46
...@@ -98,67 +98,67 @@ pub const SIGINFO = 29; /// information request...@@ -98,67 +98,67 @@ pub const SIGINFO = 29; /// information request
98pub const SIGUSR1 = 30; /// user defined signal 198pub const SIGUSR1 = 30; /// user defined signal 1
99pub const SIGUSR2 = 31; /// user defined signal 299pub const SIGUSR2 = 31; /// user defined signal 2
100100
101fn wstatus(x: i32) -> i32 { return x & 0o177; }101fn wstatus(x: i32) i32 { return x & 0o177; }
102const wstopped = 0o177;102const wstopped = 0o177;
103pub fn WEXITSTATUS(x: i32) -> i32 { return x >> 8; }103pub fn WEXITSTATUS(x: i32) i32 { return x >> 8; }
104pub fn WTERMSIG(x: i32) -> i32 { return wstatus(x); }104pub fn WTERMSIG(x: i32) i32 { return wstatus(x); }
105pub fn WSTOPSIG(x: i32) -> i32 { return x >> 8; }105pub fn WSTOPSIG(x: i32) i32 { return x >> 8; }
106pub fn WIFEXITED(x: i32) -> bool { return wstatus(x) == 0; }106pub fn WIFEXITED(x: i32) bool { return wstatus(x) == 0; }
107pub fn WIFSTOPPED(x: i32) -> bool { return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13; }107pub fn WIFSTOPPED(x: i32) bool { return wstatus(x) == wstopped and WSTOPSIG(x) != 0x13; }
108pub fn WIFSIGNALED(x: i32) -> bool { return wstatus(x) != wstopped and wstatus(x) != 0; }108pub fn WIFSIGNALED(x: i32) bool { return wstatus(x) != wstopped and wstatus(x) != 0; }
109109
110/// Get the errno from a syscall return value, or 0 for no error.110/// Get the errno from a syscall return value, or 0 for no error.
111pub fn getErrno(r: usize) -> usize {111pub fn getErrno(r: usize) usize {
112 const signed_r = @bitCast(isize, r);112 const signed_r = @bitCast(isize, r);
113 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;113 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
114}114}
115115
116pub fn close(fd: i32) -> usize {116pub fn close(fd: i32) usize {
117 return errnoWrap(c.close(fd));117 return errnoWrap(c.close(fd));
118}118}
119119
120pub fn abort() -> noreturn {120pub fn abort() noreturn {
121 c.abort();121 c.abort();
122}122}
123123
124pub fn exit(code: i32) -> noreturn {124pub fn exit(code: i32) noreturn {
125 c.exit(code);125 c.exit(code);
126}126}
127127
128pub fn isatty(fd: i32) -> bool {128pub fn isatty(fd: i32) bool {
129 return c.isatty(fd) != 0;129 return c.isatty(fd) != 0;
130}130}
131131
132pub fn fstat(fd: i32, buf: &c.Stat) -> usize {132pub fn fstat(fd: i32, buf: &c.Stat) usize {
133 return errnoWrap(c.@"fstat$INODE64"(fd, buf));133 return errnoWrap(c.@"fstat$INODE64"(fd, buf));
134}134}
135135
136pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {136pub fn lseek(fd: i32, offset: isize, whence: c_int) usize {
137 return errnoWrap(c.lseek(fd, offset, whence));137 return errnoWrap(c.lseek(fd, offset, whence));
138}138}
139139
140pub fn open(path: &const u8, flags: u32, mode: usize) -> usize {140pub fn open(path: &const u8, flags: u32, mode: usize) usize {
141 return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));141 return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));
142}142}
143143
144pub fn raise(sig: i32) -> usize {144pub fn raise(sig: i32) usize {
145 return errnoWrap(c.raise(sig));145 return errnoWrap(c.raise(sig));
146}146}
147147
148pub fn read(fd: i32, buf: &u8, nbyte: usize) -> usize {148pub fn read(fd: i32, buf: &u8, nbyte: usize) usize {
149 return errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte));149 return errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte));
150}150}
151151
152pub fn stat(noalias path: &const u8, noalias buf: &stat) -> usize {152pub fn stat(noalias path: &const u8, noalias buf: &stat) usize {
153 return errnoWrap(c.stat(path, buf));153 return errnoWrap(c.stat(path, buf));
154}154}
155155
156pub fn write(fd: i32, buf: &const u8, nbyte: usize) -> usize {156pub fn write(fd: i32, buf: &const u8, nbyte: usize) usize {
157 return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));157 return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));
158}158}
159159
160pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,160pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
161 offset: isize) -> usize161 offset: isize) usize
162{162{
163 const ptr_result = c.mmap(@ptrCast(&c_void, address), length,163 const ptr_result = c.mmap(@ptrCast(&c_void, address), length,
164 @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);164 @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
...@@ -166,87 +166,85 @@ pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,...@@ -166,87 +166,85 @@ pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
166 return errnoWrap(isize_result);166 return errnoWrap(isize_result);
167}167}
168168
169pub fn munmap(address: &u8, length: usize) -> usize {169pub fn munmap(address: &u8, length: usize) usize {
170 return errnoWrap(c.munmap(@ptrCast(&c_void, address), length));170 return errnoWrap(c.munmap(@ptrCast(&c_void, address), length));
171}171}
172172
173pub fn unlink(path: &const u8) -> usize {173pub fn unlink(path: &const u8) usize {
174 return errnoWrap(c.unlink(path));174 return errnoWrap(c.unlink(path));
175}175}
176176
177pub fn getcwd(buf: &u8, size: usize) -> usize {177pub fn getcwd(buf: &u8, size: usize) usize {
178 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0;178 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0;
179}179}
180180
181pub fn waitpid(pid: i32, status: &i32, options: u32) -> usize {181pub fn waitpid(pid: i32, status: &i32, options: u32) usize {
182 comptime assert(i32.bit_count == c_int.bit_count);182 comptime assert(i32.bit_count == c_int.bit_count);
183 return errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)));183 return errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)));
184}184}
185185
186pub fn fork() -> usize {186pub fn fork() usize {
187 return errnoWrap(c.fork());187 return errnoWrap(c.fork());
188}188}
189189
190pub fn pipe(fds: &[2]i32) -> usize {190pub fn pipe(fds: &[2]i32) usize {
191 comptime assert(i32.bit_count == c_int.bit_count);191 comptime assert(i32.bit_count == c_int.bit_count);
192 return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));192 return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));
193}193}
194194
195pub fn mkdir(path: &const u8, mode: u32) -> usize {195pub fn mkdir(path: &const u8, mode: u32) usize {
196 return errnoWrap(c.mkdir(path, mode));196 return errnoWrap(c.mkdir(path, mode));
197}197}
198198
199pub fn symlink(existing: &const u8, new: &const u8) -> usize {199pub fn symlink(existing: &const u8, new: &const u8) usize {
200 return errnoWrap(c.symlink(existing, new));200 return errnoWrap(c.symlink(existing, new));
201}201}
202202
203pub fn rename(old: &const u8, new: &const u8) -> usize {203pub fn rename(old: &const u8, new: &const u8) usize {
204 return errnoWrap(c.rename(old, new));204 return errnoWrap(c.rename(old, new));
205}205}
206206
207pub fn chdir(path: &const u8) -> usize {207pub fn chdir(path: &const u8) usize {
208 return errnoWrap(c.chdir(path));208 return errnoWrap(c.chdir(path));
209}209}
210210
211pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8)211pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) usize {
212 -> usize
213{
214 return errnoWrap(c.execve(path, argv, envp));212 return errnoWrap(c.execve(path, argv, envp));
215}213}
216214
217pub fn dup2(old: i32, new: i32) -> usize {215pub fn dup2(old: i32, new: i32) usize {
218 return errnoWrap(c.dup2(old, new));216 return errnoWrap(c.dup2(old, new));
219}217}
220218
221pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {219pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) usize {
222 return errnoWrap(c.readlink(path, buf_ptr, buf_len));220 return errnoWrap(c.readlink(path, buf_ptr, buf_len));
223}221}
224222
225pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {223pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {
226 return errnoWrap(c.nanosleep(req, rem));224 return errnoWrap(c.nanosleep(req, rem));
227}225}
228226
229pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) -> usize {227pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) usize {
230 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0;228 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0;
231}229}
232230
233pub fn setreuid(ruid: u32, euid: u32) -> usize {231pub fn setreuid(ruid: u32, euid: u32) usize {
234 return errnoWrap(c.setreuid(ruid, euid));232 return errnoWrap(c.setreuid(ruid, euid));
235}233}
236234
237pub fn setregid(rgid: u32, egid: u32) -> usize {235pub fn setregid(rgid: u32, egid: u32) usize {
238 return errnoWrap(c.setregid(rgid, egid));236 return errnoWrap(c.setregid(rgid, egid));
239}237}
240238
241pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) -> usize {239pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) usize {
242 return errnoWrap(c.sigprocmask(@bitCast(c_int, flags), set, oldset));240 return errnoWrap(c.sigprocmask(@bitCast(c_int, flags), set, oldset));
243}241}
244242
245pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> usize {243pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {
246 assert(sig != SIGKILL);244 assert(sig != SIGKILL);
247 assert(sig != SIGSTOP);245 assert(sig != SIGSTOP);
248 var cact = c.Sigaction {246 var cact = c.Sigaction {
249 .handler = @ptrCast(extern fn(c_int), act.handler),247 .handler = @ptrCast(extern fn(c_int)void, act.handler),
250 .sa_flags = @bitCast(c_int, act.flags),248 .sa_flags = @bitCast(c_int, act.flags),
251 .sa_mask = act.mask,249 .sa_mask = act.mask,
252 };250 };
...@@ -257,7 +255,7 @@ pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigacti...@@ -257,7 +255,7 @@ pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigacti
257 }255 }
258 if (oact) |old| {256 if (oact) |old| {
259 *old = Sigaction {257 *old = Sigaction {
260 .handler = @ptrCast(extern fn(i32), coact.handler),258 .handler = @ptrCast(extern fn(i32)void, coact.handler),
261 .flags = @bitCast(u32, coact.sa_flags),259 .flags = @bitCast(u32, coact.sa_flags),
262 .mask = coact.sa_mask,260 .mask = coact.sa_mask,
263 };261 };
...@@ -273,18 +271,18 @@ pub const Stat = c.Stat;...@@ -273,18 +271,18 @@ pub const Stat = c.Stat;
273271
274/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.272/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
275pub const Sigaction = struct {273pub const Sigaction = struct {
276 handler: extern fn(i32),274 handler: extern fn(i32)void,
277 mask: sigset_t,275 mask: sigset_t,
278 flags: u32,276 flags: u32,
279};277};
280278
281pub fn sigaddset(set: &sigset_t, signo: u5) {279pub fn sigaddset(set: &sigset_t, signo: u5) void {
282 *set |= u32(1) << (signo - 1);280 *set |= u32(1) << (signo - 1);
283}281}
284282
285/// Takes the return value from a syscall and formats it back in the way283/// Takes the return value from a syscall and formats it back in the way
286/// that the kernel represents it to libc. Errno was a mistake, let's make284/// that the kernel represents it to libc. Errno was a mistake, let's make
287/// it go away forever.285/// it go away forever.
288fn errnoWrap(value: isize) -> usize {286fn errnoWrap(value: isize) usize {
289 return @bitCast(usize, if (value == -1) -isize(*c._errno()) else value);287 return @bitCast(usize, if (value == -1) -isize(*c._errno()) else value);
290}288}
std/os/get_user_id.zig+2-2
...@@ -9,7 +9,7 @@ pub const UserInfo = struct {...@@ -9,7 +9,7 @@ pub const UserInfo = struct {
9};9};
1010
11/// POSIX function which gets a uid from username.11/// POSIX function which gets a uid from username.
12pub fn getUserInfo(name: []const u8) -> %UserInfo {12pub fn getUserInfo(name: []const u8) %UserInfo {
13 return switch (builtin.os) {13 return switch (builtin.os) {
14 Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),14 Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),
15 else => @compileError("Unsupported OS"),15 else => @compileError("Unsupported OS"),
...@@ -30,7 +30,7 @@ error CorruptPasswordFile;...@@ -30,7 +30,7 @@ error CorruptPasswordFile;
30// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else30// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else
31// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`.31// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`.
3232
33pub fn posixGetUserInfo(name: []const u8) -> %UserInfo {33pub fn posixGetUserInfo(name: []const u8) %UserInfo {
34 var in_stream = try io.InStream.open("/etc/passwd", null);34 var in_stream = try io.InStream.open("/etc/passwd", null);
35 defer in_stream.close();35 defer in_stream.close();
3636
std/os/index.zig+82-80
...@@ -75,7 +75,7 @@ error WouldBlock;...@@ -75,7 +75,7 @@ error WouldBlock;
75/// Fills `buf` with random bytes. If linking against libc, this calls the75/// Fills `buf` with random bytes. If linking against libc, this calls the
76/// appropriate OS-specific library call. Otherwise it uses the zig standard76/// appropriate OS-specific library call. Otherwise it uses the zig standard
77/// library implementation.77/// library implementation.
78pub fn getRandomBytes(buf: []u8) -> %void {78pub fn getRandomBytes(buf: []u8) %void {
79 switch (builtin.os) {79 switch (builtin.os) {
80 Os.linux => while (true) {80 Os.linux => while (true) {
81 // TODO check libc version and potentially call c.getrandom.81 // TODO check libc version and potentially call c.getrandom.
...@@ -127,7 +127,8 @@ test "os.getRandomBytes" {...@@ -127,7 +127,8 @@ test "os.getRandomBytes" {
127/// Raises a signal in the current kernel thread, ending its execution.127/// Raises a signal in the current kernel thread, ending its execution.
128/// If linking against libc, this calls the abort() libc function. Otherwise128/// If linking against libc, this calls the abort() libc function. Otherwise
129/// it uses the zig standard library implementation.129/// it uses the zig standard library implementation.
130pub coldcc fn abort() -> noreturn {130pub fn abort() noreturn {
131 @setCold(true);
131 if (builtin.link_libc) {132 if (builtin.link_libc) {
132 c.abort();133 c.abort();
133 }134 }
...@@ -148,7 +149,8 @@ pub coldcc fn abort() -> noreturn {...@@ -148,7 +149,8 @@ pub coldcc fn abort() -> noreturn {
148}149}
149150
150/// Exits the program cleanly with the specified status code.151/// Exits the program cleanly with the specified status code.
151pub coldcc fn exit(status: u8) -> noreturn {152pub fn exit(status: u8) noreturn {
153 @setCold(true);
152 if (builtin.link_libc) {154 if (builtin.link_libc) {
153 c.exit(status);155 c.exit(status);
154 }156 }
...@@ -164,7 +166,7 @@ pub coldcc fn exit(status: u8) -> noreturn {...@@ -164,7 +166,7 @@ pub coldcc fn exit(status: u8) -> noreturn {
164}166}
165167
166/// Closes the file handle. Keeps trying if it gets interrupted by a signal.168/// Closes the file handle. Keeps trying if it gets interrupted by a signal.
167pub fn close(handle: FileHandle) {169pub fn close(handle: FileHandle) void {
168 if (is_windows) {170 if (is_windows) {
169 windows_util.windowsClose(handle);171 windows_util.windowsClose(handle);
170 } else {172 } else {
...@@ -180,7 +182,7 @@ pub fn close(handle: FileHandle) {...@@ -180,7 +182,7 @@ pub fn close(handle: FileHandle) {
180}182}
181183
182/// Calls POSIX read, and keeps trying if it gets interrupted.184/// Calls POSIX read, and keeps trying if it gets interrupted.
183pub fn posixRead(fd: i32, buf: []u8) -> %void {185pub fn posixRead(fd: i32, buf: []u8) %void {
184 var index: usize = 0;186 var index: usize = 0;
185 while (index < buf.len) {187 while (index < buf.len) {
186 const amt_written = posix.read(fd, &buf[index], buf.len - index);188 const amt_written = posix.read(fd, &buf[index], buf.len - index);
...@@ -211,7 +213,7 @@ error NoSpaceLeft;...@@ -211,7 +213,7 @@ error NoSpaceLeft;
211error BrokenPipe;213error BrokenPipe;
212214
213/// Calls POSIX write, and keeps trying if it gets interrupted.215/// Calls POSIX write, and keeps trying if it gets interrupted.
214pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {216pub fn posixWrite(fd: i32, bytes: []const u8) %void {
215 while (true) {217 while (true) {
216 const write_ret = posix.write(fd, bytes.ptr, bytes.len);218 const write_ret = posix.write(fd, bytes.ptr, bytes.len);
217 const write_err = posix.getErrno(write_ret);219 const write_err = posix.getErrno(write_ret);
...@@ -241,7 +243,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {...@@ -241,7 +243,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {
241/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.243/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
242/// Calls POSIX open, keeps trying if it gets interrupted, and translates244/// Calls POSIX open, keeps trying if it gets interrupted, and translates
243/// the return value into zig errors.245/// the return value into zig errors.
244pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) -> %i32 {246pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) %i32 {
245 var stack_buf: [max_noalloc_path_len]u8 = undefined;247 var stack_buf: [max_noalloc_path_len]u8 = undefined;
246 var path0: []u8 = undefined;248 var path0: []u8 = undefined;
247 var need_free = false;249 var need_free = false;
...@@ -290,7 +292,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al...@@ -290,7 +292,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
290 }292 }
291}293}
292294
293pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {295pub fn posixDup2(old_fd: i32, new_fd: i32) %void {
294 while (true) {296 while (true) {
295 const err = posix.getErrno(posix.dup2(old_fd, new_fd));297 const err = posix.getErrno(posix.dup2(old_fd, new_fd));
296 if (err > 0) {298 if (err > 0) {
...@@ -305,11 +307,11 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {...@@ -305,11 +307,11 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
305 }307 }
306}308}
307309
308pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 {310pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) %[]?&u8 {
309 const envp_count = env_map.count();311 const envp_count = env_map.count();
310 const envp_buf = try allocator.alloc(?&u8, envp_count + 1);312 const envp_buf = try allocator.alloc(?&u8, envp_count + 1);
311 mem.set(?&u8, envp_buf, null);313 mem.set(?&u8, envp_buf, null);
312 %defer freeNullDelimitedEnvMap(allocator, envp_buf);314 errdefer freeNullDelimitedEnvMap(allocator, envp_buf);
313 {315 {
314 var it = env_map.iterator();316 var it = env_map.iterator();
315 var i: usize = 0;317 var i: usize = 0;
...@@ -328,7 +330,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)...@@ -328,7 +330,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)
328 return envp_buf;330 return envp_buf;
329}331}
330332
331pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {333pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) void {
332 for (envp_buf) |env| {334 for (envp_buf) |env| {
333 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;335 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
334 allocator.free(env_buf);336 allocator.free(env_buf);
...@@ -342,7 +344,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {...@@ -342,7 +344,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
342/// `argv[0]` is the executable path.344/// `argv[0]` is the executable path.
343/// This function also uses the PATH environment variable to get the full path to the executable.345/// This function also uses the PATH environment variable to get the full path to the executable.
344pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,346pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
345 allocator: &Allocator) -> %void347 allocator: &Allocator) %void
346{348{
347 const argv_buf = try allocator.alloc(?&u8, argv.len + 1);349 const argv_buf = try allocator.alloc(?&u8, argv.len + 1);
348 mem.set(?&u8, argv_buf, null);350 mem.set(?&u8, argv_buf, null);
...@@ -398,7 +400,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,...@@ -398,7 +400,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
398 return posixExecveErrnoToErr(err);400 return posixExecveErrnoToErr(err);
399}401}
400402
401fn posixExecveErrnoToErr(err: usize) -> error {403fn posixExecveErrnoToErr(err: usize) error {
402 assert(err > 0);404 assert(err > 0);
403 return switch (err) {405 return switch (err) {
404 posix.EFAULT => unreachable,406 posix.EFAULT => unreachable,
...@@ -417,9 +419,9 @@ fn posixExecveErrnoToErr(err: usize) -> error {...@@ -417,9 +419,9 @@ fn posixExecveErrnoToErr(err: usize) -> error {
417pub var posix_environ_raw: []&u8 = undefined;419pub var posix_environ_raw: []&u8 = undefined;
418420
419/// Caller must free result when done.421/// Caller must free result when done.
420pub fn getEnvMap(allocator: &Allocator) -> %BufMap {422pub fn getEnvMap(allocator: &Allocator) %BufMap {
421 var result = BufMap.init(allocator);423 var result = BufMap.init(allocator);
422 %defer result.deinit();424 errdefer result.deinit();
423425
424 if (is_windows) {426 if (is_windows) {
425 const ptr = windows.GetEnvironmentStringsA() ?? return error.OutOfMemory;427 const ptr = windows.GetEnvironmentStringsA() ?? return error.OutOfMemory;
...@@ -461,7 +463,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap {...@@ -461,7 +463,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap {
461 }463 }
462}464}
463465
464pub fn getEnvPosix(key: []const u8) -> ?[]const u8 {466pub fn getEnvPosix(key: []const u8) ?[]const u8 {
465 for (posix_environ_raw) |ptr| {467 for (posix_environ_raw) |ptr| {
466 var line_i: usize = 0;468 var line_i: usize = 0;
467 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}469 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
...@@ -481,13 +483,13 @@ pub fn getEnvPosix(key: []const u8) -> ?[]const u8 {...@@ -481,13 +483,13 @@ pub fn getEnvPosix(key: []const u8) -> ?[]const u8 {
481error EnvironmentVariableNotFound;483error EnvironmentVariableNotFound;
482484
483/// Caller must free returned memory.485/// Caller must free returned memory.
484pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {486pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) %[]u8 {
485 if (is_windows) {487 if (is_windows) {
486 const key_with_null = try cstr.addNullByte(allocator, key);488 const key_with_null = try cstr.addNullByte(allocator, key);
487 defer allocator.free(key_with_null);489 defer allocator.free(key_with_null);
488490
489 var buf = try allocator.alloc(u8, 256);491 var buf = try allocator.alloc(u8, 256);
490 %defer allocator.free(buf);492 errdefer allocator.free(buf);
491493
492 while (true) {494 while (true) {
493 const windows_buf_len = try math.cast(windows.DWORD, buf.len);495 const windows_buf_len = try math.cast(windows.DWORD, buf.len);
...@@ -515,11 +517,11 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {...@@ -515,11 +517,11 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {
515}517}
516518
517/// Caller must free the returned memory.519/// Caller must free the returned memory.
518pub fn getCwd(allocator: &Allocator) -> %[]u8 {520pub fn getCwd(allocator: &Allocator) %[]u8 {
519 switch (builtin.os) {521 switch (builtin.os) {
520 Os.windows => {522 Os.windows => {
521 var buf = try allocator.alloc(u8, 256);523 var buf = try allocator.alloc(u8, 256);
522 %defer allocator.free(buf);524 errdefer allocator.free(buf);
523525
524 while (true) {526 while (true) {
525 const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr);527 const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr);
...@@ -541,7 +543,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {...@@ -541,7 +543,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
541 },543 },
542 else => {544 else => {
543 var buf = try allocator.alloc(u8, 1024);545 var buf = try allocator.alloc(u8, 1024);
544 %defer allocator.free(buf);546 errdefer allocator.free(buf);
545 while (true) {547 while (true) {
546 const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));548 const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
547 if (err == posix.ERANGE) {549 if (err == posix.ERANGE) {
...@@ -562,7 +564,7 @@ test "os.getCwd" {...@@ -562,7 +564,7 @@ test "os.getCwd" {
562 _ = getCwd(debug.global_allocator);564 _ = getCwd(debug.global_allocator);
563}565}
564566
565pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {567pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {
566 if (is_windows) {568 if (is_windows) {
567 return symLinkWindows(allocator, existing_path, new_path);569 return symLinkWindows(allocator, existing_path, new_path);
568 } else {570 } else {
...@@ -570,7 +572,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con...@@ -570,7 +572,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
570 }572 }
571}573}
572574
573pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {575pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {
574 const existing_with_null = try cstr.addNullByte(allocator, existing_path);576 const existing_with_null = try cstr.addNullByte(allocator, existing_path);
575 defer allocator.free(existing_with_null);577 defer allocator.free(existing_with_null);
576 const new_with_null = try cstr.addNullByte(allocator, new_path);578 const new_with_null = try cstr.addNullByte(allocator, new_path);
...@@ -584,7 +586,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path...@@ -584,7 +586,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path
584 }586 }
585}587}
586588
587pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {589pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {
588 const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);590 const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);
589 defer allocator.free(full_buf);591 defer allocator.free(full_buf);
590592
...@@ -621,7 +623,7 @@ const b64_fs_encoder = base64.Base64Encoder.init(...@@ -621,7 +623,7 @@ const b64_fs_encoder = base64.Base64Encoder.init(
621 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
622 base64.standard_pad_char);624 base64.standard_pad_char);
623625
624pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {626pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) %void {
625 if (symLink(allocator, existing_path, new_path)) {627 if (symLink(allocator, existing_path, new_path)) {
626 return;628 return;
627 } else |err| {629 } else |err| {
...@@ -650,7 +652,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:...@@ -650,7 +652,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:
650652
651}653}
652654
653pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {655pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void {
654 if (builtin.os == Os.windows) {656 if (builtin.os == Os.windows) {
655 return deleteFileWindows(allocator, file_path);657 return deleteFileWindows(allocator, file_path);
656 } else {658 } else {
...@@ -661,7 +663,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {...@@ -661,7 +663,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {
661error FileNotFound;663error FileNotFound;
662error AccessDenied;664error AccessDenied;
663665
664pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void {666pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void {
665 const buf = try allocator.alloc(u8, file_path.len + 1);667 const buf = try allocator.alloc(u8, file_path.len + 1);
666 defer allocator.free(buf);668 defer allocator.free(buf);
667669
...@@ -679,7 +681,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void...@@ -679,7 +681,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void
679 }681 }
680}682}
681683
682pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {684pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void {
683 const buf = try allocator.alloc(u8, file_path.len + 1);685 const buf = try allocator.alloc(u8, file_path.len + 1);
684 defer allocator.free(buf);686 defer allocator.free(buf);
685687
...@@ -706,13 +708,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {...@@ -706,13 +708,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {
706}708}
707709
708/// Calls ::copyFileMode with 0o666 for the mode.710/// Calls ::copyFileMode with 0o666 for the mode.
709pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) -> %void {711pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []const u8) %void {
710 return copyFileMode(allocator, source_path, dest_path, 0o666);712 return copyFileMode(allocator, source_path, dest_path, 0o666);
711}713}
712714
713// TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open715// TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open
714/// Guaranteed to be atomic.716/// Guaranteed to be atomic.
715pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void {717pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) %void {
716 var rand_buf: [12]u8 = undefined;718 var rand_buf: [12]u8 = undefined;
717 const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));719 const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
718 defer allocator.free(tmp_path);720 defer allocator.free(tmp_path);
...@@ -722,7 +724,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [...@@ -722,7 +724,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [
722724
723 var out_file = try io.File.openWriteMode(tmp_path, mode, allocator);725 var out_file = try io.File.openWriteMode(tmp_path, mode, allocator);
724 defer out_file.close();726 defer out_file.close();
725 %defer _ = deleteFile(allocator, tmp_path);727 errdefer _ = deleteFile(allocator, tmp_path);
726728
727 var in_file = try io.File.openRead(source_path, allocator);729 var in_file = try io.File.openRead(source_path, allocator);
728 defer in_file.close();730 defer in_file.close();
...@@ -736,7 +738,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [...@@ -736,7 +738,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [
736 }738 }
737}739}
738740
739pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) -> %void {741pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) %void {
740 const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);742 const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);
741 defer allocator.free(full_buf);743 defer allocator.free(full_buf);
742744
...@@ -781,7 +783,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)...@@ -781,7 +783,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
781 }783 }
782}784}
783785
784pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {786pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void {
785 if (is_windows) {787 if (is_windows) {
786 return makeDirWindows(allocator, dir_path);788 return makeDirWindows(allocator, dir_path);
787 } else {789 } else {
...@@ -789,7 +791,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {...@@ -789,7 +791,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {
789 }791 }
790}792}
791793
792pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {794pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void {
793 const path_buf = try cstr.addNullByte(allocator, dir_path);795 const path_buf = try cstr.addNullByte(allocator, dir_path);
794 defer allocator.free(path_buf);796 defer allocator.free(path_buf);
795797
...@@ -803,7 +805,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {...@@ -803,7 +805,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {
803 }805 }
804}806}
805807
806pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {808pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void {
807 const path_buf = try cstr.addNullByte(allocator, dir_path);809 const path_buf = try cstr.addNullByte(allocator, dir_path);
808 defer allocator.free(path_buf);810 defer allocator.free(path_buf);
809811
...@@ -829,7 +831,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {...@@ -829,7 +831,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {
829831
830/// Calls makeDir recursively to make an entire path. Returns success if the path832/// Calls makeDir recursively to make an entire path. Returns success if the path
831/// already exists and is a directory.833/// already exists and is a directory.
832pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {834pub fn makePath(allocator: &Allocator, full_path: []const u8) %void {
833 const resolved_path = try path.resolve(allocator, full_path);835 const resolved_path = try path.resolve(allocator, full_path);
834 defer allocator.free(resolved_path);836 defer allocator.free(resolved_path);
835837
...@@ -867,7 +869,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {...@@ -867,7 +869,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {
867869
868/// Returns ::error.DirNotEmpty if the directory is not empty.870/// Returns ::error.DirNotEmpty if the directory is not empty.
869/// To delete a directory recursively, see ::deleteTree871/// To delete a directory recursively, see ::deleteTree
870pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {872pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) %void {
871 const path_buf = try allocator.alloc(u8, dir_path.len + 1);873 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
872 defer allocator.free(path_buf);874 defer allocator.free(path_buf);
873875
...@@ -896,7 +898,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {...@@ -896,7 +898,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {
896/// removes it. If it cannot be removed because it is a non-empty directory,898/// removes it. If it cannot be removed because it is a non-empty directory,
897/// this function recursively removes its entries and then tries again.899/// this function recursively removes its entries and then tries again.
898// TODO non-recursive implementation900// TODO non-recursive implementation
899pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void {901pub fn deleteTree(allocator: &Allocator, full_path: []const u8) %void {
900 start_over: while (true) {902 start_over: while (true) {
901 // First, try deleting the item as a file. This way we don't follow sym links.903 // First, try deleting the item as a file. This way we don't follow sym links.
902 if (deleteFile(allocator, full_path)) {904 if (deleteFile(allocator, full_path)) {
...@@ -965,7 +967,7 @@ pub const Dir = struct {...@@ -965,7 +967,7 @@ pub const Dir = struct {
965 };967 };
966 };968 };
967969
968 pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir {970 pub fn open(allocator: &Allocator, dir_path: []const u8) %Dir {
969 const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);971 const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);
970 return Dir {972 return Dir {
971 .allocator = allocator,973 .allocator = allocator,
...@@ -976,14 +978,14 @@ pub const Dir = struct {...@@ -976,14 +978,14 @@ pub const Dir = struct {
976 };978 };
977 }979 }
978980
979 pub fn close(self: &Dir) {981 pub fn close(self: &Dir) void {
980 self.allocator.free(self.buf);982 self.allocator.free(self.buf);
981 os.close(self.fd);983 os.close(self.fd);
982 }984 }
983985
984 /// Memory such as file names referenced in this returned entry becomes invalid986 /// Memory such as file names referenced in this returned entry becomes invalid
985 /// with subsequent calls to next, as well as when this ::Dir is deinitialized.987 /// with subsequent calls to next, as well as when this ::Dir is deinitialized.
986 pub fn next(self: &Dir) -> %?Entry {988 pub fn next(self: &Dir) %?Entry {
987 start_over: while (true) {989 start_over: while (true) {
988 if (self.index >= self.end_index) {990 if (self.index >= self.end_index) {
989 if (self.buf.len == 0) {991 if (self.buf.len == 0) {
...@@ -1040,7 +1042,7 @@ pub const Dir = struct {...@@ -1040,7 +1042,7 @@ pub const Dir = struct {
1040 }1042 }
1041};1043};
10421044
1043pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {1045pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void {
1044 const path_buf = try allocator.alloc(u8, dir_path.len + 1);1046 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
1045 defer allocator.free(path_buf);1047 defer allocator.free(path_buf);
10461048
...@@ -1064,7 +1066,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {...@@ -1064,7 +1066,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
1064}1066}
10651067
1066/// Read value of a symbolic link.1068/// Read value of a symbolic link.
1067pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {1069pub fn readLink(allocator: &Allocator, pathname: []const u8) %[]u8 {
1068 const path_buf = try allocator.alloc(u8, pathname.len + 1);1070 const path_buf = try allocator.alloc(u8, pathname.len + 1);
1069 defer allocator.free(path_buf);1071 defer allocator.free(path_buf);
10701072
...@@ -1072,7 +1074,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {...@@ -1072,7 +1074,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1072 path_buf[pathname.len] = 0;1074 path_buf[pathname.len] = 0;
10731075
1074 var result_buf = try allocator.alloc(u8, 1024);1076 var result_buf = try allocator.alloc(u8, 1024);
1075 %defer allocator.free(result_buf);1077 errdefer allocator.free(result_buf);
1076 while (true) {1078 while (true) {
1077 const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len);1079 const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len);
1078 const err = posix.getErrno(ret_val);1080 const err = posix.getErrno(ret_val);
...@@ -1097,7 +1099,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {...@@ -1097,7 +1099,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1097 }1099 }
1098}1100}
10991101
1100pub fn sleep(seconds: usize, nanoseconds: usize) {1102pub fn sleep(seconds: usize, nanoseconds: usize) void {
1101 switch(builtin.os) {1103 switch(builtin.os) {
1102 Os.linux, Os.macosx, Os.ios => {1104 Os.linux, Os.macosx, Os.ios => {
1103 posixSleep(u63(seconds), u63(nanoseconds));1105 posixSleep(u63(seconds), u63(nanoseconds));
...@@ -1111,7 +1113,7 @@ pub fn sleep(seconds: usize, nanoseconds: usize) {...@@ -1111,7 +1113,7 @@ pub fn sleep(seconds: usize, nanoseconds: usize) {
1111}1113}
11121114
1113const u63 = @IntType(false, 63);1115const u63 = @IntType(false, 63);
1114pub fn posixSleep(seconds: u63, nanoseconds: u63) {1116pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
1115 var req = posix.timespec {1117 var req = posix.timespec {
1116 .tv_sec = seconds,1118 .tv_sec = seconds,
1117 .tv_nsec = nanoseconds,1119 .tv_nsec = nanoseconds,
...@@ -1145,7 +1147,7 @@ error ResourceLimitReached;...@@ -1145,7 +1147,7 @@ error ResourceLimitReached;
1145error InvalidUserId;1147error InvalidUserId;
1146error PermissionDenied;1148error PermissionDenied;
11471149
1148pub fn posix_setuid(uid: u32) -> %void {1150pub fn posix_setuid(uid: u32) %void {
1149 const err = posix.getErrno(posix.setuid(uid));1151 const err = posix.getErrno(posix.setuid(uid));
1150 if (err == 0) return;1152 if (err == 0) return;
1151 return switch (err) {1153 return switch (err) {
...@@ -1156,7 +1158,7 @@ pub fn posix_setuid(uid: u32) -> %void {...@@ -1156,7 +1158,7 @@ pub fn posix_setuid(uid: u32) -> %void {
1156 };1158 };
1157}1159}
11581160
1159pub fn posix_setreuid(ruid: u32, euid: u32) -> %void {1161pub fn posix_setreuid(ruid: u32, euid: u32) %void {
1160 const err = posix.getErrno(posix.setreuid(ruid, euid));1162 const err = posix.getErrno(posix.setreuid(ruid, euid));
1161 if (err == 0) return;1163 if (err == 0) return;
1162 return switch (err) {1164 return switch (err) {
...@@ -1167,7 +1169,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) -> %void {...@@ -1167,7 +1169,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) -> %void {
1167 };1169 };
1168}1170}
11691171
1170pub fn posix_setgid(gid: u32) -> %void {1172pub fn posix_setgid(gid: u32) %void {
1171 const err = posix.getErrno(posix.setgid(gid));1173 const err = posix.getErrno(posix.setgid(gid));
1172 if (err == 0) return;1174 if (err == 0) return;
1173 return switch (err) {1175 return switch (err) {
...@@ -1178,7 +1180,7 @@ pub fn posix_setgid(gid: u32) -> %void {...@@ -1178,7 +1180,7 @@ pub fn posix_setgid(gid: u32) -> %void {
1178 };1180 };
1179}1181}
11801182
1181pub fn posix_setregid(rgid: u32, egid: u32) -> %void {1183pub fn posix_setregid(rgid: u32, egid: u32) %void {
1182 const err = posix.getErrno(posix.setregid(rgid, egid));1184 const err = posix.getErrno(posix.setregid(rgid, egid));
1183 if (err == 0) return;1185 if (err == 0) return;
1184 return switch (err) {1186 return switch (err) {
...@@ -1190,7 +1192,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) -> %void {...@@ -1190,7 +1192,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) -> %void {
1190}1192}
11911193
1192error NoStdHandles;1194error NoStdHandles;
1193pub fn windowsGetStdHandle(handle_id: windows.DWORD) -> %windows.HANDLE {1195pub fn windowsGetStdHandle(handle_id: windows.DWORD) %windows.HANDLE {
1194 if (windows.GetStdHandle(handle_id)) |handle| {1196 if (windows.GetStdHandle(handle_id)) |handle| {
1195 if (handle == windows.INVALID_HANDLE_VALUE) {1197 if (handle == windows.INVALID_HANDLE_VALUE) {
1196 const err = windows.GetLastError();1198 const err = windows.GetLastError();
...@@ -1208,14 +1210,14 @@ pub const ArgIteratorPosix = struct {...@@ -1208,14 +1210,14 @@ pub const ArgIteratorPosix = struct {
1208 index: usize,1210 index: usize,
1209 count: usize,1211 count: usize,
12101212
1211 pub fn init() -> ArgIteratorPosix {1213 pub fn init() ArgIteratorPosix {
1212 return ArgIteratorPosix {1214 return ArgIteratorPosix {
1213 .index = 0,1215 .index = 0,
1214 .count = raw.len,1216 .count = raw.len,
1215 };1217 };
1216 }1218 }
12171219
1218 pub fn next(self: &ArgIteratorPosix) -> ?[]const u8 {1220 pub fn next(self: &ArgIteratorPosix) ?[]const u8 {
1219 if (self.index == self.count)1221 if (self.index == self.count)
1220 return null;1222 return null;
12211223
...@@ -1224,7 +1226,7 @@ pub const ArgIteratorPosix = struct {...@@ -1224,7 +1226,7 @@ pub const ArgIteratorPosix = struct {
1224 return cstr.toSlice(s);1226 return cstr.toSlice(s);
1225 }1227 }
12261228
1227 pub fn skip(self: &ArgIteratorPosix) -> bool {1229 pub fn skip(self: &ArgIteratorPosix) bool {
1228 if (self.index == self.count)1230 if (self.index == self.count)
1229 return false;1231 return false;
12301232
...@@ -1244,11 +1246,11 @@ pub const ArgIteratorWindows = struct {...@@ -1244,11 +1246,11 @@ pub const ArgIteratorWindows = struct {
1244 quote_count: usize,1246 quote_count: usize,
1245 seen_quote_count: usize,1247 seen_quote_count: usize,
12461248
1247 pub fn init() -> ArgIteratorWindows {1249 pub fn init() ArgIteratorWindows {
1248 return initWithCmdLine(windows.GetCommandLineA());1250 return initWithCmdLine(windows.GetCommandLineA());
1249 }1251 }
12501252
1251 pub fn initWithCmdLine(cmd_line: &const u8) -> ArgIteratorWindows {1253 pub fn initWithCmdLine(cmd_line: &const u8) ArgIteratorWindows {
1252 return ArgIteratorWindows {1254 return ArgIteratorWindows {
1253 .index = 0,1255 .index = 0,
1254 .cmd_line = cmd_line,1256 .cmd_line = cmd_line,
...@@ -1259,7 +1261,7 @@ pub const ArgIteratorWindows = struct {...@@ -1259,7 +1261,7 @@ pub const ArgIteratorWindows = struct {
1259 }1261 }
12601262
1261 /// You must free the returned memory when done.1263 /// You must free the returned memory when done.
1262 pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) -> ?%[]u8 {1264 pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?%[]u8 {
1263 // march forward over whitespace1265 // march forward over whitespace
1264 while (true) : (self.index += 1) {1266 while (true) : (self.index += 1) {
1265 const byte = self.cmd_line[self.index];1267 const byte = self.cmd_line[self.index];
...@@ -1273,7 +1275,7 @@ pub const ArgIteratorWindows = struct {...@@ -1273,7 +1275,7 @@ pub const ArgIteratorWindows = struct {
1273 return self.internalNext(allocator);1275 return self.internalNext(allocator);
1274 }1276 }
12751277
1276 pub fn skip(self: &ArgIteratorWindows) -> bool {1278 pub fn skip(self: &ArgIteratorWindows) bool {
1277 // march forward over whitespace1279 // march forward over whitespace
1278 while (true) : (self.index += 1) {1280 while (true) : (self.index += 1) {
1279 const byte = self.cmd_line[self.index];1281 const byte = self.cmd_line[self.index];
...@@ -1312,7 +1314,7 @@ pub const ArgIteratorWindows = struct {...@@ -1312,7 +1314,7 @@ pub const ArgIteratorWindows = struct {
1312 }1314 }
1313 }1315 }
13141316
1315 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 {1317 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) %[]u8 {
1316 var buf = try Buffer.initSize(allocator, 0);1318 var buf = try Buffer.initSize(allocator, 0);
1317 defer buf.deinit();1319 defer buf.deinit();
13181320
...@@ -1356,14 +1358,14 @@ pub const ArgIteratorWindows = struct {...@@ -1356,14 +1358,14 @@ pub const ArgIteratorWindows = struct {
1356 }1358 }
1357 }1359 }
13581360
1359 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {1361 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) %void {
1360 var i: usize = 0;1362 var i: usize = 0;
1361 while (i < emit_count) : (i += 1) {1363 while (i < emit_count) : (i += 1) {
1362 try buf.appendByte('\\');1364 try buf.appendByte('\\');
1363 }1365 }
1364 }1366 }
13651367
1366 fn countQuotes(cmd_line: &const u8) -> usize {1368 fn countQuotes(cmd_line: &const u8) usize {
1367 var result: usize = 0;1369 var result: usize = 0;
1368 var backslash_count: usize = 0;1370 var backslash_count: usize = 0;
1369 var index: usize = 0;1371 var index: usize = 0;
...@@ -1388,14 +1390,14 @@ pub const ArgIteratorWindows = struct {...@@ -1388,14 +1390,14 @@ pub const ArgIteratorWindows = struct {
1388pub const ArgIterator = struct {1390pub const ArgIterator = struct {
1389 inner: if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix,1391 inner: if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix,
13901392
1391 pub fn init() -> ArgIterator {1393 pub fn init() ArgIterator {
1392 return ArgIterator {1394 return ArgIterator {
1393 .inner = if (builtin.os == Os.windows) ArgIteratorWindows.init() else ArgIteratorPosix.init(),1395 .inner = if (builtin.os == Os.windows) ArgIteratorWindows.init() else ArgIteratorPosix.init(),
1394 };1396 };
1395 }1397 }
1396 1398
1397 /// You must free the returned memory when done.1399 /// You must free the returned memory when done.
1398 pub fn next(self: &ArgIterator, allocator: &Allocator) -> ?%[]u8 {1400 pub fn next(self: &ArgIterator, allocator: &Allocator) ?%[]u8 {
1399 if (builtin.os == Os.windows) {1401 if (builtin.os == Os.windows) {
1400 return self.inner.next(allocator);1402 return self.inner.next(allocator);
1401 } else {1403 } else {
...@@ -1404,23 +1406,23 @@ pub const ArgIterator = struct {...@@ -1404,23 +1406,23 @@ pub const ArgIterator = struct {
1404 }1406 }
14051407
1406 /// If you only are targeting posix you can call this and not need an allocator.1408 /// If you only are targeting posix you can call this and not need an allocator.
1407 pub fn nextPosix(self: &ArgIterator) -> ?[]const u8 {1409 pub fn nextPosix(self: &ArgIterator) ?[]const u8 {
1408 return self.inner.next();1410 return self.inner.next();
1409 }1411 }
14101412
1411 /// Parse past 1 argument without capturing it.1413 /// Parse past 1 argument without capturing it.
1412 /// Returns `true` if skipped an arg, `false` if we are at the end.1414 /// Returns `true` if skipped an arg, `false` if we are at the end.
1413 pub fn skip(self: &ArgIterator) -> bool {1415 pub fn skip(self: &ArgIterator) bool {
1414 return self.inner.skip();1416 return self.inner.skip();
1415 }1417 }
1416};1418};
14171419
1418pub fn args() -> ArgIterator {1420pub fn args() ArgIterator {
1419 return ArgIterator.init();1421 return ArgIterator.init();
1420}1422}
14211423
1422/// Caller must call freeArgs on result.1424/// Caller must call freeArgs on result.
1423pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {1425pub fn argsAlloc(allocator: &mem.Allocator) %[]const []u8 {
1424 // TODO refactor to only make 1 allocation.1426 // TODO refactor to only make 1 allocation.
1425 var it = args();1427 var it = args();
1426 var contents = try Buffer.initSize(allocator, 0);1428 var contents = try Buffer.initSize(allocator, 0);
...@@ -1441,7 +1443,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {...@@ -1441,7 +1443,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
1441 const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);1443 const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);
1442 const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len);1444 const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len);
1443 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);1445 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
1444 %defer allocator.free(buf);1446 errdefer allocator.free(buf);
14451447
1446 const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]);1448 const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]);
1447 const result_contents = buf[slice_list_bytes..];1449 const result_contents = buf[slice_list_bytes..];
...@@ -1457,7 +1459,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {...@@ -1457,7 +1459,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
1457 return result_slice_list;1459 return result_slice_list;
1458}1460}
14591461
1460pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) {1462pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
1461 var total_bytes: usize = 0;1463 var total_bytes: usize = 0;
1462 for (args_alloc) |arg| {1464 for (args_alloc) |arg| {
1463 total_bytes += @sizeOf([]u8) + arg.len;1465 total_bytes += @sizeOf([]u8) + arg.len;
...@@ -1479,7 +1481,7 @@ test "windows arg parsing" {...@@ -1479,7 +1481,7 @@ test "windows arg parsing" {
1479 [][]const u8{".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", ".\\..\\zig-cache", "--help"});1481 [][]const u8{".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", ".\\..\\zig-cache", "--help"});
1480}1482}
14811483
1482fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) {1484fn testWindowsCmdLine(input_cmd_line: &const u8, expected_args: []const []const u8) void {
1483 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);1485 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
1484 for (expected_args) |expected_arg| {1486 for (expected_args) |expected_arg| {
1485 const arg = ??it.next(debug.global_allocator) catch unreachable;1487 const arg = ??it.next(debug.global_allocator) catch unreachable;
...@@ -1509,7 +1511,7 @@ const unexpected_error_tracing = false;...@@ -1509,7 +1511,7 @@ const unexpected_error_tracing = false;
15091511
1510/// Call this when you made a syscall or something that sets errno1512/// Call this when you made a syscall or something that sets errno
1511/// and you get an unexpected error.1513/// and you get an unexpected error.
1512pub fn unexpectedErrorPosix(errno: usize) -> error {1514pub fn unexpectedErrorPosix(errno: usize) error {
1513 if (unexpected_error_tracing) {1515 if (unexpected_error_tracing) {
1514 debug.warn("unexpected errno: {}\n", errno);1516 debug.warn("unexpected errno: {}\n", errno);
1515 debug.dumpStackTrace();1517 debug.dumpStackTrace();
...@@ -1519,7 +1521,7 @@ pub fn unexpectedErrorPosix(errno: usize) -> error {...@@ -1519,7 +1521,7 @@ pub fn unexpectedErrorPosix(errno: usize) -> error {
15191521
1520/// Call this when you made a windows DLL call or something that does SetLastError1522/// Call this when you made a windows DLL call or something that does SetLastError
1521/// and you get an unexpected error.1523/// and you get an unexpected error.
1522pub fn unexpectedErrorWindows(err: windows.DWORD) -> error {1524pub fn unexpectedErrorWindows(err: windows.DWORD) error {
1523 if (unexpected_error_tracing) {1525 if (unexpected_error_tracing) {
1524 debug.warn("unexpected GetLastError(): {}\n", err);1526 debug.warn("unexpected GetLastError(): {}\n", err);
1525 debug.dumpStackTrace();1527 debug.dumpStackTrace();
...@@ -1527,7 +1529,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) -> error {...@@ -1527,7 +1529,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) -> error {
1527 return error.Unexpected;1529 return error.Unexpected;
1528}1530}
15291531
1530pub fn openSelfExe() -> %io.File {1532pub fn openSelfExe() %io.File {
1531 switch (builtin.os) {1533 switch (builtin.os) {
1532 Os.linux => {1534 Os.linux => {
1533 return io.File.openRead("/proc/self/exe", null);1535 return io.File.openRead("/proc/self/exe", null);
...@@ -1545,7 +1547,7 @@ pub fn openSelfExe() -> %io.File {...@@ -1545,7 +1547,7 @@ pub fn openSelfExe() -> %io.File {
1545/// This function may return an error if the current executable1547/// This function may return an error if the current executable
1546/// was deleted after spawning.1548/// was deleted after spawning.
1547/// Caller owns returned memory.1549/// Caller owns returned memory.
1548pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {1550pub fn selfExePath(allocator: &mem.Allocator) %[]u8 {
1549 switch (builtin.os) {1551 switch (builtin.os) {
1550 Os.linux => {1552 Os.linux => {
1551 // If the currently executing binary has been deleted,1553 // If the currently executing binary has been deleted,
...@@ -1554,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {...@@ -1554,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
1554 },1556 },
1555 Os.windows => {1557 Os.windows => {
1556 var out_path = try Buffer.initSize(allocator, 0xff);1558 var out_path = try Buffer.initSize(allocator, 0xff);
1557 %defer out_path.deinit();1559 errdefer out_path.deinit();
1558 while (true) {1560 while (true) {
1559 const dword_len = try math.cast(windows.DWORD, out_path.len());1561 const dword_len = try math.cast(windows.DWORD, out_path.len());
1560 const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);1562 const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);
...@@ -1577,7 +1579,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {...@@ -1577,7 +1579,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
1577 const ret1 = c._NSGetExecutablePath(undefined, &u32_len);1579 const ret1 = c._NSGetExecutablePath(undefined, &u32_len);
1578 assert(ret1 != 0);1580 assert(ret1 != 0);
1579 const bytes = try allocator.alloc(u8, u32_len);1581 const bytes = try allocator.alloc(u8, u32_len);
1580 %defer allocator.free(bytes);1582 errdefer allocator.free(bytes);
1581 const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len);1583 const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len);
1582 assert(ret2 == 0);1584 assert(ret2 == 0);
1583 return bytes;1585 return bytes;
...@@ -1588,7 +1590,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {...@@ -1588,7 +1590,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
15881590
1589/// Get the directory path that contains the current executable.1591/// Get the directory path that contains the current executable.
1590/// Caller owns returned memory.1592/// Caller owns returned memory.
1591pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {1593pub fn selfExeDirPath(allocator: &mem.Allocator) %[]u8 {
1592 switch (builtin.os) {1594 switch (builtin.os) {
1593 Os.linux => {1595 Os.linux => {
1594 // If the currently executing binary has been deleted,1596 // If the currently executing binary has been deleted,
...@@ -1596,13 +1598,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {...@@ -1596,13 +1598,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
1596 // This path cannot be opened, but it's valid for determining the directory1598 // This path cannot be opened, but it's valid for determining the directory
1597 // the executable was in when it was run.1599 // the executable was in when it was run.
1598 const full_exe_path = try readLink(allocator, "/proc/self/exe");1600 const full_exe_path = try readLink(allocator, "/proc/self/exe");
1599 %defer allocator.free(full_exe_path);1601 errdefer allocator.free(full_exe_path);
1600 const dir = path.dirname(full_exe_path);1602 const dir = path.dirname(full_exe_path);
1601 return allocator.shrink(u8, full_exe_path, dir.len);1603 return allocator.shrink(u8, full_exe_path, dir.len);
1602 },1604 },
1603 Os.windows, Os.macosx, Os.ios => {1605 Os.windows, Os.macosx, Os.ios => {
1604 const self_exe_path = try selfExePath(allocator);1606 const self_exe_path = try selfExePath(allocator);
1605 %defer allocator.free(self_exe_path);1607 errdefer allocator.free(self_exe_path);
1606 const dirname = os.path.dirname(self_exe_path);1608 const dirname = os.path.dirname(self_exe_path);
1607 return allocator.shrink(u8, self_exe_path, dirname.len);1609 return allocator.shrink(u8, self_exe_path, dirname.len);
1608 },1610 },
...@@ -1610,7 +1612,7 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {...@@ -1610,7 +1612,7 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
1610 }1612 }
1611}1613}
16121614
1613pub fn isTty(handle: FileHandle) -> bool {1615pub fn isTty(handle: FileHandle) bool {
1614 if (is_windows) {1616 if (is_windows) {
1615 return windows_util.windowsIsTty(handle);1617 return windows_util.windowsIsTty(handle);
1616 } else {1618 } else {
std/os/linux.zig+83-85
...@@ -368,14 +368,14 @@ pub const TFD_CLOEXEC = O_CLOEXEC;...@@ -368,14 +368,14 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
368pub const TFD_TIMER_ABSTIME = 1;368pub const TFD_TIMER_ABSTIME = 1;
369pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);369pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
370370
371fn unsigned(s: i32) -> u32 { return @bitCast(u32, s); }371fn unsigned(s: i32) u32 { return @bitCast(u32, s); }
372fn signed(s: u32) -> i32 { return @bitCast(i32, s); }372fn signed(s: u32) i32 { return @bitCast(i32, s); }
373pub fn WEXITSTATUS(s: i32) -> i32 { return signed((unsigned(s) & 0xff00) >> 8); }373pub fn WEXITSTATUS(s: i32) i32 { return signed((unsigned(s) & 0xff00) >> 8); }
374pub fn WTERMSIG(s: i32) -> i32 { return signed(unsigned(s) & 0x7f); }374pub fn WTERMSIG(s: i32) i32 { return signed(unsigned(s) & 0x7f); }
375pub fn WSTOPSIG(s: i32) -> i32 { return WEXITSTATUS(s); }375pub fn WSTOPSIG(s: i32) i32 { return WEXITSTATUS(s); }
376pub fn WIFEXITED(s: i32) -> bool { return WTERMSIG(s) == 0; }376pub fn WIFEXITED(s: i32) bool { return WTERMSIG(s) == 0; }
377pub fn WIFSTOPPED(s: i32) -> bool { return (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00; }377pub fn WIFSTOPPED(s: i32) bool { return (u16)(((unsigned(s)&0xffff)*%0x10001)>>8) > 0x7f00; }
378pub fn WIFSIGNALED(s: i32) -> bool { return (unsigned(s)&0xffff)-%1 < 0xff; }378pub fn WIFSIGNALED(s: i32) bool { return (unsigned(s)&0xffff)-%1 < 0xff; }
379379
380380
381pub const winsize = extern struct {381pub const winsize = extern struct {
...@@ -386,161 +386,159 @@ pub const winsize = extern struct {...@@ -386,161 +386,159 @@ pub const winsize = extern struct {
386};386};
387387
388/// Get the errno from a syscall return value, or 0 for no error.388/// Get the errno from a syscall return value, or 0 for no error.
389pub fn getErrno(r: usize) -> usize {389pub fn getErrno(r: usize) usize {
390 const signed_r = @bitCast(isize, r);390 const signed_r = @bitCast(isize, r);
391 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;391 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
392}392}
393393
394pub fn dup2(old: i32, new: i32) -> usize {394pub fn dup2(old: i32, new: i32) usize {
395 return arch.syscall2(arch.SYS_dup2, usize(old), usize(new));395 return arch.syscall2(arch.SYS_dup2, usize(old), usize(new));
396}396}
397397
398pub fn chdir(path: &const u8) -> usize {398pub fn chdir(path: &const u8) usize {
399 return arch.syscall1(arch.SYS_chdir, @ptrToInt(path));399 return arch.syscall1(arch.SYS_chdir, @ptrToInt(path));
400}400}
401401
402pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) -> usize {402pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) usize {
403 return arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));403 return arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));
404}404}
405405
406pub fn fork() -> usize {406pub fn fork() usize {
407 return arch.syscall0(arch.SYS_fork);407 return arch.syscall0(arch.SYS_fork);
408}408}
409409
410pub fn getcwd(buf: &u8, size: usize) -> usize {410pub fn getcwd(buf: &u8, size: usize) usize {
411 return arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size);411 return arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size);
412}412}
413413
414pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize {414pub fn getdents(fd: i32, dirp: &u8, count: usize) usize {
415 return arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count);415 return arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count);
416}416}
417417
418pub fn isatty(fd: i32) -> bool {418pub fn isatty(fd: i32) bool {
419 var wsz: winsize = undefined;419 var wsz: winsize = undefined;
420 return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;420 return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
421}421}
422422
423pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {423pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) usize {
424 return arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);424 return arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
425}425}
426426
427pub fn mkdir(path: &const u8, mode: u32) -> usize {427pub fn mkdir(path: &const u8, mode: u32) usize {
428 return arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode);428 return arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode);
429}429}
430430
431pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize)431pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) usize {
432 -> usize
433{
434 return arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),432 return arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
435 @bitCast(usize, offset));433 @bitCast(usize, offset));
436}434}
437435
438pub fn munmap(address: &u8, length: usize) -> usize {436pub fn munmap(address: &u8, length: usize) usize {
439 return arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length);437 return arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length);
440}438}
441439
442pub fn read(fd: i32, buf: &u8, count: usize) -> usize {440pub fn read(fd: i32, buf: &u8, count: usize) usize {
443 return arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count);441 return arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count);
444}442}
445443
446pub fn rmdir(path: &const u8) -> usize {444pub fn rmdir(path: &const u8) usize {
447 return arch.syscall1(arch.SYS_rmdir, @ptrToInt(path));445 return arch.syscall1(arch.SYS_rmdir, @ptrToInt(path));
448}446}
449447
450pub fn symlink(existing: &const u8, new: &const u8) -> usize {448pub fn symlink(existing: &const u8, new: &const u8) usize {
451 return arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new));449 return arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
452}450}
453451
454pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) -> usize {452pub fn pread(fd: i32, buf: &u8, count: usize, offset: usize) usize {
455 return arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset);453 return arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset);
456}454}
457455
458pub fn pipe(fd: &[2]i32) -> usize {456pub fn pipe(fd: &[2]i32) usize {
459 return pipe2(fd, 0);457 return pipe2(fd, 0);
460}458}
461459
462pub fn pipe2(fd: &[2]i32, flags: usize) -> usize {460pub fn pipe2(fd: &[2]i32, flags: usize) usize {
463 return arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags);461 return arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags);
464}462}
465463
466pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {464pub fn write(fd: i32, buf: &const u8, count: usize) usize {
467 return arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count);465 return arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count);
468}466}
469467
470pub fn pwrite(fd: i32, buf: &const u8, count: usize, offset: usize) -> usize {468pub fn pwrite(fd: i32, buf: &const u8, count: usize, offset: usize) usize {
471 return arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);469 return arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);
472}470}
473471
474pub fn rename(old: &const u8, new: &const u8) -> usize {472pub fn rename(old: &const u8, new: &const u8) usize {
475 return arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new));473 return arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new));
476}474}
477475
478pub fn open(path: &const u8, flags: u32, perm: usize) -> usize {476pub fn open(path: &const u8, flags: u32, perm: usize) usize {
479 return arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm);477 return arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm);
480}478}
481479
482pub fn create(path: &const u8, perm: usize) -> usize {480pub fn create(path: &const u8, perm: usize) usize {
483 return arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm);481 return arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm);
484}482}
485483
486pub fn openat(dirfd: i32, path: &const u8, flags: usize, mode: usize) -> usize {484pub fn openat(dirfd: i32, path: &const u8, flags: usize, mode: usize) usize {
487 return arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);485 return arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);
488}486}
489487
490pub fn close(fd: i32) -> usize {488pub fn close(fd: i32) usize {
491 return arch.syscall1(arch.SYS_close, usize(fd));489 return arch.syscall1(arch.SYS_close, usize(fd));
492}490}
493491
494pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize {492pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {
495 return arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos);493 return arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos);
496}494}
497495
498pub fn exit(status: i32) -> noreturn {496pub fn exit(status: i32) noreturn {
499 _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));497 _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));
500 unreachable;498 unreachable;
501}499}
502500
503pub fn getrandom(buf: &u8, count: usize, flags: u32) -> usize {501pub fn getrandom(buf: &u8, count: usize, flags: u32) usize {
504 return arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags));502 return arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags));
505}503}
506504
507pub fn kill(pid: i32, sig: i32) -> usize {505pub fn kill(pid: i32, sig: i32) usize {
508 return arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig));506 return arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig));
509}507}
510508
511pub fn unlink(path: &const u8) -> usize {509pub fn unlink(path: &const u8) usize {
512 return arch.syscall1(arch.SYS_unlink, @ptrToInt(path));510 return arch.syscall1(arch.SYS_unlink, @ptrToInt(path));
513}511}
514512
515pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize {513pub fn waitpid(pid: i32, status: &i32, options: i32) usize {
516 return arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);514 return arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
517}515}
518516
519pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {517pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {
520 return arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem));518 return arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem));
521}519}
522520
523pub fn setuid(uid: u32) -> usize {521pub fn setuid(uid: u32) usize {
524 return arch.syscall1(arch.SYS_setuid, uid);522 return arch.syscall1(arch.SYS_setuid, uid);
525}523}
526524
527pub fn setgid(gid: u32) -> usize {525pub fn setgid(gid: u32) usize {
528 return arch.syscall1(arch.SYS_setgid, gid);526 return arch.syscall1(arch.SYS_setgid, gid);
529}527}
530528
531pub fn setreuid(ruid: u32, euid: u32) -> usize {529pub fn setreuid(ruid: u32, euid: u32) usize {
532 return arch.syscall2(arch.SYS_setreuid, ruid, euid);530 return arch.syscall2(arch.SYS_setreuid, ruid, euid);
533}531}
534532
535pub fn setregid(rgid: u32, egid: u32) -> usize {533pub fn setregid(rgid: u32, egid: u32) usize {
536 return arch.syscall2(arch.SYS_setregid, rgid, egid);534 return arch.syscall2(arch.SYS_setregid, rgid, egid);
537}535}
538536
539pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) -> usize {537pub fn sigprocmask(flags: u32, noalias set: &const sigset_t, noalias oldset: ?&sigset_t) usize {
540 return arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8);538 return arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8);
541}539}
542540
543pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) -> usize {541pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigaction) usize {
544 assert(sig >= 1);542 assert(sig >= 1);
545 assert(sig != SIGKILL);543 assert(sig != SIGKILL);
546 assert(sig != SIGSTOP);544 assert(sig != SIGSTOP);
...@@ -548,7 +546,7 @@ pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigacti...@@ -548,7 +546,7 @@ pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigacti
548 .handler = act.handler,546 .handler = act.handler,
549 .flags = act.flags | SA_RESTORER,547 .flags = act.flags | SA_RESTORER,
550 .mask = undefined,548 .mask = undefined,
551 .restorer = @ptrCast(extern fn(), arch.restore_rt),549 .restorer = @ptrCast(extern fn()void, arch.restore_rt),
552 };550 };
553 var ksa_old: k_sigaction = undefined;551 var ksa_old: k_sigaction = undefined;
554 @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8);552 @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8);
...@@ -571,25 +569,25 @@ const all_mask = []usize{@maxValue(usize)};...@@ -571,25 +569,25 @@ const all_mask = []usize{@maxValue(usize)};
571const app_mask = []usize{0xfffffffc7fffffff};569const app_mask = []usize{0xfffffffc7fffffff};
572570
573const k_sigaction = extern struct {571const k_sigaction = extern struct {
574 handler: extern fn(i32),572 handler: extern fn(i32)void,
575 flags: usize,573 flags: usize,
576 restorer: extern fn(),574 restorer: extern fn()void,
577 mask: [2]u32,575 mask: [2]u32,
578};576};
579577
580/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.578/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
581pub const Sigaction = struct {579pub const Sigaction = struct {
582 handler: extern fn(i32),580 handler: extern fn(i32)void,
583 mask: sigset_t,581 mask: sigset_t,
584 flags: u32,582 flags: u32,
585};583};
586584
587pub const SIG_ERR = @intToPtr(extern fn(i32), @maxValue(usize));585pub const SIG_ERR = @intToPtr(extern fn(i32)void, @maxValue(usize));
588pub const SIG_DFL = @intToPtr(extern fn(i32), 0);586pub const SIG_DFL = @intToPtr(extern fn(i32)void, 0);
589pub const SIG_IGN = @intToPtr(extern fn(i32), 1);587pub const SIG_IGN = @intToPtr(extern fn(i32)void, 1);
590pub const empty_sigset = []usize{0} ** sigset_t.len;588pub const empty_sigset = []usize{0} ** sigset_t.len;
591589
592pub fn raise(sig: i32) -> usize {590pub fn raise(sig: i32) usize {
593 var set: sigset_t = undefined;591 var set: sigset_t = undefined;
594 blockAppSignals(&set);592 blockAppSignals(&set);
595 const tid = i32(arch.syscall0(arch.SYS_gettid));593 const tid = i32(arch.syscall0(arch.SYS_gettid));
...@@ -598,24 +596,24 @@ pub fn raise(sig: i32) -> usize {...@@ -598,24 +596,24 @@ pub fn raise(sig: i32) -> usize {
598 return ret;596 return ret;
599}597}
600598
601fn blockAllSignals(set: &sigset_t) {599fn blockAllSignals(set: &sigset_t) void {
602 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG/8);600 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG/8);
603}601}
604602
605fn blockAppSignals(set: &sigset_t) {603fn blockAppSignals(set: &sigset_t) void {
606 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG/8);604 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG/8);
607}605}
608606
609fn restoreSignals(set: &sigset_t) {607fn restoreSignals(set: &sigset_t) void {
610 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG/8);608 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG/8);
611}609}
612610
613pub fn sigaddset(set: &sigset_t, sig: u6) {611pub fn sigaddset(set: &sigset_t, sig: u6) void {
614 const s = sig - 1;612 const s = sig - 1;
615 (*set)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));613 (*set)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));
616}614}
617615
618pub fn sigismember(set: &const sigset_t, sig: u6) -> bool {616pub fn sigismember(set: &const sigset_t, sig: u6) bool {
619 const s = sig - 1;617 const s = sig - 1;
620 return ((*set)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;618 return ((*set)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;
621}619}
...@@ -652,69 +650,69 @@ pub const iovec = extern struct {...@@ -652,69 +650,69 @@ pub const iovec = extern struct {
652 iov_len: usize,650 iov_len: usize,
653};651};
654652
655pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {653pub fn getsockname(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) usize {
656 return arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len));654 return arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len));
657}655}
658656
659pub fn getpeername(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {657pub fn getpeername(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) usize {
660 return arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len));658 return arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len));
661}659}
662660
663pub fn socket(domain: i32, socket_type: i32, protocol: i32) -> usize {661pub fn socket(domain: i32, socket_type: i32, protocol: i32) usize {
664 return arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol));662 return arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol));
665}663}
666664
667pub fn setsockopt(fd: i32, level: i32, optname: i32, optval: &const u8, optlen: socklen_t) -> usize {665pub fn setsockopt(fd: i32, level: i32, optname: i32, optval: &const u8, optlen: socklen_t) usize {
668 return arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen));666 return arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen));
669}667}
670668
671pub fn getsockopt(fd: i32, level: i32, optname: i32, noalias optval: &u8, noalias optlen: &socklen_t) -> usize {669pub fn getsockopt(fd: i32, level: i32, optname: i32, noalias optval: &u8, noalias optlen: &socklen_t) usize {
672 return arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen));670 return arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen));
673}671}
674672
675pub fn sendmsg(fd: i32, msg: &const arch.msghdr, flags: u32) -> usize {673pub fn sendmsg(fd: i32, msg: &const arch.msghdr, flags: u32) usize {
676 return arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags);674 return arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags);
677}675}
678676
679pub fn connect(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize {677pub fn connect(fd: i32, addr: &const sockaddr, len: socklen_t) usize {
680 return arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len));678 return arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len));
681}679}
682680
683pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) -> usize {681pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) usize {
684 return arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);682 return arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
685}683}
686684
687pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32,685pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32,
688 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> usize686 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) usize
689{687{
690 return arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));688 return arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
691}689}
692690
693pub fn shutdown(fd: i32, how: i32) -> usize {691pub fn shutdown(fd: i32, how: i32) usize {
694 return arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how));692 return arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how));
695}693}
696694
697pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) -> usize {695pub fn bind(fd: i32, addr: &const sockaddr, len: socklen_t) usize {
698 return arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len));696 return arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len));
699}697}
700698
701pub fn listen(fd: i32, backlog: i32) -> usize {699pub fn listen(fd: i32, backlog: i32) usize {
702 return arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog));700 return arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog));
703}701}
704702
705pub fn sendto(fd: i32, buf: &const u8, len: usize, flags: u32, addr: ?&const sockaddr, alen: socklen_t) -> usize {703pub fn sendto(fd: i32, buf: &const u8, len: usize, flags: u32, addr: ?&const sockaddr, alen: socklen_t) usize {
706 return arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));704 return arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));
707}705}
708706
709pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) -> usize {707pub fn socketpair(domain: i32, socket_type: i32, protocol: i32, fd: [2]i32) usize {
710 return arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0]));708 return arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0]));
711}709}
712710
713pub fn accept(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) -> usize {711pub fn accept(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t) usize {
714 return accept4(fd, addr, len, 0);712 return accept4(fd, addr, len, 0);
715}713}
716714
717pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags: u32) -> usize {715pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags: u32) usize {
718 return arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags);716 return arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags);
719}717}
720718
...@@ -722,7 +720,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:...@@ -722,7 +720,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
722// error SystemResources;720// error SystemResources;
723// error Io;721// error Io;
724// 722//
725// pub fn if_nametoindex(name: []u8) -> %u32 {723// pub fn if_nametoindex(name: []u8) %u32 {
726// var ifr: ifreq = undefined;724// var ifr: ifreq = undefined;
727// 725//
728// if (name.len >= ifr.ifr_name.len) {726// if (name.len >= ifr.ifr_name.len) {
...@@ -749,7 +747,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:...@@ -749,7 +747,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
749pub const Stat = arch.Stat;747pub const Stat = arch.Stat;
750pub const timespec = arch.timespec;748pub const timespec = arch.timespec;
751749
752pub fn fstat(fd: i32, stat_buf: &Stat) -> usize {750pub fn fstat(fd: i32, stat_buf: &Stat) usize {
753 return arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf));751 return arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf));
754}752}
755753
...@@ -760,19 +758,19 @@ pub const epoll_event = extern struct {...@@ -760,19 +758,19 @@ pub const epoll_event = extern struct {
760 data: epoll_data758 data: epoll_data
761};759};
762760
763pub fn epoll_create() -> usize {761pub fn epoll_create() usize {
764 return arch.syscall1(arch.SYS_epoll_create, usize(1));762 return arch.syscall1(arch.SYS_epoll_create, usize(1));
765}763}
766764
767pub fn epoll_ctl(epoll_fd: i32, op: i32, fd: i32, ev: &epoll_event) -> usize {765pub fn epoll_ctl(epoll_fd: i32, op: i32, fd: i32, ev: &epoll_event) usize {
768 return arch.syscall4(arch.SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));766 return arch.syscall4(arch.SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));
769}767}
770768
771pub fn epoll_wait(epoll_fd: i32, events: &epoll_event, maxevents: i32, timeout: i32) -> usize {769pub fn epoll_wait(epoll_fd: i32, events: &epoll_event, maxevents: i32, timeout: i32) usize {
772 return arch.syscall4(arch.SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));770 return arch.syscall4(arch.SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));
773}771}
774772
775pub fn timerfd_create(clockid: i32, flags: u32) -> usize {773pub fn timerfd_create(clockid: i32, flags: u32) usize {
776 return arch.syscall2(arch.SYS_timerfd_create, usize(clockid), usize(flags));774 return arch.syscall2(arch.SYS_timerfd_create, usize(clockid), usize(flags));
777}775}
778776
...@@ -781,11 +779,11 @@ pub const itimerspec = extern struct {...@@ -781,11 +779,11 @@ pub const itimerspec = extern struct {
781 it_value: timespec779 it_value: timespec
782};780};
783781
784pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) -> usize {782pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) usize {
785 return arch.syscall2(arch.SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value));783 return arch.syscall2(arch.SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value));
786}784}
787785
788pub fn timerfd_settime(fd: i32, flags: u32, new_value: &const itimerspec, old_value: ?&itimerspec) -> usize {786pub fn timerfd_settime(fd: i32, flags: u32, new_value: &const itimerspec, old_value: ?&itimerspec) usize {
789 return arch.syscall4(arch.SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value));787 return arch.syscall4(arch.SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value));
790}788}
791789
std/os/linux_i386.zig+7-7
...@@ -419,20 +419,20 @@ pub const F_GETOWN_EX = 16;...@@ -419,20 +419,20 @@ pub const F_GETOWN_EX = 16;
419419
420pub const F_GETOWNER_UIDS = 17;420pub const F_GETOWNER_UIDS = 17;
421421
422pub inline fn syscall0(number: usize) -> usize {422pub inline fn syscall0(number: usize) usize {
423 asm volatile ("int $0x80"423 asm volatile ("int $0x80"
424 : [ret] "={eax}" (-> usize)424 : [ret] "={eax}" (-> usize)
425 : [number] "{eax}" (number))425 : [number] "{eax}" (number))
426}426}
427427
428pub inline fn syscall1(number: usize, arg1: usize) -> usize {428pub inline fn syscall1(number: usize, arg1: usize) usize {
429 asm volatile ("int $0x80"429 asm volatile ("int $0x80"
430 : [ret] "={eax}" (-> usize)430 : [ret] "={eax}" (-> usize)
431 : [number] "{eax}" (number),431 : [number] "{eax}" (number),
432 [arg1] "{ebx}" (arg1))432 [arg1] "{ebx}" (arg1))
433}433}
434434
435pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {435pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
436 asm volatile ("int $0x80"436 asm volatile ("int $0x80"
437 : [ret] "={eax}" (-> usize)437 : [ret] "={eax}" (-> usize)
438 : [number] "{eax}" (number),438 : [number] "{eax}" (number),
...@@ -440,7 +440,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {...@@ -440,7 +440,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
440 [arg2] "{ecx}" (arg2))440 [arg2] "{ecx}" (arg2))
441}441}
442442
443pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {443pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
444 asm volatile ("int $0x80"444 asm volatile ("int $0x80"
445 : [ret] "={eax}" (-> usize)445 : [ret] "={eax}" (-> usize)
446 : [number] "{eax}" (number),446 : [number] "{eax}" (number),
...@@ -449,7 +449,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->...@@ -449,7 +449,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->
449 [arg3] "{edx}" (arg3))449 [arg3] "{edx}" (arg3))
450}450}
451451
452pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {452pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
453 asm volatile ("int $0x80"453 asm volatile ("int $0x80"
454 : [ret] "={eax}" (-> usize)454 : [ret] "={eax}" (-> usize)
455 : [number] "{eax}" (number),455 : [number] "{eax}" (number),
...@@ -486,7 +486,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize,...@@ -486,7 +486,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize,
486 [arg6] "{ebp}" (arg6))486 [arg6] "{ebp}" (arg6))
487}487}
488488
489pub nakedcc fn restore() {489pub nakedcc fn restore() void {
490 asm volatile (490 asm volatile (
491 \\popl %%eax491 \\popl %%eax
492 \\movl $119, %%eax492 \\movl $119, %%eax
...@@ -496,7 +496,7 @@ pub nakedcc fn restore() {...@@ -496,7 +496,7 @@ pub nakedcc fn restore() {
496 : "rcx", "r11")496 : "rcx", "r11")
497}497}
498498
499pub nakedcc fn restore_rt() {499pub nakedcc fn restore_rt() void {
500 asm volatile ("int $0x80"500 asm volatile ("int $0x80"
501 :501 :
502 : [number] "{eax}" (usize(SYS_rt_sigreturn))502 : [number] "{eax}" (usize(SYS_rt_sigreturn))
std/os/linux_x86_64.zig+8-8
...@@ -370,14 +370,14 @@ pub const F_GETOWN_EX = 16;...@@ -370,14 +370,14 @@ pub const F_GETOWN_EX = 16;
370370
371pub const F_GETOWNER_UIDS = 17;371pub const F_GETOWNER_UIDS = 17;
372372
373pub fn syscall0(number: usize) -> usize {373pub fn syscall0(number: usize) usize {
374 return asm volatile ("syscall"374 return asm volatile ("syscall"
375 : [ret] "={rax}" (-> usize)375 : [ret] "={rax}" (-> usize)
376 : [number] "{rax}" (number)376 : [number] "{rax}" (number)
377 : "rcx", "r11");377 : "rcx", "r11");
378}378}
379379
380pub fn syscall1(number: usize, arg1: usize) -> usize {380pub fn syscall1(number: usize, arg1: usize) usize {
381 return asm volatile ("syscall"381 return asm volatile ("syscall"
382 : [ret] "={rax}" (-> usize)382 : [ret] "={rax}" (-> usize)
383 : [number] "{rax}" (number),383 : [number] "{rax}" (number),
...@@ -385,7 +385,7 @@ pub fn syscall1(number: usize, arg1: usize) -> usize {...@@ -385,7 +385,7 @@ pub fn syscall1(number: usize, arg1: usize) -> usize {
385 : "rcx", "r11");385 : "rcx", "r11");
386}386}
387387
388pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {388pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
389 return asm volatile ("syscall"389 return asm volatile ("syscall"
390 : [ret] "={rax}" (-> usize)390 : [ret] "={rax}" (-> usize)
391 : [number] "{rax}" (number),391 : [number] "{rax}" (number),
...@@ -394,7 +394,7 @@ pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {...@@ -394,7 +394,7 @@ pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
394 : "rcx", "r11");394 : "rcx", "r11");
395}395}
396396
397pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {397pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
398 return asm volatile ("syscall"398 return asm volatile ("syscall"
399 : [ret] "={rax}" (-> usize)399 : [ret] "={rax}" (-> usize)
400 : [number] "{rax}" (number),400 : [number] "{rax}" (number),
...@@ -404,7 +404,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {...@@ -404,7 +404,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
404 : "rcx", "r11");404 : "rcx", "r11");
405}405}
406406
407pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {407pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
408 return asm volatile ("syscall"408 return asm volatile ("syscall"
409 : [ret] "={rax}" (-> usize)409 : [ret] "={rax}" (-> usize)
410 : [number] "{rax}" (number),410 : [number] "{rax}" (number),
...@@ -415,7 +415,7 @@ pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz...@@ -415,7 +415,7 @@ pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
415 : "rcx", "r11");415 : "rcx", "r11");
416}416}
417417
418pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> usize {418pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) usize {
419 return asm volatile ("syscall"419 return asm volatile ("syscall"
420 : [ret] "={rax}" (-> usize)420 : [ret] "={rax}" (-> usize)
421 : [number] "{rax}" (number),421 : [number] "{rax}" (number),
...@@ -428,7 +428,7 @@ pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz...@@ -428,7 +428,7 @@ pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
428}428}
429429
430pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,430pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
431 arg5: usize, arg6: usize) -> usize431 arg5: usize, arg6: usize) usize
432{432{
433 return asm volatile ("syscall"433 return asm volatile ("syscall"
434 : [ret] "={rax}" (-> usize)434 : [ret] "={rax}" (-> usize)
...@@ -442,7 +442,7 @@ pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz...@@ -442,7 +442,7 @@ pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
442 : "rcx", "r11");442 : "rcx", "r11");
443}443}
444444
445pub nakedcc fn restore_rt() {445pub nakedcc fn restore_rt() void {
446 return asm volatile ("syscall"446 return asm volatile ("syscall"
447 :447 :
448 : [number] "{rax}" (usize(SYS_rt_sigreturn))448 : [number] "{rax}" (usize(SYS_rt_sigreturn))
std/os/path.zig+45-45
...@@ -22,7 +22,7 @@ pub const delimiter = if (is_windows) delimiter_windows else delimiter_posix;...@@ -22,7 +22,7 @@ pub const delimiter = if (is_windows) delimiter_windows else delimiter_posix;
2222
23const is_windows = builtin.os == builtin.Os.windows;23const is_windows = builtin.os == builtin.Os.windows;
2424
25pub fn isSep(byte: u8) -> bool {25pub fn isSep(byte: u8) bool {
26 if (is_windows) {26 if (is_windows) {
27 return byte == '/' or byte == '\\';27 return byte == '/' or byte == '\\';
28 } else {28 } else {
...@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) -> bool {...@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) -> bool {
3232
33/// Naively combines a series of paths with the native path seperator.33/// Naively combines a series of paths with the native path seperator.
34/// Allocates memory for the result, which must be freed by the caller.34/// Allocates memory for the result, which must be freed by the caller.
35pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {35pub fn join(allocator: &Allocator, paths: ...) %[]u8 {
36 if (is_windows) {36 if (is_windows) {
37 return joinWindows(allocator, paths);37 return joinWindows(allocator, paths);
38 } else {38 } else {
...@@ -40,11 +40,11 @@ pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {...@@ -40,11 +40,11 @@ pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {
40 }40 }
41}41}
4242
43pub fn joinWindows(allocator: &Allocator, paths: ...) -> %[]u8 {43pub fn joinWindows(allocator: &Allocator, paths: ...) %[]u8 {
44 return mem.join(allocator, sep_windows, paths);44 return mem.join(allocator, sep_windows, paths);
45}45}
4646
47pub fn joinPosix(allocator: &Allocator, paths: ...) -> %[]u8 {47pub fn joinPosix(allocator: &Allocator, paths: ...) %[]u8 {
48 return mem.join(allocator, sep_posix, paths);48 return mem.join(allocator, sep_posix, paths);
49}49}
5050
...@@ -69,7 +69,7 @@ test "os.path.join" {...@@ -69,7 +69,7 @@ test "os.path.join" {
69 "/home/andy/dev/zig/build/lib/zig/std/io.zig"));69 "/home/andy/dev/zig/build/lib/zig/std/io.zig"));
70}70}
7171
72pub fn isAbsolute(path: []const u8) -> bool {72pub fn isAbsolute(path: []const u8) bool {
73 if (is_windows) {73 if (is_windows) {
74 return isAbsoluteWindows(path);74 return isAbsoluteWindows(path);
75 } else {75 } else {
...@@ -77,7 +77,7 @@ pub fn isAbsolute(path: []const u8) -> bool {...@@ -77,7 +77,7 @@ pub fn isAbsolute(path: []const u8) -> bool {
77 }77 }
78}78}
7979
80pub fn isAbsoluteWindows(path: []const u8) -> bool {80pub fn isAbsoluteWindows(path: []const u8) bool {
81 if (path[0] == '/')81 if (path[0] == '/')
82 return true;82 return true;
8383
...@@ -96,7 +96,7 @@ pub fn isAbsoluteWindows(path: []const u8) -> bool {...@@ -96,7 +96,7 @@ pub fn isAbsoluteWindows(path: []const u8) -> bool {
96 return false;96 return false;
97}97}
9898
99pub fn isAbsolutePosix(path: []const u8) -> bool {99pub fn isAbsolutePosix(path: []const u8) bool {
100 return path[0] == sep_posix;100 return path[0] == sep_posix;
101}101}
102102
...@@ -129,11 +129,11 @@ test "os.path.isAbsolutePosix" {...@@ -129,11 +129,11 @@ test "os.path.isAbsolutePosix" {
129 testIsAbsolutePosix("./baz", false);129 testIsAbsolutePosix("./baz", false);
130}130}
131131
132fn testIsAbsoluteWindows(path: []const u8, expected_result: bool) {132fn testIsAbsoluteWindows(path: []const u8, expected_result: bool) void {
133 assert(isAbsoluteWindows(path) == expected_result);133 assert(isAbsoluteWindows(path) == expected_result);
134}134}
135135
136fn testIsAbsolutePosix(path: []const u8, expected_result: bool) {136fn testIsAbsolutePosix(path: []const u8, expected_result: bool) void {
137 assert(isAbsolutePosix(path) == expected_result);137 assert(isAbsolutePosix(path) == expected_result);
138}138}
139139
...@@ -149,7 +149,7 @@ pub const WindowsPath = struct {...@@ -149,7 +149,7 @@ pub const WindowsPath = struct {
149 };149 };
150};150};
151151
152pub fn windowsParsePath(path: []const u8) -> WindowsPath {152pub fn windowsParsePath(path: []const u8) WindowsPath {
153 if (path.len >= 2 and path[1] == ':') {153 if (path.len >= 2 and path[1] == ':') {
154 return WindowsPath {154 return WindowsPath {
155 .is_abs = isAbsoluteWindows(path),155 .is_abs = isAbsoluteWindows(path),
...@@ -248,7 +248,7 @@ test "os.path.windowsParsePath" {...@@ -248,7 +248,7 @@ test "os.path.windowsParsePath" {
248 }248 }
249}249}
250250
251pub fn diskDesignator(path: []const u8) -> []const u8 {251pub fn diskDesignator(path: []const u8) []const u8 {
252 if (is_windows) {252 if (is_windows) {
253 return diskDesignatorWindows(path);253 return diskDesignatorWindows(path);
254 } else {254 } else {
...@@ -256,11 +256,11 @@ pub fn diskDesignator(path: []const u8) -> []const u8 {...@@ -256,11 +256,11 @@ pub fn diskDesignator(path: []const u8) -> []const u8 {
256 }256 }
257}257}
258258
259pub fn diskDesignatorWindows(path: []const u8) -> []const u8 {259pub fn diskDesignatorWindows(path: []const u8) []const u8 {
260 return windowsParsePath(path).disk_designator;260 return windowsParsePath(path).disk_designator;
261}261}
262262
263fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool {263fn networkShareServersEql(ns1: []const u8, ns2: []const u8) bool {
264 const sep1 = ns1[0];264 const sep1 = ns1[0];
265 const sep2 = ns2[0];265 const sep2 = ns2[0];
266266
...@@ -271,7 +271,7 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool {...@@ -271,7 +271,7 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool {
271 return asciiEqlIgnoreCase(??it1.next(), ??it2.next());271 return asciiEqlIgnoreCase(??it1.next(), ??it2.next());
272}272}
273273
274fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8) -> bool {274fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8) bool {
275 switch (kind) {275 switch (kind) {
276 WindowsPath.Kind.None => {276 WindowsPath.Kind.None => {
277 assert(p1.len == 0);277 assert(p1.len == 0);
...@@ -294,14 +294,14 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8...@@ -294,14 +294,14 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8
294 }294 }
295}295}
296296
297fn asciiUpper(byte: u8) -> u8 {297fn asciiUpper(byte: u8) u8 {
298 return switch (byte) {298 return switch (byte) {
299 'a' ... 'z' => 'A' + (byte - 'a'),299 'a' ... 'z' => 'A' + (byte - 'a'),
300 else => byte,300 else => byte,
301 };301 };
302}302}
303303
304fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) -> bool {304fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
305 if (s1.len != s2.len)305 if (s1.len != s2.len)
306 return false;306 return false;
307 var i: usize = 0;307 var i: usize = 0;
...@@ -313,7 +313,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) -> bool {...@@ -313,7 +313,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) -> bool {
313}313}
314314
315/// Converts the command line arguments into a slice and calls `resolveSlice`.315/// Converts the command line arguments into a slice and calls `resolveSlice`.
316pub fn resolve(allocator: &Allocator, args: ...) -> %[]u8 {316pub fn resolve(allocator: &Allocator, args: ...) %[]u8 {
317 var paths: [args.len][]const u8 = undefined;317 var paths: [args.len][]const u8 = undefined;
318 comptime var arg_i = 0;318 comptime var arg_i = 0;
319 inline while (arg_i < args.len) : (arg_i += 1) {319 inline while (arg_i < args.len) : (arg_i += 1) {
...@@ -323,7 +323,7 @@ pub fn resolve(allocator: &Allocator, args: ...) -> %[]u8 {...@@ -323,7 +323,7 @@ pub fn resolve(allocator: &Allocator, args: ...) -> %[]u8 {
323}323}
324324
325/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.325/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
326pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {326pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) %[]u8 {
327 if (is_windows) {327 if (is_windows) {
328 return resolveWindows(allocator, paths);328 return resolveWindows(allocator, paths);
329 } else {329 } else {
...@@ -337,7 +337,7 @@ pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {...@@ -337,7 +337,7 @@ pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
337/// If all paths are relative it uses the current working directory as a starting point.337/// If all paths are relative it uses the current working directory as a starting point.
338/// Each drive has its own current working directory.338/// Each drive has its own current working directory.
339/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.339/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
340pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {340pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) %[]u8 {
341 if (paths.len == 0) {341 if (paths.len == 0) {
342 assert(is_windows); // resolveWindows called on non windows can't use getCwd342 assert(is_windows); // resolveWindows called on non windows can't use getCwd
343 return os.getCwd(allocator);343 return os.getCwd(allocator);
...@@ -468,7 +468,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8...@@ -468,7 +468,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
468 }468 }
469 have_drive_kind = parsed_cwd.kind;469 have_drive_kind = parsed_cwd.kind;
470 }470 }
471 %defer allocator.free(result);471 errdefer allocator.free(result);
472472
473 // Now we know the disk designator to use, if any, and what kind it is. And our result473 // Now we know the disk designator to use, if any, and what kind it is. And our result
474 // is big enough to append all the paths to.474 // is big enough to append all the paths to.
...@@ -520,7 +520,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8...@@ -520,7 +520,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
520/// It resolves "." and "..".520/// It resolves "." and "..".
521/// The result does not have a trailing path separator.521/// The result does not have a trailing path separator.
522/// If all paths are relative it uses the current working directory as a starting point.522/// If all paths are relative it uses the current working directory as a starting point.
523pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {523pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) %[]u8 {
524 if (paths.len == 0) {524 if (paths.len == 0) {
525 assert(!is_windows); // resolvePosix called on windows can't use getCwd525 assert(!is_windows); // resolvePosix called on windows can't use getCwd
526 return os.getCwd(allocator);526 return os.getCwd(allocator);
...@@ -551,7 +551,7 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {...@@ -551,7 +551,7 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
551 mem.copy(u8, result, cwd);551 mem.copy(u8, result, cwd);
552 result_index += cwd.len;552 result_index += cwd.len;
553 }553 }
554 %defer allocator.free(result);554 errdefer allocator.free(result);
555555
556 for (paths[first_index..]) |p, i| {556 for (paths[first_index..]) |p, i| {
557 var it = mem.split(p, "/");557 var it = mem.split(p, "/");
...@@ -648,15 +648,15 @@ test "os.path.resolvePosix" {...@@ -648,15 +648,15 @@ test "os.path.resolvePosix" {
648 assert(mem.eql(u8, testResolvePosix([][]const u8{"/foo/tmp.3/", "../tmp.3/cycles/root.js"}), "/foo/tmp.3/cycles/root.js"));648 assert(mem.eql(u8, testResolvePosix([][]const u8{"/foo/tmp.3/", "../tmp.3/cycles/root.js"}), "/foo/tmp.3/cycles/root.js"));
649}649}
650650
651fn testResolveWindows(paths: []const []const u8) -> []u8 {651fn testResolveWindows(paths: []const []const u8) []u8 {
652 return resolveWindows(debug.global_allocator, paths) catch unreachable;652 return resolveWindows(debug.global_allocator, paths) catch unreachable;
653}653}
654654
655fn testResolvePosix(paths: []const []const u8) -> []u8 {655fn testResolvePosix(paths: []const []const u8) []u8 {
656 return resolvePosix(debug.global_allocator, paths) catch unreachable;656 return resolvePosix(debug.global_allocator, paths) catch unreachable;
657}657}
658658
659pub fn dirname(path: []const u8) -> []const u8 {659pub fn dirname(path: []const u8) []const u8 {
660 if (is_windows) {660 if (is_windows) {
661 return dirnameWindows(path);661 return dirnameWindows(path);
662 } else {662 } else {
...@@ -664,7 +664,7 @@ pub fn dirname(path: []const u8) -> []const u8 {...@@ -664,7 +664,7 @@ pub fn dirname(path: []const u8) -> []const u8 {
664 }664 }
665}665}
666666
667pub fn dirnameWindows(path: []const u8) -> []const u8 {667pub fn dirnameWindows(path: []const u8) []const u8 {
668 if (path.len == 0)668 if (path.len == 0)
669 return path[0..0];669 return path[0..0];
670670
...@@ -695,7 +695,7 @@ pub fn dirnameWindows(path: []const u8) -> []const u8 {...@@ -695,7 +695,7 @@ pub fn dirnameWindows(path: []const u8) -> []const u8 {
695 return path[0..end_index];695 return path[0..end_index];
696}696}
697697
698pub fn dirnamePosix(path: []const u8) -> []const u8 {698pub fn dirnamePosix(path: []const u8) []const u8 {
699 if (path.len == 0)699 if (path.len == 0)
700 return path[0..0];700 return path[0..0];
701701
...@@ -766,15 +766,15 @@ test "os.path.dirnameWindows" {...@@ -766,15 +766,15 @@ test "os.path.dirnameWindows" {
766 testDirnameWindows("foo", "");766 testDirnameWindows("foo", "");
767}767}
768768
769fn testDirnamePosix(input: []const u8, expected_output: []const u8) {769fn testDirnamePosix(input: []const u8, expected_output: []const u8) void {
770 assert(mem.eql(u8, dirnamePosix(input), expected_output));770 assert(mem.eql(u8, dirnamePosix(input), expected_output));
771}771}
772772
773fn testDirnameWindows(input: []const u8, expected_output: []const u8) {773fn testDirnameWindows(input: []const u8, expected_output: []const u8) void {
774 assert(mem.eql(u8, dirnameWindows(input), expected_output));774 assert(mem.eql(u8, dirnameWindows(input), expected_output));
775}775}
776776
777pub fn basename(path: []const u8) -> []const u8 {777pub fn basename(path: []const u8) []const u8 {
778 if (is_windows) {778 if (is_windows) {
779 return basenameWindows(path);779 return basenameWindows(path);
780 } else {780 } else {
...@@ -782,7 +782,7 @@ pub fn basename(path: []const u8) -> []const u8 {...@@ -782,7 +782,7 @@ pub fn basename(path: []const u8) -> []const u8 {
782 }782 }
783}783}
784784
785pub fn basenamePosix(path: []const u8) -> []const u8 {785pub fn basenamePosix(path: []const u8) []const u8 {
786 if (path.len == 0)786 if (path.len == 0)
787 return []u8{};787 return []u8{};
788788
...@@ -803,7 +803,7 @@ pub fn basenamePosix(path: []const u8) -> []const u8 {...@@ -803,7 +803,7 @@ pub fn basenamePosix(path: []const u8) -> []const u8 {
803 return path[start_index + 1..end_index];803 return path[start_index + 1..end_index];
804}804}
805805
806pub fn basenameWindows(path: []const u8) -> []const u8 {806pub fn basenameWindows(path: []const u8) []const u8 {
807 if (path.len == 0)807 if (path.len == 0)
808 return []u8{};808 return []u8{};
809809
...@@ -874,15 +874,15 @@ test "os.path.basename" {...@@ -874,15 +874,15 @@ test "os.path.basename" {
874 testBasenameWindows("file:stream", "file:stream");874 testBasenameWindows("file:stream", "file:stream");
875}875}
876876
877fn testBasename(input: []const u8, expected_output: []const u8) {877fn testBasename(input: []const u8, expected_output: []const u8) void {
878 assert(mem.eql(u8, basename(input), expected_output));878 assert(mem.eql(u8, basename(input), expected_output));
879}879}
880880
881fn testBasenamePosix(input: []const u8, expected_output: []const u8) {881fn testBasenamePosix(input: []const u8, expected_output: []const u8) void {
882 assert(mem.eql(u8, basenamePosix(input), expected_output));882 assert(mem.eql(u8, basenamePosix(input), expected_output));
883}883}
884884
885fn testBasenameWindows(input: []const u8, expected_output: []const u8) {885fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
886 assert(mem.eql(u8, basenameWindows(input), expected_output));886 assert(mem.eql(u8, basenameWindows(input), expected_output));
887}887}
888888
...@@ -890,7 +890,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) {...@@ -890,7 +890,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) {
890/// resolve to the same path (after calling `resolve` on each), a zero-length890/// resolve to the same path (after calling `resolve` on each), a zero-length
891/// string is returned.891/// string is returned.
892/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.892/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
893pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 {893pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
894 if (is_windows) {894 if (is_windows) {
895 return relativeWindows(allocator, from, to);895 return relativeWindows(allocator, from, to);
896 } else {896 } else {
...@@ -898,7 +898,7 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u...@@ -898,7 +898,7 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u
898 }898 }
899}899}
900900
901pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 {901pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
902 const resolved_from = try resolveWindows(allocator, [][]const u8{from});902 const resolved_from = try resolveWindows(allocator, [][]const u8{from});
903 defer allocator.free(resolved_from);903 defer allocator.free(resolved_from);
904904
...@@ -943,7 +943,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)...@@ -943,7 +943,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
943 }943 }
944 const up_index_end = up_count * "..\\".len;944 const up_index_end = up_count * "..\\".len;
945 const result = try allocator.alloc(u8, up_index_end + to_rest.len);945 const result = try allocator.alloc(u8, up_index_end + to_rest.len);
946 %defer allocator.free(result);946 errdefer allocator.free(result);
947947
948 var result_index: usize = 0;948 var result_index: usize = 0;
949 while (result_index < up_index_end) {949 while (result_index < up_index_end) {
...@@ -971,7 +971,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)...@@ -971,7 +971,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
971 return []u8{};971 return []u8{};
972}972}
973973
974pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 {974pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
975 const resolved_from = try resolvePosix(allocator, [][]const u8{from});975 const resolved_from = try resolvePosix(allocator, [][]const u8{from});
976 defer allocator.free(resolved_from);976 defer allocator.free(resolved_from);
977977
...@@ -993,7 +993,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ->...@@ -993,7 +993,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ->
993 }993 }
994 const up_index_end = up_count * "../".len;994 const up_index_end = up_count * "../".len;
995 const result = try allocator.alloc(u8, up_index_end + to_rest.len);995 const result = try allocator.alloc(u8, up_index_end + to_rest.len);
996 %defer allocator.free(result);996 errdefer allocator.free(result);
997997
998 var result_index: usize = 0;998 var result_index: usize = 0;
999 while (result_index < up_index_end) {999 while (result_index < up_index_end) {
...@@ -1056,12 +1056,12 @@ test "os.path.relative" {...@@ -1056,12 +1056,12 @@ test "os.path.relative" {
1056 testRelativePosix("/baz", "/baz-quux", "../baz-quux");1056 testRelativePosix("/baz", "/baz-quux", "../baz-quux");
1057}1057}
10581058
1059fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) {1059fn testRelativePosix(from: []const u8, to: []const u8, expected_output: []const u8) void {
1060 const result = relativePosix(debug.global_allocator, from, to) catch unreachable;1060 const result = relativePosix(debug.global_allocator, from, to) catch unreachable;
1061 assert(mem.eql(u8, result, expected_output));1061 assert(mem.eql(u8, result, expected_output));
1062}1062}
10631063
1064fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) {1064fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []const u8) void {
1065 const result = relativeWindows(debug.global_allocator, from, to) catch unreachable;1065 const result = relativeWindows(debug.global_allocator, from, to) catch unreachable;
1066 assert(mem.eql(u8, result, expected_output));1066 assert(mem.eql(u8, result, expected_output));
1067}1067}
...@@ -1077,7 +1077,7 @@ error InputOutput;...@@ -1077,7 +1077,7 @@ error InputOutput;
1077/// Expands all symbolic links and resolves references to `.`, `..`, and1077/// Expands all symbolic links and resolves references to `.`, `..`, and
1078/// extra `/` characters in ::pathname.1078/// extra `/` characters in ::pathname.
1079/// Caller must deallocate result.1079/// Caller must deallocate result.
1080pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {1080pub fn real(allocator: &Allocator, pathname: []const u8) %[]u8 {
1081 switch (builtin.os) {1081 switch (builtin.os) {
1082 Os.windows => {1082 Os.windows => {
1083 const pathname_buf = try allocator.alloc(u8, pathname.len + 1);1083 const pathname_buf = try allocator.alloc(u8, pathname.len + 1);
...@@ -1100,7 +1100,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {...@@ -1100,7 +1100,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1100 }1100 }
1101 defer os.close(h_file);1101 defer os.close(h_file);
1102 var buf = try allocator.alloc(u8, 256);1102 var buf = try allocator.alloc(u8, 256);
1103 %defer allocator.free(buf);1103 errdefer allocator.free(buf);
1104 while (true) {1104 while (true) {
1105 const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong;1105 const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong;
1106 const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS);1106 const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS);
...@@ -1144,7 +1144,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {...@@ -1144,7 +1144,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1144 defer allocator.free(pathname_buf);1144 defer allocator.free(pathname_buf);
11451145
1146 const result_buf = try allocator.alloc(u8, posix.PATH_MAX);1146 const result_buf = try allocator.alloc(u8, posix.PATH_MAX);
1147 %defer allocator.free(result_buf);1147 errdefer allocator.free(result_buf);
11481148
1149 mem.copy(u8, pathname_buf, pathname);1149 mem.copy(u8, pathname_buf, pathname);
1150 pathname_buf[pathname.len] = 0;1150 pathname_buf[pathname.len] = 0;
std/os/windows/index.zig+44-37
...@@ -1,97 +1,100 @@...@@ -1,97 +1,100 @@
1pub const ERROR = @import("error.zig");1pub const ERROR = @import("error.zig");
22
3pub extern "advapi32" stdcallcc fn CryptAcquireContextA(phProv: &HCRYPTPROV, pszContainer: ?LPCSTR,3pub extern "advapi32" stdcallcc fn CryptAcquireContextA(phProv: &HCRYPTPROV, pszContainer: ?LPCSTR,
4 pszProvider: ?LPCSTR, dwProvType: DWORD, dwFlags: DWORD) -> BOOL;4 pszProvider: ?LPCSTR, dwProvType: DWORD, dwFlags: DWORD) BOOL;
55
6pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;6pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;
77
8pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: &BYTE) -> BOOL;8pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: &BYTE) BOOL;
99
1010
11pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) -> BOOL;11pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
1212
13pub extern "kernel32" stdcallcc fn CreateDirectoryA(lpPathName: LPCSTR,13pub extern "kernel32" stdcallcc fn CreateDirectoryA(lpPathName: LPCSTR,
14 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES) -> BOOL;14 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES) BOOL;
1515
16pub extern "kernel32" stdcallcc fn CreateFileA(lpFileName: LPCSTR, dwDesiredAccess: DWORD,16pub extern "kernel32" stdcallcc fn CreateFileA(lpFileName: LPCSTR, dwDesiredAccess: DWORD,
17 dwShareMode: DWORD, lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD,17 dwShareMode: DWORD, lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD,
18 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) -> HANDLE;18 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) HANDLE;
1919
20pub extern "kernel32" stdcallcc fn CreatePipe(hReadPipe: &HANDLE, hWritePipe: &HANDLE,20pub extern "kernel32" stdcallcc fn CreatePipe(hReadPipe: &HANDLE, hWritePipe: &HANDLE,
21 lpPipeAttributes: &const SECURITY_ATTRIBUTES, nSize: DWORD) -> BOOL;21 lpPipeAttributes: &const SECURITY_ATTRIBUTES, nSize: DWORD) BOOL;
2222
23pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,23pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,
24 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,24 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,
25 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,25 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
26 lpProcessInformation: &PROCESS_INFORMATION) -> BOOL;26 lpProcessInformation: &PROCESS_INFORMATION) BOOL;
2727
28pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,28pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(lpSymlinkFileName: LPCSTR, lpTargetFileName: LPCSTR,
29 dwFlags: DWORD) -> BOOLEAN;29 dwFlags: DWORD) BOOLEAN;
3030
31pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) -> BOOL;31pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL;
3232
33pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) -> noreturn;33pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;
3434
35pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: LPCH) -> BOOL;35pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: LPCH) BOOL;
3636
37pub extern "kernel32" stdcallcc fn GetCommandLineA() -> LPSTR;37pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
3838
39pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: &DWORD) -> BOOL;39pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: &DWORD) BOOL;
4040
41pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) -> DWORD;41pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
4242
43pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() -> ?LPCH;43pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?LPCH;
4444
45pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) -> DWORD;45pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
4646
47pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: &DWORD) -> BOOL;47pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: &DWORD) BOOL;
4848
49pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: &LARGE_INTEGER) -> BOOL;49pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: &LARGE_INTEGER) BOOL;
5050
51pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) -> DWORD;51pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) DWORD;
5252
53pub extern "kernel32" stdcallcc fn GetLastError() -> DWORD;53pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
5454
55pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,55pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,
56 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: &c_void,56 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: &c_void,
57 in_dwBufferSize: DWORD) -> BOOL;57 in_dwBufferSize: DWORD) BOOL;
5858
59pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(hFile: HANDLE, lpszFilePath: LPSTR,59pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(hFile: HANDLE, lpszFilePath: LPSTR,
60 cchFilePath: DWORD, dwFlags: DWORD) -> DWORD;60 cchFilePath: DWORD, dwFlags: DWORD) DWORD;
6161
62pub extern "kernel32" stdcallcc fn GetProcessHeap() -> ?HANDLE;62pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;
6363
64pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) -> ?HANDLE;64pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;
6565
66pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> ?LPVOID;66pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?LPVOID;
6767
68pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;68pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) BOOL;
6969
70pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR,70pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR,
71 dwFlags: DWORD) -> BOOL;71 dwFlags: DWORD) BOOL;
7272
73pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID,73pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID,
74 in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD,74 in_nNumberOfBytesToRead: DWORD, out_lpNumberOfBytesRead: &DWORD,
75 in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL;75 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;
7676
77pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) -> BOOL;77pub extern "kernel32" stdcallcc fn SetFilePointerEx(in_fFile: HANDLE, in_liDistanceToMove: LARGE_INTEGER,
78 out_opt_ldNewFilePointer: ?&LARGE_INTEGER, in_dwMoveMethod: DWORD) BOOL;
7879
79pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD);80pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;
8081
81pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL;82pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
8283
83pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD;84pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
85
86pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
8487
85pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &const c_void,88pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &const c_void,
86 in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?&DWORD,89 in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?&DWORD,
87 in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL;90 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;
8891
89//TODO: call unicode versions instead of relying on ANSI code page92//TODO: call unicode versions instead of relying on ANSI code page
90pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) -> ?HMODULE;93pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE;
9194
92pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) -> BOOL; 95pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;
9396
94pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) -> c_int;97pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;
9598
96pub const PROV_RSA_FULL = 1;99pub const PROV_RSA_FULL = 1;
97100
...@@ -289,3 +292,7 @@ pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4;...@@ -289,3 +292,7 @@ pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4;
289pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32;292pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32;
290pub const MOVEFILE_REPLACE_EXISTING = 1;293pub const MOVEFILE_REPLACE_EXISTING = 1;
291pub const MOVEFILE_WRITE_THROUGH = 8;294pub const MOVEFILE_WRITE_THROUGH = 8;
295
296pub const FILE_BEGIN = 0;
297pub const FILE_CURRENT = 1;
298pub const FILE_END = 2;
std/os/windows/util.zig+10-10
...@@ -10,7 +10,7 @@ error WaitAbandoned;...@@ -10,7 +10,7 @@ error WaitAbandoned;
10error WaitTimeOut;10error WaitTimeOut;
11error Unexpected;11error Unexpected;
1212
13pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) -> %void {13pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) %void {
14 const result = windows.WaitForSingleObject(handle, milliseconds);14 const result = windows.WaitForSingleObject(handle, milliseconds);
15 return switch (result) {15 return switch (result) {
16 windows.WAIT_ABANDONED => error.WaitAbandoned,16 windows.WAIT_ABANDONED => error.WaitAbandoned,
...@@ -26,7 +26,7 @@ pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) ->...@@ -26,7 +26,7 @@ pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) ->
26 };26 };
27}27}
2828
29pub fn windowsClose(handle: windows.HANDLE) {29pub fn windowsClose(handle: windows.HANDLE) void {
30 assert(windows.CloseHandle(handle) != 0);30 assert(windows.CloseHandle(handle) != 0);
31}31}
3232
...@@ -35,7 +35,7 @@ error OperationAborted;...@@ -35,7 +35,7 @@ error OperationAborted;
35error IoPending;35error IoPending;
36error BrokenPipe;36error BrokenPipe;
3737
38pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {38pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) %void {
39 if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {39 if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
40 const err = windows.GetLastError();40 const err = windows.GetLastError();
41 return switch (err) {41 return switch (err) {
...@@ -50,7 +50,7 @@ pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {...@@ -50,7 +50,7 @@ pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {
50 }50 }
51}51}
5252
53pub fn windowsIsTty(handle: windows.HANDLE) -> bool {53pub fn windowsIsTty(handle: windows.HANDLE) bool {
54 if (windowsIsCygwinPty(handle))54 if (windowsIsCygwinPty(handle))
55 return true;55 return true;
5656
...@@ -58,7 +58,7 @@ pub fn windowsIsTty(handle: windows.HANDLE) -> bool {...@@ -58,7 +58,7 @@ pub fn windowsIsTty(handle: windows.HANDLE) -> bool {
58 return windows.GetConsoleMode(handle, &out) != 0;58 return windows.GetConsoleMode(handle, &out) != 0;
59}59}
6060
61pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {61pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
62 const size = @sizeOf(windows.FILE_NAME_INFO);62 const size = @sizeOf(windows.FILE_NAME_INFO);
63 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);63 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
6464
...@@ -83,7 +83,7 @@ error PipeBusy;...@@ -83,7 +83,7 @@ error PipeBusy;
83/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.83/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.
84/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.84/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
85pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD,85pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD,
86 creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&mem.Allocator) -> %windows.HANDLE86 creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&mem.Allocator) %windows.HANDLE
87{87{
88 var stack_buf: [os.max_noalloc_path_len]u8 = undefined;88 var stack_buf: [os.max_noalloc_path_len]u8 = undefined;
89 var path0: []u8 = undefined;89 var path0: []u8 = undefined;
...@@ -120,7 +120,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m...@@ -120,7 +120,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
120}120}
121121
122/// Caller must free result.122/// Caller must free result.
123pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) -> %[]u8 {123pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) %[]u8 {
124 // count bytes needed124 // count bytes needed
125 const bytes_needed = x: {125 const bytes_needed = x: {
126 var bytes_needed: usize = 1; // 1 for the final null byte126 var bytes_needed: usize = 1; // 1 for the final null byte
...@@ -133,7 +133,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)...@@ -133,7 +133,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
133 break :x bytes_needed;133 break :x bytes_needed;
134 };134 };
135 const result = try allocator.alloc(u8, bytes_needed);135 const result = try allocator.alloc(u8, bytes_needed);
136 %defer allocator.free(result);136 errdefer allocator.free(result);
137137
138 var it = env_map.iterator();138 var it = env_map.iterator();
139 var i: usize = 0;139 var i: usize = 0;
...@@ -152,13 +152,13 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)...@@ -152,13 +152,13 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
152}152}
153153
154error DllNotFound;154error DllNotFound;
155pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) -> %windows.HMODULE {155pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) %windows.HMODULE {
156 const padded_buff = try cstr.addNullByte(allocator, dll_path);156 const padded_buff = try cstr.addNullByte(allocator, dll_path);
157 defer allocator.free(padded_buff);157 defer allocator.free(padded_buff);
158 return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;158 return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;
159}159}
160160
161pub fn windowsUnloadDll(hModule: windows.HMODULE) {161pub fn windowsUnloadDll(hModule: windows.HMODULE) void {
162 assert(windows.FreeLibrary(hModule)!= 0);162 assert(windows.FreeLibrary(hModule)!= 0);
163}163}
164164
std/os/zen.zig+12-12
...@@ -21,28 +21,28 @@ pub const SYS_createThread = 5;...@@ -21,28 +21,28 @@ pub const SYS_createThread = 5;
21//// Syscalls ////21//// Syscalls ////
22////////////////////22////////////////////
2323
24pub fn exit(status: i32) -> noreturn {24pub fn exit(status: i32) noreturn {
25 _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));25 _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));
26 unreachable;26 unreachable;
27}27}
2828
29pub fn createMailbox(id: u16) {29pub fn createMailbox(id: u16) void {
30 _ = syscall1(SYS_createMailbox, id);30 _ = syscall1(SYS_createMailbox, id);
31}31}
3232
33pub fn send(mailbox_id: u16, data: usize) {33pub fn send(mailbox_id: u16, data: usize) void {
34 _ = syscall2(SYS_send, mailbox_id, data);34 _ = syscall2(SYS_send, mailbox_id, data);
35}35}
3636
37pub fn receive(mailbox_id: u16) -> usize {37pub fn receive(mailbox_id: u16) usize {
38 return syscall1(SYS_receive, mailbox_id);38 return syscall1(SYS_receive, mailbox_id);
39}39}
4040
41pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) -> bool {41pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) bool {
42 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;42 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;
43}43}
4444
45pub fn createThread(function: fn()) -> u16 {45pub fn createThread(function: fn()) u16 {
46 return u16(syscall1(SYS_createThread, @ptrToInt(function)));46 return u16(syscall1(SYS_createThread, @ptrToInt(function)));
47}47}
4848
...@@ -51,20 +51,20 @@ pub fn createThread(function: fn()) -> u16 {...@@ -51,20 +51,20 @@ pub fn createThread(function: fn()) -> u16 {
51//// Syscall stubs ////51//// Syscall stubs ////
52/////////////////////////52/////////////////////////
5353
54pub inline fn syscall0(number: usize) -> usize {54pub inline fn syscall0(number: usize) usize {
55 return asm volatile ("int $0x80"55 return asm volatile ("int $0x80"
56 : [ret] "={eax}" (-> usize)56 : [ret] "={eax}" (-> usize)
57 : [number] "{eax}" (number));57 : [number] "{eax}" (number));
58}58}
5959
60pub inline fn syscall1(number: usize, arg1: usize) -> usize {60pub inline fn syscall1(number: usize, arg1: usize) usize {
61 return asm volatile ("int $0x80"61 return asm volatile ("int $0x80"
62 : [ret] "={eax}" (-> usize)62 : [ret] "={eax}" (-> usize)
63 : [number] "{eax}" (number),63 : [number] "{eax}" (number),
64 [arg1] "{ecx}" (arg1));64 [arg1] "{ecx}" (arg1));
65}65}
6666
67pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {67pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
68 return asm volatile ("int $0x80"68 return asm volatile ("int $0x80"
69 : [ret] "={eax}" (-> usize)69 : [ret] "={eax}" (-> usize)
70 : [number] "{eax}" (number),70 : [number] "{eax}" (number),
...@@ -72,7 +72,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {...@@ -72,7 +72,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
72 [arg2] "{edx}" (arg2));72 [arg2] "{edx}" (arg2));
73}73}
7474
75pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {75pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) usize {
76 return asm volatile ("int $0x80"76 return asm volatile ("int $0x80"
77 : [ret] "={eax}" (-> usize)77 : [ret] "={eax}" (-> usize)
78 : [number] "{eax}" (number),78 : [number] "{eax}" (number),
...@@ -81,7 +81,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->...@@ -81,7 +81,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->
81 [arg3] "{ebx}" (arg3));81 [arg3] "{ebx}" (arg3));
82}82}
8383
84pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {84pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) usize {
85 return asm volatile ("int $0x80"85 return asm volatile ("int $0x80"
86 : [ret] "={eax}" (-> usize)86 : [ret] "={eax}" (-> usize)
87 : [number] "{eax}" (number),87 : [number] "{eax}" (number),
...@@ -92,7 +92,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg...@@ -92,7 +92,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
92}92}
9393
94pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,94pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,
95 arg4: usize, arg5: usize) -> usize95 arg4: usize, arg5: usize) usize
96{96{
97 return asm volatile ("int $0x80"97 return asm volatile ("int $0x80"
98 : [ret] "={eax}" (-> usize)98 : [ret] "={eax}" (-> usize)
std/rand.zig+9-9
...@@ -28,14 +28,14 @@ pub const Rand = struct {...@@ -28,14 +28,14 @@ pub const Rand = struct {
28 rng: Rng,28 rng: Rng,
2929
30 /// Initialize random state with the given seed.30 /// Initialize random state with the given seed.
31 pub fn init(seed: usize) -> Rand {31 pub fn init(seed: usize) Rand {
32 return Rand {32 return Rand {
33 .rng = Rng.init(seed),33 .rng = Rng.init(seed),
34 };34 };
35 }35 }
3636
37 /// Get an integer or boolean with random bits.37 /// Get an integer or boolean with random bits.
38 pub fn scalar(r: &Rand, comptime T: type) -> T {38 pub fn scalar(r: &Rand, comptime T: type) T {
39 if (T == usize) {39 if (T == usize) {
40 return r.rng.get();40 return r.rng.get();
41 } else if (T == bool) {41 } else if (T == bool) {
...@@ -48,7 +48,7 @@ pub const Rand = struct {...@@ -48,7 +48,7 @@ pub const Rand = struct {
48 }48 }
4949
50 /// Fill `buf` with randomness.50 /// Fill `buf` with randomness.
51 pub fn fillBytes(r: &Rand, buf: []u8) {51 pub fn fillBytes(r: &Rand, buf: []u8) void {
52 var bytes_left = buf.len;52 var bytes_left = buf.len;
53 while (bytes_left >= @sizeOf(usize)) {53 while (bytes_left >= @sizeOf(usize)) {
54 mem.writeInt(buf[buf.len - bytes_left..], r.rng.get(), builtin.Endian.Little);54 mem.writeInt(buf[buf.len - bytes_left..], r.rng.get(), builtin.Endian.Little);
...@@ -66,7 +66,7 @@ pub const Rand = struct {...@@ -66,7 +66,7 @@ pub const Rand = struct {
6666
67 /// Get a random unsigned integer with even distribution between `start`67 /// Get a random unsigned integer with even distribution between `start`
68 /// inclusive and `end` exclusive.68 /// inclusive and `end` exclusive.
69 pub fn range(r: &Rand, comptime T: type, start: T, end: T) -> T {69 pub fn range(r: &Rand, comptime T: type, start: T, end: T) T {
70 assert(start <= end);70 assert(start <= end);
71 if (T.is_signed) {71 if (T.is_signed) {
72 const uint = @IntType(false, T.bit_count);72 const uint = @IntType(false, T.bit_count);
...@@ -108,7 +108,7 @@ pub const Rand = struct {...@@ -108,7 +108,7 @@ pub const Rand = struct {
108 }108 }
109109
110 /// Get a floating point value in the range 0.0..1.0.110 /// Get a floating point value in the range 0.0..1.0.
111 pub fn float(r: &Rand, comptime T: type) -> T {111 pub fn float(r: &Rand, comptime T: type) T {
112 // TODO Implement this way instead:112 // TODO Implement this way instead:
113 // const int = @int_type(false, @sizeOf(T) * 8);113 // const int = @int_type(false, @sizeOf(T) * 8);
114 // const mask = ((1 << @float_mantissa_bit_count(T)) - 1);114 // const mask = ((1 << @float_mantissa_bit_count(T)) - 1);
...@@ -132,7 +132,7 @@ fn MersenneTwister(...@@ -132,7 +132,7 @@ fn MersenneTwister(
132 comptime u: math.Log2Int(int), comptime d: int,132 comptime u: math.Log2Int(int), comptime d: int,
133 comptime s: math.Log2Int(int), comptime b: int,133 comptime s: math.Log2Int(int), comptime b: int,
134 comptime t: math.Log2Int(int), comptime c: int,134 comptime t: math.Log2Int(int), comptime c: int,
135 comptime l: math.Log2Int(int), comptime f: int) -> type135 comptime l: math.Log2Int(int), comptime f: int) type
136{136{
137 return struct {137 return struct {
138 const Self = this;138 const Self = this;
...@@ -140,7 +140,7 @@ fn MersenneTwister(...@@ -140,7 +140,7 @@ fn MersenneTwister(
140 array: [n]int,140 array: [n]int,
141 index: usize,141 index: usize,
142142
143 pub fn init(seed: int) -> Self {143 pub fn init(seed: int) Self {
144 var mt = Self {144 var mt = Self {
145 .array = undefined,145 .array = undefined,
146 .index = n,146 .index = n,
...@@ -156,7 +156,7 @@ fn MersenneTwister(...@@ -156,7 +156,7 @@ fn MersenneTwister(
156 return mt;156 return mt;
157 }157 }
158158
159 pub fn get(mt: &Self) -> int {159 pub fn get(mt: &Self) int {
160 const mag01 = []int{0, a};160 const mag01 = []int{0, a};
161 const LM: int = (1 << r) - 1;161 const LM: int = (1 << r) - 1;
162 const UM = ~LM;162 const UM = ~LM;
...@@ -224,7 +224,7 @@ test "rand.Rand.range" {...@@ -224,7 +224,7 @@ test "rand.Rand.range" {
224 testRange(&r, 10, 14);224 testRange(&r, 10, 14);
225}225}
226226
227fn testRange(r: &Rand, start: i32, end: i32) {227fn testRange(r: &Rand, start: i32, end: i32) void {
228 const count = usize(end - start);228 const count = usize(end - start);
229 var values_buffer = []bool{false} ** 20;229 var values_buffer = []bool{false} ** 20;
230 const values = values_buffer[0..count];230 const values = values_buffer[0..count];
std/sort.zig+31-31
...@@ -5,7 +5,7 @@ const math = std.math;...@@ -5,7 +5,7 @@ const math = std.math;
5const builtin = @import("builtin");5const builtin = @import("builtin");
66
7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).7/// Stable in-place sort. O(n) best case, O(pow(n, 2)) worst case. O(1) memory (no allocator required).
8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)->bool) {8pub fn insertionSort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {
9 {var i: usize = 1; while (i < items.len) : (i += 1) {9 {var i: usize = 1; while (i < items.len) : (i += 1) {
10 const x = items[i];10 const x = items[i];
11 var j: usize = i;11 var j: usize = i;
...@@ -20,11 +20,11 @@ const Range = struct {...@@ -20,11 +20,11 @@ const Range = struct {
20 start: usize,20 start: usize,
21 end: usize,21 end: usize,
2222
23 fn init(start: usize, end: usize) -> Range {23 fn init(start: usize, end: usize) Range {
24 return Range { .start = start, .end = end };24 return Range { .start = start, .end = end };
25 }25 }
2626
27 fn length(self: &const Range) -> usize {27 fn length(self: &const Range) usize {
28 return self.end - self.start;28 return self.end - self.start;
29 }29 }
30};30};
...@@ -39,7 +39,7 @@ const Iterator = struct {...@@ -39,7 +39,7 @@ const Iterator = struct {
39 decimal_step: usize,39 decimal_step: usize,
40 numerator_step: usize,40 numerator_step: usize,
4141
42 fn init(size2: usize, min_level: usize) -> Iterator {42 fn init(size2: usize, min_level: usize) Iterator {
43 const power_of_two = math.floorPowerOfTwo(usize, size2);43 const power_of_two = math.floorPowerOfTwo(usize, size2);
44 const denominator = power_of_two / min_level;44 const denominator = power_of_two / min_level;
45 return Iterator {45 return Iterator {
...@@ -53,12 +53,12 @@ const Iterator = struct {...@@ -53,12 +53,12 @@ const Iterator = struct {
53 };53 };
54 }54 }
5555
56 fn begin(self: &Iterator) {56 fn begin(self: &Iterator) void {
57 self.numerator = 0;57 self.numerator = 0;
58 self.decimal = 0;58 self.decimal = 0;
59 }59 }
6060
61 fn nextRange(self: &Iterator) -> Range {61 fn nextRange(self: &Iterator) Range {
62 const start = self.decimal;62 const start = self.decimal;
6363
64 self.decimal += self.decimal_step;64 self.decimal += self.decimal_step;
...@@ -71,11 +71,11 @@ const Iterator = struct {...@@ -71,11 +71,11 @@ const Iterator = struct {
71 return Range {.start = start, .end = self.decimal};71 return Range {.start = start, .end = self.decimal};
72 }72 }
7373
74 fn finished(self: &Iterator) -> bool {74 fn finished(self: &Iterator) bool {
75 return self.decimal >= self.size;75 return self.decimal >= self.size;
76 }76 }
7777
78 fn nextLevel(self: &Iterator) -> bool {78 fn nextLevel(self: &Iterator) bool {
79 self.decimal_step += self.decimal_step;79 self.decimal_step += self.decimal_step;
80 self.numerator_step += self.numerator_step;80 self.numerator_step += self.numerator_step;
81 if (self.numerator_step >= self.denominator) {81 if (self.numerator_step >= self.denominator) {
...@@ -86,7 +86,7 @@ const Iterator = struct {...@@ -86,7 +86,7 @@ const Iterator = struct {
86 return (self.decimal_step < self.size);86 return (self.decimal_step < self.size);
87 }87 }
8888
89 fn length(self: &Iterator) -> usize {89 fn length(self: &Iterator) usize {
90 return self.decimal_step;90 return self.decimal_step;
91 }91 }
92};92};
...@@ -100,7 +100,7 @@ const Pull = struct {...@@ -100,7 +100,7 @@ const Pull = struct {
100100
101/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).101/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).
102/// Currently implemented as block sort.102/// Currently implemented as block sort.
103pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)->bool) {103pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) void {
104 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c104 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c
105 var cache: [512]T = undefined;105 var cache: [512]T = undefined;
106106
...@@ -709,7 +709,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons...@@ -709,7 +709,7 @@ pub fn sort(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &cons
709}709}
710710
711// merge operation without a buffer711// merge operation without a buffer
712fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T,&const T)->bool) {712fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const Range, lessThan: fn(&const T,&const T)bool) void {
713 if (A_arg.length() == 0 or B_arg.length() == 0) return;713 if (A_arg.length() == 0 or B_arg.length() == 0) return;
714 714
715 // this just repeatedly binary searches into B and rotates A into position.715 // this just repeatedly binary searches into B and rotates A into position.
...@@ -751,7 +751,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const...@@ -751,7 +751,7 @@ fn mergeInPlace(comptime T: type, items: []T, A_arg: &const Range, B_arg: &const
751}751}
752752
753// merge operation using an internal buffer753// merge operation using an internal buffer
754fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)->bool, buffer: &const Range) {754fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, buffer: &const Range) void {
755 // whenever we find a value to add to the final array, swap it with the value that's already in that spot755 // whenever we find a value to add to the final array, swap it with the value that's already in that spot
756 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order756 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order
757 var A_count: usize = 0;757 var A_count: usize = 0;
...@@ -778,7 +778,7 @@ fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range,...@@ -778,7 +778,7 @@ fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
778 blockSwap(T, items, buffer.start + A_count, A.start + insert, A.length() - A_count);778 blockSwap(T, items, buffer.start + A_count, A.start + insert, A.length() - A_count);
779}779}
780780
781fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_size: usize) {781fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_size: usize) void {
782 var index: usize = 0;782 var index: usize = 0;
783 while (index < block_size) : (index += 1) {783 while (index < block_size) : (index += 1) {
784 mem.swap(T, &items[start1 + index], &items[start2 + index]);784 mem.swap(T, &items[start1 + index], &items[start2 + index]);
...@@ -787,7 +787,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s...@@ -787,7 +787,7 @@ fn blockSwap(comptime T: type, items: []T, start1: usize, start2: usize, block_s
787787
788// combine a linear search with a binary search to reduce the number of comparisons in situations788// combine a linear search with a binary search to reduce the number of comparisons in situations
789// where have some idea as to how many unique values there are and where the next value might be789// where have some idea as to how many unique values there are and where the next value might be
790fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool, unique: usize) -> usize {790fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
791 if (range.length() == 0) return range.start;791 if (range.length() == 0) return range.start;
792 const skip = math.max(range.length()/unique, usize(1));792 const skip = math.max(range.length()/unique, usize(1));
793 793
...@@ -801,7 +801,7 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const...@@ -801,7 +801,7 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const
801 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);801 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);
802}802}
803803
804fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool, unique: usize) -> usize {804fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
805 if (range.length() == 0) return range.start;805 if (range.length() == 0) return range.start;
806 const skip = math.max(range.length()/unique, usize(1));806 const skip = math.max(range.length()/unique, usize(1));
807 807
...@@ -815,7 +815,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons...@@ -815,7 +815,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons
815 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);815 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);
816}816}
817817
818fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool, unique: usize) -> usize {818fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
819 if (range.length() == 0) return range.start;819 if (range.length() == 0) return range.start;
820 const skip = math.max(range.length()/unique, usize(1));820 const skip = math.max(range.length()/unique, usize(1));
821 821
...@@ -829,7 +829,7 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const...@@ -829,7 +829,7 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const
829 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);829 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);
830}830}
831831
832fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool, unique: usize) -> usize {832fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool, unique: usize) usize {
833 if (range.length() == 0) return range.start;833 if (range.length() == 0) return range.start;
834 const skip = math.max(range.length()/unique, usize(1));834 const skip = math.max(range.length()/unique, usize(1));
835 835
...@@ -843,7 +843,7 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const...@@ -843,7 +843,7 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const
843 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);843 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);
844}844}
845845
846fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool) -> usize {846fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {
847 var start = range.start;847 var start = range.start;
848 var end = range.end - 1;848 var end = range.end - 1;
849 if (range.start >= range.end) return range.end;849 if (range.start >= range.end) return range.end;
...@@ -861,7 +861,7 @@ fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Rang...@@ -861,7 +861,7 @@ fn binaryFirst(comptime T: type, items: []T, value: &const T, range: &const Rang
861 return start;861 return start;
862}862}
863863
864fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)->bool) -> usize {864fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range, lessThan: fn(&const T,&const T)bool) usize {
865 var start = range.start;865 var start = range.start;
866 var end = range.end - 1;866 var end = range.end - 1;
867 if (range.start >= range.end) return range.end;867 if (range.start >= range.end) return range.end;
...@@ -879,7 +879,7 @@ fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range...@@ -879,7 +879,7 @@ fn binaryLast(comptime T: type, items: []T, value: &const T, range: &const Range
879 return start;879 return start;
880}880}
881881
882fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)->bool, into: []T) {882fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, into: []T) void {
883 var A_index: usize = A.start;883 var A_index: usize = A.start;
884 var B_index: usize = B.start;884 var B_index: usize = B.start;
885 const A_last = A.end;885 const A_last = A.end;
...@@ -909,7 +909,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less...@@ -909,7 +909,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less
909 }909 }
910}910}
911911
912fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)->bool, cache: []T) {912fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range, lessThan: fn(&const T,&const T)bool, cache: []T) void {
913 // A fits into the cache, so use that instead of the internal buffer913 // A fits into the cache, so use that instead of the internal buffer
914 var A_index: usize = 0;914 var A_index: usize = 0;
915 var B_index: usize = B.start;915 var B_index: usize = B.start;
...@@ -937,7 +937,7 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,...@@ -937,7 +937,7 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
937 mem.copy(T, items[insert_index..], cache[A_index..A_last]);937 mem.copy(T, items[insert_index..], cache[A_index..A_last]);
938}938}
939939
940fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)->bool, order: &[8]u8, x: usize, y: usize) {940fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool, order: &[8]u8, x: usize, y: usize) void {
941 if (lessThan(items[y], items[x]) or941 if (lessThan(items[y], items[x]) or
942 ((*order)[x] > (*order)[y] and !lessThan(items[x], items[y])))942 ((*order)[x] > (*order)[y] and !lessThan(items[x], items[y])))
943 {943 {
...@@ -946,19 +946,19 @@ fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)...@@ -946,19 +946,19 @@ fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)
946 }946 }
947}947}
948948
949fn i32asc(lhs: &const i32, rhs: &const i32) -> bool {949fn i32asc(lhs: &const i32, rhs: &const i32) bool {
950 return *lhs < *rhs;950 return *lhs < *rhs;
951}951}
952952
953fn i32desc(lhs: &const i32, rhs: &const i32) -> bool {953fn i32desc(lhs: &const i32, rhs: &const i32) bool {
954 return *rhs < *lhs;954 return *rhs < *lhs;
955}955}
956956
957fn u8asc(lhs: &const u8, rhs: &const u8) -> bool {957fn u8asc(lhs: &const u8, rhs: &const u8) bool {
958 return *lhs < *rhs;958 return *lhs < *rhs;
959}959}
960960
961fn u8desc(lhs: &const u8, rhs: &const u8) -> bool {961fn u8desc(lhs: &const u8, rhs: &const u8) bool {
962 return *rhs < *lhs;962 return *rhs < *lhs;
963}963}
964964
...@@ -967,7 +967,7 @@ test "stable sort" {...@@ -967,7 +967,7 @@ test "stable sort" {
967 // TODO: uncomment this after https://github.com/zig-lang/zig/issues/639967 // TODO: uncomment this after https://github.com/zig-lang/zig/issues/639
968 //comptime testStableSort();968 //comptime testStableSort();
969}969}
970fn testStableSort() {970fn testStableSort() void {
971 var expected = []IdAndValue {971 var expected = []IdAndValue {
972 IdAndValue{.id = 0, .value = 0},972 IdAndValue{.id = 0, .value = 0},
973 IdAndValue{.id = 1, .value = 0},973 IdAndValue{.id = 1, .value = 0},
...@@ -1015,7 +1015,7 @@ const IdAndValue = struct {...@@ -1015,7 +1015,7 @@ const IdAndValue = struct {
1015 id: usize,1015 id: usize,
1016 value: i32,1016 value: i32,
1017};1017};
1018fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) -> bool {1018fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) bool {
1019 return i32asc(a.value, b.value);1019 return i32asc(a.value, b.value);
1020}1020}
10211021
...@@ -1092,7 +1092,7 @@ test "sort fuzz testing" {...@@ -1092,7 +1092,7 @@ test "sort fuzz testing" {
10921092
1093var fixed_buffer_mem: [100 * 1024]u8 = undefined;1093var fixed_buffer_mem: [100 * 1024]u8 = undefined;
10941094
1095fn fuzzTest(rng: &std.rand.Rand) {1095fn fuzzTest(rng: &std.rand.Rand) void {
1096 const array_size = rng.range(usize, 0, 1000);1096 const array_size = rng.range(usize, 0, 1000);
1097 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);1097 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
1098 var array = fixed_allocator.allocator.alloc(IdAndValue, array_size) catch unreachable;1098 var array = fixed_allocator.allocator.alloc(IdAndValue, array_size) catch unreachable;
...@@ -1113,7 +1113,7 @@ fn fuzzTest(rng: &std.rand.Rand) {...@@ -1113,7 +1113,7 @@ fn fuzzTest(rng: &std.rand.Rand) {
1113 }1113 }
1114}1114}
11151115
1116pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)->bool) -> T {1116pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {
1117 var i: usize = 0;1117 var i: usize = 0;
1118 var smallest = items[0];1118 var smallest = items[0];
1119 for (items[1..]) |item| {1119 for (items[1..]) |item| {
...@@ -1124,7 +1124,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const...@@ -1124,7 +1124,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const
1124 return smallest;1124 return smallest;
1125}1125}
11261126
1127pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)->bool) -> T {1127pub fn max(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)bool) T {
1128 var i: usize = 0;1128 var i: usize = 0;
1129 var biggest = items[0];1129 var biggest = items[0];
1130 for (items[1..]) |item| {1130 for (items[1..]) |item| {
std/special/bootstrap.zig+7-7
...@@ -20,11 +20,11 @@ comptime {...@@ -20,11 +20,11 @@ comptime {
20 }20 }
21}21}
2222
23extern fn zenMain() -> noreturn {23extern fn zenMain() noreturn {
24 std.os.posix.exit(callMain());24 std.os.posix.exit(callMain());
25}25}
2626
27nakedcc fn _start() -> noreturn {27nakedcc fn _start() noreturn {
28 switch (builtin.arch) {28 switch (builtin.arch) {
29 builtin.Arch.x86_64 => {29 builtin.Arch.x86_64 => {
30 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));30 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
...@@ -39,20 +39,20 @@ nakedcc fn _start() -> noreturn {...@@ -39,20 +39,20 @@ nakedcc fn _start() -> noreturn {
39 @noInlineCall(posixCallMainAndExit);39 @noInlineCall(posixCallMainAndExit);
40}40}
4141
42extern fn WinMainCRTStartup() -> noreturn {42extern fn WinMainCRTStartup() noreturn {
43 @setAlignStack(16);43 @setAlignStack(16);
4444
45 std.os.windows.ExitProcess(callMain());45 std.os.windows.ExitProcess(callMain());
46}46}
4747
48fn posixCallMainAndExit() -> noreturn {48fn posixCallMainAndExit() noreturn {
49 const argc = *argc_ptr;49 const argc = *argc_ptr;
50 const argv = @ptrCast(&&u8, &argc_ptr[1]);50 const argv = @ptrCast(&&u8, &argc_ptr[1]);
51 const envp = @ptrCast(&?&u8, &argv[argc + 1]);51 const envp = @ptrCast(&?&u8, &argv[argc + 1]);
52 std.os.posix.exit(callMainWithArgs(argc, argv, envp));52 std.os.posix.exit(callMainWithArgs(argc, argv, envp));
53}53}
5454
55fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 {55fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) u8 {
56 std.os.ArgIteratorPosix.raw = argv[0..argc];56 std.os.ArgIteratorPosix.raw = argv[0..argc];
5757
58 var env_count: usize = 0;58 var env_count: usize = 0;
...@@ -62,11 +62,11 @@ fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 {...@@ -62,11 +62,11 @@ fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 {
62 return callMain();62 return callMain();
63}63}
6464
65extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {65extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) i32 {
66 return callMainWithArgs(usize(c_argc), c_argv, c_envp);66 return callMainWithArgs(usize(c_argc), c_argv, c_envp);
67}67}
6868
69fn callMain() -> u8 {69fn callMain() u8 {
70 switch (@typeId(@typeOf(root.main).ReturnType)) {70 switch (@typeId(@typeOf(root.main).ReturnType)) {
71 builtin.TypeId.NoReturn => {71 builtin.TypeId.NoReturn => {
72 root.main();72 root.main();
std/special/bootstrap_lib.zig+1-1
...@@ -7,7 +7,7 @@ comptime {...@@ -7,7 +7,7 @@ comptime {
7}7}
88
9stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,9stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,
10 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL10 lpReserved: std.os.windows.LPVOID) std.os.windows.BOOL
11{11{
12 return std.os.windows.TRUE;12 return std.os.windows.TRUE;
13}13}
std/special/build_file_template.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) {3pub fn build(b: &Builder) %void {
4 const mode = b.standardReleaseOptions();4 const mode = b.standardReleaseOptions();
5 const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");5 const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");
6 exe.setBuildMode(mode);6 exe.setBuildMode(mode);
std/special/build_runner.zig+4-4
...@@ -10,7 +10,7 @@ const warn = std.debug.warn;...@@ -10,7 +10,7 @@ const warn = std.debug.warn;
1010
11error InvalidArgs;11error InvalidArgs;
1212
13pub fn main() -> %void {13pub fn main() %void {
14 var arg_it = os.args();14 var arg_it = os.args();
1515
16 // TODO use a more general purpose allocator here16 // TODO use a more general purpose allocator here
...@@ -125,7 +125,7 @@ pub fn main() -> %void {...@@ -125,7 +125,7 @@ pub fn main() -> %void {
125 };125 };
126}126}
127127
128fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> %void {128fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) %void {
129 // run the build script to collect the options129 // run the build script to collect the options
130 if (!already_ran_build) {130 if (!already_ran_build) {
131 builder.setInstallPrefix(null);131 builder.setInstallPrefix(null);
...@@ -183,12 +183,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)...@@ -183,12 +183,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
183 );183 );
184}184}
185185
186fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> error {186fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) error {
187 usage(builder, already_ran_build, out_stream) catch {};187 usage(builder, already_ran_build, out_stream) catch {};
188 return error.InvalidArgs;188 return error.InvalidArgs;
189}189}
190190
191fn unwrapArg(arg: %[]u8) -> %[]u8 {191fn unwrapArg(arg: %[]u8) %[]u8 {
192 return arg catch |err| {192 return arg catch |err| {
193 warn("Unable to parse command line: {}\n", err);193 warn("Unable to parse command line: {}\n", err);
194 return err;194 return err;
std/special/builtin.zig+17-16
...@@ -3,10 +3,11 @@...@@ -3,10 +3,11 @@
33
4const builtin = @import("builtin");4const builtin = @import("builtin");
55
6// Avoid dragging in the debug safety mechanisms into this .o file,6// Avoid dragging in the runtime safety mechanisms into this .o file,
7// unless we're trying to test this file.7// unless we're trying to test this file.
8pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noreturn {8pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) noreturn {
9 if (builtin.is_test) {9 if (builtin.is_test) {
10 @setCold(true);
10 @import("std").debug.panic("{}", msg);11 @import("std").debug.panic("{}", msg);
11 } else {12 } else {
12 unreachable;13 unreachable;
...@@ -16,8 +17,8 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -...@@ -16,8 +17,8 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -
16// Note that memset does not return `dest`, like the libc API.17// Note that memset does not return `dest`, like the libc API.
17// The semantics of memset is dictated by the corresponding18// The semantics of memset is dictated by the corresponding
18// LLVM intrinsics, not by the libc API.19// LLVM intrinsics, not by the libc API.
19export fn memset(dest: ?&u8, c: u8, n: usize) {20export fn memset(dest: ?&u8, c: u8, n: usize) void {
20 @setDebugSafety(this, false);21 @setRuntimeSafety(false);
2122
22 var index: usize = 0;23 var index: usize = 0;
23 while (index != n) : (index += 1)24 while (index != n) : (index += 1)
...@@ -27,8 +28,8 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {...@@ -27,8 +28,8 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {
27// Note that memcpy does not return `dest`, like the libc API.28// Note that memcpy does not return `dest`, like the libc API.
28// The semantics of memcpy is dictated by the corresponding29// The semantics of memcpy is dictated by the corresponding
29// LLVM intrinsics, not by the libc API.30// LLVM intrinsics, not by the libc API.
30export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {31export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) void {
31 @setDebugSafety(this, false);32 @setRuntimeSafety(false);
3233
33 var index: usize = 0;34 var index: usize = 0;
34 while (index != n) : (index += 1)35 while (index != n) : (index += 1)
...@@ -40,24 +41,24 @@ comptime {...@@ -40,24 +41,24 @@ comptime {
40 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);41 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);
41 }42 }
42}43}
43extern fn __stack_chk_fail() -> noreturn {44extern fn __stack_chk_fail() noreturn {
44 @panic("stack smashing detected");45 @panic("stack smashing detected");
45}46}
4647
47const math = @import("../math/index.zig");48const math = @import("../math/index.zig");
4849
49export fn fmodf(x: f32, y: f32) -> f32 { return generic_fmod(f32, x, y); }50export fn fmodf(x: f32, y: f32) f32 { return generic_fmod(f32, x, y); }
50export fn fmod(x: f64, y: f64) -> f64 { return generic_fmod(f64, x, y); }51export fn fmod(x: f64, y: f64) f64 { return generic_fmod(f64, x, y); }
5152
52// TODO add intrinsics for these (and probably the double version too)53// TODO add intrinsics for these (and probably the double version too)
53// and have the math stuff use the intrinsic. same as @mod and @rem54// and have the math stuff use the intrinsic. same as @mod and @rem
54export fn floorf(x: f32) -> f32 { return math.floor(x); }55export fn floorf(x: f32) f32 { return math.floor(x); }
55export fn ceilf(x: f32) -> f32 { return math.ceil(x); }56export fn ceilf(x: f32) f32 { return math.ceil(x); }
56export fn floor(x: f64) -> f64 { return math.floor(x); }57export fn floor(x: f64) f64 { return math.floor(x); }
57export fn ceil(x: f64) -> f64 { return math.ceil(x); }58export fn ceil(x: f64) f64 { return math.ceil(x); }
5859
59fn generic_fmod(comptime T: type, x: T, y: T) -> T {60fn generic_fmod(comptime T: type, x: T, y: T) T {
60 @setDebugSafety(this, false);61 @setRuntimeSafety(false);
6162
62 const uint = @IntType(false, T.bit_count);63 const uint = @IntType(false, T.bit_count);
63 const log2uint = math.Log2Int(uint);64 const log2uint = math.Log2Int(uint);
...@@ -132,7 +133,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {...@@ -132,7 +133,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {
132 return @bitCast(T, ux);133 return @bitCast(T, ux);
133}134}
134135
135fn isNan(comptime T: type, bits: T) -> bool {136fn isNan(comptime T: type, bits: T) bool {
136 if (T == u32) {137 if (T == u32) {
137 return (bits & 0x7fffffff) > 0x7f800000;138 return (bits & 0x7fffffff) > 0x7f800000;
138 } else if (T == u64) {139 } else if (T == u64) {
std/special/compiler_rt/aulldiv.zig+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub nakedcc fn _aulldiv() {1pub nakedcc fn _aulldiv() void {
2 @setDebugSafety(this, false);2 @setRuntimeSafety(false);
3 asm volatile (3 asm volatile (
4 \\.intel_syntax noprefix4 \\.intel_syntax noprefix
5 \\5 \\
std/special/compiler_rt/aullrem.zig+2-2
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1pub nakedcc fn _aullrem() {1pub nakedcc fn _aullrem() void {
2 @setDebugSafety(this, false);2 @setRuntimeSafety(false);
3 asm volatile (3 asm volatile (
4 \\.intel_syntax noprefix4 \\.intel_syntax noprefix
5 \\5 \\
std/special/compiler_rt/comparetf2.zig+6-6
...@@ -21,8 +21,8 @@ const infRep = exponentMask;...@@ -21,8 +21,8 @@ const infRep = exponentMask;
21const builtin = @import("builtin");21const builtin = @import("builtin");
22const is_test = builtin.is_test;22const is_test = builtin.is_test;
2323
24pub extern fn __letf2(a: f128, b: f128) -> c_int {24pub extern fn __letf2(a: f128, b: f128) c_int {
25 @setDebugSafety(this, is_test);25 @setRuntimeSafety(is_test);
2626
27 const aInt = @bitCast(rep_t, a);27 const aInt = @bitCast(rep_t, a);
28 const bInt = @bitCast(rep_t, b);28 const bInt = @bitCast(rep_t, b);
...@@ -66,8 +66,8 @@ const GE_EQUAL = c_int(0);...@@ -66,8 +66,8 @@ const GE_EQUAL = c_int(0);
66const GE_GREATER = c_int(1);66const GE_GREATER = c_int(1);
67const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED67const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
6868
69pub extern fn __getf2(a: f128, b: f128) -> c_int {69pub extern fn __getf2(a: f128, b: f128) c_int {
70 @setDebugSafety(this, is_test);70 @setRuntimeSafety(is_test);
7171
72 const aInt = @bitCast(srep_t, a);72 const aInt = @bitCast(srep_t, a);
73 const bInt = @bitCast(srep_t, b);73 const bInt = @bitCast(srep_t, b);
...@@ -93,8 +93,8 @@ pub extern fn __getf2(a: f128, b: f128) -> c_int {...@@ -93,8 +93,8 @@ pub extern fn __getf2(a: f128, b: f128) -> c_int {
93 ;93 ;
94}94}
9595
96pub extern fn __unordtf2(a: f128, b: f128) -> c_int {96pub extern fn __unordtf2(a: f128, b: f128) c_int {
97 @setDebugSafety(this, is_test);97 @setRuntimeSafety(is_test);
9898
99 const aAbs = @bitCast(rep_t, a) & absMask;99 const aAbs = @bitCast(rep_t, a) & absMask;
100 const bAbs = @bitCast(rep_t, b) & absMask;100 const bAbs = @bitCast(rep_t, b) & absMask;
std/special/compiler_rt/fixuint.zig+4-4
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const is_test = @import("builtin").is_test;1const is_test = @import("builtin").is_test;
2const Log2Int = @import("../../math/index.zig").Log2Int;2const Log2Int = @import("../../math/index.zig").Log2Int;
33
4pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuint_t {4pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t {
5 @setDebugSafety(this, is_test);5 @setRuntimeSafety(is_test);
66
7 const rep_t = switch (fp_t) {7 const rep_t = switch (fp_t) {
8 f32 => u32,8 f32 => u32,
...@@ -48,12 +48,12 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuin...@@ -48,12 +48,12 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuin
48 if (exponent < significandBits) {48 if (exponent < significandBits) {
49 // TODO this is a workaround for the mysterious "integer cast truncated bits"49 // TODO this is a workaround for the mysterious "integer cast truncated bits"
50 // happening on the next line50 // happening on the next line
51 @setDebugSafety(this, false);51 @setRuntimeSafety(false);
52 return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent));52 return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent));
53 } else {53 } else {
54 // TODO this is a workaround for the mysterious "integer cast truncated bits"54 // TODO this is a workaround for the mysterious "integer cast truncated bits"
55 // happening on the next line55 // happening on the next line
56 @setDebugSafety(this, false);56 @setRuntimeSafety(false);
57 return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits);57 return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits);
58 }58 }
59}59}
std/special/compiler_rt/fixunsdfdi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunsdfdi(a: f64) -> u64 {4pub extern fn __fixunsdfdi(a: f64) u64 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f64, u64, a);6 return fixuint(f64, u64, a);
7}7}
88
std/special/compiler_rt/fixunsdfdi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;1const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfdi(a: f64, expected: u64) {4fn test__fixunsdfdi(a: f64, expected: u64) void {
5 const x = __fixunsdfdi(a);5 const x = __fixunsdfdi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunsdfsi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunsdfsi(a: f64) -> u32 {4pub extern fn __fixunsdfsi(a: f64) u32 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f64, u32, a);6 return fixuint(f64, u32, a);
7}7}
88
std/special/compiler_rt/fixunsdfsi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;1const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfsi(a: f64, expected: u32) {4fn test__fixunsdfsi(a: f64, expected: u32) void {
5 const x = __fixunsdfsi(a);5 const x = __fixunsdfsi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunsdfti.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunsdfti(a: f64) -> u128 {4pub extern fn __fixunsdfti(a: f64) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f64, u128, a);6 return fixuint(f64, u128, a);
7}7}
88
std/special/compiler_rt/fixunsdfti_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;1const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfti(a: f64, expected: u128) {4fn test__fixunsdfti(a: f64, expected: u128) void {
5 const x = __fixunsdfti(a);5 const x = __fixunsdfti(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunssfdi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunssfdi(a: f32) -> u64 {4pub extern fn __fixunssfdi(a: f32) u64 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f32, u64, a);6 return fixuint(f32, u64, a);
7}7}
88
std/special/compiler_rt/fixunssfdi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;1const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfdi(a: f32, expected: u64) {4fn test__fixunssfdi(a: f32, expected: u64) void {
5 const x = __fixunssfdi(a);5 const x = __fixunssfdi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunssfsi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunssfsi(a: f32) -> u32 {4pub extern fn __fixunssfsi(a: f32) u32 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f32, u32, a);6 return fixuint(f32, u32, a);
7}7}
88
std/special/compiler_rt/fixunssfsi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;1const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfsi(a: f32, expected: u32) {4fn test__fixunssfsi(a: f32, expected: u32) void {
5 const x = __fixunssfsi(a);5 const x = __fixunssfsi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunssfti.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunssfti(a: f32) -> u128 {4pub extern fn __fixunssfti(a: f32) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f32, u128, a);6 return fixuint(f32, u128, a);
7}7}
88
std/special/compiler_rt/fixunssfti_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;1const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfti(a: f32, expected: u128) {4fn test__fixunssfti(a: f32, expected: u128) void {
5 const x = __fixunssfti(a);5 const x = __fixunssfti(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunstfdi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunstfdi(a: f128) -> u64 {4pub extern fn __fixunstfdi(a: f128) u64 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f128, u64, a);6 return fixuint(f128, u64, a);
7}7}
88
std/special/compiler_rt/fixunstfdi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;1const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfdi(a: f128, expected: u64) {4fn test__fixunstfdi(a: f128, expected: u64) void {
5 const x = __fixunstfdi(a);5 const x = __fixunstfdi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunstfsi.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunstfsi(a: f128) -> u32 {4pub extern fn __fixunstfsi(a: f128) u32 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f128, u32, a);6 return fixuint(f128, u32, a);
7}7}
88
std/special/compiler_rt/fixunstfsi_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;1const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfsi(a: f128, expected: u32) {4fn test__fixunstfsi(a: f128, expected: u32) void {
5 const x = __fixunstfsi(a);5 const x = __fixunstfsi(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/fixunstfti.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const fixuint = @import("fixuint.zig").fixuint;1const fixuint = @import("fixuint.zig").fixuint;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __fixunstfti(a: f128) -> u128 {4pub extern fn __fixunstfti(a: f128) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return fixuint(f128, u128, a);6 return fixuint(f128, u128, a);
7}7}
88
std/special/compiler_rt/fixunstfti_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;1const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;
2const assert = @import("../../index.zig").debug.assert;2const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfti(a: f128, expected: u128) {4fn test__fixunstfti(a: f128, expected: u128) void {
5 const x = __fixunstfti(a);5 const x = __fixunstfti(a);
6 assert(x == expected);6 assert(x == expected);
7}7}
std/special/compiler_rt/index.zig+26-25
...@@ -72,9 +72,10 @@ const assert = @import("../../index.zig").debug.assert;...@@ -72,9 +72,10 @@ const assert = @import("../../index.zig").debug.assert;
7272
73const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;73const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
7474
75// Avoid dragging in the debug safety mechanisms into this .o file,75// Avoid dragging in the runtime safety mechanisms into this .o file,
76// unless we're trying to test this file.76// unless we're trying to test this file.
77pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noreturn {77pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) noreturn {
78 @setCold(true);
78 if (is_test) {79 if (is_test) {
79 @import("std").debug.panic("{}", msg);80 @import("std").debug.panic("{}", msg);
80 } else {81 } else {
...@@ -82,13 +83,13 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -...@@ -82,13 +83,13 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -
82 }83 }
83}84}
8485
85extern fn __udivdi3(a: u64, b: u64) -> u64 {86extern fn __udivdi3(a: u64, b: u64) u64 {
86 @setDebugSafety(this, is_test);87 @setRuntimeSafety(is_test);
87 return __udivmoddi4(a, b, null);88 return __udivmoddi4(a, b, null);
88}89}
8990
90extern fn __umoddi3(a: u64, b: u64) -> u64 {91extern fn __umoddi3(a: u64, b: u64) u64 {
91 @setDebugSafety(this, is_test);92 @setRuntimeSafety(is_test);
9293
93 var r: u64 = undefined;94 var r: u64 = undefined;
94 _ = __udivmoddi4(a, b, &r);95 _ = __udivmoddi4(a, b, &r);
...@@ -99,14 +100,14 @@ const AeabiUlDivModResult = extern struct {...@@ -99,14 +100,14 @@ const AeabiUlDivModResult = extern struct {
99 quot: u64,100 quot: u64,
100 rem: u64,101 rem: u64,
101};102};
102extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {103extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult {
103 @setDebugSafety(this, is_test);104 @setRuntimeSafety(is_test);
104 var result: AeabiUlDivModResult = undefined;105 var result: AeabiUlDivModResult = undefined;
105 result.quot = __udivmoddi4(numerator, denominator, &result.rem);106 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
106 return result;107 return result;
107}108}
108109
109fn isArmArch() -> bool {110fn isArmArch() bool {
110 return switch (builtin.arch) {111 return switch (builtin.arch) {
111 builtin.Arch.armv8_2a,112 builtin.Arch.armv8_2a,
112 builtin.Arch.armv8_1a,113 builtin.Arch.armv8_1a,
...@@ -148,8 +149,8 @@ fn isArmArch() -> bool {...@@ -148,8 +149,8 @@ fn isArmArch() -> bool {
148 };149 };
149}150}
150151
151nakedcc fn __aeabi_uidivmod() {152nakedcc fn __aeabi_uidivmod() void {
152 @setDebugSafety(this, false);153 @setRuntimeSafety(false);
153 asm volatile (154 asm volatile (
154 \\ push { lr }155 \\ push { lr }
155 \\ sub sp, sp, #4156 \\ sub sp, sp, #4
...@@ -165,8 +166,8 @@ nakedcc fn __aeabi_uidivmod() {...@@ -165,8 +166,8 @@ nakedcc fn __aeabi_uidivmod() {
165// then decrement %esp by %eax. Preserves all registers except %esp and flags.166// then decrement %esp by %eax. Preserves all registers except %esp and flags.
166// This routine is windows specific167// This routine is windows specific
167// http://msdn.microsoft.com/en-us/library/ms648426.aspx168// http://msdn.microsoft.com/en-us/library/ms648426.aspx
168nakedcc fn _chkstk() align(4) {169nakedcc fn _chkstk() align(4) void {
169 @setDebugSafety(this, false);170 @setRuntimeSafety(false);
170171
171 asm volatile (172 asm volatile (
172 \\ push %%ecx173 \\ push %%ecx
...@@ -189,8 +190,8 @@ nakedcc fn _chkstk() align(4) {...@@ -189,8 +190,8 @@ nakedcc fn _chkstk() align(4) {
189 );190 );
190}191}
191192
192nakedcc fn __chkstk() align(4) {193nakedcc fn __chkstk() align(4) void {
193 @setDebugSafety(this, false);194 @setRuntimeSafety(false);
194195
195 asm volatile (196 asm volatile (
196 \\ push %%rcx197 \\ push %%rcx
...@@ -216,8 +217,8 @@ nakedcc fn __chkstk() align(4) {...@@ -216,8 +217,8 @@ nakedcc fn __chkstk() align(4) {
216// _chkstk routine217// _chkstk routine
217// This routine is windows specific218// This routine is windows specific
218// http://msdn.microsoft.com/en-us/library/ms648426.aspx219// http://msdn.microsoft.com/en-us/library/ms648426.aspx
219nakedcc fn __chkstk_ms() align(4) {220nakedcc fn __chkstk_ms() align(4) void {
220 @setDebugSafety(this, false);221 @setRuntimeSafety(false);
221222
222 asm volatile (223 asm volatile (
223 \\ push %%ecx224 \\ push %%ecx
...@@ -240,8 +241,8 @@ nakedcc fn __chkstk_ms() align(4) {...@@ -240,8 +241,8 @@ nakedcc fn __chkstk_ms() align(4) {
240 );241 );
241}242}
242243
243nakedcc fn ___chkstk_ms() align(4) {244nakedcc fn ___chkstk_ms() align(4) void {
244 @setDebugSafety(this, false);245 @setRuntimeSafety(false);
245246
246 asm volatile (247 asm volatile (
247 \\ push %%rcx248 \\ push %%rcx
...@@ -264,8 +265,8 @@ nakedcc fn ___chkstk_ms() align(4) {...@@ -264,8 +265,8 @@ nakedcc fn ___chkstk_ms() align(4) {
264 );265 );
265}266}
266267
267extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {268extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) u32 {
268 @setDebugSafety(this, is_test);269 @setRuntimeSafety(is_test);
269270
270 const d = __udivsi3(a, b);271 const d = __udivsi3(a, b);
271 *rem = u32(i32(a) -% (i32(d) * i32(b)));272 *rem = u32(i32(a) -% (i32(d) * i32(b)));
...@@ -273,8 +274,8 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {...@@ -273,8 +274,8 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
273}274}
274275
275276
276extern fn __udivsi3(n: u32, d: u32) -> u32 {277extern fn __udivsi3(n: u32, d: u32) u32 {
277 @setDebugSafety(this, is_test);278 @setRuntimeSafety(is_test);
278279
279 const n_uword_bits: c_uint = u32.bit_count;280 const n_uword_bits: c_uint = u32.bit_count;
280 // special cases281 // special cases
...@@ -320,7 +321,7 @@ test "test_umoddi3" {...@@ -320,7 +321,7 @@ test "test_umoddi3" {
320 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);321 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
321}322}
322323
323fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) {324fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
324 const r = __umoddi3(a, b);325 const r = __umoddi3(a, b);
325 assert(r == expected_r);326 assert(r == expected_r);
326}327}
...@@ -466,7 +467,7 @@ test "test_udivsi3" {...@@ -466,7 +467,7 @@ test "test_udivsi3" {
466 }467 }
467}468}
468469
469fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {470fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
470 const q: u32 = __udivsi3(a, b);471 const q: u32 = __udivsi3(a, b);
471 assert(q == expected_q);472 assert(q == expected_q);
472}473}
std/special/compiler_rt/udivmod.zig+2-2
...@@ -4,8 +4,8 @@ const is_test = builtin.is_test;...@@ -4,8 +4,8 @@ const is_test = builtin.is_test;
4const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Little => 0 };4const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Little => 0 };
5const high = 1 - low;5const high = 1 - low;
66
7pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) -> DoubleInt {7pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) DoubleInt {
8 @setDebugSafety(this, is_test);8 @setRuntimeSafety(is_test);
99
10 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));10 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));
11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);11 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
std/special/compiler_rt/udivmoddi4.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {4pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) u64 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return udivmod(u64, a, b, maybe_rem);6 return udivmod(u64, a, b, maybe_rem);
7}7}
88
std/special/compiler_rt/udivmoddi4_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;1const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
2const assert = @import("std").debug.assert;2const assert = @import("std").debug.assert;
33
4fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) {4fn test__udivmoddi4(a: u64, b: u64, expected_q: u64, expected_r: u64) void {
5 var r: u64 = undefined;5 var r: u64 = undefined;
6 const q = __udivmoddi4(a, b, &r);6 const q = __udivmoddi4(a, b, &r);
7 assert(q == expected_q);7 assert(q == expected_q);
std/special/compiler_rt/udivmodti4.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const udivmod = @import("udivmod.zig").udivmod;1const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {4pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return udivmod(u128, a, b, maybe_rem);6 return udivmod(u128, a, b, maybe_rem);
7}7}
88
std/special/compiler_rt/udivmodti4_test.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const assert = @import("std").debug.assert;2const assert = @import("std").debug.assert;
33
4fn test__udivmodti4(a: u128, b: u128, expected_q: u128, expected_r: u128) {4fn test__udivmodti4(a: u128, b: u128, expected_q: u128, expected_r: u128) void {
5 var r: u128 = undefined;5 var r: u128 = undefined;
6 const q = __udivmodti4(a, b, &r);6 const q = __udivmodti4(a, b, &r);
7 assert(q == expected_q);7 assert(q == expected_q);
std/special/compiler_rt/udivti3.zig+2-2
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __udivti3(a: u128, b: u128) -> u128 {4pub extern fn __udivti3(a: u128, b: u128) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 return __udivmodti4(a, b, null);6 return __udivmodti4(a, b, null);
7}7}
std/special/compiler_rt/umodti3.zig+2-2
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;1const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub extern fn __umodti3(a: u128, b: u128) -> u128 {4pub extern fn __umodti3(a: u128, b: u128) u128 {
5 @setDebugSafety(this, builtin.is_test);5 @setRuntimeSafety(builtin.is_test);
6 var r: u128 = undefined;6 var r: u128 = undefined;
7 _ = __udivmodti4(a, b, &r);7 _ = __udivmodti4(a, b, &r);
8 return r;8 return r;
std/special/panic.zig+2-1
...@@ -6,7 +6,8 @@...@@ -6,7 +6,8 @@
6const builtin = @import("builtin");6const builtin = @import("builtin");
7const std = @import("std");7const std = @import("std");
88
9pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noreturn {9pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) noreturn {
10 @setCold(true);
10 switch (builtin.os) {11 switch (builtin.os) {
11 // TODO: fix panic in zen.12 // TODO: fix panic in zen.
12 builtin.Os.freestanding, builtin.Os.zen => {13 builtin.Os.freestanding, builtin.Os.zen => {
std/special/test_runner.zig+1-1
...@@ -4,7 +4,7 @@ const builtin = @import("builtin");...@@ -4,7 +4,7 @@ const builtin = @import("builtin");
4const test_fn_list = builtin.__zig_test_fn_slice;4const test_fn_list = builtin.__zig_test_fn_slice;
5const warn = std.debug.warn;5const warn = std.debug.warn;
66
7pub fn main() -> %void {7pub fn main() %void {
8 for (test_fn_list) |test_fn, i| {8 for (test_fn_list) |test_fn, i| {
9 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);9 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
1010
std/unicode.zig+8-8
...@@ -5,7 +5,7 @@ error Utf8InvalidStartByte;...@@ -5,7 +5,7 @@ error Utf8InvalidStartByte;
5/// Given the first byte of a UTF-8 codepoint,5/// Given the first byte of a UTF-8 codepoint,
6/// returns a number 1-4 indicating the total length of the codepoint in bytes.6/// returns a number 1-4 indicating the total length of the codepoint in bytes.
7/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.7/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
8pub fn utf8ByteSequenceLength(first_byte: u8) -> %u3 {8pub fn utf8ByteSequenceLength(first_byte: u8) %u3 {
9 if (first_byte < 0b10000000) return u3(1);9 if (first_byte < 0b10000000) return u3(1);
10 if (first_byte & 0b11100000 == 0b11000000) return u3(2);10 if (first_byte & 0b11100000 == 0b11000000) return u3(2);
11 if (first_byte & 0b11110000 == 0b11100000) return u3(3);11 if (first_byte & 0b11110000 == 0b11100000) return u3(3);
...@@ -22,7 +22,7 @@ error Utf8CodepointTooLarge;...@@ -22,7 +22,7 @@ error Utf8CodepointTooLarge;
22/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.22/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.
23/// If you already know the length at comptime, you can call one of23/// If you already know the length at comptime, you can call one of
24/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.24/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
25pub fn utf8Decode(bytes: []const u8) -> %u32 {25pub fn utf8Decode(bytes: []const u8) %u32 {
26 return switch (bytes.len) {26 return switch (bytes.len) {
27 1 => u32(bytes[0]),27 1 => u32(bytes[0]),
28 2 => utf8Decode2(bytes),28 2 => utf8Decode2(bytes),
...@@ -31,7 +31,7 @@ pub fn utf8Decode(bytes: []const u8) -> %u32 {...@@ -31,7 +31,7 @@ pub fn utf8Decode(bytes: []const u8) -> %u32 {
31 else => unreachable,31 else => unreachable,
32 };32 };
33}33}
34pub fn utf8Decode2(bytes: []const u8) -> %u32 {34pub fn utf8Decode2(bytes: []const u8) %u32 {
35 std.debug.assert(bytes.len == 2);35 std.debug.assert(bytes.len == 2);
36 std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);36 std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);
37 var value: u32 = bytes[0] & 0b00011111;37 var value: u32 = bytes[0] & 0b00011111;
...@@ -44,7 +44,7 @@ pub fn utf8Decode2(bytes: []const u8) -> %u32 {...@@ -44,7 +44,7 @@ pub fn utf8Decode2(bytes: []const u8) -> %u32 {
4444
45 return value;45 return value;
46}46}
47pub fn utf8Decode3(bytes: []const u8) -> %u32 {47pub fn utf8Decode3(bytes: []const u8) %u32 {
48 std.debug.assert(bytes.len == 3);48 std.debug.assert(bytes.len == 3);
49 std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);49 std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);
50 var value: u32 = bytes[0] & 0b00001111;50 var value: u32 = bytes[0] & 0b00001111;
...@@ -62,7 +62,7 @@ pub fn utf8Decode3(bytes: []const u8) -> %u32 {...@@ -62,7 +62,7 @@ pub fn utf8Decode3(bytes: []const u8) -> %u32 {
6262
63 return value;63 return value;
64}64}
65pub fn utf8Decode4(bytes: []const u8) -> %u32 {65pub fn utf8Decode4(bytes: []const u8) %u32 {
66 std.debug.assert(bytes.len == 4);66 std.debug.assert(bytes.len == 4);
67 std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);67 std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);
68 var value: u32 = bytes[0] & 0b00000111;68 var value: u32 = bytes[0] & 0b00000111;
...@@ -149,7 +149,7 @@ test "misc invalid utf8" {...@@ -149,7 +149,7 @@ test "misc invalid utf8" {
149 testValid("\xee\x80\x80", 0xe000);149 testValid("\xee\x80\x80", 0xe000);
150}150}
151151
152fn testError(bytes: []const u8, expected_err: error) {152fn testError(bytes: []const u8, expected_err: error) void {
153 if (testDecode(bytes)) |_| {153 if (testDecode(bytes)) |_| {
154 unreachable;154 unreachable;
155 } else |err| {155 } else |err| {
...@@ -157,11 +157,11 @@ fn testError(bytes: []const u8, expected_err: error) {...@@ -157,11 +157,11 @@ fn testError(bytes: []const u8, expected_err: error) {
157 }157 }
158}158}
159159
160fn testValid(bytes: []const u8, expected_codepoint: u32) {160fn testValid(bytes: []const u8, expected_codepoint: u32) void {
161 std.debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);161 std.debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);
162}162}
163163
164fn testDecode(bytes: []const u8) -> %u32 {164fn testDecode(bytes: []const u8) %u32 {
165 const length = try utf8ByteSequenceLength(bytes[0]);165 const length = try utf8ByteSequenceLength(bytes[0]);
166 if (bytes.len < length) return error.UnexpectedEof;166 if (bytes.len < length) return error.UnexpectedEof;
167 std.debug.assert(bytes.len == length);167 std.debug.assert(bytes.len == length);
std/zlib/deflate.zig deleted-522
...@@ -1,522 +0,0 @@
1const z_stream = struct {
2 /// next input byte */
3 next_in: &const u8,
4
5 /// number of bytes available at next_in
6 avail_in: u16,
7 /// total number of input bytes read so far
8 total_in: u32,
9
10 /// next output byte will go here
11 next_out: u8,
12 /// remaining free space at next_out
13 avail_out: u16,
14 /// total number of bytes output so far
15 total_out: u32,
16
17 /// last error message, NULL if no error
18 msg: ?&const u8,
19 /// not visible by applications
20 state:
21 struct internal_state FAR *state; // not visible by applications */
22
23 alloc_func zalloc; // used to allocate the internal state */
24 free_func zfree; // used to free the internal state */
25 voidpf opaque; // private data object passed to zalloc and zfree */
26
27 int data_type; // best guess about the data type: binary or text
28 // for deflate, or the decoding state for inflate */
29 uint32_t adler; // Adler-32 or CRC-32 value of the uncompressed data */
30 uint32_t reserved; // reserved for future use */
31};
32
33typedef struct internal_state {
34 z_stream * strm; /* pointer back to this zlib stream */
35 int status; /* as the name implies */
36 uint8_t *pending_buf; /* output still pending */
37 ulg pending_buf_size; /* size of pending_buf */
38 uint8_t *pending_out; /* next pending byte to output to the stream */
39 ulg pending; /* nb of bytes in the pending buffer */
40 int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
41 gz_headerp gzhead; /* gzip header information to write */
42 ulg gzindex; /* where in extra, name, or comment */
43 uint8_t method; /* can only be DEFLATED */
44 int last_flush; /* value of flush param for previous deflate call */
45
46 /* used by deflate.c: */
47
48 uint16_t w_size; /* LZ77 window size (32K by default) */
49 uint16_t w_bits; /* log2(w_size) (8..16) */
50 uint16_t w_mask; /* w_size - 1 */
51
52 uint8_t *window;
53 /* Sliding window. Input bytes are read into the second half of the window,
54 * and move to the first half later to keep a dictionary of at least wSize
55 * bytes. With this organization, matches are limited to a distance of
56 * wSize-MAX_MATCH bytes, but this ensures that IO is always
57 * performed with a length multiple of the block size. Also, it limits
58 * the window size to 64K, which is quite useful on MSDOS.
59 * To do: use the user input buffer as sliding window.
60 */
61
62 ulg window_size;
63 /* Actual size of window: 2*wSize, except when the user input buffer
64 * is directly used as sliding window.
65 */
66
67 Posf *prev;
68 /* Link to older string with same hash index. To limit the size of this
69 * array to 64K, this link is maintained only for the last 32K strings.
70 * An index in this array is thus a window index modulo 32K.
71 */
72
73 Posf *head; /* Heads of the hash chains or NIL. */
74
75 uint16_t ins_h; /* hash index of string to be inserted */
76 uint16_t hash_size; /* number of elements in hash table */
77 uint16_t hash_bits; /* log2(hash_size) */
78 uint16_t hash_mask; /* hash_size-1 */
79
80 uint16_t hash_shift;
81 /* Number of bits by which ins_h must be shifted at each input
82 * step. It must be such that after MIN_MATCH steps, the oldest
83 * byte no longer takes part in the hash key, that is:
84 * hash_shift * MIN_MATCH >= hash_bits
85 */
86
87 long block_start;
88 /* Window position at the beginning of the current output block. Gets
89 * negative when the window is moved backwards.
90 */
91
92 uint16_t match_length; /* length of best match */
93 IPos prev_match; /* previous match */
94 int match_available; /* set if previous match exists */
95 uint16_t strstart; /* start of string to insert */
96 uint16_t match_start; /* start of matching string */
97 uint16_t lookahead; /* number of valid bytes ahead in window */
98
99 uint16_t prev_length;
100 /* Length of the best match at previous step. Matches not greater than this
101 * are discarded. This is used in the lazy match evaluation.
102 */
103
104 uint16_t max_chain_length;
105 /* To speed up deflation, hash chains are never searched beyond this
106 * length. A higher limit improves compression ratio but degrades the
107 * speed.
108 */
109
110 uint16_t max_lazy_match;
111 /* Attempt to find a better match only when the current match is strictly
112 * smaller than this value. This mechanism is used only for compression
113 * levels >= 4.
114 */
115# define max_insert_length max_lazy_match
116 /* Insert new strings in the hash table only if the match length is not
117 * greater than this length. This saves time but degrades compression.
118 * max_insert_length is used only for compression levels <= 3.
119 */
120
121 int level; /* compression level (1..9) */
122 int strategy; /* favor or force Huffman coding*/
123
124 uint16_t good_match;
125 /* Use a faster search when the previous match is longer than this */
126
127 int nice_match; /* Stop searching when current match exceeds this */
128
129 /* used by trees.c: */
130 /* Didn't use ct_data typedef below to suppress compiler warning */
131 struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
132 struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
133 struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
134
135 struct tree_desc_s l_desc; /* desc. for literal tree */
136 struct tree_desc_s d_desc; /* desc. for distance tree */
137 struct tree_desc_s bl_desc; /* desc. for bit length tree */
138
139 ush bl_count[MAX_BITS+1];
140 /* number of codes at each bit length for an optimal tree */
141
142 int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
143 int heap_len; /* number of elements in the heap */
144 int heap_max; /* element of largest frequency */
145 /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
146 * The same heap array is used to build all trees.
147 */
148
149 uch depth[2*L_CODES+1];
150 /* Depth of each subtree used as tie breaker for trees of equal frequency
151 */
152
153 uchf *l_buf; /* buffer for literals or lengths */
154
155 uint16_t lit_bufsize;
156 /* Size of match buffer for literals/lengths. There are 4 reasons for
157 * limiting lit_bufsize to 64K:
158 * - frequencies can be kept in 16 bit counters
159 * - if compression is not successful for the first block, all input
160 * data is still in the window so we can still emit a stored block even
161 * when input comes from standard input. (This can also be done for
162 * all blocks if lit_bufsize is not greater than 32K.)
163 * - if compression is not successful for a file smaller than 64K, we can
164 * even emit a stored file instead of a stored block (saving 5 bytes).
165 * This is applicable only for zip (not gzip or zlib).
166 * - creating new Huffman trees less frequently may not provide fast
167 * adaptation to changes in the input data statistics. (Take for
168 * example a binary file with poorly compressible code followed by
169 * a highly compressible string table.) Smaller buffer sizes give
170 * fast adaptation but have of course the overhead of transmitting
171 * trees more frequently.
172 * - I can't count above 4
173 */
174
175 uint16_t last_lit; /* running index in l_buf */
176
177 ushf *d_buf;
178 /* Buffer for distances. To simplify the code, d_buf and l_buf have
179 * the same number of elements. To use different lengths, an extra flag
180 * array would be necessary.
181 */
182
183 ulg opt_len; /* bit length of current block with optimal trees */
184 ulg static_len; /* bit length of current block with static trees */
185 uint16_t matches; /* number of string matches in current block */
186 uint16_t insert; /* bytes at end of window left to insert */
187
188#ifdef ZLIB_DEBUG
189 ulg compressed_len; /* total bit length of compressed file mod 2^32 */
190 ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
191#endif
192
193 ush bi_buf;
194 /* Output buffer. bits are inserted starting at the bottom (least
195 * significant bits).
196 */
197 int bi_valid;
198 /* Number of valid bits in bi_buf. All bits above the last valid bit
199 * are always zero.
200 */
201
202 ulg high_water;
203 /* High water mark offset in window for initialized bytes -- bytes above
204 * this are set to zero in order to avoid memory check warnings when
205 * longest match routines access bytes past the input. This is then
206 * updated to the new high water mark.
207 */
208
209} FAR deflate_state;
210
211fn deflate(strm: &z_stream, flush: int) -> %void {
212
213}
214
215int deflate (z_stream * strm, int flush) {
216 int old_flush; /* value of flush param for previous deflate call */
217 deflate_state *s;
218
219 if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
220 return Z_STREAM_ERROR;
221 }
222 s = strm->state;
223
224 if (strm->next_out == Z_NULL ||
225 (strm->avail_in != 0 && strm->next_in == Z_NULL) ||
226 (s->status == FINISH_STATE && flush != Z_FINISH)) {
227 ERR_RETURN(strm, Z_STREAM_ERROR);
228 }
229 if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
230
231 old_flush = s->last_flush;
232 s->last_flush = flush;
233
234 /* Flush as much pending output as possible */
235 if (s->pending != 0) {
236 flush_pending(strm);
237 if (strm->avail_out == 0) {
238 /* Since avail_out is 0, deflate will be called again with
239 * more output space, but possibly with both pending and
240 * avail_in equal to zero. There won't be anything to do,
241 * but this is not an error situation so make sure we
242 * return OK instead of BUF_ERROR at next call of deflate:
243 */
244 s->last_flush = -1;
245 return Z_OK;
246 }
247
248 /* Make sure there is something to do and avoid duplicate consecutive
249 * flushes. For repeated and useless calls with Z_FINISH, we keep
250 * returning Z_STREAM_END instead of Z_BUF_ERROR.
251 */
252 } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
253 flush != Z_FINISH) {
254 ERR_RETURN(strm, Z_BUF_ERROR);
255 }
256
257 /* User must not provide more input after the first FINISH: */
258 if (s->status == FINISH_STATE && strm->avail_in != 0) {
259 ERR_RETURN(strm, Z_BUF_ERROR);
260 }
261
262 /* Write the header */
263 if (s->status == INIT_STATE) {
264 /* zlib header */
265 uint16_t header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
266 uint16_t level_flags;
267
268 if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
269 level_flags = 0;
270 else if (s->level < 6)
271 level_flags = 1;
272 else if (s->level == 6)
273 level_flags = 2;
274 else
275 level_flags = 3;
276 header |= (level_flags << 6);
277 if (s->strstart != 0) header |= PRESET_DICT;
278 header += 31 - (header % 31);
279
280 putShortMSB(s, header);
281
282 /* Save the adler32 of the preset dictionary: */
283 if (s->strstart != 0) {
284 putShortMSB(s, (uint16_t)(strm->adler >> 16));
285 putShortMSB(s, (uint16_t)(strm->adler & 0xffff));
286 }
287 strm->adler = adler32(0L, Z_NULL, 0);
288 s->status = BUSY_STATE;
289
290 /* Compression must start with an empty pending buffer */
291 flush_pending(strm);
292 if (s->pending != 0) {
293 s->last_flush = -1;
294 return Z_OK;
295 }
296 }
297#ifdef GZIP
298 if (s->status == GZIP_STATE) {
299 /* gzip header */
300 strm->adler = crc32(0L, Z_NULL, 0);
301 put_byte(s, 31);
302 put_byte(s, 139);
303 put_byte(s, 8);
304 if (s->gzhead == Z_NULL) {
305 put_byte(s, 0);
306 put_byte(s, 0);
307 put_byte(s, 0);
308 put_byte(s, 0);
309 put_byte(s, 0);
310 put_byte(s, s->level == 9 ? 2 :
311 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
312 4 : 0));
313 put_byte(s, OS_CODE);
314 s->status = BUSY_STATE;
315
316 /* Compression must start with an empty pending buffer */
317 flush_pending(strm);
318 if (s->pending != 0) {
319 s->last_flush = -1;
320 return Z_OK;
321 }
322 }
323 else {
324 put_byte(s, (s->gzhead->text ? 1 : 0) +
325 (s->gzhead->hcrc ? 2 : 0) +
326 (s->gzhead->extra == Z_NULL ? 0 : 4) +
327 (s->gzhead->name == Z_NULL ? 0 : 8) +
328 (s->gzhead->comment == Z_NULL ? 0 : 16)
329 );
330 put_byte(s, (uint8_t)(s->gzhead->time & 0xff));
331 put_byte(s, (uint8_t)((s->gzhead->time >> 8) & 0xff));
332 put_byte(s, (uint8_t)((s->gzhead->time >> 16) & 0xff));
333 put_byte(s, (uint8_t)((s->gzhead->time >> 24) & 0xff));
334 put_byte(s, s->level == 9 ? 2 :
335 (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
336 4 : 0));
337 put_byte(s, s->gzhead->os & 0xff);
338 if (s->gzhead->extra != Z_NULL) {
339 put_byte(s, s->gzhead->extra_len & 0xff);
340 put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
341 }
342 if (s->gzhead->hcrc)
343 strm->adler = crc32(strm->adler, s->pending_buf,
344 s->pending);
345 s->gzindex = 0;
346 s->status = EXTRA_STATE;
347 }
348 }
349 if (s->status == EXTRA_STATE) {
350 if (s->gzhead->extra != Z_NULL) {
351 ulg beg = s->pending; /* start of bytes to update crc */
352 uint16_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex;
353 while (s->pending + left > s->pending_buf_size) {
354 uint16_t copy = s->pending_buf_size - s->pending;
355 zmemcpy(s->pending_buf + s->pending,
356 s->gzhead->extra + s->gzindex, copy);
357 s->pending = s->pending_buf_size;
358 HCRC_UPDATE(beg);
359 s->gzindex += copy;
360 flush_pending(strm);
361 if (s->pending != 0) {
362 s->last_flush = -1;
363 return Z_OK;
364 }
365 beg = 0;
366 left -= copy;
367 }
368 zmemcpy(s->pending_buf + s->pending,
369 s->gzhead->extra + s->gzindex, left);
370 s->pending += left;
371 HCRC_UPDATE(beg);
372 s->gzindex = 0;
373 }
374 s->status = NAME_STATE;
375 }
376 if (s->status == NAME_STATE) {
377 if (s->gzhead->name != Z_NULL) {
378 ulg beg = s->pending; /* start of bytes to update crc */
379 int val;
380 do {
381 if (s->pending == s->pending_buf_size) {
382 HCRC_UPDATE(beg);
383 flush_pending(strm);
384 if (s->pending != 0) {
385 s->last_flush = -1;
386 return Z_OK;
387 }
388 beg = 0;
389 }
390 val = s->gzhead->name[s->gzindex++];
391 put_byte(s, val);
392 } while (val != 0);
393 HCRC_UPDATE(beg);
394 s->gzindex = 0;
395 }
396 s->status = COMMENT_STATE;
397 }
398 if (s->status == COMMENT_STATE) {
399 if (s->gzhead->comment != Z_NULL) {
400 ulg beg = s->pending; /* start of bytes to update crc */
401 int val;
402 do {
403 if (s->pending == s->pending_buf_size) {
404 HCRC_UPDATE(beg);
405 flush_pending(strm);
406 if (s->pending != 0) {
407 s->last_flush = -1;
408 return Z_OK;
409 }
410 beg = 0;
411 }
412 val = s->gzhead->comment[s->gzindex++];
413 put_byte(s, val);
414 } while (val != 0);
415 HCRC_UPDATE(beg);
416 }
417 s->status = HCRC_STATE;
418 }
419 if (s->status == HCRC_STATE) {
420 if (s->gzhead->hcrc) {
421 if (s->pending + 2 > s->pending_buf_size) {
422 flush_pending(strm);
423 if (s->pending != 0) {
424 s->last_flush = -1;
425 return Z_OK;
426 }
427 }
428 put_byte(s, (uint8_t)(strm->adler & 0xff));
429 put_byte(s, (uint8_t)((strm->adler >> 8) & 0xff));
430 strm->adler = crc32(0L, Z_NULL, 0);
431 }
432 s->status = BUSY_STATE;
433
434 /* Compression must start with an empty pending buffer */
435 flush_pending(strm);
436 if (s->pending != 0) {
437 s->last_flush = -1;
438 return Z_OK;
439 }
440 }
441#endif
442
443 /* Start a new block or continue the current one.
444 */
445 if (strm->avail_in != 0 || s->lookahead != 0 ||
446 (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
447 block_state bstate;
448
449 bstate = s->level == 0 ? deflate_stored(s, flush) :
450 s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
451 s->strategy == Z_RLE ? deflate_rle(s, flush) :
452 (*(configuration_table[s->level].func))(s, flush);
453
454 if (bstate == finish_started || bstate == finish_done) {
455 s->status = FINISH_STATE;
456 }
457 if (bstate == need_more || bstate == finish_started) {
458 if (strm->avail_out == 0) {
459 s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
460 }
461 return Z_OK;
462 /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
463 * of deflate should use the same flush parameter to make sure
464 * that the flush is complete. So we don't have to output an
465 * empty block here, this will be done at next call. This also
466 * ensures that for a very small output buffer, we emit at most
467 * one empty block.
468 */
469 }
470 if (bstate == block_done) {
471 if (flush == Z_PARTIAL_FLUSH) {
472 _tr_align(s);
473 } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
474 _tr_stored_block(s, (char*)0, 0L, 0);
475 /* For a full flush, this empty block will be recognized
476 * as a special marker by inflate_sync().
477 */
478 if (flush == Z_FULL_FLUSH) {
479 CLEAR_HASH(s); /* forget history */
480 if (s->lookahead == 0) {
481 s->strstart = 0;
482 s->block_start = 0L;
483 s->insert = 0;
484 }
485 }
486 }
487 flush_pending(strm);
488 if (strm->avail_out == 0) {
489 s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
490 return Z_OK;
491 }
492 }
493 }
494
495 if (flush != Z_FINISH) return Z_OK;
496 if (s->wrap <= 0) return Z_STREAM_END;
497
498 /* Write the trailer */
499#ifdef GZIP
500 if (s->wrap == 2) {
501 put_byte(s, (uint8_t)(strm->adler & 0xff));
502 put_byte(s, (uint8_t)((strm->adler >> 8) & 0xff));
503 put_byte(s, (uint8_t)((strm->adler >> 16) & 0xff));
504 put_byte(s, (uint8_t)((strm->adler >> 24) & 0xff));
505 put_byte(s, (uint8_t)(strm->total_in & 0xff));
506 put_byte(s, (uint8_t)((strm->total_in >> 8) & 0xff));
507 put_byte(s, (uint8_t)((strm->total_in >> 16) & 0xff));
508 put_byte(s, (uint8_t)((strm->total_in >> 24) & 0xff));
509 }
510 else
511#endif
512 {
513 putShortMSB(s, (uint16_t)(strm->adler >> 16));
514 putShortMSB(s, (uint16_t)(strm->adler & 0xffff));
515 }
516 flush_pending(strm);
517 /* If avail_out is zero, the application will call deflate again
518 * to flush the rest.
519 */
520 if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
521 return s->pending != 0 ? Z_OK : Z_STREAM_END;
522}
std/zlib/inflate.zig deleted-969
...@@ -1,969 +0,0 @@
1
2error Z_STREAM_ERROR;
3error Z_STREAM_END;
4error Z_NEED_DICT;
5error Z_ERRNO;
6error Z_STREAM_ERROR;
7error Z_DATA_ERROR;
8error Z_MEM_ERROR;
9error Z_BUF_ERROR;
10error Z_VERSION_ERROR;
11
12pub Flush = enum {
13 NO_FLUSH,
14 PARTIAL_FLUSH,
15 SYNC_FLUSH,
16 FULL_FLUSH,
17 FINISH,
18 BLOCK,
19 TREES,
20};
21
22const code = struct {
23 /// operation, extra bits, table bits
24 op: u8,
25 /// bits in this part of the code
26 bits: u8,
27 /// offset in table or code value
28 val: u16,
29};
30
31/// State maintained between inflate() calls -- approximately 7K bytes, not
32/// including the allocated sliding window, which is up to 32K bytes.
33const inflate_state = struct {
34 z_stream * strm; /* pointer back to this zlib stream */
35 inflate_mode mode; /* current inflate mode */
36 int last; /* true if processing last block */
37 int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
38 bit 2 true to validate check value */
39 int havedict; /* true if dictionary provided */
40 int flags; /* gzip header method and flags (0 if zlib) */
41 unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
42 unsigned long check; /* protected copy of check value */
43 unsigned long total; /* protected copy of output count */
44 gz_headerp head; /* where to save gzip header information */
45 /* sliding window */
46 unsigned wbits; /* log base 2 of requested window size */
47 unsigned wsize; /* window size or zero if not using window */
48 unsigned whave; /* valid bytes in the window */
49 unsigned wnext; /* window write index */
50 u8 FAR *window; /* allocated sliding window, if needed */
51 /* bit accumulator */
52 unsigned long hold; /* input bit accumulator */
53 unsigned bits; /* number of bits in "in" */
54 /* for string and stored block copying */
55 unsigned length; /* literal or length of data to copy */
56 unsigned offset; /* distance back to copy string from */
57 /* for table and code decoding */
58 unsigned extra; /* extra bits needed */
59 /* fixed and dynamic code tables */
60 code const FAR *lencode; /* starting table for length/literal codes */
61 code const FAR *distcode; /* starting table for distance codes */
62 unsigned lenbits; /* index bits for lencode */
63 unsigned distbits; /* index bits for distcode */
64 /* dynamic table building */
65 unsigned ncode; /* number of code length code lengths */
66 unsigned nlen; /* number of length code lengths */
67 unsigned ndist; /* number of distance code lengths */
68 unsigned have; /* number of code lengths in lens[] */
69 code FAR *next; /* next available space in codes[] */
70 unsigned short lens[320]; /* temporary storage for code lengths */
71 unsigned short work[288]; /* work area for code table building */
72 code codes[ENOUGH]; /* space for code tables */
73 int sane; /* if false, allow invalid distance too far */
74 int back; /* bits back of last unprocessed length/lit */
75 unsigned was; /* initial length of match */
76};
77
78const alloc_func = fn(opaque: &c_void, items: u16, size: u16);
79const free_func = fn(opaque: &c_void, address: &c_void);
80
81const z_stream = struct {
82 /// next input byte
83 next_in: &u8,
84 /// number of bytes available at next_in
85 avail_in: u16,
86 /// total number of input bytes read so far
87 total_in: u32,
88
89 /// next output byte will go here
90 next_out: &u8,
91 /// remaining free space at next_out
92 avail_out: u16,
93 /// total number of bytes output so far */
94 total_out: u32,
95
96 /// last error message, NULL if no error
97 msg: &const u8,
98 /// not visible by applications
99 state: &inflate_state,
100
101 /// used to allocate the internal state
102 zalloc: alloc_func,
103 /// used to free the internal state
104 zfree: free_func,
105 /// private data object passed to zalloc and zfree
106 opaque: &c_void,
107
108 /// best guess about the data type: binary or text
109 /// for deflate, or the decoding state for inflate
110 data_type: i32,
111
112 /// Adler-32 or CRC-32 value of the uncompressed data
113 adler: u32,
114};
115
116// Possible inflate modes between inflate() calls
117/// i: waiting for magic header
118pub const HEAD = 16180;
119/// i: waiting for method and flags (gzip)
120pub const FLAGS = 16181;
121/// i: waiting for modification time (gzip)
122pub const TIME = 16182;
123/// i: waiting for extra flags and operating system (gzip)
124pub const OS = 16183;
125/// i: waiting for extra length (gzip)
126pub const EXLEN = 16184;
127/// i: waiting for extra bytes (gzip)
128pub const EXTRA = 16185;
129/// i: waiting for end of file name (gzip)
130pub const NAME = 16186;
131/// i: waiting for end of comment (gzip)
132pub const COMMENT = 16187;
133/// i: waiting for header crc (gzip)
134pub const HCRC = 16188;
135/// i: waiting for dictionary check value
136pub const DICTID = 16189;
137/// waiting for inflateSetDictionary() call
138pub const DICT = 16190;
139/// i: waiting for type bits, including last-flag bit
140pub const TYPE = 16191;
141/// i: same, but skip check to exit inflate on new block
142pub const TYPEDO = 16192;
143/// i: waiting for stored size (length and complement)
144pub const STORED = 16193;
145/// i/o: same as COPY below, but only first time in
146pub const COPY_ = 16194;
147/// i/o: waiting for input or output to copy stored block
148pub const COPY = 16195;
149/// i: waiting for dynamic block table lengths
150pub const TABLE = 16196;
151/// i: waiting for code length code lengths
152pub const LENLENS = 16197;
153/// i: waiting for length/lit and distance code lengths
154pub const CODELENS = 16198;
155/// i: same as LEN below, but only first time in
156pub const LEN_ = 16199;
157/// i: waiting for length/lit/eob code
158pub const LEN = 16200;
159/// i: waiting for length extra bits
160pub const LENEXT = 16201;
161/// i: waiting for distance code
162pub const DIST = 16202;
163/// i: waiting for distance extra bits
164pub const DISTEXT = 16203;
165/// o: waiting for output space to copy string
166pub const MATCH = 16204;
167/// o: waiting for output space to write literal
168pub const LIT = 16205;
169/// i: waiting for 32-bit check value
170pub const CHECK = 16206;
171/// i: waiting for 32-bit length (gzip)
172pub const LENGTH = 16207;
173/// finished check, done -- remain here until reset
174pub const DONE = 16208;
175/// got a data error -- remain here until reset
176pub const BAD = 16209;
177/// got an inflate() memory error -- remain here until reset
178pub const MEM = 16210;
179/// looking for synchronization bytes to restart inflate() */
180pub const SYNC = 16211;
181
182/// inflate() uses a state machine to process as much input data and generate as
183/// much output data as possible before returning. The state machine is
184/// structured roughly as follows:
185///
186/// for (;;) switch (state) {
187/// ...
188/// case STATEn:
189/// if (not enough input data or output space to make progress)
190/// return;
191/// ... make progress ...
192/// state = STATEm;
193/// break;
194/// ...
195/// }
196///
197/// so when inflate() is called again, the same case is attempted again, and
198/// if the appropriate resources are provided, the machine proceeds to the
199/// next state. The NEEDBITS() macro is usually the way the state evaluates
200/// whether it can proceed or should return. NEEDBITS() does the return if
201/// the requested bits are not available. The typical use of the BITS macros
202/// is:
203///
204/// NEEDBITS(n);
205/// ... do something with BITS(n) ...
206/// DROPBITS(n);
207///
208/// where NEEDBITS(n) either returns from inflate() if there isn't enough
209/// input left to load n bits into the accumulator, or it continues. BITS(n)
210/// gives the low n bits in the accumulator. When done, DROPBITS(n) drops
211/// the low n bits off the accumulator. INITBITS() clears the accumulator
212/// and sets the number of available bits to zero. BYTEBITS() discards just
213/// enough bits to put the accumulator on a byte boundary. After BYTEBITS()
214/// and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
215///
216/// NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
217/// if there is no input available. The decoding of variable length codes uses
218/// PULLBYTE() directly in order to pull just enough bytes to decode the next
219/// code, and no more.
220///
221/// Some states loop until they get enough input, making sure that enough
222/// state information is maintained to continue the loop where it left off
223/// if NEEDBITS() returns in the loop. For example, want, need, and keep
224/// would all have to actually be part of the saved state in case NEEDBITS()
225/// returns:
226///
227/// case STATEw:
228/// while (want < need) {
229/// NEEDBITS(n);
230/// keep[want++] = BITS(n);
231/// DROPBITS(n);
232/// }
233/// state = STATEx;
234/// case STATEx:
235///
236/// As shown above, if the next state is also the next case, then the break
237/// is omitted.
238///
239/// A state may also return if there is not enough output space available to
240/// complete that state. Those states are copying stored data, writing a
241/// literal byte, and copying a matching string.
242///
243/// When returning, a "goto inf_leave" is used to update the total counters,
244/// update the check value, and determine whether any progress has been made
245/// during that inflate() call in order to return the proper return code.
246/// Progress is defined as a change in either strm->avail_in or strm->avail_out.
247/// When there is a window, goto inf_leave will update the window with the last
248/// output written. If a goto inf_leave occurs in the middle of decompression
249/// and there is no window currently, goto inf_leave will create one and copy
250/// output to the window for the next call of inflate().
251///
252/// In this implementation, the flush parameter of inflate() only affects the
253/// return code (per zlib.h). inflate() always writes as much as possible to
254/// strm->next_out, given the space available and the provided input--the effect
255/// documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
256/// the allocation of and copying into a sliding window until necessary, which
257/// provides the effect documented in zlib.h for Z_FINISH when the entire input
258/// stream available. So the only thing the flush parameter actually does is:
259/// when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
260/// will return Z_BUF_ERROR if it has not reached the end of the stream.
261pub fn inflate(strm: &z_stream, flush: Flush, gunzip: bool) -> %void {
262 // next input
263 var next: &const u8 = undefined;
264 // next output
265 var put: &u8 = undefined;
266
267 // available input and output
268 var have: u16 = undefined;
269 var left: u16 = undefined;
270
271 // bit buffer
272 var hold: u32 = undefined;
273 // bits in bit buffer
274 var bits: u16 = undefined;
275 // save starting available input and output
276 var in: u16 = undefined;
277 var out: u16 = undefined;
278 // number of stored or match bytes to copy
279 var copy: u16 = undefined;
280 // where to copy match bytes from
281 var from: &u8 = undefined;
282 // current decoding table entry
283 var here: code = undefined;
284 // parent table entry
285 var last: code = undefined;
286 // length to copy for repeats, bits to drop
287 var len: u16 = undefined;
288
289 // return code
290 var ret: error = undefined;
291
292 // buffer for gzip header crc calculation
293 var hbuf: [4]u8 = undefined;
294
295 // permutation of code lengths
296 const short_order = []u16 = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
297
298 if (inflateStateCheck(strm) or strm.next_out == Z_NULL or (strm.next_in == Z_NULL and strm.avail_in != 0)) {
299 return error.Z_STREAM_ERROR;
300 }
301
302 var state: &inflate_state = strm.state;
303 if (state.mode == TYPE) {
304 state.mode = TYPEDO; // skip check
305 }
306 put = strm.next_out; \
307 left = strm.avail_out; \
308 next = strm.next_in; \
309 have = strm.avail_in; \
310 hold = state.hold; \
311 bits = state.bits; \
312 in = have;
313 out = left;
314 ret = Z_OK;
315 for (;;)
316 switch (state.mode) {
317 case HEAD:
318 if (state.wrap == 0) {
319 state.mode = TYPEDO;
320 break;
321 }
322 NEEDBITS(16);
323#ifdef GUNZIP
324 if ((state.wrap & 2) && hold == 0x8b1f) { /* gzip header */
325 if (state.wbits == 0)
326 state.wbits = 15;
327 state.check = crc32(0L, Z_NULL, 0);
328 CRC2(state.check, hold);
329 INITBITS();
330 state.mode = FLAGS;
331 break;
332 }
333 state.flags = 0; /* expect zlib header */
334 if (state.head != Z_NULL)
335 state.head.done = -1;
336 if (!(state.wrap & 1) || /* check if zlib header allowed */
337#else
338 if (
339#endif
340 ((BITS(8) << 8) + (hold >> 8)) % 31) {
341 strm.msg = (char *)"incorrect header check";
342 state.mode = BAD;
343 break;
344 }
345 if (BITS(4) != Z_DEFLATED) {
346 strm.msg = (char *)"unknown compression method";
347 state.mode = BAD;
348 break;
349 }
350 DROPBITS(4);
351 len = BITS(4) + 8;
352 if (state.wbits == 0)
353 state.wbits = len;
354 if (len > 15 || len > state.wbits) {
355 strm.msg = (char *)"invalid window size";
356 state.mode = BAD;
357 break;
358 }
359 state.dmax = 1U << len;
360 Tracev((stderr, "inflate: zlib header ok\n"));
361 strm.adler = state.check = adler32(0L, Z_NULL, 0);
362 state.mode = hold & 0x200 ? DICTID : TYPE;
363 INITBITS();
364 break;
365#ifdef GUNZIP
366 case FLAGS:
367 NEEDBITS(16);
368 state.flags = (int)(hold);
369 if ((state.flags & 0xff) != Z_DEFLATED) {
370 strm.msg = (char *)"unknown compression method";
371 state.mode = BAD;
372 break;
373 }
374 if (state.flags & 0xe000) {
375 strm.msg = (char *)"unknown header flags set";
376 state.mode = BAD;
377 break;
378 }
379 if (state.head != Z_NULL)
380 state.head.text = (int)((hold >> 8) & 1);
381 if ((state.flags & 0x0200) && (state.wrap & 4))
382 CRC2(state.check, hold);
383 INITBITS();
384 state.mode = TIME;
385 case TIME:
386 NEEDBITS(32);
387 if (state.head != Z_NULL)
388 state.head.time = hold;
389 if ((state.flags & 0x0200) && (state.wrap & 4))
390 CRC4(state.check, hold);
391 INITBITS();
392 state.mode = OS;
393 case OS:
394 NEEDBITS(16);
395 if (state.head != Z_NULL) {
396 state.head.xflags = (int)(hold & 0xff);
397 state.head.os = (int)(hold >> 8);
398 }
399 if ((state.flags & 0x0200) && (state.wrap & 4))
400 CRC2(state.check, hold);
401 INITBITS();
402 state.mode = EXLEN;
403 case EXLEN:
404 if (state.flags & 0x0400) {
405 NEEDBITS(16);
406 state.length = (unsigned)(hold);
407 if (state.head != Z_NULL)
408 state.head.extra_len = (unsigned)hold;
409 if ((state.flags & 0x0200) && (state.wrap & 4))
410 CRC2(state.check, hold);
411 INITBITS();
412 }
413 else if (state.head != Z_NULL)
414 state.head.extra = Z_NULL;
415 state.mode = EXTRA;
416 case EXTRA:
417 if (state.flags & 0x0400) {
418 copy = state.length;
419 if (copy > have) copy = have;
420 if (copy) {
421 if (state.head != Z_NULL &&
422 state.head.extra != Z_NULL) {
423 len = state.head.extra_len - state.length;
424 zmemcpy(state.head.extra + len, next,
425 len + copy > state.head.extra_max ?
426 state.head.extra_max - len : copy);
427 }
428 if ((state.flags & 0x0200) && (state.wrap & 4))
429 state.check = crc32(state.check, next, copy);
430 have -= copy;
431 next += copy;
432 state.length -= copy;
433 }
434 if (state.length) goto inf_leave;
435 }
436 state.length = 0;
437 state.mode = NAME;
438 case NAME:
439 if (state.flags & 0x0800) {
440 if (have == 0) goto inf_leave;
441 copy = 0;
442 do {
443 len = (unsigned)(next[copy++]);
444 if (state.head != Z_NULL &&
445 state.head.name != Z_NULL &&
446 state.length < state.head.name_max)
447 state.head.name[state.length++] = (Bytef)len;
448 } while (len && copy < have);
449 if ((state.flags & 0x0200) && (state.wrap & 4))
450 state.check = crc32(state.check, next, copy);
451 have -= copy;
452 next += copy;
453 if (len) goto inf_leave;
454 }
455 else if (state.head != Z_NULL)
456 state.head.name = Z_NULL;
457 state.length = 0;
458 state.mode = COMMENT;
459 case COMMENT:
460 if (state.flags & 0x1000) {
461 if (have == 0) goto inf_leave;
462 copy = 0;
463 do {
464 len = (unsigned)(next[copy++]);
465 if (state.head != Z_NULL &&
466 state.head.comment != Z_NULL &&
467 state.length < state.head.comm_max)
468 state.head.comment[state.length++] = (Bytef)len;
469 } while (len && copy < have);
470 if ((state.flags & 0x0200) && (state.wrap & 4))
471 state.check = crc32(state.check, next, copy);
472 have -= copy;
473 next += copy;
474 if (len) goto inf_leave;
475 }
476 else if (state.head != Z_NULL)
477 state.head.comment = Z_NULL;
478 state.mode = HCRC;
479 case HCRC:
480 if (state.flags & 0x0200) {
481 NEEDBITS(16);
482 if ((state.wrap & 4) && hold != (state.check & 0xffff)) {
483 strm.msg = (char *)"header crc mismatch";
484 state.mode = BAD;
485 break;
486 }
487 INITBITS();
488 }
489 if (state.head != Z_NULL) {
490 state.head.hcrc = (int)((state.flags >> 9) & 1);
491 state.head.done = 1;
492 }
493 strm.adler = state.check = crc32(0L, Z_NULL, 0);
494 state.mode = TYPE;
495 break;
496#endif
497 case DICTID:
498 NEEDBITS(32);
499 strm.adler = state.check = ZSWAP32(hold);
500 INITBITS();
501 state.mode = DICT;
502 case DICT:
503 if (state.havedict == 0) {
504 strm.next_out = put; \
505 strm.avail_out = left; \
506 strm.next_in = next; \
507 strm.avail_in = have; \
508 state.hold = hold; \
509 state.bits = bits; \
510 return Z_NEED_DICT;
511 }
512 strm.adler = state.check = adler32(0L, Z_NULL, 0);
513 state.mode = TYPE;
514 case TYPE:
515 if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
516 case TYPEDO:
517 if (state.last) {
518 BYTEBITS();
519 state.mode = CHECK;
520 break;
521 }
522 NEEDBITS(3);
523 state.last = BITS(1);
524 DROPBITS(1);
525 switch (BITS(2)) {
526 case 0: /* stored block */
527 Tracev((stderr, "inflate: stored block%s\n",
528 state.last ? " (last)" : ""));
529 state.mode = STORED;
530 break;
531 case 1: /* fixed block */
532 fixedtables(state);
533 Tracev((stderr, "inflate: fixed codes block%s\n",
534 state.last ? " (last)" : ""));
535 state.mode = LEN_; /* decode codes */
536 if (flush == Z_TREES) {
537 DROPBITS(2);
538 goto inf_leave;
539 }
540 break;
541 case 2: /* dynamic block */
542 Tracev((stderr, "inflate: dynamic codes block%s\n",
543 state.last ? " (last)" : ""));
544 state.mode = TABLE;
545 break;
546 case 3:
547 strm.msg = (char *)"invalid block type";
548 state.mode = BAD;
549 }
550 DROPBITS(2);
551 break;
552 case STORED:
553 BYTEBITS(); /* go to byte boundary */
554 NEEDBITS(32);
555 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
556 strm.msg = (char *)"invalid stored block lengths";
557 state.mode = BAD;
558 break;
559 }
560 state.length = (unsigned)hold & 0xffff;
561 Tracev((stderr, "inflate: stored length %u\n",
562 state.length));
563 INITBITS();
564 state.mode = COPY_;
565 if (flush == Z_TREES) goto inf_leave;
566 case COPY_:
567 state.mode = COPY;
568 case COPY:
569 copy = state.length;
570 if (copy) {
571 if (copy > have) copy = have;
572 if (copy > left) copy = left;
573 if (copy == 0) goto inf_leave;
574 zmemcpy(put, next, copy);
575 have -= copy;
576 next += copy;
577 left -= copy;
578 put += copy;
579 state.length -= copy;
580 break;
581 }
582 Tracev((stderr, "inflate: stored end\n"));
583 state.mode = TYPE;
584 break;
585 case TABLE:
586 NEEDBITS(14);
587 state.nlen = BITS(5) + 257;
588 DROPBITS(5);
589 state.ndist = BITS(5) + 1;
590 DROPBITS(5);
591 state.ncode = BITS(4) + 4;
592 DROPBITS(4);
593#ifndef PKZIP_BUG_WORKAROUND
594 if (state.nlen > 286 || state.ndist > 30) {
595 strm.msg = (char *)"too many length or distance symbols";
596 state.mode = BAD;
597 break;
598 }
599#endif
600 Tracev((stderr, "inflate: table sizes ok\n"));
601 state.have = 0;
602 state.mode = LENLENS;
603 case LENLENS:
604 while (state.have < state.ncode) {
605 NEEDBITS(3);
606 state.lens[order[state.have++]] = (unsigned short)BITS(3);
607 DROPBITS(3);
608 }
609 while (state.have < 19)
610 state.lens[order[state.have++]] = 0;
611 state.next = state.codes;
612 state.lencode = (const code FAR *)(state.next);
613 state.lenbits = 7;
614 ret = inflate_table(CODES, state.lens, 19, &(state.next),
615 &(state.lenbits), state.work);
616 if (ret) {
617 strm.msg = (char *)"invalid code lengths set";
618 state.mode = BAD;
619 break;
620 }
621 Tracev((stderr, "inflate: code lengths ok\n"));
622 state.have = 0;
623 state.mode = CODELENS;
624 case CODELENS:
625 while (state.have < state.nlen + state.ndist) {
626 for (;;) {
627 here = state.lencode[BITS(state.lenbits)];
628 if ((unsigned)(here.bits) <= bits) break;
629 PULLBYTE();
630 }
631 if (here.val < 16) {
632 DROPBITS(here.bits);
633 state.lens[state.have++] = here.val;
634 }
635 else {
636 if (here.val == 16) {
637 NEEDBITS(here.bits + 2);
638 DROPBITS(here.bits);
639 if (state.have == 0) {
640 strm.msg = (char *)"invalid bit length repeat";
641 state.mode = BAD;
642 break;
643 }
644 len = state.lens[state.have - 1];
645 copy = 3 + BITS(2);
646 DROPBITS(2);
647 }
648 else if (here.val == 17) {
649 NEEDBITS(here.bits + 3);
650 DROPBITS(here.bits);
651 len = 0;
652 copy = 3 + BITS(3);
653 DROPBITS(3);
654 }
655 else {
656 NEEDBITS(here.bits + 7);
657 DROPBITS(here.bits);
658 len = 0;
659 copy = 11 + BITS(7);
660 DROPBITS(7);
661 }
662 if (state.have + copy > state.nlen + state.ndist) {
663 strm.msg = (char *)"invalid bit length repeat";
664 state.mode = BAD;
665 break;
666 }
667 while (copy--)
668 state.lens[state.have++] = (unsigned short)len;
669 }
670 }
671
672 /* handle error breaks in while */
673 if (state.mode == BAD) break;
674
675 /* check for end-of-block code (better have one) */
676 if (state.lens[256] == 0) {
677 strm.msg = (char *)"invalid code -- missing end-of-block";
678 state.mode = BAD;
679 break;
680 }
681
682 /* build code tables -- note: do not change the lenbits or distbits
683 values here (9 and 6) without reading the comments in inftrees.h
684 concerning the ENOUGH constants, which depend on those values */
685 state.next = state.codes;
686 state.lencode = (const code FAR *)(state.next);
687 state.lenbits = 9;
688 ret = inflate_table(LENS, state.lens, state.nlen, &(state.next),
689 &(state.lenbits), state.work);
690 if (ret) {
691 strm.msg = (char *)"invalid literal/lengths set";
692 state.mode = BAD;
693 break;
694 }
695 state.distcode = (const code FAR *)(state.next);
696 state.distbits = 6;
697 ret = inflate_table(DISTS, state.lens + state.nlen, state.ndist,
698 &(state.next), &(state.distbits), state.work);
699 if (ret) {
700 strm.msg = (char *)"invalid distances set";
701 state.mode = BAD;
702 break;
703 }
704 Tracev((stderr, "inflate: codes ok\n"));
705 state.mode = LEN_;
706 if (flush == Z_TREES) goto inf_leave;
707 case LEN_:
708 state.mode = LEN;
709 case LEN:
710 if (have >= 6 && left >= 258) {
711 strm.next_out = put; \
712 strm.avail_out = left; \
713 strm.next_in = next; \
714 strm.avail_in = have; \
715 state.hold = hold; \
716 state.bits = bits; \
717
718 inflate_fast(strm, out);
719
720 put = strm.next_out; \
721 left = strm.avail_out; \
722 next = strm.next_in; \
723 have = strm.avail_in; \
724 hold = state.hold; \
725 bits = state.bits; \
726 if (state.mode == TYPE)
727 state.back = -1;
728 break;
729 }
730 state.back = 0;
731 for (;;) {
732 here = state.lencode[BITS(state.lenbits)];
733 if ((unsigned)(here.bits) <= bits) break;
734 PULLBYTE();
735 }
736 if (here.op && (here.op & 0xf0) == 0) {
737 last = here;
738 for (;;) {
739 here = state.lencode[last.val +
740 (BITS(last.bits + last.op) >> last.bits)];
741 if ((unsigned)(last.bits + here.bits) <= bits) break;
742 PULLBYTE();
743 }
744 DROPBITS(last.bits);
745 state.back += last.bits;
746 }
747 DROPBITS(here.bits);
748 state.back += here.bits;
749 state.length = (unsigned)here.val;
750 if ((int)(here.op) == 0) {
751 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
752 "inflate: literal '%c'\n" :
753 "inflate: literal 0x%02x\n", here.val));
754 state.mode = LIT;
755 break;
756 }
757 if (here.op & 32) {
758 Tracevv((stderr, "inflate: end of block\n"));
759 state.back = -1;
760 state.mode = TYPE;
761 break;
762 }
763 if (here.op & 64) {
764 strm.msg = (char *)"invalid literal/length code";
765 state.mode = BAD;
766 break;
767 }
768 state.extra = (unsigned)(here.op) & 15;
769 state.mode = LENEXT;
770 case LENEXT:
771 if (state.extra) {
772 NEEDBITS(state.extra);
773 state.length += BITS(state.extra);
774 DROPBITS(state.extra);
775 state.back += state.extra;
776 }
777 Tracevv((stderr, "inflate: length %u\n", state.length));
778 state.was = state.length;
779 state.mode = DIST;
780 case DIST:
781 for (;;) {
782 here = state.distcode[BITS(state.distbits)];
783 if ((unsigned)(here.bits) <= bits) break;
784 PULLBYTE();
785 }
786 if ((here.op & 0xf0) == 0) {
787 last = here;
788 for (;;) {
789 here = state.distcode[last.val +
790 (BITS(last.bits + last.op) >> last.bits)];
791 if ((unsigned)(last.bits + here.bits) <= bits) break;
792 PULLBYTE();
793 }
794 DROPBITS(last.bits);
795 state.back += last.bits;
796 }
797 DROPBITS(here.bits);
798 state.back += here.bits;
799 if (here.op & 64) {
800 strm.msg = (char *)"invalid distance code";
801 state.mode = BAD;
802 break;
803 }
804 state.offset = (unsigned)here.val;
805 state.extra = (unsigned)(here.op) & 15;
806 state.mode = DISTEXT;
807 case DISTEXT:
808 if (state.extra) {
809 NEEDBITS(state.extra);
810 state.offset += BITS(state.extra);
811 DROPBITS(state.extra);
812 state.back += state.extra;
813 }
814#ifdef INFLATE_STRICT
815 if (state.offset > state.dmax) {
816 strm.msg = (char *)"invalid distance too far back";
817 state.mode = BAD;
818 break;
819 }
820#endif
821 Tracevv((stderr, "inflate: distance %u\n", state.offset));
822 state.mode = MATCH;
823 case MATCH:
824 if (left == 0) goto inf_leave;
825 copy = out - left;
826 if (state.offset > copy) { /* copy from window */
827 copy = state.offset - copy;
828 if (copy > state.whave) {
829 if (state.sane) {
830 strm.msg = (char *)"invalid distance too far back";
831 state.mode = BAD;
832 break;
833 }
834#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
835 Trace((stderr, "inflate.c too far\n"));
836 copy -= state.whave;
837 if (copy > state.length) copy = state.length;
838 if (copy > left) copy = left;
839 left -= copy;
840 state.length -= copy;
841 do {
842 *put++ = 0;
843 } while (--copy);
844 if (state.length == 0) state.mode = LEN;
845 break;
846#endif
847 }
848 if (copy > state.wnext) {
849 copy -= state.wnext;
850 from = state.window + (state.wsize - copy);
851 }
852 else
853 from = state.window + (state.wnext - copy);
854 if (copy > state.length) copy = state.length;
855 }
856 else { /* copy from output */
857 from = put - state.offset;
858 copy = state.length;
859 }
860 if (copy > left) copy = left;
861 left -= copy;
862 state.length -= copy;
863 do {
864 *put++ = *from++;
865 } while (--copy);
866 if (state.length == 0) state.mode = LEN;
867 break;
868 case LIT:
869 if (left == 0) goto inf_leave;
870 *put++ = (u8)(state.length);
871 left--;
872 state.mode = LEN;
873 break;
874 case CHECK:
875 if (state.wrap) {
876 NEEDBITS(32);
877 out -= left;
878 strm.total_out += out;
879 state.total += out;
880 if ((state.wrap & 4) && out)
881 strm.adler = state.check =
882 UPDATE(state.check, put - out, out);
883 out = left;
884 if ((state.wrap & 4) && (
885#ifdef GUNZIP
886 state.flags ? hold :
887#endif
888 ZSWAP32(hold)) != state.check) {
889 strm.msg = (char *)"incorrect data check";
890 state.mode = BAD;
891 break;
892 }
893 INITBITS();
894 Tracev((stderr, "inflate: check matches trailer\n"));
895 }
896#ifdef GUNZIP
897 state.mode = LENGTH;
898 case LENGTH:
899 if (state.wrap && state.flags) {
900 NEEDBITS(32);
901 if (hold != (state.total & 0xffffffffUL)) {
902 strm.msg = (char *)"incorrect length check";
903 state.mode = BAD;
904 break;
905 }
906 INITBITS();
907 Tracev((stderr, "inflate: length matches trailer\n"));
908 }
909#endif
910 state.mode = DONE;
911 case DONE:
912 ret = Z_STREAM_END;
913 goto inf_leave;
914 case BAD:
915 ret = Z_DATA_ERROR;
916 goto inf_leave;
917 case MEM:
918 return Z_MEM_ERROR;
919 case SYNC:
920 default:
921 return Z_STREAM_ERROR;
922 }
923
924 /*
925 Return from inflate(), updating the total counts and the check value.
926 If there was no progress during the inflate() call, return a buffer
927 error. Call updatewindow() to create and/or update the window state.
928 Note: a memory error from inflate() is non-recoverable.
929 */
930 inf_leave:
931 strm.next_out = put; \
932 strm.avail_out = left; \
933 strm.next_in = next; \
934 strm.avail_in = have; \
935 state.hold = hold; \
936 state.bits = bits; \
937 if (state.wsize || (out != strm.avail_out && state.mode < BAD &&
938 (state.mode < CHECK || flush != Z_FINISH)))
939 if (updatewindow(strm, strm.next_out, out - strm.avail_out)) {
940 state.mode = MEM;
941 return Z_MEM_ERROR;
942 }
943 in -= strm.avail_in;
944 out -= strm.avail_out;
945 strm.total_in += in;
946 strm.total_out += out;
947 state.total += out;
948 if ((state.wrap & 4) && out)
949 strm.adler = state.check =
950 UPDATE(state.check, strm.next_out - out, out);
951 strm.data_type = (int)state.bits + (state.last ? 64 : 0) +
952 (state.mode == TYPE ? 128 : 0) +
953 (state.mode == LEN_ || state.mode == COPY_ ? 256 : 0);
954 if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
955 ret = Z_BUF_ERROR;
956 return ret;
957}
958
959local int inflateStateCheck(z_stream * strm) {
960 struct inflate_state FAR *state;
961 if (strm == Z_NULL ||
962 strm.zalloc == (alloc_func)0 || strm.zfree == (free_func)0)
963 return 1;
964 state = (struct inflate_state FAR *)strm.state;
965 if (state == Z_NULL || state.strm != strm ||
966 state.mode < HEAD || state.mode > SYNC)
967 return 1;
968 return 0;
969}
test/assemble_and_link.zig+1-1
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const builtin = @import("builtin");1const builtin = @import("builtin");
2const tests = @import("tests.zig");2const tests = @import("tests.zig");
33
4pub fn addCases(cases: &tests.CompareOutputContext) {4pub fn addCases(cases: &tests.CompareOutputContext) void {
5 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {5 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {
6 cases.addAsm("hello world linux x86_64",6 cases.addAsm("hello world linux x86_64",
7 \\.text7 \\.text
test/build_examples.zig+1-1
...@@ -2,7 +2,7 @@ const tests = @import("tests.zig");...@@ -2,7 +2,7 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const is_windows = builtin.os == builtin.Os.windows;3const is_windows = builtin.os == builtin.Os.windows;
44
5pub fn addCases(cases: &tests.BuildExamplesContext) {5pub fn addCases(cases: &tests.BuildExamplesContext) void {
6 cases.add("example/hello_world/hello.zig");6 cases.add("example/hello_world/hello.zig");
7 cases.addC("example/hello_world/hello_libc.zig");7 cases.addC("example/hello_world/hello_libc.zig");
8 cases.add("example/cat/main.zig");8 cases.add("example/cat/main.zig");
test/cases/align.zig+23-23
...@@ -10,14 +10,14 @@ test "global variable alignment" {...@@ -10,14 +10,14 @@ test "global variable alignment" {
10 assert(@typeOf(slice) == []align(4) u8);10 assert(@typeOf(slice) == []align(4) u8);
11}11}
1212
13fn derp() align(@sizeOf(usize) * 2) -> i32 { return 1234; }13fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
14fn noop1() align(1) {}14fn noop1() align(1) void {}
15fn noop4() align(4) {}15fn noop4() align(4) void {}
1616
17test "function alignment" {17test "function alignment" {
18 assert(derp() == 1234);18 assert(derp() == 1234);
19 assert(@typeOf(noop1) == fn() align(1));19 assert(@typeOf(noop1) == fn() align(1) void);
20 assert(@typeOf(noop4) == fn() align(4));20 assert(@typeOf(noop4) == fn() align(4) void);
21 noop1();21 noop1();
22 noop4();22 noop4();
23}23}
...@@ -53,19 +53,19 @@ test "implicitly decreasing pointer alignment" {...@@ -53,19 +53,19 @@ test "implicitly decreasing pointer alignment" {
53 assert(addUnaligned(&a, &b) == 7);53 assert(addUnaligned(&a, &b) == 7);
54}54}
5555
56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) -> u32 { return *a + *b; }56fn addUnaligned(a: &align(1) const u32, b: &align(1) const u32) u32 { return *a + *b; }
5757
58test "implicitly decreasing slice alignment" {58test "implicitly decreasing slice alignment" {
59 const a: u32 align(4) = 3;59 const a: u32 align(4) = 3;
60 const b: u32 align(8) = 4;60 const b: u32 align(8) = 4;
61 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);61 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
62}62}
63fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) -> u32 { return a[0] + b[0]; }63fn addUnalignedSlice(a: []align(1) const u32, b: []align(1) const u32) u32 { return a[0] + b[0]; }
6464
65test "specifying alignment allows pointer cast" {65test "specifying alignment allows pointer cast" {
66 testBytesAlign(0x33);66 testBytesAlign(0x33);
67}67}
68fn testBytesAlign(b: u8) {68fn testBytesAlign(b: u8) void {
69 var bytes align(4) = []u8{b, b, b, b};69 var bytes align(4) = []u8{b, b, b, b};
70 const ptr = @ptrCast(&u32, &bytes[0]);70 const ptr = @ptrCast(&u32, &bytes[0]);
71 assert(*ptr == 0x33333333);71 assert(*ptr == 0x33333333);
...@@ -74,7 +74,7 @@ fn testBytesAlign(b: u8) {...@@ -74,7 +74,7 @@ fn testBytesAlign(b: u8) {
74test "specifying alignment allows slice cast" {74test "specifying alignment allows slice cast" {
75 testBytesAlignSlice(0x33);75 testBytesAlignSlice(0x33);
76}76}
77fn testBytesAlignSlice(b: u8) {77fn testBytesAlignSlice(b: u8) void {
78 var bytes align(4) = []u8{b, b, b, b};78 var bytes align(4) = []u8{b, b, b, b};
79 const slice = ([]u32)(bytes[0..]);79 const slice = ([]u32)(bytes[0..]);
80 assert(slice[0] == 0x33333333);80 assert(slice[0] == 0x33333333);
...@@ -85,10 +85,10 @@ test "@alignCast pointers" {...@@ -85,10 +85,10 @@ test "@alignCast pointers" {
85 expectsOnly1(&x);85 expectsOnly1(&x);
86 assert(x == 2);86 assert(x == 2);
87}87}
88fn expectsOnly1(x: &align(1) u32) {88fn expectsOnly1(x: &align(1) u32) void {
89 expects4(@alignCast(4, x));89 expects4(@alignCast(4, x));
90}90}
91fn expects4(x: &align(4) u32) {91fn expects4(x: &align(4) u32) void {
92 *x += 1;92 *x += 1;
93}93}
9494
...@@ -98,10 +98,10 @@ test "@alignCast slices" {...@@ -98,10 +98,10 @@ test "@alignCast slices" {
98 sliceExpectsOnly1(slice);98 sliceExpectsOnly1(slice);
99 assert(slice[0] == 2);99 assert(slice[0] == 2);
100}100}
101fn sliceExpectsOnly1(slice: []align(1) u32) {101fn sliceExpectsOnly1(slice: []align(1) u32) void {
102 sliceExpects4(@alignCast(4, slice));102 sliceExpects4(@alignCast(4, slice));
103}103}
104fn sliceExpects4(slice: []align(4) u32) {104fn sliceExpects4(slice: []align(4) u32) void {
105 slice[0] += 1;105 slice[0] += 1;
106}106}
107107
...@@ -111,24 +111,24 @@ test "implicitly decreasing fn alignment" {...@@ -111,24 +111,24 @@ test "implicitly decreasing fn alignment" {
111 testImplicitlyDecreaseFnAlign(alignedBig, 5678);111 testImplicitlyDecreaseFnAlign(alignedBig, 5678);
112}112}
113113
114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) -> i32, answer: i32) {114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {
115 assert(ptr() == answer);115 assert(ptr() == answer);
116}116}
117117
118fn alignedSmall() align(8) -> i32 { return 1234; }118fn alignedSmall() align(8) i32 { return 1234; }
119fn alignedBig() align(16) -> i32 { return 5678; }119fn alignedBig() align(16) i32 { return 5678; }
120120
121121
122test "@alignCast functions" {122test "@alignCast functions" {
123 assert(fnExpectsOnly1(simple4) == 0x19);123 assert(fnExpectsOnly1(simple4) == 0x19);
124}124}
125fn fnExpectsOnly1(ptr: fn()align(1) -> i32) -> i32 {125fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 {
126 return fnExpects4(@alignCast(4, ptr));126 return fnExpects4(@alignCast(4, ptr));
127}127}
128fn fnExpects4(ptr: fn()align(4) -> i32) -> i32 {128fn fnExpects4(ptr: fn()align(4) i32) i32 {
129 return ptr();129 return ptr();
130}130}
131fn simple4() align(4) -> i32 { return 0x19; }131fn simple4() align(4) i32 { return 0x19; }
132132
133133
134test "generic function with align param" {134test "generic function with align param" {
...@@ -137,7 +137,7 @@ test "generic function with align param" {...@@ -137,7 +137,7 @@ test "generic function with align param" {
137 assert(whyWouldYouEverDoThis(8) == 0x1);137 assert(whyWouldYouEverDoThis(8) == 0x1);
138}138}
139139
140fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) -> u8 { return 0x1; }140fn whyWouldYouEverDoThis(comptime align_bytes: u8) align(align_bytes) u8 { return 0x1; }
141141
142142
143test "@ptrCast preserves alignment of bigger source" {143test "@ptrCast preserves alignment of bigger source" {
...@@ -175,10 +175,10 @@ test "compile-time known array index has best alignment possible" {...@@ -175,10 +175,10 @@ test "compile-time known array index has best alignment possible" {
175 testIndex2(&array[0], 2, &u8);175 testIndex2(&array[0], 2, &u8);
176 testIndex2(&array[0], 3, &u8);176 testIndex2(&array[0], 3, &u8);
177}177}
178fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) {178fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) void {
179 assert(@typeOf(&smaller[index]) == T);179 assert(@typeOf(&smaller[index]) == T);
180}180}
181fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) {181fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {
182 assert(@typeOf(&ptr[index]) == T);182 assert(@typeOf(&ptr[index]) == T);
183}183}
184184
...@@ -187,7 +187,7 @@ test "alignstack" {...@@ -187,7 +187,7 @@ test "alignstack" {
187 assert(fnWithAlignedStack() == 1234);187 assert(fnWithAlignedStack() == 1234);
188}188}
189189
190fn fnWithAlignedStack() -> i32 {190fn fnWithAlignedStack() i32 {
191 @setAlignStack(256);191 @setAlignStack(256);
192 return 1234;192 return 1234;
193}193}
test/cases/array.zig+1-1
...@@ -21,7 +21,7 @@ test "arrays" {...@@ -21,7 +21,7 @@ test "arrays" {
21 assert(accumulator == 15);21 assert(accumulator == 15);
22 assert(getArrayLen(array) == 5);22 assert(getArrayLen(array) == 5);
23}23}
24fn getArrayLen(a: []const u32) -> usize {24fn getArrayLen(a: []const u32) usize {
25 return a.len;25 return a.len;
26}26}
2727
test/cases/asm.zig+2-2
...@@ -17,8 +17,8 @@ test "module level assembly" {...@@ -17,8 +17,8 @@ test "module level assembly" {
17 }17 }
18}18}
1919
20extern fn aoeu() -> i32;20extern fn aoeu() i32;
2121
22export fn derp() -> i32 {22export fn derp() i32 {
23 return 1234;23 return 1234;
24}24}
test/cases/bitcast.zig+3-3
...@@ -5,10 +5,10 @@ test "@bitCast i32 -> u32" {...@@ -5,10 +5,10 @@ test "@bitCast i32 -> u32" {
5 comptime testBitCast_i32_u32();5 comptime testBitCast_i32_u32();
6}6}
77
8fn testBitCast_i32_u32() {8fn testBitCast_i32_u32() void {
9 assert(conv(-1) == @maxValue(u32));9 assert(conv(-1) == @maxValue(u32));
10 assert(conv2(@maxValue(u32)) == -1);10 assert(conv2(@maxValue(u32)) == -1);
11}11}
1212
13fn conv(x: i32) -> u32 { return @bitCast(u32, x); }13fn conv(x: i32) u32 { return @bitCast(u32, x); }
14fn conv2(x: u32) -> i32 { return @bitCast(i32, x); }14fn conv2(x: u32) i32 { return @bitCast(i32, x); }
test/cases/bool.zig+2-2
...@@ -13,7 +13,7 @@ test "cast bool to int" {...@@ -13,7 +13,7 @@ test "cast bool to int" {
13 nonConstCastBoolToInt(t, f);13 nonConstCastBoolToInt(t, f);
14}14}
1515
16fn nonConstCastBoolToInt(t: bool, f: bool) {16fn nonConstCastBoolToInt(t: bool, f: bool) void {
17 assert(i32(t) == i32(1));17 assert(i32(t) == i32(1));
18 assert(i32(f) == i32(0));18 assert(i32(f) == i32(0));
19}19}
...@@ -21,7 +21,7 @@ fn nonConstCastBoolToInt(t: bool, f: bool) {...@@ -21,7 +21,7 @@ fn nonConstCastBoolToInt(t: bool, f: bool) {
21test "bool cmp" {21test "bool cmp" {
22 assert(testBoolCmp(true, false) == false);22 assert(testBoolCmp(true, false) == false);
23}23}
24fn testBoolCmp(a: bool, b: bool) -> bool {24fn testBoolCmp(a: bool, b: bool) bool {
25 return a == b;25 return a == b;
26}26}
2727
test/cases/bugs/655.zig+1-1
...@@ -7,6 +7,6 @@ test "function with &const parameter with type dereferenced by namespace" {...@@ -7,6 +7,6 @@ test "function with &const parameter with type dereferenced by namespace" {
7 foo(x);7 foo(x);
8}8}
99
10fn foo(x: &const other_file.Integer) {10fn foo(x: &const other_file.Integer) void {
11 std.debug.assert(*x == 1234);11 std.debug.assert(*x == 1234);
12}12}
test/cases/bugs/656.zig+1-1
...@@ -13,7 +13,7 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an...@@ -13,7 +13,7 @@ test "nullable if after an if in a switch prong of a switch with 2 prongs in an
13 foo(false, true);13 foo(false, true);
14}14}
1515
16fn foo(a: bool, b: bool) {16fn foo(a: bool, b: bool) void {
17 var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };17 var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };
18 if (a) {18 if (a) {
19 } else {19 } else {
test/cases/cast.zig+23-23
...@@ -28,7 +28,7 @@ test "implicitly cast a pointer to a const pointer of it" {...@@ -28,7 +28,7 @@ test "implicitly cast a pointer to a const pointer of it" {
28 assert(x == 2);28 assert(x == 2);
29}29}
3030
31fn funcWithConstPtrPtr(x: &const &i32) {31fn funcWithConstPtrPtr(x: &const &i32) void {
32 **x += 1;32 **x += 1;
33}33}
3434
...@@ -37,7 +37,7 @@ test "explicit cast from integer to error type" {...@@ -37,7 +37,7 @@ test "explicit cast from integer to error type" {
37 testCastIntToErr(error.ItBroke);37 testCastIntToErr(error.ItBroke);
38 comptime testCastIntToErr(error.ItBroke);38 comptime testCastIntToErr(error.ItBroke);
39}39}
40fn testCastIntToErr(err: error) {40fn testCastIntToErr(err: error) void {
41 const x = usize(err);41 const x = usize(err);
42 const y = error(x);42 const y = error(x);
43 assert(error.ItBroke == y);43 assert(error.ItBroke == y);
...@@ -49,7 +49,7 @@ test "peer resolve arrays of different size to const slice" {...@@ -49,7 +49,7 @@ test "peer resolve arrays of different size to const slice" {
49 comptime assert(mem.eql(u8, boolToStr(true), "true"));49 comptime assert(mem.eql(u8, boolToStr(true), "true"));
50 comptime assert(mem.eql(u8, boolToStr(false), "false"));50 comptime assert(mem.eql(u8, boolToStr(false), "false"));
51}51}
52fn boolToStr(b: bool) -> []const u8 {52fn boolToStr(b: bool) []const u8 {
53 return if (b) "true" else "false";53 return if (b) "true" else "false";
54}54}
5555
...@@ -58,7 +58,7 @@ test "peer resolve array and const slice" {...@@ -58,7 +58,7 @@ test "peer resolve array and const slice" {
58 testPeerResolveArrayConstSlice(true);58 testPeerResolveArrayConstSlice(true);
59 comptime testPeerResolveArrayConstSlice(true);59 comptime testPeerResolveArrayConstSlice(true);
60}60}
61fn testPeerResolveArrayConstSlice(b: bool) {61fn testPeerResolveArrayConstSlice(b: bool) void {
62 const value1 = if (b) "aoeu" else ([]const u8)("zz");62 const value1 = if (b) "aoeu" else ([]const u8)("zz");
63 const value2 = if (b) ([]const u8)("zz") else "aoeu";63 const value2 = if (b) ([]const u8)("zz") else "aoeu";
64 assert(mem.eql(u8, value1, "aoeu"));64 assert(mem.eql(u8, value1, "aoeu"));
...@@ -82,7 +82,7 @@ test "implicitly cast from T to %?T" {...@@ -82,7 +82,7 @@ test "implicitly cast from T to %?T" {
82const A = struct {82const A = struct {
83 a: i32,83 a: i32,
84};84};
85fn castToMaybeTypeError(z: i32) {85fn castToMaybeTypeError(z: i32) void {
86 const x = i32(1);86 const x = i32(1);
87 const y: %?i32 = x;87 const y: %?i32 = x;
88 assert(??(try y) == 1);88 assert(??(try y) == 1);
...@@ -99,22 +99,22 @@ test "implicitly cast from int to %?T" {...@@ -99,22 +99,22 @@ test "implicitly cast from int to %?T" {
99 implicitIntLitToMaybe();99 implicitIntLitToMaybe();
100 comptime implicitIntLitToMaybe();100 comptime implicitIntLitToMaybe();
101}101}
102fn implicitIntLitToMaybe() {102fn implicitIntLitToMaybe() void {
103 const f: ?i32 = 1;103 const f: ?i32 = 1;
104 const g: %?i32 = 1;104 const g: %?i32 = 1;
105}105}
106106
107107
108test "return null from fn() -> %?&T" {108test "return null from fn() %?&T" {
109 const a = returnNullFromMaybeTypeErrorRef();109 const a = returnNullFromMaybeTypeErrorRef();
110 const b = returnNullLitFromMaybeTypeErrorRef();110 const b = returnNullLitFromMaybeTypeErrorRef();
111 assert((try a) == null and (try b) == null);111 assert((try a) == null and (try b) == null);
112}112}
113fn returnNullFromMaybeTypeErrorRef() -> %?&A {113fn returnNullFromMaybeTypeErrorRef() %?&A {
114 const a: ?&A = null;114 const a: ?&A = null;
115 return a;115 return a;
116}116}
117fn returnNullLitFromMaybeTypeErrorRef() -> %?&A {117fn returnNullLitFromMaybeTypeErrorRef() %?&A {
118 return null;118 return null;
119}119}
120120
...@@ -126,7 +126,7 @@ test "peer type resolution: ?T and T" {...@@ -126,7 +126,7 @@ test "peer type resolution: ?T and T" {
126 assert(??peerTypeTAndMaybeT(false, false) == 3);126 assert(??peerTypeTAndMaybeT(false, false) == 3);
127 }127 }
128}128}
129fn peerTypeTAndMaybeT(c: bool, b: bool) -> ?usize {129fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
130 if (c) {130 if (c) {
131 return if (b) null else usize(0);131 return if (b) null else usize(0);
132 }132 }
...@@ -143,7 +143,7 @@ test "peer type resolution: [0]u8 and []const u8" {...@@ -143,7 +143,7 @@ test "peer type resolution: [0]u8 and []const u8" {
143 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);143 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
144 }144 }
145}145}
146fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) -> []const u8 {146fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
147 if (a) {147 if (a) {
148 return []const u8 {};148 return []const u8 {};
149 }149 }
...@@ -156,7 +156,7 @@ test "implicitly cast from [N]T to ?[]const T" {...@@ -156,7 +156,7 @@ test "implicitly cast from [N]T to ?[]const T" {
156 comptime assert(mem.eql(u8, ??castToMaybeSlice(), "hi"));156 comptime assert(mem.eql(u8, ??castToMaybeSlice(), "hi"));
157}157}
158158
159fn castToMaybeSlice() -> ?[]const u8 {159fn castToMaybeSlice() ?[]const u8 {
160 return "hi";160 return "hi";
161}161}
162162
...@@ -166,11 +166,11 @@ test "implicitly cast from [0]T to %[]T" {...@@ -166,11 +166,11 @@ test "implicitly cast from [0]T to %[]T" {
166 comptime testCastZeroArrayToErrSliceMut();166 comptime testCastZeroArrayToErrSliceMut();
167}167}
168168
169fn testCastZeroArrayToErrSliceMut() {169fn testCastZeroArrayToErrSliceMut() void {
170 assert((gimmeErrOrSlice() catch unreachable).len == 0);170 assert((gimmeErrOrSlice() catch unreachable).len == 0);
171}171}
172172
173fn gimmeErrOrSlice() -> %[]u8 {173fn gimmeErrOrSlice() %[]u8 {
174 return []u8{};174 return []u8{};
175}175}
176176
...@@ -188,7 +188,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {...@@ -188,7 +188,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
188 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);188 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
189 }189 }
190}190}
191fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) -> %[]u8 {191fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) %[]u8 {
192 if (a) {192 if (a) {
193 return []u8{};193 return []u8{};
194 }194 }
...@@ -200,7 +200,7 @@ test "resolve undefined with integer" {...@@ -200,7 +200,7 @@ test "resolve undefined with integer" {
200 testResolveUndefWithInt(true, 1234);200 testResolveUndefWithInt(true, 1234);
201 comptime testResolveUndefWithInt(true, 1234);201 comptime testResolveUndefWithInt(true, 1234);
202}202}
203fn testResolveUndefWithInt(b: bool, x: i32) {203fn testResolveUndefWithInt(b: bool, x: i32) void {
204 const value = if (b) x else undefined;204 const value = if (b) x else undefined;
205 if (b) {205 if (b) {
206 assert(value == x);206 assert(value == x);
...@@ -212,7 +212,7 @@ test "implicit cast from &const [N]T to []const T" {...@@ -212,7 +212,7 @@ test "implicit cast from &const [N]T to []const T" {
212 comptime testCastConstArrayRefToConstSlice();212 comptime testCastConstArrayRefToConstSlice();
213}213}
214214
215fn testCastConstArrayRefToConstSlice() {215fn testCastConstArrayRefToConstSlice() void {
216 const blah = "aoeu";216 const blah = "aoeu";
217 const const_array_ref = &blah;217 const const_array_ref = &blah;
218 assert(@typeOf(const_array_ref) == &const [4]u8);218 assert(@typeOf(const_array_ref) == &const [4]u8);
...@@ -224,7 +224,7 @@ test "var args implicitly casts by value arg to const ref" {...@@ -224,7 +224,7 @@ test "var args implicitly casts by value arg to const ref" {
224 foo("hello");224 foo("hello");
225}225}
226226
227fn foo(args: ...) {227fn foo(args: ...) void {
228 assert(@typeOf(args[0]) == &const [5]u8);228 assert(@typeOf(args[0]) == &const [5]u8);
229}229}
230230
...@@ -239,13 +239,13 @@ test "peer type resolution: error and [N]T" {...@@ -239,13 +239,13 @@ test "peer type resolution: error and [N]T" {
239}239}
240240
241error BadValue;241error BadValue;
242//fn testPeerErrorAndArray(x: u8) -> %[]const u8 {242//fn testPeerErrorAndArray(x: u8) %[]const u8 {
243// return switch (x) {243// return switch (x) {
244// 0x00 => "OK",244// 0x00 => "OK",
245// else => error.BadValue,245// else => error.BadValue,
246// };246// };
247//}247//}
248fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {248fn testPeerErrorAndArray2(x: u8) %[]const u8 {
249 return switch (x) {249 return switch (x) {
250 0x00 => "OK",250 0x00 => "OK",
251 0x01 => "OKK",251 0x01 => "OKK",
...@@ -265,15 +265,15 @@ test "cast u128 to f128 and back" {...@@ -265,15 +265,15 @@ test "cast u128 to f128 and back" {
265 testCast128();265 testCast128();
266}266}
267267
268fn testCast128() {268fn testCast128() void {
269 assert(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);269 assert(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
270}270}
271271
272fn cast128Int(x: f128) -> u128 {272fn cast128Int(x: f128) u128 {
273 return @bitCast(u128, x);273 return @bitCast(u128, x);
274}274}
275275
276fn cast128Float(x: u128) -> f128 {276fn cast128Float(x: u128) f128 {
277 return @bitCast(f128, x);277 return @bitCast(f128, x);
278}278}
279279
test/cases/const_slice_child.zig+4-4
...@@ -13,14 +13,14 @@ test "const slice child" {...@@ -13,14 +13,14 @@ test "const slice child" {
13 bar(strs.len);13 bar(strs.len);
14}14}
1515
16fn foo(args: [][]const u8) {16fn foo(args: [][]const u8) void {
17 assert(args.len == 3);17 assert(args.len == 3);
18 assert(streql(args[0], "one"));18 assert(streql(args[0], "one"));
19 assert(streql(args[1], "two"));19 assert(streql(args[1], "two"));
20 assert(streql(args[2], "three"));20 assert(streql(args[2], "three"));
21}21}
2222
23fn bar(argc: usize) {23fn bar(argc: usize) void {
24 const args = debug.global_allocator.alloc([]const u8, argc) catch unreachable;24 const args = debug.global_allocator.alloc([]const u8, argc) catch unreachable;
25 for (args) |_, i| {25 for (args) |_, i| {
26 const ptr = argv[i];26 const ptr = argv[i];
...@@ -29,13 +29,13 @@ fn bar(argc: usize) {...@@ -29,13 +29,13 @@ fn bar(argc: usize) {
29 foo(args);29 foo(args);
30}30}
3131
32fn strlen(ptr: &const u8) -> usize {32fn strlen(ptr: &const u8) usize {
33 var count: usize = 0;33 var count: usize = 0;
34 while (ptr[count] != 0) : (count += 1) {}34 while (ptr[count] != 0) : (count += 1) {}
35 return count;35 return count;
36}36}
3737
38fn streql(a: []const u8, b: []const u8) -> bool {38fn streql(a: []const u8, b: []const u8) bool {
39 if (a.len != b.len) return false;39 if (a.len != b.len) return false;
40 for (a) |item, index| {40 for (a) |item, index| {
41 if (b[index] != item) return false;41 if (b[index] != item) return false;
test/cases/defer.zig+3-3
...@@ -5,10 +5,10 @@ var index: usize = undefined;...@@ -5,10 +5,10 @@ var index: usize = undefined;
55
6error FalseNotAllowed;6error FalseNotAllowed;
77
8fn runSomeErrorDefers(x: bool) -> %bool {8fn runSomeErrorDefers(x: bool) %bool {
9 index = 0;9 index = 0;
10 defer {result[index] = 'a'; index += 1;}10 defer {result[index] = 'a'; index += 1;}
11 %defer {result[index] = 'b'; index += 1;}11 errdefer {result[index] = 'b'; index += 1;}
12 defer {result[index] = 'c'; index += 1;}12 defer {result[index] = 'c'; index += 1;}
13 return if (x) x else error.FalseNotAllowed;13 return if (x) x else error.FalseNotAllowed;
14}14}
...@@ -33,7 +33,7 @@ test "break and continue inside loop inside defer expression" {...@@ -33,7 +33,7 @@ test "break and continue inside loop inside defer expression" {
33 comptime testBreakContInDefer(10);33 comptime testBreakContInDefer(10);
34}34}
3535
36fn testBreakContInDefer(x: usize) {36fn testBreakContInDefer(x: usize) void {
37 defer {37 defer {
38 var i: usize = 0;38 var i: usize = 0;
39 while (i < x) : (i += 1) {39 while (i < x) : (i += 1) {
test/cases/enum.zig+13-13
...@@ -40,7 +40,7 @@ const Bar = enum {...@@ -40,7 +40,7 @@ const Bar = enum {
40 D,40 D,
41};41};
4242
43fn returnAnInt(x: i32) -> Foo {43fn returnAnInt(x: i32) Foo {
44 return Foo { .One = x };44 return Foo { .One = x };
45}45}
4646
...@@ -52,14 +52,14 @@ test "constant enum with payload" {...@@ -52,14 +52,14 @@ test "constant enum with payload" {
52 shouldBeNotEmpty(full);52 shouldBeNotEmpty(full);
53}53}
5454
55fn shouldBeEmpty(x: &const AnEnumWithPayload) {55fn shouldBeEmpty(x: &const AnEnumWithPayload) void {
56 switch (*x) {56 switch (*x) {
57 AnEnumWithPayload.Empty => {},57 AnEnumWithPayload.Empty => {},
58 else => unreachable,58 else => unreachable,
59 }59 }
60}60}
6161
62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) {62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {
63 switch (*x) {63 switch (*x) {
64 AnEnumWithPayload.Empty => unreachable,64 AnEnumWithPayload.Empty => unreachable,
65 else => {},65 else => {},
...@@ -89,7 +89,7 @@ test "enum to int" {...@@ -89,7 +89,7 @@ test "enum to int" {
89 shouldEqual(Number.Four, 4);89 shouldEqual(Number.Four, 4);
90}90}
9191
92fn shouldEqual(n: Number, expected: u3) {92fn shouldEqual(n: Number, expected: u3) void {
93 assert(u3(n) == expected);93 assert(u3(n) == expected);
94}94}
9595
...@@ -97,7 +97,7 @@ fn shouldEqual(n: Number, expected: u3) {...@@ -97,7 +97,7 @@ fn shouldEqual(n: Number, expected: u3) {
97test "int to enum" {97test "int to enum" {
98 testIntToEnumEval(3);98 testIntToEnumEval(3);
99}99}
100fn testIntToEnumEval(x: i32) {100fn testIntToEnumEval(x: i32) void {
101 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);101 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
102}102}
103const IntToEnumNumber = enum {103const IntToEnumNumber = enum {
...@@ -114,7 +114,7 @@ test "@tagName" {...@@ -114,7 +114,7 @@ test "@tagName" {
114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
115}115}
116116
117fn testEnumTagNameBare(n: BareNumber) -> []const u8 {117fn testEnumTagNameBare(n: BareNumber) []const u8 {
118 return @tagName(n);118 return @tagName(n);
119}119}
120120
...@@ -270,15 +270,15 @@ test "bit field access with enum fields" {...@@ -270,15 +270,15 @@ test "bit field access with enum fields" {
270 assert(data.b == B.Four3);270 assert(data.b == B.Four3);
271}271}
272272
273fn getA(data: &const BitFieldOfEnums) -> A {273fn getA(data: &const BitFieldOfEnums) A {
274 return data.a;274 return data.a;
275}275}
276276
277fn getB(data: &const BitFieldOfEnums) -> B {277fn getB(data: &const BitFieldOfEnums) B {
278 return data.b;278 return data.b;
279}279}
280280
281fn getC(data: &const BitFieldOfEnums) -> C {281fn getC(data: &const BitFieldOfEnums) C {
282 return data.c;282 return data.c;
283}283}
284284
...@@ -287,7 +287,7 @@ test "casting enum to its tag type" {...@@ -287,7 +287,7 @@ test "casting enum to its tag type" {
287 comptime testCastEnumToTagType(Small2.Two);287 comptime testCastEnumToTagType(Small2.Two);
288}288}
289289
290fn testCastEnumToTagType(value: Small2) {290fn testCastEnumToTagType(value: Small2) void {
291 assert(u2(value) == 1);291 assert(u2(value) == 1);
292}292}
293293
...@@ -303,7 +303,7 @@ test "enum with specified tag values" {...@@ -303,7 +303,7 @@ test "enum with specified tag values" {
303 comptime testEnumWithSpecifiedTagValues(MultipleChoice.C);303 comptime testEnumWithSpecifiedTagValues(MultipleChoice.C);
304}304}
305305
306fn testEnumWithSpecifiedTagValues(x: MultipleChoice) {306fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
307 assert(u32(x) == 60);307 assert(u32(x) == 60);
308 assert(1234 == switch (x) {308 assert(1234 == switch (x) {
309 MultipleChoice.A => 1,309 MultipleChoice.A => 1,
...@@ -330,7 +330,7 @@ test "enum with specified and unspecified tag values" {...@@ -330,7 +330,7 @@ test "enum with specified and unspecified tag values" {
330 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);330 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
331}331}
332332
333fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) {333fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
334 assert(u32(x) == 1000);334 assert(u32(x) == 1000);
335 assert(1234 == switch (x) {335 assert(1234 == switch (x) {
336 MultipleChoice2.A => 1,336 MultipleChoice2.A => 1,
...@@ -354,7 +354,7 @@ const EnumWithOneMember = enum {...@@ -354,7 +354,7 @@ const EnumWithOneMember = enum {
354 Eof,354 Eof,
355};355};
356356
357fn doALoopThing(id: EnumWithOneMember) {357fn doALoopThing(id: EnumWithOneMember) void {
358 while (true) {358 while (true) {
359 if (id == EnumWithOneMember.Eof) {359 if (id == EnumWithOneMember.Eof) {
360 break;360 break;
test/cases/enum_with_members.zig+1-1
...@@ -6,7 +6,7 @@ const ET = union(enum) {...@@ -6,7 +6,7 @@ const ET = union(enum) {
6 SINT: i32,6 SINT: i32,
7 UINT: u32,7 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) -> %usize {9 pub fn print(a: &const ET, buf: []u8) %usize {
10 return switch (*a) {10 return switch (*a) {
11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),11 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),12 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
test/cases/error.zig+9-9
...@@ -1,16 +1,16 @@...@@ -1,16 +1,16 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4pub fn foo() -> %i32 {4pub fn foo() %i32 {
5 const x = try bar();5 const x = try bar();
6 return x + 1;6 return x + 1;
7}7}
88
9pub fn bar() -> %i32 {9pub fn bar() %i32 {
10 return 13;10 return 13;
11}11}
1212
13pub fn baz() -> %i32 {13pub fn baz() %i32 {
14 const y = foo() catch 1234;14 const y = foo() catch 1234;
15 return y + 1;15 return y + 1;
16}16}
...@@ -20,7 +20,7 @@ test "error wrapping" {...@@ -20,7 +20,7 @@ test "error wrapping" {
20}20}
2121
22error ItBroke;22error ItBroke;
23fn gimmeItBroke() -> []const u8 {23fn gimmeItBroke() []const u8 {
24 return @errorName(error.ItBroke);24 return @errorName(error.ItBroke);
25}25}
2626
...@@ -47,7 +47,7 @@ test "redefinition of error values allowed" {...@@ -47,7 +47,7 @@ test "redefinition of error values allowed" {
47error AnError;47error AnError;
48error AnError;48error AnError;
49error SecondError;49error SecondError;
50fn shouldBeNotEqual(a: error, b: error) {50fn shouldBeNotEqual(a: error, b: error) void {
51 if (a == b) unreachable;51 if (a == b) unreachable;
52}52}
5353
...@@ -59,7 +59,7 @@ test "error binary operator" {...@@ -59,7 +59,7 @@ test "error binary operator" {
59 assert(b == 10);59 assert(b == 10);
60}60}
61error ItBroke;61error ItBroke;
62fn errBinaryOperatorG(x: bool) -> %isize {62fn errBinaryOperatorG(x: bool) %isize {
63 return if (x) error.ItBroke else isize(10);63 return if (x) error.ItBroke else isize(10);
64}64}
6565
...@@ -68,18 +68,18 @@ test "unwrap simple value from error" {...@@ -68,18 +68,18 @@ test "unwrap simple value from error" {
68 const i = unwrapSimpleValueFromErrorDo() catch unreachable;68 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
69 assert(i == 13);69 assert(i == 13);
70}70}
71fn unwrapSimpleValueFromErrorDo() -> %isize { return 13; }71fn unwrapSimpleValueFromErrorDo() %isize { return 13; }
7272
7373
74test "error return in assignment" {74test "error return in assignment" {
75 doErrReturnInAssignment() catch unreachable;75 doErrReturnInAssignment() catch unreachable;
76}76}
7777
78fn doErrReturnInAssignment() -> %void {78fn doErrReturnInAssignment() %void {
79 var x : i32 = undefined;79 var x : i32 = undefined;
80 x = try makeANonErr();80 x = try makeANonErr();
81}81}
8282
83fn makeANonErr() -> %i32 {83fn makeANonErr() %i32 {
84 return 1;84 return 1;
85}85}
test/cases/eval.zig+25-25
...@@ -5,14 +5,14 @@ test "compile time recursion" {...@@ -5,14 +5,14 @@ test "compile time recursion" {
5 assert(some_data.len == 21);5 assert(some_data.len == 21);
6}6}
7var some_data: [usize(fibonacci(7))]u8 = undefined;7var some_data: [usize(fibonacci(7))]u8 = undefined;
8fn fibonacci(x: i32) -> i32 {8fn fibonacci(x: i32) i32 {
9 if (x <= 1) return 1;9 if (x <= 1) return 1;
10 return fibonacci(x - 1) + fibonacci(x - 2);10 return fibonacci(x - 1) + fibonacci(x - 2);
11}11}
1212
1313
1414
15fn unwrapAndAddOne(blah: ?i32) -> i32 {15fn unwrapAndAddOne(blah: ?i32) i32 {
16 return ??blah + 1;16 return ??blah + 1;
17}17}
18const should_be_1235 = unwrapAndAddOne(1234);18const should_be_1235 = unwrapAndAddOne(1234);
...@@ -28,7 +28,7 @@ test "inlined loop" {...@@ -28,7 +28,7 @@ test "inlined loop" {
28 assert(sum == 15);28 assert(sum == 15);
29}29}
3030
31fn gimme1or2(comptime a: bool) -> i32 {31fn gimme1or2(comptime a: bool) i32 {
32 const x: i32 = 1;32 const x: i32 = 1;
33 const y: i32 = 2;33 const y: i32 = 2;
34 comptime var z: i32 = if (a) x else y;34 comptime var z: i32 = if (a) x else y;
...@@ -44,14 +44,14 @@ test "static function evaluation" {...@@ -44,14 +44,14 @@ test "static function evaluation" {
44 assert(statically_added_number == 3);44 assert(statically_added_number == 3);
45}45}
46const statically_added_number = staticAdd(1, 2);46const statically_added_number = staticAdd(1, 2);
47fn staticAdd(a: i32, b: i32) -> i32 { return a + b; }47fn staticAdd(a: i32, b: i32) i32 { return a + b; }
4848
4949
50test "const expr eval on single expr blocks" {50test "const expr eval on single expr blocks" {
51 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);51 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
52}52}
5353
54fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {54fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
55 const literal = 3;55 const literal = 3;
5656
57 const result = if (b) b: {57 const result = if (b) b: {
...@@ -77,7 +77,7 @@ const Point = struct {...@@ -77,7 +77,7 @@ const Point = struct {
77 y: i32,77 y: i32,
78};78};
79const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };79const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };
80fn makePoint(x: i32, y: i32) -> Point {80fn makePoint(x: i32, y: i32) Point {
81 return Point {81 return Point {
82 .x = x,82 .x = x,
83 .y = y,83 .y = y,
...@@ -93,7 +93,7 @@ const static_vec3 = vec3(0.0, 0.0, 1.0);...@@ -93,7 +93,7 @@ const static_vec3 = vec3(0.0, 0.0, 1.0);
93pub const Vec3 = struct {93pub const Vec3 = struct {
94 data: [3]f32,94 data: [3]f32,
95};95};
96pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {96pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
97 return Vec3 {97 return Vec3 {
98 .data = []f32 { x, y, z, },98 .data = []f32 { x, y, z, },
99 };99 };
...@@ -156,7 +156,7 @@ test "try to trick eval with runtime if" {...@@ -156,7 +156,7 @@ test "try to trick eval with runtime if" {
156 assert(testTryToTrickEvalWithRuntimeIf(true) == 10);156 assert(testTryToTrickEvalWithRuntimeIf(true) == 10);
157}157}
158158
159fn testTryToTrickEvalWithRuntimeIf(b: bool) -> usize {159fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
160 comptime var i: usize = 0;160 comptime var i: usize = 0;
161 inline while (i < 10) : (i += 1) {161 inline while (i < 10) : (i += 1) {
162 const result = if (b) false else true;162 const result = if (b) false else true;
...@@ -166,7 +166,7 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) -> usize {...@@ -166,7 +166,7 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) -> usize {
166 }166 }
167}167}
168168
169fn max(comptime T: type, a: T, b: T) -> T {169fn max(comptime T: type, a: T, b: T) T {
170 if (T == bool) {170 if (T == bool) {
171 return a or b;171 return a or b;
172 } else if (a > b) {172 } else if (a > b) {
...@@ -175,7 +175,7 @@ fn max(comptime T: type, a: T, b: T) -> T {...@@ -175,7 +175,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
175 return b;175 return b;
176 }176 }
177}177}
178fn letsTryToCompareBools(a: bool, b: bool) -> bool {178fn letsTryToCompareBools(a: bool, b: bool) bool {
179 return max(bool, a, b);179 return max(bool, a, b);
180}180}
181test "inlined block and runtime block phi" {181test "inlined block and runtime block phi" {
...@@ -194,7 +194,7 @@ test "inlined block and runtime block phi" {...@@ -194,7 +194,7 @@ test "inlined block and runtime block phi" {
194194
195const CmdFn = struct {195const CmdFn = struct {
196 name: []const u8,196 name: []const u8,
197 func: fn(i32) -> i32,197 func: fn(i32) i32,
198};198};
199199
200const cmd_fns = []CmdFn{200const cmd_fns = []CmdFn{
...@@ -202,11 +202,11 @@ const cmd_fns = []CmdFn{...@@ -202,11 +202,11 @@ const cmd_fns = []CmdFn{
202 CmdFn {.name = "two", .func = two},202 CmdFn {.name = "two", .func = two},
203 CmdFn {.name = "three", .func = three},203 CmdFn {.name = "three", .func = three},
204};204};
205fn one(value: i32) -> i32 { return value + 1; }205fn one(value: i32) i32 { return value + 1; }
206fn two(value: i32) -> i32 { return value + 2; }206fn two(value: i32) i32 { return value + 2; }
207fn three(value: i32) -> i32 { return value + 3; }207fn three(value: i32) i32 { return value + 3; }
208208
209fn performFn(comptime prefix_char: u8, start_value: i32) -> i32 {209fn performFn(comptime prefix_char: u8, start_value: i32) i32 {
210 var result: i32 = start_value;210 var result: i32 = start_value;
211 comptime var i = 0;211 comptime var i = 0;
212 inline while (i < cmd_fns.len) : (i += 1) {212 inline while (i < cmd_fns.len) : (i += 1) {
...@@ -223,13 +223,13 @@ test "comptime iterate over fn ptr list" {...@@ -223,13 +223,13 @@ test "comptime iterate over fn ptr list" {
223 assert(performFn('w', 99) == 99);223 assert(performFn('w', 99) == 99);
224}224}
225225
226test "eval @setDebugSafety at compile-time" {226test "eval @setRuntimeSafety at compile-time" {
227 const result = comptime fnWithSetDebugSafety();227 const result = comptime fnWithSetRuntimeSafety();
228 assert(result == 1234);228 assert(result == 1234);
229}229}
230230
231fn fnWithSetDebugSafety() -> i32{231fn fnWithSetRuntimeSafety() i32{
232 @setDebugSafety(this, true);232 @setRuntimeSafety(true);
233 return 1234;233 return 1234;
234}234}
235235
...@@ -238,7 +238,7 @@ test "eval @setFloatMode at compile-time" {...@@ -238,7 +238,7 @@ test "eval @setFloatMode at compile-time" {
238 assert(result == 1234.0);238 assert(result == 1234.0);
239}239}
240240
241fn fnWithFloatMode() -> f32 {241fn fnWithFloatMode() f32 {
242 @setFloatMode(this, builtin.FloatMode.Strict);242 @setFloatMode(this, builtin.FloatMode.Strict);
243 return 1234.0;243 return 1234.0;
244}244}
...@@ -247,7 +247,7 @@ fn fnWithFloatMode() -> f32 {...@@ -247,7 +247,7 @@ fn fnWithFloatMode() -> f32 {
247const SimpleStruct = struct {247const SimpleStruct = struct {
248 field: i32,248 field: i32,
249249
250 fn method(self: &const SimpleStruct) -> i32 {250 fn method(self: &const SimpleStruct) i32 {
251 return self.field + 3;251 return self.field + 3;
252 }252 }
253};253};
...@@ -271,7 +271,7 @@ test "ptr to local array argument at comptime" {...@@ -271,7 +271,7 @@ test "ptr to local array argument at comptime" {
271 }271 }
272}272}
273273
274fn modifySomeBytes(bytes: []u8) {274fn modifySomeBytes(bytes: []u8) void {
275 bytes[0] = 'a';275 bytes[0] = 'a';
276 bytes[9] = 'b';276 bytes[9] = 'b';
277}277}
...@@ -280,7 +280,7 @@ fn modifySomeBytes(bytes: []u8) {...@@ -280,7 +280,7 @@ fn modifySomeBytes(bytes: []u8) {
280test "comparisons 0 <= uint and 0 > uint should be comptime" {280test "comparisons 0 <= uint and 0 > uint should be comptime" {
281 testCompTimeUIntComparisons(1234);281 testCompTimeUIntComparisons(1234);
282}282}
283fn testCompTimeUIntComparisons(x: u32) {283fn testCompTimeUIntComparisons(x: u32) void {
284 if (!(0 <= x)) {284 if (!(0 <= x)) {
285 @compileError("this condition should be comptime known");285 @compileError("this condition should be comptime known");
286 }286 }
...@@ -339,7 +339,7 @@ test "const global shares pointer with other same one" {...@@ -339,7 +339,7 @@ test "const global shares pointer with other same one" {
339 assertEqualPtrs(&hi1[0], &hi2[0]);339 assertEqualPtrs(&hi1[0], &hi2[0]);
340 comptime assert(&hi1[0] == &hi2[0]);340 comptime assert(&hi1[0] == &hi2[0]);
341}341}
342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) void {
343 assert(ptr1 == ptr2);343 assert(ptr1 == ptr2);
344}344}
345345
...@@ -376,7 +376,7 @@ test "f128 at compile time is lossy" {...@@ -376,7 +376,7 @@ test "f128 at compile time is lossy" {
376// TODO need a better implementation of bigfloat_init_bigint376// TODO need a better implementation of bigfloat_init_bigint
377// assert(f128(1 << 113) == 10384593717069655257060992658440192);377// assert(f128(1 << 113) == 10384593717069655257060992658440192);
378378
379pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) -> type {379pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
380 return struct {380 return struct {
381 pub const Node = struct { };381 pub const Node = struct { };
382 };382 };
test/cases/field_parent_ptr.zig+2-2
...@@ -24,7 +24,7 @@ const foo = Foo {...@@ -24,7 +24,7 @@ const foo = Foo {
24 .d = -10,24 .d = -10,
25};25};
2626
27fn testParentFieldPtr(c: &const i32) {27fn testParentFieldPtr(c: &const i32) void {
28 assert(c == &foo.c);28 assert(c == &foo.c);
2929
30 const base = @fieldParentPtr(Foo, "c", c);30 const base = @fieldParentPtr(Foo, "c", c);
...@@ -32,7 +32,7 @@ fn testParentFieldPtr(c: &const i32) {...@@ -32,7 +32,7 @@ fn testParentFieldPtr(c: &const i32) {
32 assert(&base.c == c);32 assert(&base.c == c);
33}33}
3434
35fn testParentFieldPtrFirst(a: &const bool) {35fn testParentFieldPtrFirst(a: &const bool) void {
36 assert(a == &foo.a);36 assert(a == &foo.a);
3737
38 const base = @fieldParentPtr(Foo, "a", a);38 const base = @fieldParentPtr(Foo, "a", a);
test/cases/fn.zig+12-12
...@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;...@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;
3test "params" {3test "params" {
4 assert(testParamsAdd(22, 11) == 33);4 assert(testParamsAdd(22, 11) == 33);
5}5}
6fn testParamsAdd(a: i32, b: i32) -> i32 {6fn testParamsAdd(a: i32, b: i32) i32 {
7 return a + b;7 return a + b;
8}8}
99
...@@ -11,7 +11,7 @@ fn testParamsAdd(a: i32, b: i32) -> i32 {...@@ -11,7 +11,7 @@ fn testParamsAdd(a: i32, b: i32) -> i32 {
11test "local variables" {11test "local variables" {
12 testLocVars(2);12 testLocVars(2);
13}13}
14fn testLocVars(b: i32) {14fn testLocVars(b: i32) void {
15 const a: i32 = 1;15 const a: i32 = 1;
16 if (a + b != 3) unreachable;16 if (a + b != 3) unreachable;
17}17}
...@@ -20,7 +20,7 @@ fn testLocVars(b: i32) {...@@ -20,7 +20,7 @@ fn testLocVars(b: i32) {
20test "void parameters" {20test "void parameters" {
21 voidFun(1, void{}, 2, {});21 voidFun(1, void{}, 2, {});
22}22}
23fn voidFun(a: i32, b: void, c: i32, d: void) {23fn voidFun(a: i32, b: void, c: i32, d: void) void {
24 const v = b;24 const v = b;
25 const vv: void = if (a == 1) v else {};25 const vv: void = if (a == 1) v else {};
26 assert(a + c == 3);26 assert(a + c == 3);
...@@ -56,10 +56,10 @@ test "call function with empty string" {...@@ -56,10 +56,10 @@ test "call function with empty string" {
56 acceptsString("");56 acceptsString("");
57}57}
5858
59fn acceptsString(foo: []u8) { }59fn acceptsString(foo: []u8) void { }
6060
6161
62fn @"weird function name"() -> i32 {62fn @"weird function name"() i32 {
63 return 1234;63 return 1234;
64}64}
65test "weird function name" {65test "weird function name" {
...@@ -70,9 +70,9 @@ test "implicit cast function unreachable return" {...@@ -70,9 +70,9 @@ test "implicit cast function unreachable return" {
70 wantsFnWithVoid(fnWithUnreachable);70 wantsFnWithVoid(fnWithUnreachable);
71}71}
7272
73fn wantsFnWithVoid(f: fn()) { }73fn wantsFnWithVoid(f: fn() void) void { }
7474
75fn fnWithUnreachable() -> noreturn {75fn fnWithUnreachable() noreturn {
76 unreachable;76 unreachable;
77}77}
7878
...@@ -83,14 +83,14 @@ test "function pointers" {...@@ -83,14 +83,14 @@ test "function pointers" {
83 assert(f() == u32(i) + 5);83 assert(f() == u32(i) + 5);
84 }84 }
85}85}
86fn fn1() -> u32 {return 5;}86fn fn1() u32 {return 5;}
87fn fn2() -> u32 {return 6;}87fn fn2() u32 {return 6;}
88fn fn3() -> u32 {return 7;}88fn fn3() u32 {return 7;}
89fn fn4() -> u32 {return 8;}89fn fn4() u32 {return 8;}
9090
9191
92test "inline function call" {92test "inline function call" {
93 assert(@inlineCall(add, 3, 9) == 12);93 assert(@inlineCall(add, 3, 9) == 12);
94}94}
9595
96fn add(a: i32, b: i32) -> i32 { return a + b; }96fn add(a: i32, b: i32) i32 { return a + b; }
test/cases/for.zig+3-3
...@@ -22,7 +22,7 @@ test "for loop with pointer elem var" {...@@ -22,7 +22,7 @@ test "for loop with pointer elem var" {
22 mangleString(target[0..]);22 mangleString(target[0..]);
23 assert(mem.eql(u8, target, "bcdefgh"));23 assert(mem.eql(u8, target, "bcdefgh"));
24}24}
25fn mangleString(s: []u8) {25fn mangleString(s: []u8) void {
26 for (s) |*c| {26 for (s) |*c| {
27 *c += 1;27 *c += 1;
28 }28 }
...@@ -61,7 +61,7 @@ test "break from outer for loop" {...@@ -61,7 +61,7 @@ test "break from outer for loop" {
61 comptime testBreakOuter();61 comptime testBreakOuter();
62}62}
6363
64fn testBreakOuter() {64fn testBreakOuter() void {
65 var array = "aoeu";65 var array = "aoeu";
66 var count: usize = 0;66 var count: usize = 0;
67 outer: for (array) |_| {67 outer: for (array) |_| {
...@@ -78,7 +78,7 @@ test "continue outer for loop" {...@@ -78,7 +78,7 @@ test "continue outer for loop" {
78 comptime testContinueOuter();78 comptime testContinueOuter();
79}79}
8080
81fn testContinueOuter() {81fn testContinueOuter() void {
82 var array = "aoeu";82 var array = "aoeu";
83 var counter: usize = 0;83 var counter: usize = 0;
84 outer: for (array) |_| {84 outer: for (array) |_| {
test/cases/generics.zig+19-19
...@@ -6,11 +6,11 @@ test "simple generic fn" {...@@ -6,11 +6,11 @@ test "simple generic fn" {
6 assert(add(2, 3) == 5);6 assert(add(2, 3) == 5);
7}7}
88
9fn max(comptime T: type, a: T, b: T) -> T {9fn max(comptime T: type, a: T, b: T) T {
10 return if (a > b) a else b;10 return if (a > b) a else b;
11}11}
1212
13fn add(comptime a: i32, b: i32) -> i32 {13fn add(comptime a: i32, b: i32) i32 {
14 return (comptime a) + b;14 return (comptime a) + b;
15}15}
1616
...@@ -19,15 +19,15 @@ test "compile time generic eval" {...@@ -19,15 +19,15 @@ test "compile time generic eval" {
19 assert(the_max == 5678);19 assert(the_max == 5678);
20}20}
2121
22fn gimmeTheBigOne(a: u32, b: u32) -> u32 {22fn gimmeTheBigOne(a: u32, b: u32) u32 {
23 return max(u32, a, b);23 return max(u32, a, b);
24}24}
2525
26fn shouldCallSameInstance(a: u32, b: u32) -> u32 {26fn shouldCallSameInstance(a: u32, b: u32) u32 {
27 return max(u32, a, b);27 return max(u32, a, b);
28}28}
2929
30fn sameButWithFloats(a: f64, b: f64) -> f64 {30fn sameButWithFloats(a: f64, b: f64) f64 {
31 return max(f64, a, b);31 return max(f64, a, b);
32}32}
3333
...@@ -48,24 +48,24 @@ comptime {...@@ -48,24 +48,24 @@ comptime {
48 assert(max_f64(1.2, 3.4) == 3.4);48 assert(max_f64(1.2, 3.4) == 3.4);
49}49}
5050
51fn max_var(a: var, b: var) -> @typeOf(a + b) {51fn max_var(a: var, b: var) @typeOf(a + b) {
52 return if (a > b) a else b;52 return if (a > b) a else b;
53}53}
5454
55fn max_i32(a: i32, b: i32) -> i32 {55fn max_i32(a: i32, b: i32) i32 {
56 return max_var(a, b);56 return max_var(a, b);
57}57}
5858
59fn max_f64(a: f64, b: f64) -> f64 {59fn max_f64(a: f64, b: f64) f64 {
60 return max_var(a, b);60 return max_var(a, b);
61}61}
6262
6363
64pub fn List(comptime T: type) -> type {64pub fn List(comptime T: type) type {
65 return SmallList(T, 8);65 return SmallList(T, 8);
66}66}
6767
68pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {68pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type {
69 return struct {69 return struct {
70 items: []T,70 items: []T,
71 length: usize,71 length: usize,
...@@ -90,18 +90,18 @@ test "generic struct" {...@@ -90,18 +90,18 @@ test "generic struct" {
90 assert(a1.value == a1.getVal());90 assert(a1.value == a1.getVal());
91 assert(b1.getVal());91 assert(b1.getVal());
92}92}
93fn GenNode(comptime T: type) -> type {93fn GenNode(comptime T: type) type {
94 return struct {94 return struct {
95 value: T,95 value: T,
96 next: ?&GenNode(T),96 next: ?&GenNode(T),
97 fn getVal(n: &const GenNode(T)) -> T { return n.value; }97 fn getVal(n: &const GenNode(T)) T { return n.value; }
98 };98 };
99}99}
100100
101test "const decls in struct" {101test "const decls in struct" {
102 assert(GenericDataThing(3).count_plus_one == 4);102 assert(GenericDataThing(3).count_plus_one == 4);
103}103}
104fn GenericDataThing(comptime count: isize) -> type {104fn GenericDataThing(comptime count: isize) type {
105 return struct {105 return struct {
106 const count_plus_one = count + 1;106 const count_plus_one = count + 1;
107 };107 };
...@@ -111,7 +111,7 @@ fn GenericDataThing(comptime count: isize) -> type {...@@ -111,7 +111,7 @@ fn GenericDataThing(comptime count: isize) -> type {
111test "use generic param in generic param" {111test "use generic param in generic param" {
112 assert(aGenericFn(i32, 3, 4) == 7);112 assert(aGenericFn(i32, 3, 4) == 7);
113}113}
114fn aGenericFn(comptime T: type, comptime a: T, b: T) -> T {114fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
115 return a + b;115 return a + b;
116}116}
117117
...@@ -120,16 +120,16 @@ test "generic fn with implicit cast" {...@@ -120,16 +120,16 @@ test "generic fn with implicit cast" {
120 assert(getFirstByte(u8, []u8 {13}) == 13);120 assert(getFirstByte(u8, []u8 {13}) == 13);
121 assert(getFirstByte(u16, []u16 {0, 13}) == 0);121 assert(getFirstByte(u16, []u16 {0, 13}) == 0);
122}122}
123fn getByte(ptr: ?&const u8) -> u8 {return *??ptr;}123fn getByte(ptr: ?&const u8) u8 {return *??ptr;}
124fn getFirstByte(comptime T: type, mem: []const T) -> u8 {124fn getFirstByte(comptime T: type, mem: []const T) u8 {
125 return getByte(@ptrCast(&const u8, &mem[0]));125 return getByte(@ptrCast(&const u8, &mem[0]));
126}126}
127127
128128
129const foos = []fn(var) -> bool { foo1, foo2 };129const foos = []fn(var) bool { foo1, foo2 };
130130
131fn foo1(arg: var) -> bool { return arg; }131fn foo1(arg: var) bool { return arg; }
132fn foo2(arg: var) -> bool { return !arg; }132fn foo2(arg: var) bool { return !arg; }
133133
134test "array of generic fns" {134test "array of generic fns" {
135 assert(foos[0](true));135 assert(foos[0](true));
test/cases/if.zig+3-3
...@@ -4,14 +4,14 @@ test "if statements" {...@@ -4,14 +4,14 @@ test "if statements" {
4 shouldBeEqual(1, 1);4 shouldBeEqual(1, 1);
5 firstEqlThird(2, 1, 2);5 firstEqlThird(2, 1, 2);
6}6}
7fn shouldBeEqual(a: i32, b: i32) {7fn shouldBeEqual(a: i32, b: i32) void {
8 if (a != b) {8 if (a != b) {
9 unreachable;9 unreachable;
10 } else {10 } else {
11 return;11 return;
12 }12 }
13}13}
14fn firstEqlThird(a: i32, b: i32, c: i32) {14fn firstEqlThird(a: i32, b: i32, c: i32) void {
15 if (a == b) {15 if (a == b) {
16 unreachable;16 unreachable;
17 } else if (b == c) {17 } else if (b == c) {
...@@ -27,7 +27,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) {...@@ -27,7 +27,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) {
27test "else if expression" {27test "else if expression" {
28 assert(elseIfExpressionF(1) == 1);28 assert(elseIfExpressionF(1) == 1);
29}29}
30fn elseIfExpressionF(c: u8) -> u8 {30fn elseIfExpressionF(c: u8) u8 {
31 if (c == 0) {31 if (c == 0) {
32 return 0;32 return 0;
33 } else if (c == 1) {33 } else if (c == 1) {
test/cases/import/a_namespace.zig+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1pub fn foo() -> i32 { return 1234; }1pub fn foo() i32 { return 1234; }
test/cases/incomplete_struct_param_tld.zig+2-2
...@@ -11,12 +11,12 @@ const B = struct {...@@ -11,12 +11,12 @@ const B = struct {
11const C = struct {11const C = struct {
12 x: i32,12 x: i32,
1313
14 fn d(c: &const C) -> i32 {14 fn d(c: &const C) i32 {
15 return c.x;15 return c.x;
16 }16 }
17};17};
1818
19fn foo(a: &const A) -> i32 {19fn foo(a: &const A) i32 {
20 return a.b.c.d();20 return a.b.c.d();
21}21}
2222
test/cases/ir_block_deps.zig+2-2
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3fn foo(id: u64) -> %i32 {3fn foo(id: u64) %i32 {
4 return switch (id) {4 return switch (id) {
5 1 => getErrInt(),5 1 => getErrInt(),
6 2 => {6 2 => {
...@@ -11,7 +11,7 @@ fn foo(id: u64) -> %i32 {...@@ -11,7 +11,7 @@ fn foo(id: u64) -> %i32 {
11 };11 };
12}12}
1313
14fn getErrInt() -> %i32 { return 0; }14fn getErrInt() %i32 { return 0; }
1515
16error ItBroke;16error ItBroke;
1717
test/cases/math.zig+26-26
...@@ -4,7 +4,7 @@ test "division" {...@@ -4,7 +4,7 @@ test "division" {
4 testDivision();4 testDivision();
5 comptime testDivision();5 comptime testDivision();
6}6}
7fn testDivision() {7fn testDivision() void {
8 assert(div(u32, 13, 3) == 4);8 assert(div(u32, 13, 3) == 4);
9 assert(div(f32, 1.0, 2.0) == 0.5);9 assert(div(f32, 1.0, 2.0) == 0.5);
1010
...@@ -50,16 +50,16 @@ fn testDivision() {...@@ -50,16 +50,16 @@ fn testDivision() {
50 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);50 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);
51 }51 }
52}52}
53fn div(comptime T: type, a: T, b: T) -> T {53fn div(comptime T: type, a: T, b: T) T {
54 return a / b;54 return a / b;
55}55}
56fn divExact(comptime T: type, a: T, b: T) -> T {56fn divExact(comptime T: type, a: T, b: T) T {
57 return @divExact(a, b);57 return @divExact(a, b);
58}58}
59fn divFloor(comptime T: type, a: T, b: T) -> T {59fn divFloor(comptime T: type, a: T, b: T) T {
60 return @divFloor(a, b);60 return @divFloor(a, b);
61}61}
62fn divTrunc(comptime T: type, a: T, b: T) -> T {62fn divTrunc(comptime T: type, a: T, b: T) T {
63 return @divTrunc(a, b);63 return @divTrunc(a, b);
64}64}
6565
...@@ -85,7 +85,7 @@ test "@clz" {...@@ -85,7 +85,7 @@ test "@clz" {
85 comptime testClz();85 comptime testClz();
86}86}
8787
88fn testClz() {88fn testClz() void {
89 assert(clz(u8(0b00001010)) == 4);89 assert(clz(u8(0b00001010)) == 4);
90 assert(clz(u8(0b10001010)) == 0);90 assert(clz(u8(0b10001010)) == 0);
91 assert(clz(u8(0b00000000)) == 8);91 assert(clz(u8(0b00000000)) == 8);
...@@ -93,7 +93,7 @@ fn testClz() {...@@ -93,7 +93,7 @@ fn testClz() {
93 assert(clz(u128(0x10000000000000000)) == 63);93 assert(clz(u128(0x10000000000000000)) == 63);
94}94}
9595
96fn clz(x: var) -> usize {96fn clz(x: var) usize {
97 return @clz(x);97 return @clz(x);
98}98}
9999
...@@ -102,13 +102,13 @@ test "@ctz" {...@@ -102,13 +102,13 @@ test "@ctz" {
102 comptime testCtz();102 comptime testCtz();
103}103}
104104
105fn testCtz() {105fn testCtz() void {
106 assert(ctz(u8(0b10100000)) == 5);106 assert(ctz(u8(0b10100000)) == 5);
107 assert(ctz(u8(0b10001010)) == 1);107 assert(ctz(u8(0b10001010)) == 1);
108 assert(ctz(u8(0b00000000)) == 8);108 assert(ctz(u8(0b00000000)) == 8);
109}109}
110110
111fn ctz(x: var) -> usize {111fn ctz(x: var) usize {
112 return @ctz(x);112 return @ctz(x);
113}113}
114114
...@@ -132,7 +132,7 @@ test "three expr in a row" {...@@ -132,7 +132,7 @@ test "three expr in a row" {
132 testThreeExprInARow(false, true);132 testThreeExprInARow(false, true);
133 comptime testThreeExprInARow(false, true);133 comptime testThreeExprInARow(false, true);
134}134}
135fn testThreeExprInARow(f: bool, t: bool) {135fn testThreeExprInARow(f: bool, t: bool) void {
136 assertFalse(f or f or f);136 assertFalse(f or f or f);
137 assertFalse(t and t and f);137 assertFalse(t and t and f);
138 assertFalse(1 | 2 | 4 != 7);138 assertFalse(1 | 2 | 4 != 7);
...@@ -146,7 +146,7 @@ fn testThreeExprInARow(f: bool, t: bool) {...@@ -146,7 +146,7 @@ fn testThreeExprInARow(f: bool, t: bool) {
146 assertFalse(!!false);146 assertFalse(!!false);
147 assertFalse(i32(7) != --(i32(7)));147 assertFalse(i32(7) != --(i32(7)));
148}148}
149fn assertFalse(b: bool) {149fn assertFalse(b: bool) void {
150 assert(!b);150 assert(!b);
151}151}
152152
...@@ -165,7 +165,7 @@ test "unsigned wrapping" {...@@ -165,7 +165,7 @@ test "unsigned wrapping" {
165 testUnsignedWrappingEval(@maxValue(u32));165 testUnsignedWrappingEval(@maxValue(u32));
166 comptime testUnsignedWrappingEval(@maxValue(u32));166 comptime testUnsignedWrappingEval(@maxValue(u32));
167}167}
168fn testUnsignedWrappingEval(x: u32) {168fn testUnsignedWrappingEval(x: u32) void {
169 const zero = x +% 1;169 const zero = x +% 1;
170 assert(zero == 0);170 assert(zero == 0);
171 const orig = zero -% 1;171 const orig = zero -% 1;
...@@ -176,7 +176,7 @@ test "signed wrapping" {...@@ -176,7 +176,7 @@ test "signed wrapping" {
176 testSignedWrappingEval(@maxValue(i32));176 testSignedWrappingEval(@maxValue(i32));
177 comptime testSignedWrappingEval(@maxValue(i32));177 comptime testSignedWrappingEval(@maxValue(i32));
178}178}
179fn testSignedWrappingEval(x: i32) {179fn testSignedWrappingEval(x: i32) void {
180 const min_val = x +% 1;180 const min_val = x +% 1;
181 assert(min_val == @minValue(i32));181 assert(min_val == @minValue(i32));
182 const max_val = min_val -% 1;182 const max_val = min_val -% 1;
...@@ -187,7 +187,7 @@ test "negation wrapping" {...@@ -187,7 +187,7 @@ test "negation wrapping" {
187 testNegationWrappingEval(@minValue(i16));187 testNegationWrappingEval(@minValue(i16));
188 comptime testNegationWrappingEval(@minValue(i16));188 comptime testNegationWrappingEval(@minValue(i16));
189}189}
190fn testNegationWrappingEval(x: i16) {190fn testNegationWrappingEval(x: i16) void {
191 assert(x == -32768);191 assert(x == -32768);
192 const neg = -%x;192 const neg = -%x;
193 assert(neg == -32768);193 assert(neg == -32768);
...@@ -197,12 +197,12 @@ test "unsigned 64-bit division" {...@@ -197,12 +197,12 @@ test "unsigned 64-bit division" {
197 test_u64_div();197 test_u64_div();
198 comptime test_u64_div();198 comptime test_u64_div();
199}199}
200fn test_u64_div() {200fn test_u64_div() void {
201 const result = divWithResult(1152921504606846976, 34359738365);201 const result = divWithResult(1152921504606846976, 34359738365);
202 assert(result.quotient == 33554432);202 assert(result.quotient == 33554432);
203 assert(result.remainder == 100663296);203 assert(result.remainder == 100663296);
204}204}
205fn divWithResult(a: u64, b: u64) -> DivResult {205fn divWithResult(a: u64, b: u64) DivResult {
206 return DivResult {206 return DivResult {
207 .quotient = a / b,207 .quotient = a / b,
208 .remainder = a % b,208 .remainder = a % b,
...@@ -219,7 +219,7 @@ test "binary not" {...@@ -219,7 +219,7 @@ test "binary not" {
219 testBinaryNot(0b1010101010101010);219 testBinaryNot(0b1010101010101010);
220}220}
221221
222fn testBinaryNot(x: u16) {222fn testBinaryNot(x: u16) void {
223 assert(~x == 0b0101010101010101);223 assert(~x == 0b0101010101010101);
224}224}
225225
...@@ -250,7 +250,7 @@ test "float equality" {...@@ -250,7 +250,7 @@ test "float equality" {
250 comptime testFloatEqualityImpl(x, y);250 comptime testFloatEqualityImpl(x, y);
251}251}
252252
253fn testFloatEqualityImpl(x: f64, y: f64) {253fn testFloatEqualityImpl(x: f64, y: f64) void {
254 const y2 = x + 1.0;254 const y2 = x + 1.0;
255 assert(y == y2);255 assert(y == y2);
256}256}
...@@ -285,7 +285,7 @@ test "truncating shift left" {...@@ -285,7 +285,7 @@ test "truncating shift left" {
285 testShlTrunc(@maxValue(u16));285 testShlTrunc(@maxValue(u16));
286 comptime testShlTrunc(@maxValue(u16));286 comptime testShlTrunc(@maxValue(u16));
287}287}
288fn testShlTrunc(x: u16) {288fn testShlTrunc(x: u16) void {
289 const shifted = x << 1;289 const shifted = x << 1;
290 assert(shifted == 65534);290 assert(shifted == 65534);
291}291}
...@@ -294,7 +294,7 @@ test "truncating shift right" {...@@ -294,7 +294,7 @@ test "truncating shift right" {
294 testShrTrunc(@maxValue(u16));294 testShrTrunc(@maxValue(u16));
295 comptime testShrTrunc(@maxValue(u16));295 comptime testShrTrunc(@maxValue(u16));
296}296}
297fn testShrTrunc(x: u16) {297fn testShrTrunc(x: u16) void {
298 const shifted = x >> 1;298 const shifted = x >> 1;
299 assert(shifted == 32767);299 assert(shifted == 32767);
300}300}
...@@ -303,7 +303,7 @@ test "exact shift left" {...@@ -303,7 +303,7 @@ test "exact shift left" {
303 testShlExact(0b00110101);303 testShlExact(0b00110101);
304 comptime testShlExact(0b00110101);304 comptime testShlExact(0b00110101);
305}305}
306fn testShlExact(x: u8) {306fn testShlExact(x: u8) void {
307 const shifted = @shlExact(x, 2);307 const shifted = @shlExact(x, 2);
308 assert(shifted == 0b11010100);308 assert(shifted == 0b11010100);
309}309}
...@@ -312,7 +312,7 @@ test "exact shift right" {...@@ -312,7 +312,7 @@ test "exact shift right" {
312 testShrExact(0b10110100);312 testShrExact(0b10110100);
313 comptime testShrExact(0b10110100);313 comptime testShrExact(0b10110100);
314}314}
315fn testShrExact(x: u8) {315fn testShrExact(x: u8) void {
316 const shifted = @shrExact(x, 2);316 const shifted = @shrExact(x, 2);
317 assert(shifted == 0b00101101);317 assert(shifted == 0b00101101);
318}318}
...@@ -354,7 +354,7 @@ test "xor" {...@@ -354,7 +354,7 @@ test "xor" {
354 comptime test_xor();354 comptime test_xor();
355}355}
356356
357fn test_xor() {357fn test_xor() void {
358 assert(0xFF ^ 0x00 == 0xFF);358 assert(0xFF ^ 0x00 == 0xFF);
359 assert(0xF0 ^ 0x0F == 0xFF);359 assert(0xF0 ^ 0x0F == 0xFF);
360 assert(0xFF ^ 0xF0 == 0x0F);360 assert(0xFF ^ 0xF0 == 0x0F);
...@@ -380,9 +380,9 @@ test "f128" {...@@ -380,9 +380,9 @@ test "f128" {
380 comptime test_f128();380 comptime test_f128();
381}381}
382382
383fn make_f128(x: f128) -> f128 { return x; }383fn make_f128(x: f128) f128 { return x; }
384384
385fn test_f128() {385fn test_f128() void {
386 assert(@sizeOf(f128) == 16);386 assert(@sizeOf(f128) == 16);
387 assert(make_f128(1.0) == 1.0);387 assert(make_f128(1.0) == 1.0);
388 assert(make_f128(1.0) != 1.1);388 assert(make_f128(1.0) != 1.1);
...@@ -392,6 +392,6 @@ fn test_f128() {...@@ -392,6 +392,6 @@ fn test_f128() {
392 should_not_be_zero(1.0);392 should_not_be_zero(1.0);
393}393}
394394
395fn should_not_be_zero(x: f128) {395fn should_not_be_zero(x: f128) void {
396 assert(x != 0.0);396 assert(x != 0.0);
397}397}
\ No newline at end of file
test/cases/misc.zig+39-30
...@@ -6,7 +6,7 @@ const builtin = @import("builtin");...@@ -6,7 +6,7 @@ const builtin = @import("builtin");
6// normal comment6// normal comment
7/// this is a documentation comment7/// this is a documentation comment
8/// doc comment line 28/// doc comment line 2
9fn emptyFunctionWithComments() {}9fn emptyFunctionWithComments() void {}
1010
11test "empty function with comments" {11test "empty function with comments" {
12 emptyFunctionWithComments();12 emptyFunctionWithComments();
...@@ -16,7 +16,7 @@ comptime {...@@ -16,7 +16,7 @@ comptime {
16 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);16 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
17}17}
1818
19extern fn disabledExternFn() {19extern fn disabledExternFn() void {
20}20}
2121
22test "call disabled extern fn" {22test "call disabled extern fn" {
...@@ -104,7 +104,7 @@ test "short circuit" {...@@ -104,7 +104,7 @@ test "short circuit" {
104 comptime testShortCircuit(false, true);104 comptime testShortCircuit(false, true);
105}105}
106106
107fn testShortCircuit(f: bool, t: bool) {107fn testShortCircuit(f: bool, t: bool) void {
108 var hit_1 = f;108 var hit_1 = f;
109 var hit_2 = f;109 var hit_2 = f;
110 var hit_3 = f;110 var hit_3 = f;
...@@ -134,11 +134,11 @@ fn testShortCircuit(f: bool, t: bool) {...@@ -134,11 +134,11 @@ fn testShortCircuit(f: bool, t: bool) {
134test "truncate" {134test "truncate" {
135 assert(testTruncate(0x10fd) == 0xfd);135 assert(testTruncate(0x10fd) == 0xfd);
136}136}
137fn testTruncate(x: u32) -> u8 {137fn testTruncate(x: u32) u8 {
138 return @truncate(u8, x);138 return @truncate(u8, x);
139}139}
140140
141fn first4KeysOfHomeRow() -> []const u8 {141fn first4KeysOfHomeRow() []const u8 {
142 return "aoeu";142 return "aoeu";
143}143}
144144
...@@ -193,7 +193,7 @@ test "constant equal function pointers" {...@@ -193,7 +193,7 @@ test "constant equal function pointers" {
193 assert(comptime x: {break :x emptyFn == alias;});193 assert(comptime x: {break :x emptyFn == alias;});
194}194}
195195
196fn emptyFn() {}196fn emptyFn() void {}
197197
198198
199test "hex escape" {199test "hex escape" {
...@@ -262,10 +262,10 @@ test "generic malloc free" {...@@ -262,10 +262,10 @@ test "generic malloc free" {
262 memFree(u8, a);262 memFree(u8, a);
263}263}
264const some_mem : [100]u8 = undefined;264const some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) -> %[]T {265fn memAlloc(comptime T: type, n: usize) %[]T {
266 return @ptrCast(&T, &some_mem[0])[0..n];266 return @ptrCast(&T, &some_mem[0])[0..n];
267}267}
268fn memFree(comptime T: type, memory: []T) { }268fn memFree(comptime T: type, memory: []T) void { }
269269
270270
271test "cast undefined" {271test "cast undefined" {
...@@ -273,22 +273,22 @@ test "cast undefined" {...@@ -273,22 +273,22 @@ test "cast undefined" {
273 const slice = ([]const u8)(array);273 const slice = ([]const u8)(array);
274 testCastUndefined(slice);274 testCastUndefined(slice);
275}275}
276fn testCastUndefined(x: []const u8) {}276fn testCastUndefined(x: []const u8) void {}
277277
278278
279test "cast small unsigned to larger signed" {279test "cast small unsigned to larger signed" {
280 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));280 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
281 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));281 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
282}282}
283fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { return x; }283fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; }
284fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { return x; }284fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; }
285285
286286
287test "implicit cast after unreachable" {287test "implicit cast after unreachable" {
288 assert(outer() == 1234);288 assert(outer() == 1234);
289}289}
290fn inner() -> i32 { return 1234; }290fn inner() i32 { return 1234; }
291fn outer() -> i64 {291fn outer() i64 {
292 return inner();292 return inner();
293}293}
294294
...@@ -307,11 +307,11 @@ test "call result of if else expression" {...@@ -307,11 +307,11 @@ test "call result of if else expression" {
307 assert(mem.eql(u8, f2(true), "a"));307 assert(mem.eql(u8, f2(true), "a"));
308 assert(mem.eql(u8, f2(false), "b"));308 assert(mem.eql(u8, f2(false), "b"));
309}309}
310fn f2(x: bool) -> []const u8 {310fn f2(x: bool) []const u8 {
311 return (if (x) fA else fB)();311 return (if (x) fA else fB)();
312}312}
313fn fA() -> []const u8 { return "a"; }313fn fA() []const u8 { return "a"; }
314fn fB() -> []const u8 { return "b"; }314fn fB() []const u8 { return "b"; }
315315
316316
317test "const expression eval handling of variables" {317test "const expression eval handling of variables" {
...@@ -338,7 +338,7 @@ const Test3Point = struct {...@@ -338,7 +338,7 @@ const Test3Point = struct {
338};338};
339const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};339const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};
340const test3_bar = Test3Foo { .Two = 13};340const test3_bar = Test3Foo { .Two = 13};
341fn test3_1(f: &const Test3Foo) {341fn test3_1(f: &const Test3Foo) void {
342 switch (*f) {342 switch (*f) {
343 Test3Foo.Three => |pt| {343 Test3Foo.Three => |pt| {
344 assert(pt.x == 3);344 assert(pt.x == 3);
...@@ -347,7 +347,7 @@ fn test3_1(f: &const Test3Foo) {...@@ -347,7 +347,7 @@ fn test3_1(f: &const Test3Foo) {
347 else => unreachable,347 else => unreachable,
348 }348 }
349}349}
350fn test3_2(f: &const Test3Foo) {350fn test3_2(f: &const Test3Foo) void {
351 switch (*f) {351 switch (*f) {
352 Test3Foo.Two => |x| {352 Test3Foo.Two => |x| {
353 assert(x == 13);353 assert(x == 13);
...@@ -367,7 +367,7 @@ const single_quote = '\'';...@@ -367,7 +367,7 @@ const single_quote = '\'';
367test "take address of parameter" {367test "take address of parameter" {
368 testTakeAddressOfParameter(12.34);368 testTakeAddressOfParameter(12.34);
369}369}
370fn testTakeAddressOfParameter(f: f32) {370fn testTakeAddressOfParameter(f: f32) void {
371 const f_ptr = &f;371 const f_ptr = &f;
372 assert(*f_ptr == 12.34);372 assert(*f_ptr == 12.34);
373}373}
...@@ -378,7 +378,7 @@ test "pointer comparison" {...@@ -378,7 +378,7 @@ test "pointer comparison" {
378 const b = &a;378 const b = &a;
379 assert(ptrEql(b, b));379 assert(ptrEql(b, b));
380}380}
381fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {381fn ptrEql(a: &const []const u8, b: &const []const u8) bool {
382 return a == b;382 return a == b;
383}383}
384384
...@@ -419,12 +419,12 @@ test "cast slice to u8 slice" {...@@ -419,12 +419,12 @@ test "cast slice to u8 slice" {
419test "pointer to void return type" {419test "pointer to void return type" {
420 testPointerToVoidReturnType() catch unreachable;420 testPointerToVoidReturnType() catch unreachable;
421}421}
422fn testPointerToVoidReturnType() -> %void {422fn testPointerToVoidReturnType() %void {
423 const a = testPointerToVoidReturnType2();423 const a = testPointerToVoidReturnType2();
424 return *a;424 return *a;
425}425}
426const test_pointer_to_void_return_type_x = void{};426const test_pointer_to_void_return_type_x = void{};
427fn testPointerToVoidReturnType2() -> &const void {427fn testPointerToVoidReturnType2() &const void {
428 return &test_pointer_to_void_return_type_x;428 return &test_pointer_to_void_return_type_x;
429}429}
430430
...@@ -444,7 +444,7 @@ test "array 2D const double ptr" {...@@ -444,7 +444,7 @@ test "array 2D const double ptr" {
444 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);444 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
445}445}
446446
447fn testArray2DConstDoublePtr(ptr: &const f32) {447fn testArray2DConstDoublePtr(ptr: &const f32) void {
448 assert(ptr[0] == 1.0);448 assert(ptr[0] == 1.0);
449 assert(ptr[1] == 2.0);449 assert(ptr[1] == 2.0);
450}450}
...@@ -481,7 +481,7 @@ test "@typeId" {...@@ -481,7 +481,7 @@ test "@typeId" {
481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482 assert(@typeId(AUnionEnum) == Tid.Union);482 assert(@typeId(AUnionEnum) == Tid.Union);
483 assert(@typeId(AUnion) == Tid.Union);483 assert(@typeId(AUnion) == Tid.Union);
484 assert(@typeId(fn()) == Tid.Fn);484 assert(@typeId(fn()void) == Tid.Fn);
485 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);485 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
486 assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);486 assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);
487 // TODO bound fn487 // TODO bound fn
...@@ -536,7 +536,7 @@ var global_ptr = &gdt[0];...@@ -536,7 +536,7 @@ var global_ptr = &gdt[0];
536// can't really run this test but we can make sure it has no compile error536// can't really run this test but we can make sure it has no compile error
537// and generates code537// and generates code
538const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];538const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
539export fn writeToVRam() {539export fn writeToVRam() void {
540 vram[0] = 'X';540 vram[0] = 'X';
541}541}
542542
...@@ -556,7 +556,7 @@ test "variable is allowed to be a pointer to an opaque type" {...@@ -556,7 +556,7 @@ test "variable is allowed to be a pointer to an opaque type" {
556 var x: i32 = 1234;556 var x: i32 = 1234;
557 _ = hereIsAnOpaqueType(@ptrCast(&OpaqueA, &x));557 _ = hereIsAnOpaqueType(@ptrCast(&OpaqueA, &x));
558}558}
559fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {559fn hereIsAnOpaqueType(ptr: &OpaqueA) &OpaqueA {
560 var a = ptr;560 var a = ptr;
561 return a;561 return a;
562}562}
...@@ -565,7 +565,7 @@ test "comptime if inside runtime while which unconditionally breaks" {...@@ -565,7 +565,7 @@ test "comptime if inside runtime while which unconditionally breaks" {
565 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);565 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
566 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);566 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
567}567}
568fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) {568fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
569 while (cond) {569 while (cond) {
570 if (false) { }570 if (false) { }
571 break;571 break;
...@@ -583,7 +583,7 @@ test "struct inside function" {...@@ -583,7 +583,7 @@ test "struct inside function" {
583 comptime testStructInFn();583 comptime testStructInFn();
584}584}
585585
586fn testStructInFn() {586fn testStructInFn() void {
587 const BlockKind = u32;587 const BlockKind = u32;
588588
589 const Block = struct {589 const Block = struct {
...@@ -597,10 +597,10 @@ fn testStructInFn() {...@@ -597,10 +597,10 @@ fn testStructInFn() {
597 assert(block.kind == 1235);597 assert(block.kind == 1235);
598}598}
599599
600fn fnThatClosesOverLocalConst() -> type {600fn fnThatClosesOverLocalConst() type {
601 const c = 1;601 const c = 1;
602 return struct {602 return struct {
603 fn g() -> i32 { return c; }603 fn g() i32 { return c; }
604 };604 };
605}605}
606606
...@@ -608,3 +608,12 @@ test "function closes over local const" {...@@ -608,3 +608,12 @@ test "function closes over local const" {
608 const x = fnThatClosesOverLocalConst().g();608 const x = fnThatClosesOverLocalConst().g();
609 assert(x == 1);609 assert(x == 1);
610}610}
611
612test "cold function" {
613 thisIsAColdFn();
614 comptime thisIsAColdFn();
615}
616
617fn thisIsAColdFn() void {
618 @setCold(true);
619}
test/cases/null.zig+6-6
...@@ -48,14 +48,14 @@ test "maybe return" {...@@ -48,14 +48,14 @@ test "maybe return" {
48 comptime maybeReturnImpl();48 comptime maybeReturnImpl();
49}49}
5050
51fn maybeReturnImpl() {51fn maybeReturnImpl() void {
52 assert(??foo(1235));52 assert(??foo(1235));
53 if (foo(null) != null)53 if (foo(null) != null)
54 unreachable;54 unreachable;
55 assert(!??foo(1234));55 assert(!??foo(1234));
56}56}
5757
58fn foo(x: ?i32) -> ?bool {58fn foo(x: ?i32) ?bool {
59 const value = x ?? return null;59 const value = x ?? return null;
60 return value > 1234;60 return value > 1234;
61}61}
...@@ -64,7 +64,7 @@ fn foo(x: ?i32) -> ?bool {...@@ -64,7 +64,7 @@ fn foo(x: ?i32) -> ?bool {
64test "if var maybe pointer" {64test "if var maybe pointer" {
65 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);65 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
66}66}
67fn shouldBeAPlus1(p: &const Particle) -> u64 {67fn shouldBeAPlus1(p: &const Particle) u64 {
68 var maybe_particle: ?Particle = *p;68 var maybe_particle: ?Particle = *p;
69 if (maybe_particle) |*particle| {69 if (maybe_particle) |*particle| {
70 particle.a += 1;70 particle.a += 1;
...@@ -100,7 +100,7 @@ const here_is_a_null_literal = SillyStruct {...@@ -100,7 +100,7 @@ const here_is_a_null_literal = SillyStruct {
100test "test null runtime" {100test "test null runtime" {
101 testTestNullRuntime(null);101 testTestNullRuntime(null);
102}102}
103fn testTestNullRuntime(x: ?i32) {103fn testTestNullRuntime(x: ?i32) void {
104 assert(x == null);104 assert(x == null);
105 assert(!(x != null));105 assert(!(x != null));
106}106}
...@@ -110,12 +110,12 @@ test "nullable void" {...@@ -110,12 +110,12 @@ test "nullable void" {
110 comptime nullableVoidImpl();110 comptime nullableVoidImpl();
111}111}
112112
113fn nullableVoidImpl() {113fn nullableVoidImpl() void {
114 assert(bar(null) == null);114 assert(bar(null) == null);
115 assert(bar({}) != null);115 assert(bar({}) != null);
116}116}
117117
118fn bar(x: ?void) -> ?void {118fn bar(x: ?void) ?void {
119 if (x) |_| {119 if (x) |_| {
120 return {};120 return {};
121 } else {121 } else {
test/cases/pub_enum/index.zig+1-1
...@@ -4,7 +4,7 @@ const assert = @import("std").debug.assert;...@@ -4,7 +4,7 @@ const assert = @import("std").debug.assert;
4test "pub enum" {4test "pub enum" {
5 pubEnumTest(other.APubEnum.Two);5 pubEnumTest(other.APubEnum.Two);
6}6}
7fn pubEnumTest(foo: other.APubEnum) {7fn pubEnumTest(foo: other.APubEnum) void {
8 assert(foo == other.APubEnum.Two);8 assert(foo == other.APubEnum.Two);
9}9}
1010
test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig+2-2
...@@ -16,7 +16,7 @@ const Num = enum {...@@ -16,7 +16,7 @@ const Num = enum {
16 Two,16 Two,
17};17};
1818
19fn foo(c: bool, k: Num, c2: bool, b: []const u8) {19fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
20 switch (k) {20 switch (k) {
21 Num.Two => {},21 Num.Two => {},
22 Num.One => {22 Num.One => {
...@@ -31,7 +31,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) {...@@ -31,7 +31,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) {
31 }31 }
32}32}
3333
34fn a(x: []const u8) {34fn a(x: []const u8) void {
35 assert(mem.eql(u8, x, "aoeu"));35 assert(mem.eql(u8, x, "aoeu"));
36 ok = true;36 ok = true;
37}37}
test/cases/reflection.zig+2-2
...@@ -22,8 +22,8 @@ test "reflection: function return type, var args, and param types" {...@@ -22,8 +22,8 @@ test "reflection: function return type, var args, and param types" {
22 }22 }
23}23}
2424
25fn dummy(a: bool, b: i32, c: f32) -> i32 { return 1234; }25fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; }
26fn dummy_varargs(args: ...) {}26fn dummy_varargs(args: ...) void {}
2727
28test "reflection: struct member types and names" {28test "reflection: struct member types and names" {
29 comptime {29 comptime {
test/cases/slice.zig+3-3
...@@ -17,12 +17,12 @@ test "slice child property" {...@@ -17,12 +17,12 @@ test "slice child property" {
17 assert(@typeOf(slice).Child == i32);17 assert(@typeOf(slice).Child == i32);
18}18}
1919
20test "debug safety lets us slice from len..len" {20test "runtime safety lets us slice from len..len" {
21 var an_array = []u8{1, 2, 3};21 var an_array = []u8{1, 2, 3};
22 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));22 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
23}23}
2424
25fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) -> []u8 {25fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
26 return a_slice[start..end];26 return a_slice[start..end];
27}27}
2828
...@@ -31,6 +31,6 @@ test "implicitly cast array of size 0 to slice" {...@@ -31,6 +31,6 @@ test "implicitly cast array of size 0 to slice" {
31 assertLenIsZero(msg);31 assertLenIsZero(msg);
32}32}
3333
34fn assertLenIsZero(msg: []const u8) {34fn assertLenIsZero(msg: []const u8) void {
35 assert(msg.len == 0);35 assert(msg.len == 0);
36}36}
test/cases/struct.zig+17-17
...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4const StructWithNoFields = struct {4const StructWithNoFields = struct {
5 fn add(a: i32, b: i32) -> i32 { return a + b; }5 fn add(a: i32, b: i32) i32 { return a + b; }
6};6};
7const empty_global_instance = StructWithNoFields {};7const empty_global_instance = StructWithNoFields {};
88
...@@ -14,7 +14,7 @@ test "call struct static method" {...@@ -14,7 +14,7 @@ test "call struct static method" {
14test "return empty struct instance" {14test "return empty struct instance" {
15 _ = returnEmptyStructInstance();15 _ = returnEmptyStructInstance();
16}16}
17fn returnEmptyStructInstance() -> StructWithNoFields {17fn returnEmptyStructInstance() StructWithNoFields {
18 return empty_global_instance;18 return empty_global_instance;
19}19}
2020
...@@ -54,10 +54,10 @@ const StructFoo = struct {...@@ -54,10 +54,10 @@ const StructFoo = struct {
54 b : bool,54 b : bool,
55 c : f32,55 c : f32,
56};56};
57fn testFoo(foo: &const StructFoo) {57fn testFoo(foo: &const StructFoo) void {
58 assert(foo.b);58 assert(foo.b);
59}59}
60fn testMutation(foo: &StructFoo) {60fn testMutation(foo: &StructFoo) void {
61 foo.c = 100;61 foo.c = 100;
62}62}
6363
...@@ -95,7 +95,7 @@ test "struct byval assign" {...@@ -95,7 +95,7 @@ test "struct byval assign" {
95 assert(foo2.a == 1234);95 assert(foo2.a == 1234);
96}96}
9797
98fn structInitializer() {98fn structInitializer() void {
99 const val = Val { .x = 42 };99 const val = Val { .x = 42 };
100 assert(val.x == 42);100 assert(val.x == 42);
101}101}
...@@ -106,12 +106,12 @@ test "fn call of struct field" {...@@ -106,12 +106,12 @@ test "fn call of struct field" {
106}106}
107107
108const Foo = struct {108const Foo = struct {
109 ptr: fn() -> i32,109 ptr: fn() i32,
110};110};
111111
112fn aFunc() -> i32 { return 13; }112fn aFunc() i32 { return 13; }
113113
114fn callStructField(foo: &const Foo) -> i32 {114fn callStructField(foo: &const Foo) i32 {
115 return foo.ptr();115 return foo.ptr();
116}116}
117117
...@@ -124,7 +124,7 @@ test "store member function in variable" {...@@ -124,7 +124,7 @@ test "store member function in variable" {
124}124}
125const MemberFnTestFoo = struct {125const MemberFnTestFoo = struct {
126 x: i32,126 x: i32,
127 fn member(foo: &const MemberFnTestFoo) -> i32 { return foo.x; }127 fn member(foo: &const MemberFnTestFoo) i32 { return foo.x; }
128};128};
129129
130130
...@@ -140,7 +140,7 @@ test "member functions" {...@@ -140,7 +140,7 @@ test "member functions" {
140}140}
141const MemberFnRand = struct {141const MemberFnRand = struct {
142 seed: u32,142 seed: u32,
143 pub fn getSeed(r: &const MemberFnRand) -> u32 {143 pub fn getSeed(r: &const MemberFnRand) u32 {
144 return r.seed;144 return r.seed;
145 }145 }
146};146};
...@@ -153,7 +153,7 @@ const Bar = struct {...@@ -153,7 +153,7 @@ const Bar = struct {
153 x: i32,153 x: i32,
154 y: i32,154 y: i32,
155};155};
156fn makeBar(x: i32, y: i32) -> Bar {156fn makeBar(x: i32, y: i32) Bar {
157 return Bar {157 return Bar {
158 .x = x,158 .x = x,
159 .y = y,159 .y = y,
...@@ -165,7 +165,7 @@ test "empty struct method call" {...@@ -165,7 +165,7 @@ test "empty struct method call" {
165 assert(es.method() == 1234);165 assert(es.method() == 1234);
166}166}
167const EmptyStruct = struct {167const EmptyStruct = struct {
168 fn method(es: &const EmptyStruct) -> i32 {168 fn method(es: &const EmptyStruct) i32 {
169 return 1234;169 return 1234;
170 }170 }
171};171};
...@@ -175,14 +175,14 @@ test "return empty struct from fn" {...@@ -175,14 +175,14 @@ test "return empty struct from fn" {
175 _ = testReturnEmptyStructFromFn();175 _ = testReturnEmptyStructFromFn();
176}176}
177const EmptyStruct2 = struct {};177const EmptyStruct2 = struct {};
178fn testReturnEmptyStructFromFn() -> EmptyStruct2 {178fn testReturnEmptyStructFromFn() EmptyStruct2 {
179 return EmptyStruct2 {};179 return EmptyStruct2 {};
180}180}
181181
182test "pass slice of empty struct to fn" {182test "pass slice of empty struct to fn" {
183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
184}184}
185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) -> usize {185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
186 return slice.len;186 return slice.len;
187}187}
188188
...@@ -229,15 +229,15 @@ test "bit field access" {...@@ -229,15 +229,15 @@ test "bit field access" {
229 assert(data.b == 3);229 assert(data.b == 3);
230}230}
231231
232fn getA(data: &const BitField1) -> u3 {232fn getA(data: &const BitField1) u3 {
233 return data.a;233 return data.a;
234}234}
235235
236fn getB(data: &const BitField1) -> u3 {236fn getB(data: &const BitField1) u3 {
237 return data.b;237 return data.b;
238}238}
239239
240fn getC(data: &const BitField1) -> u2 {240fn getC(data: &const BitField1) u2 {
241 return data.c;241 return data.c;
242}242}
243243
test/cases/switch.zig+15-15
...@@ -4,7 +4,7 @@ test "switch with numbers" {...@@ -4,7 +4,7 @@ test "switch with numbers" {
4 testSwitchWithNumbers(13);4 testSwitchWithNumbers(13);
5}5}
66
7fn testSwitchWithNumbers(x: u32) {7fn testSwitchWithNumbers(x: u32) void {
8 const result = switch (x) {8 const result = switch (x) {
9 1, 2, 3, 4 ... 8 => false,9 1, 2, 3, 4 ... 8 => false,
10 13 => true,10 13 => true,
...@@ -20,7 +20,7 @@ test "switch with all ranges" {...@@ -20,7 +20,7 @@ test "switch with all ranges" {
20 assert(testSwitchWithAllRanges(301, 6) == 6);20 assert(testSwitchWithAllRanges(301, 6) == 6);
21}21}
2222
23fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 {23fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
24 return switch (x) {24 return switch (x) {
25 0 ... 100 => 1,25 0 ... 100 => 1,
26 101 ... 200 => 2,26 101 ... 200 => 2,
...@@ -53,7 +53,7 @@ const Fruit = enum {...@@ -53,7 +53,7 @@ const Fruit = enum {
53 Orange,53 Orange,
54 Banana,54 Banana,
55};55};
56fn nonConstSwitchOnEnum(fruit: Fruit) {56fn nonConstSwitchOnEnum(fruit: Fruit) void {
57 switch (fruit) {57 switch (fruit) {
58 Fruit.Apple => unreachable,58 Fruit.Apple => unreachable,
59 Fruit.Orange => {},59 Fruit.Orange => {},
...@@ -65,7 +65,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) {...@@ -65,7 +65,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) {
65test "switch statement" {65test "switch statement" {
66 nonConstSwitch(SwitchStatmentFoo.C);66 nonConstSwitch(SwitchStatmentFoo.C);
67}67}
68fn nonConstSwitch(foo: SwitchStatmentFoo) {68fn nonConstSwitch(foo: SwitchStatmentFoo) void {
69 const val = switch (foo) {69 const val = switch (foo) {
70 SwitchStatmentFoo.A => i32(1),70 SwitchStatmentFoo.A => i32(1),
71 SwitchStatmentFoo.B => 2,71 SwitchStatmentFoo.B => 2,
...@@ -92,7 +92,7 @@ const SwitchProngWithVarEnum = union(enum) {...@@ -92,7 +92,7 @@ const SwitchProngWithVarEnum = union(enum) {
92 Two: f32,92 Two: f32,
93 Meh: void,93 Meh: void,
94};94};
95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) {95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {
96 switch(*a) {96 switch(*a) {
97 SwitchProngWithVarEnum.One => |x| {97 SwitchProngWithVarEnum.One => |x| {
98 assert(x == 13);98 assert(x == 13);
...@@ -111,7 +111,7 @@ test "switch on enum using pointer capture" {...@@ -111,7 +111,7 @@ test "switch on enum using pointer capture" {
111 comptime testSwitchEnumPtrCapture();111 comptime testSwitchEnumPtrCapture();
112}112}
113113
114fn testSwitchEnumPtrCapture() {114fn testSwitchEnumPtrCapture() void {
115 var value = SwitchProngWithVarEnum { .One = 1234 };115 var value = SwitchProngWithVarEnum { .One = 1234 };
116 switch (value) {116 switch (value) {
117 SwitchProngWithVarEnum.One => |*x| *x += 1,117 SwitchProngWithVarEnum.One => |*x| *x += 1,
...@@ -131,7 +131,7 @@ test "switch with multiple expressions" {...@@ -131,7 +131,7 @@ test "switch with multiple expressions" {
131 };131 };
132 assert(x == 2);132 assert(x == 2);
133}133}
134fn returnsFive() -> i32 {134fn returnsFive() i32 {
135 return 5;135 return 5;
136}136}
137137
...@@ -144,7 +144,7 @@ const Number = union(enum) {...@@ -144,7 +144,7 @@ const Number = union(enum) {
144144
145const number = Number { .Three = 1.23 };145const number = Number { .Three = 1.23 };
146146
147fn returnsFalse() -> bool {147fn returnsFalse() bool {
148 switch (number) {148 switch (number) {
149 Number.One => |x| return x > 1234,149 Number.One => |x| return x > 1234,
150 Number.Two => |x| return x == 'a',150 Number.Two => |x| return x == 'a',
...@@ -160,7 +160,7 @@ test "switch on type" {...@@ -160,7 +160,7 @@ test "switch on type" {
160 assert(!trueIfBoolFalseOtherwise(i32));160 assert(!trueIfBoolFalseOtherwise(i32));
161}161}
162162
163fn trueIfBoolFalseOtherwise(comptime T: type) -> bool {163fn trueIfBoolFalseOtherwise(comptime T: type) bool {
164 return switch (T) {164 return switch (T) {
165 bool => true,165 bool => true,
166 else => false,166 else => false,
...@@ -172,7 +172,7 @@ test "switch handles all cases of number" {...@@ -172,7 +172,7 @@ test "switch handles all cases of number" {
172 comptime testSwitchHandleAllCases();172 comptime testSwitchHandleAllCases();
173}173}
174174
175fn testSwitchHandleAllCases() {175fn testSwitchHandleAllCases() void {
176 assert(testSwitchHandleAllCasesExhaustive(0) == 3);176 assert(testSwitchHandleAllCasesExhaustive(0) == 3);
177 assert(testSwitchHandleAllCasesExhaustive(1) == 2);177 assert(testSwitchHandleAllCasesExhaustive(1) == 2);
178 assert(testSwitchHandleAllCasesExhaustive(2) == 1);178 assert(testSwitchHandleAllCasesExhaustive(2) == 1);
...@@ -185,7 +185,7 @@ fn testSwitchHandleAllCases() {...@@ -185,7 +185,7 @@ fn testSwitchHandleAllCases() {
185 assert(testSwitchHandleAllCasesRange(230) == 3);185 assert(testSwitchHandleAllCasesRange(230) == 3);
186}186}
187187
188fn testSwitchHandleAllCasesExhaustive(x: u2) -> u2 {188fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
189 return switch (x) {189 return switch (x) {
190 0 => u2(3),190 0 => u2(3),
191 1 => 2,191 1 => 2,
...@@ -194,7 +194,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) -> u2 {...@@ -194,7 +194,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) -> u2 {
194 };194 };
195}195}
196196
197fn testSwitchHandleAllCasesRange(x: u8) -> u8 {197fn testSwitchHandleAllCasesRange(x: u8) u8 {
198 return switch (x) {198 return switch (x) {
199 0 ... 100 => u8(0),199 0 ... 100 => u8(0),
200 101 ... 200 => 1,200 101 ... 200 => 1,
...@@ -209,12 +209,12 @@ test "switch all prongs unreachable" {...@@ -209,12 +209,12 @@ test "switch all prongs unreachable" {
209 comptime testAllProngsUnreachable();209 comptime testAllProngsUnreachable();
210}210}
211211
212fn testAllProngsUnreachable() {212fn testAllProngsUnreachable() void {
213 assert(switchWithUnreachable(1) == 2);213 assert(switchWithUnreachable(1) == 2);
214 assert(switchWithUnreachable(2) == 10);214 assert(switchWithUnreachable(2) == 10);
215}215}
216216
217fn switchWithUnreachable(x: i32) -> i32 {217fn switchWithUnreachable(x: i32) i32 {
218 while (true) {218 while (true) {
219 switch (x) {219 switch (x) {
220 1 => return 2,220 1 => return 2,
...@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) -> i32 {...@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) -> i32 {
225 return 10;225 return 10;
226}226}
227227
228fn return_a_number() -> %i32 {228fn return_a_number() %i32 {
229 return 1;229 return 1;
230}230}
231231
test/cases/switch_prong_err_enum.zig+2-2
...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;...@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22
3var read_count: u64 = 0;3var read_count: u64 = 0;
44
5fn readOnce() -> %u64 {5fn readOnce() %u64 {
6 read_count += 1;6 read_count += 1;
7 return read_count;7 return read_count;
8}8}
...@@ -14,7 +14,7 @@ const FormValue = union(enum) {...@@ -14,7 +14,7 @@ const FormValue = union(enum) {
14 Other: bool,14 Other: bool,
15};15};
1616
17fn doThing(form_id: u64) -> %FormValue {17fn doThing(form_id: u64) %FormValue {
18 return switch (form_id) {18 return switch (form_id) {
19 17 => FormValue { .Address = try readOnce() },19 17 => FormValue { .Address = try readOnce() },
20 else => error.InvalidDebugInfo,20 else => error.InvalidDebugInfo,
test/cases/switch_prong_implicit_cast.zig+1-1
...@@ -7,7 +7,7 @@ const FormValue = union(enum) {...@@ -7,7 +7,7 @@ const FormValue = union(enum) {
77
8error Whatever;8error Whatever;
99
10fn foo(id: u64) -> %FormValue {10fn foo(id: u64) %FormValue {
11 return switch (id) {11 return switch (id) {
12 2 => FormValue { .Two = true },12 2 => FormValue { .Two = true },
13 1 => FormValue { .One = {} },13 1 => FormValue { .One = {} },
test/cases/syntax.zig+11-11
...@@ -3,18 +3,18 @@...@@ -3,18 +3,18 @@
3const struct_trailing_comma = struct { x: i32, y: i32, };3const struct_trailing_comma = struct { x: i32, y: i32, };
4const struct_no_comma = struct { x: i32, y: i32 };4const struct_no_comma = struct { x: i32, y: i32 };
5const struct_no_comma_void_type = struct { x: i32, y };5const struct_no_comma_void_type = struct { x: i32, y };
6const struct_fn_no_comma = struct { fn m() {} y: i32 };6const struct_fn_no_comma = struct { fn m() void {} y: i32 };
77
8const enum_no_comma = enum { A, B };8const enum_no_comma = enum { A, B };
9const enum_no_comma_type = enum { A, B: i32 };9const enum_no_comma_type = enum { A, B: i32 };
1010
11fn container_init() {11fn container_init() void {
12 const S = struct { x: i32, y: i32 };12 const S = struct { x: i32, y: i32 };
13 _ = S { .x = 1, .y = 2 };13 _ = S { .x = 1, .y = 2 };
14 _ = S { .x = 1, .y = 2, };14 _ = S { .x = 1, .y = 2, };
15}15}
1616
17fn switch_cases(x: i32) {17fn switch_cases(x: i32) void {
18 switch (x) {18 switch (x) {
19 1,2,3 => {},19 1,2,3 => {},
20 4,5, => {},20 4,5, => {},
...@@ -23,7 +23,7 @@ fn switch_cases(x: i32) {...@@ -23,7 +23,7 @@ fn switch_cases(x: i32) {
23 }23 }
24}24}
2525
26fn switch_prongs(x: i32) {26fn switch_prongs(x: i32) void {
27 switch (x) {27 switch (x) {
28 0 => {},28 0 => {},
29 else => {},29 else => {},
...@@ -34,21 +34,21 @@ fn switch_prongs(x: i32) {...@@ -34,21 +34,21 @@ fn switch_prongs(x: i32) {
34 }34 }
35}35}
3636
37const fn_no_comma = fn(i32, i32);37const fn_no_comma = fn(i32, i32)void;
38const fn_trailing_comma = fn(i32, i32,);38const fn_trailing_comma = fn(i32, i32,)void;
39const fn_vararg_trailing_comma = fn(i32, i32, ...,);39const fn_vararg_trailing_comma = fn(i32, i32, ...,)void;
4040
41fn fn_calls() {41fn fn_calls() void {
42 fn add(x: i32, y: i32,) -> i32 { x + y };42 fn add(x: i32, y: i32,) i32 { x + y };
43 _ = add(1, 2);43 _ = add(1, 2);
44 _ = add(1, 2,);44 _ = add(1, 2,);
4545
46 fn swallow(x: ...,) {};46 fn swallow(x: ...,) void {};
47 _ = swallow(1,2,3,);47 _ = swallow(1,2,3,);
48 _ = swallow();48 _ = swallow();
49}49}
5050
51fn asm_lists() {51fn asm_lists() void {
52 if (false) { // Build AST but don't analyze52 if (false) { // Build AST but don't analyze
53 asm ("not real assembly"53 asm ("not real assembly"
54 :[a] "x" (x),);54 :[a] "x" (x),);
test/cases/this.zig+4-4
...@@ -2,24 +2,24 @@ const assert = @import("std").debug.assert;...@@ -2,24 +2,24 @@ const assert = @import("std").debug.assert;
22
3const module = this;3const module = this;
44
5fn Point(comptime T: type) -> type {5fn Point(comptime T: type) type {
6 return struct {6 return struct {
7 const Self = this;7 const Self = this;
8 x: T,8 x: T,
9 y: T,9 y: T,
1010
11 fn addOne(self: &Self) {11 fn addOne(self: &Self) void {
12 self.x += 1;12 self.x += 1;
13 self.y += 1;13 self.y += 1;
14 }14 }
15 };15 };
16}16}
1717
18fn add(x: i32, y: i32) -> i32 {18fn add(x: i32, y: i32) i32 {
19 return x + y;19 return x + y;
20}20}
2121
22fn factorial(x: i32) -> i32 {22fn factorial(x: i32) i32 {
23 const selfFn = this;23 const selfFn = this;
24 return if (x == 0) 1 else x * selfFn(x - 1);24 return if (x == 0) 1 else x * selfFn(x - 1);
25}25}
test/cases/try.zig+3-3
...@@ -6,7 +6,7 @@ test "try on error union" {...@@ -6,7 +6,7 @@ test "try on error union" {
66
7}7}
88
9fn tryOnErrorUnionImpl() {9fn tryOnErrorUnionImpl() void {
10 const x = if (returnsTen()) |val|10 const x = if (returnsTen()) |val|
11 val + 111 val + 1
12 else |err| switch (err) {12 else |err| switch (err) {
...@@ -20,7 +20,7 @@ fn tryOnErrorUnionImpl() {...@@ -20,7 +20,7 @@ fn tryOnErrorUnionImpl() {
20error ItBroke;20error ItBroke;
21error NoMem;21error NoMem;
22error CrappedOut;22error CrappedOut;
23fn returnsTen() -> %i32 {23fn returnsTen() %i32 {
24 return 10;24 return 10;
25}25}
2626
...@@ -32,7 +32,7 @@ test "try without vars" {...@@ -32,7 +32,7 @@ test "try without vars" {
32 assert(result2 == 1);32 assert(result2 == 1);
33}33}
3434
35fn failIfTrue(ok: bool) -> %void {35fn failIfTrue(ok: bool) %void {
36 if (ok) {36 if (ok) {
37 return error.ItBroke;37 return error.ItBroke;
38 } else {38 } else {
test/cases/undefined.zig+3-3
...@@ -1,7 +1,7 @@...@@ -1,7 +1,7 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
2const mem = @import("std").mem;2const mem = @import("std").mem;
33
4fn initStaticArray() -> [10]i32 {4fn initStaticArray() [10]i32 {
5 var array: [10]i32 = undefined;5 var array: [10]i32 = undefined;
6 array[0] = 1;6 array[0] = 1;
7 array[4] = 2;7 array[4] = 2;
...@@ -27,12 +27,12 @@ test "init static array to undefined" {...@@ -27,12 +27,12 @@ test "init static array to undefined" {
27const Foo = struct {27const Foo = struct {
28 x: i32,28 x: i32,
2929
30 fn setFooXMethod(foo: &Foo) {30 fn setFooXMethod(foo: &Foo) void {
31 foo.x = 3;31 foo.x = 3;
32 }32 }
33};33};
3434
35fn setFooX(foo: &Foo) {35fn setFooX(foo: &Foo) void {
36 foo.x = 2;36 foo.x = 2;
37}37}
3838
test/cases/union.zig+36-9
...@@ -55,11 +55,11 @@ test "init union with runtime value" {...@@ -55,11 +55,11 @@ test "init union with runtime value" {
55 assert(foo.int == 42);55 assert(foo.int == 42);
56}56}
5757
58fn setFloat(foo: &Foo, x: f64) {58fn setFloat(foo: &Foo, x: f64) void {
59 *foo = Foo { .float = x };59 *foo = Foo { .float = x };
60}60}
6161
62fn setInt(foo: &Foo, x: i32) {62fn setInt(foo: &Foo, x: i32) void {
63 *foo = Foo { .int = x };63 *foo = Foo { .int = x };
64}64}
6565
...@@ -92,11 +92,11 @@ test "union with specified enum tag" {...@@ -92,11 +92,11 @@ test "union with specified enum tag" {
92 comptime doTest();92 comptime doTest();
93}93}
9494
95fn doTest() {95fn doTest() void {
96 assert(bar(Payload {.A = 1234}) == -10);96 assert(bar(Payload {.A = 1234}) == -10);
97}97}
9898
99fn bar(value: &const Payload) -> i32 {99fn bar(value: &const Payload) i32 {
100 assert(Letter(*value) == Letter.A);100 assert(Letter(*value) == Letter.A);
101 return switch (*value) {101 return switch (*value) {
102 Payload.A => |x| return x - 1244,102 Payload.A => |x| return x - 1244,
...@@ -135,7 +135,7 @@ test "union(enum(u32)) with specified and unspecified tag values" {...@@ -135,7 +135,7 @@ test "union(enum(u32)) with specified and unspecified tag values" {
135 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );135 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );
136}136}
137137
138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) {138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {
139 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);139 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);
140 assert(1123 == switch (*x) {140 assert(1123 == switch (*x) {
141 MultipleChoice2.A => 1,141 MultipleChoice2.A => 1,
...@@ -187,7 +187,7 @@ test "cast union to tag type of union" {...@@ -187,7 +187,7 @@ test "cast union to tag type of union" {
187 comptime testCastUnionToTagType(TheUnion {.B = 1234});187 comptime testCastUnionToTagType(TheUnion {.B = 1234});
188}188}
189189
190fn testCastUnionToTagType(x: &const TheUnion) {190fn testCastUnionToTagType(x: &const TheUnion) void {
191 assert(TheTag(*x) == TheTag.B);191 assert(TheTag(*x) == TheTag.B);
192}192}
193193
...@@ -203,7 +203,7 @@ test "implicit cast union to its tag type" {...@@ -203,7 +203,7 @@ test "implicit cast union to its tag type" {
203 assert(x == Letter2.B);203 assert(x == Letter2.B);
204 giveMeLetterB(x);204 giveMeLetterB(x);
205}205}
206fn giveMeLetterB(x: Letter2) {206fn giveMeLetterB(x: Letter2) void {
207 assert(x == Value2.B);207 assert(x == Value2.B);
208}208}
209209
...@@ -216,7 +216,7 @@ const TheUnion2 = union(enum) {...@@ -216,7 +216,7 @@ const TheUnion2 = union(enum) {
216 Item2: i32,216 Item2: i32,
217};217};
218218
219fn assertIsTheUnion2Item1(value: &const TheUnion2) {219fn assertIsTheUnion2Item1(value: &const TheUnion2) void {
220 assert(*value == TheUnion2.Item1);220 assert(*value == TheUnion2.Item1);
221}221}
222222
...@@ -232,6 +232,33 @@ test "constant packed union" {...@@ -232,6 +232,33 @@ test "constant packed union" {
232 });232 });
233}233}
234234
235fn testConstPackedUnion(expected_tokens: []const PackThis) {235fn testConstPackedUnion(expected_tokens: []const PackThis) void {
236 assert(expected_tokens[0].StringLiteral == 1);236 assert(expected_tokens[0].StringLiteral == 1);
237}237}
238
239test "switch on union with only 1 field" {
240 var r: PartialInst = undefined;
241 r = PartialInst.Compiled;
242 switch (r) {
243 PartialInst.Compiled => {
244 var z: PartialInstWithPayload = undefined;
245 z = PartialInstWithPayload { .Compiled = 1234 };
246 switch (z) {
247 PartialInstWithPayload.Compiled => |x| {
248 assert(x == 1234);
249 return;
250 },
251 }
252 },
253 }
254 unreachable;
255}
256
257const PartialInst = union(enum) {
258 Compiled,
259};
260
261const PartialInstWithPayload = union(enum) {
262 Compiled: i32,
263};
264
test/cases/var_args.zig+16-8
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const assert = @import("std").debug.assert;1const assert = @import("std").debug.assert;
22
3fn add(args: ...) -> i32 {3fn add(args: ...) i32 {
4 var sum = i32(0);4 var sum = i32(0);
5 {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {5 {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
6 sum += args[i];6 sum += args[i];
...@@ -14,7 +14,7 @@ test "add arbitrary args" {...@@ -14,7 +14,7 @@ test "add arbitrary args" {
14 assert(add() == 0);14 assert(add() == 0);
15}15}
1616
17fn readFirstVarArg(args: ...) {17fn readFirstVarArg(args: ...) void {
18 const value = args[0];18 const value = args[0];
19}19}
2020
...@@ -28,7 +28,7 @@ test "pass args directly" {...@@ -28,7 +28,7 @@ test "pass args directly" {
28 assert(addSomeStuff() == 0);28 assert(addSomeStuff() == 0);
29}29}
3030
31fn addSomeStuff(args: ...) -> i32 {31fn addSomeStuff(args: ...) i32 {
32 return add(args);32 return add(args);
33}33}
3434
...@@ -45,7 +45,7 @@ test "runtime parameter before var args" {...@@ -45,7 +45,7 @@ test "runtime parameter before var args" {
45 //}45 //}
46}46}
4747
48fn extraFn(extra: u32, args: ...) -> usize {48fn extraFn(extra: u32, args: ...) usize {
49 if (args.len >= 1) {49 if (args.len >= 1) {
50 assert(args[0] == false);50 assert(args[0] == false);
51 }51 }
...@@ -56,10 +56,10 @@ fn extraFn(extra: u32, args: ...) -> usize {...@@ -56,10 +56,10 @@ fn extraFn(extra: u32, args: ...) -> usize {
56}56}
5757
5858
59const foos = []fn(...) -> bool { foo1, foo2 };59const foos = []fn(...) bool { foo1, foo2 };
6060
61fn foo1(args: ...) -> bool { return true; }61fn foo1(args: ...) bool { return true; }
62fn foo2(args: ...) -> bool { return false; }62fn foo2(args: ...) bool { return false; }
6363
64test "array of var args functions" {64test "array of var args functions" {
65 assert(foos[0]());65 assert(foos[0]());
...@@ -73,9 +73,17 @@ test "pass array and slice of same array to var args should have same pointers"...@@ -73,9 +73,17 @@ test "pass array and slice of same array to var args should have same pointers"
73 return assertSlicePtrsEql(array, slice);73 return assertSlicePtrsEql(array, slice);
74}74}
7575
76fn assertSlicePtrsEql(args: ...) {76fn assertSlicePtrsEql(args: ...) void {
77 const s1 = ([]const u8)(args[0]);77 const s1 = ([]const u8)(args[0]);
78 const s2 = args[1];78 const s2 = args[1];
79 assert(s1.ptr == s2.ptr);79 assert(s1.ptr == s2.ptr);
80}80}
8181
82
83test "pass zero length array to var args param" {
84 doNothingWithFirstArg("");
85}
86
87fn doNothingWithFirstArg(args: ...) void {
88 const a = args[0];
89}
test/cases/while.zig+16-16
...@@ -8,10 +8,10 @@ test "while loop" {...@@ -8,10 +8,10 @@ test "while loop" {
8 assert(i == 4);8 assert(i == 4);
9 assert(whileLoop1() == 1);9 assert(whileLoop1() == 1);
10}10}
11fn whileLoop1() -> i32 {11fn whileLoop1() i32 {
12 return whileLoop2();12 return whileLoop2();
13}13}
14fn whileLoop2() -> i32 {14fn whileLoop2() i32 {
15 while (true) {15 while (true) {
16 return 1;16 return 1;
17 }17 }
...@@ -20,10 +20,10 @@ test "static eval while" {...@@ -20,10 +20,10 @@ test "static eval while" {
20 assert(static_eval_while_number == 1);20 assert(static_eval_while_number == 1);
21}21}
22const static_eval_while_number = staticWhileLoop1();22const static_eval_while_number = staticWhileLoop1();
23fn staticWhileLoop1() -> i32 {23fn staticWhileLoop1() i32 {
24 return whileLoop2();24 return whileLoop2();
25}25}
26fn staticWhileLoop2() -> i32 {26fn staticWhileLoop2() i32 {
27 while (true) {27 while (true) {
28 return 1;28 return 1;
29 }29 }
...@@ -34,7 +34,7 @@ test "continue and break" {...@@ -34,7 +34,7 @@ test "continue and break" {
34 assert(continue_and_break_counter == 8);34 assert(continue_and_break_counter == 8);
35}35}
36var continue_and_break_counter: i32 = 0;36var continue_and_break_counter: i32 = 0;
37fn runContinueAndBreakTest() {37fn runContinueAndBreakTest() void {
38 var i : i32 = 0;38 var i : i32 = 0;
39 while (true) {39 while (true) {
40 continue_and_break_counter += 2;40 continue_and_break_counter += 2;
...@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() {...@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() {
50test "return with implicit cast from while loop" {50test "return with implicit cast from while loop" {
51 returnWithImplicitCastFromWhileLoopTest() catch unreachable;51 returnWithImplicitCastFromWhileLoopTest() catch unreachable;
52}52}
53fn returnWithImplicitCastFromWhileLoopTest() -> %void {53fn returnWithImplicitCastFromWhileLoopTest() %void {
54 while (true) {54 while (true) {
55 return;55 return;
56 }56 }
...@@ -117,7 +117,7 @@ test "while with error union condition" {...@@ -117,7 +117,7 @@ test "while with error union condition" {
117117
118var numbers_left: i32 = undefined;118var numbers_left: i32 = undefined;
119error OutOfNumbers;119error OutOfNumbers;
120fn getNumberOrErr() -> %i32 {120fn getNumberOrErr() %i32 {
121 return if (numbers_left == 0)121 return if (numbers_left == 0)
122 error.OutOfNumbers122 error.OutOfNumbers
123 else x: {123 else x: {
...@@ -125,7 +125,7 @@ fn getNumberOrErr() -> %i32 {...@@ -125,7 +125,7 @@ fn getNumberOrErr() -> %i32 {
125 break :x numbers_left;125 break :x numbers_left;
126 };126 };
127}127}
128fn getNumberOrNull() -> ?i32 {128fn getNumberOrNull() ?i32 {
129 return if (numbers_left == 0)129 return if (numbers_left == 0)
130 null130 null
131 else x: {131 else x: {
...@@ -181,7 +181,7 @@ test "break from outer while loop" {...@@ -181,7 +181,7 @@ test "break from outer while loop" {
181 comptime testBreakOuter();181 comptime testBreakOuter();
182}182}
183183
184fn testBreakOuter() {184fn testBreakOuter() void {
185 outer: while (true) {185 outer: while (true) {
186 while (true) {186 while (true) {
187 break :outer;187 break :outer;
...@@ -194,7 +194,7 @@ test "continue outer while loop" {...@@ -194,7 +194,7 @@ test "continue outer while loop" {
194 comptime testContinueOuter();194 comptime testContinueOuter();
195}195}
196196
197fn testContinueOuter() {197fn testContinueOuter() void {
198 var i: usize = 0;198 var i: usize = 0;
199 outer: while (i < 10) : (i += 1) {199 outer: while (i < 10) : (i += 1) {
200 while (true) {200 while (true) {
...@@ -203,10 +203,10 @@ fn testContinueOuter() {...@@ -203,10 +203,10 @@ fn testContinueOuter() {
203 }203 }
204}204}
205205
206fn returnNull() -> ?i32 { return null; }206fn returnNull() ?i32 { return null; }
207fn returnMaybe(x: i32) -> ?i32 { return x; }207fn returnMaybe(x: i32) ?i32 { return x; }
208error YouWantedAnError;208error YouWantedAnError;
209fn returnError() -> %i32 { return error.YouWantedAnError; }209fn returnError() %i32 { return error.YouWantedAnError; }
210fn returnSuccess(x: i32) -> %i32 { return x; }210fn returnSuccess(x: i32) %i32 { return x; }
211fn returnFalse() -> bool { return false; }211fn returnFalse() bool { return false; }
212fn returnTrue() -> bool { return true; }212fn returnTrue() bool { return true; }
test/compare_output.zig+37-37
...@@ -1,10 +1,10 @@...@@ -1,10 +1,10 @@
1const os = @import("std").os;1const os = @import("std").os;
2const tests = @import("tests.zig");2const tests = @import("tests.zig");
33
4pub fn addCases(cases: &tests.CompareOutputContext) {4pub fn addCases(cases: &tests.CompareOutputContext) void {
5 cases.addC("hello world with libc",5 cases.addC("hello world with libc",
6 \\const c = @cImport(@cInclude("stdio.h"));6 \\const c = @cImport(@cInclude("stdio.h"));
7 \\export fn main(argc: c_int, argv: &&u8) -> c_int {7 \\export fn main(argc: c_int, argv: &&u8) c_int {
8 \\ _ = c.puts(c"Hello, world!");8 \\ _ = c.puts(c"Hello, world!");
9 \\ return 0;9 \\ return 0;
10 \\}10 \\}
...@@ -15,13 +15,13 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -15,13 +15,13 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
15 \\use @import("std").io;15 \\use @import("std").io;
16 \\use @import("foo.zig");16 \\use @import("foo.zig");
17 \\17 \\
18 \\pub fn main() -> %void {18 \\pub fn main() %void {
19 \\ privateFunction();19 \\ privateFunction();
20 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);20 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
21 \\ stdout.print("OK 2\n") catch unreachable;21 \\ stdout.print("OK 2\n") catch unreachable;
22 \\}22 \\}
23 \\23 \\
24 \\fn privateFunction() {24 \\fn privateFunction() void {
25 \\ printText();25 \\ printText();
26 \\}26 \\}
27 , "OK 1\nOK 2\n");27 , "OK 1\nOK 2\n");
...@@ -31,12 +31,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -31,12 +31,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
31 \\31 \\
32 \\// purposefully conflicting function with main.zig32 \\// purposefully conflicting function with main.zig
33 \\// but it's private so it should be OK33 \\// but it's private so it should be OK
34 \\fn privateFunction() {34 \\fn privateFunction() void {
35 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);35 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
36 \\ stdout.print("OK 1\n") catch unreachable;36 \\ stdout.print("OK 1\n") catch unreachable;
37 \\}37 \\}
38 \\38 \\
39 \\pub fn printText() {39 \\pub fn printText() void {
40 \\ privateFunction();40 \\ privateFunction();
41 \\}41 \\}
42 );42 );
...@@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
49 \\use @import("foo.zig");49 \\use @import("foo.zig");
50 \\use @import("bar.zig");50 \\use @import("bar.zig");
51 \\51 \\
52 \\pub fn main() -> %void {52 \\pub fn main() %void {
53 \\ foo_function();53 \\ foo_function();
54 \\ bar_function();54 \\ bar_function();
55 \\}55 \\}
...@@ -57,7 +57,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -57,7 +57,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
5757
58 tc.addSourceFile("foo.zig",58 tc.addSourceFile("foo.zig",
59 \\use @import("std").io;59 \\use @import("std").io;
60 \\pub fn foo_function() {60 \\pub fn foo_function() void {
61 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);61 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
62 \\ stdout.print("OK\n") catch unreachable;62 \\ stdout.print("OK\n") catch unreachable;
63 \\}63 \\}
...@@ -67,7 +67,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -67,7 +67,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
67 \\use @import("other.zig");67 \\use @import("other.zig");
68 \\use @import("std").io;68 \\use @import("std").io;
69 \\69 \\
70 \\pub fn bar_function() {70 \\pub fn bar_function() void {
71 \\ if (foo_function()) {71 \\ if (foo_function()) {
72 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);72 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
73 \\ stdout.print("OK\n") catch unreachable;73 \\ stdout.print("OK\n") catch unreachable;
...@@ -76,7 +76,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -76,7 +76,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
76 );76 );
7777
78 tc.addSourceFile("other.zig",78 tc.addSourceFile("other.zig",
79 \\pub fn foo_function() -> bool {79 \\pub fn foo_function() bool {
80 \\ // this one conflicts with the one from foo80 \\ // this one conflicts with the one from foo
81 \\ return true;81 \\ return true;
82 \\}82 \\}
...@@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
89 var tc = cases.create("two files use import each other",89 var tc = cases.create("two files use import each other",
90 \\use @import("a.zig");90 \\use @import("a.zig");
91 \\91 \\
92 \\pub fn main() -> %void {92 \\pub fn main() %void {
93 \\ ok();93 \\ ok();
94 \\}94 \\}
95 , "OK\n");95 , "OK\n");
...@@ -100,7 +100,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -100,7 +100,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
100 \\100 \\
101 \\pub const a_text = "OK\n";101 \\pub const a_text = "OK\n";
102 \\102 \\
103 \\pub fn ok() {103 \\pub fn ok() void {
104 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);104 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
105 \\ stdout.print(b_text) catch unreachable;105 \\ stdout.print(b_text) catch unreachable;
106 \\}106 \\}
...@@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
118 cases.add("hello world without libc",118 cases.add("hello world without libc",
119 \\const io = @import("std").io;119 \\const io = @import("std").io;
120 \\120 \\
121 \\pub fn main() -> %void {121 \\pub fn main() %void {
122 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);122 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
123 \\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;123 \\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
124 \\}124 \\}
...@@ -137,7 +137,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -137,7 +137,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
137 \\ @cInclude("stdio.h");137 \\ @cInclude("stdio.h");
138 \\});138 \\});
139 \\139 \\
140 \\export fn main(argc: c_int, argv: &&u8) -> c_int {140 \\export fn main(argc: c_int, argv: &&u8) c_int {
141 \\ if (is_windows) {141 \\ if (is_windows) {
142 \\ // we want actual \n, not \r\n142 \\ // we want actual \n, not \r\n
143 \\ _ = c._setmode(1, c._O_BINARY);143 \\ _ = c._setmode(1, c._O_BINARY);
...@@ -268,10 +268,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -268,10 +268,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
268 \\const z = io.stdin_fileno;268 \\const z = io.stdin_fileno;
269 \\const x : @typeOf(y) = 1234;269 \\const x : @typeOf(y) = 1234;
270 \\const y : u16 = 5678;270 \\const y : u16 = 5678;
271 \\pub fn main() -> %void {271 \\pub fn main() %void {
272 \\ var x_local : i32 = print_ok(x);272 \\ var x_local : i32 = print_ok(x);
273 \\}273 \\}
274 \\fn print_ok(val: @typeOf(x)) -> @typeOf(foo) {274 \\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
275 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);275 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
276 \\ stdout.print("OK\n") catch unreachable;276 \\ stdout.print("OK\n") catch unreachable;
277 \\ return 0;277 \\ return 0;
...@@ -282,7 +282,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -282,7 +282,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
282 cases.addC("expose function pointer to C land",282 cases.addC("expose function pointer to C land",
283 \\const c = @cImport(@cInclude("stdlib.h"));283 \\const c = @cImport(@cInclude("stdlib.h"));
284 \\284 \\
285 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) -> c_int {285 \\export fn compare_fn(a: ?&const c_void, b: ?&const c_void) c_int {
286 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);286 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
287 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);287 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
288 \\ if (*a_int < *b_int) {288 \\ if (*a_int < *b_int) {
...@@ -294,7 +294,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -294,7 +294,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
294 \\ }294 \\ }
295 \\}295 \\}
296 \\296 \\
297 \\export fn main() -> c_int {297 \\export fn main() c_int {
298 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };298 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
299 \\299 \\
300 \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);300 \\ c.qsort(@ptrCast(&c_void, &array[0]), c_ulong(array.len), @sizeOf(i32), compare_fn);
...@@ -322,7 +322,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -322,7 +322,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
322 \\ @cInclude("stdio.h");322 \\ @cInclude("stdio.h");
323 \\});323 \\});
324 \\324 \\
325 \\export fn main(argc: c_int, argv: &&u8) -> c_int {325 \\export fn main(argc: c_int, argv: &&u8) c_int {
326 \\ if (is_windows) {326 \\ if (is_windows) {
327 \\ // we want actual \n, not \r\n327 \\ // we want actual \n, not \r\n
328 \\ _ = c._setmode(1, c._O_BINARY);328 \\ _ = c._setmode(1, c._O_BINARY);
...@@ -342,16 +342,16 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -342,16 +342,16 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
342 \\const Foo = struct {342 \\const Foo = struct {
343 \\ field1: Bar,343 \\ field1: Bar,
344 \\344 \\
345 \\ fn method(a: &const Foo) -> bool { return true; }345 \\ fn method(a: &const Foo) bool { return true; }
346 \\};346 \\};
347 \\347 \\
348 \\const Bar = struct {348 \\const Bar = struct {
349 \\ field2: i32,349 \\ field2: i32,
350 \\350 \\
351 \\ fn method(b: &const Bar) -> bool { return true; }351 \\ fn method(b: &const Bar) bool { return true; }
352 \\};352 \\};
353 \\353 \\
354 \\pub fn main() -> %void {354 \\pub fn main() %void {
355 \\ const bar = Bar {.field2 = 13,};355 \\ const bar = Bar {.field2 = 13,};
356 \\ const foo = Foo {.field1 = bar,};356 \\ const foo = Foo {.field1 = bar,};
357 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);357 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
367367
368 cases.add("defer with only fallthrough",368 cases.add("defer with only fallthrough",
369 \\const io = @import("std").io;369 \\const io = @import("std").io;
370 \\pub fn main() -> %void {370 \\pub fn main() %void {
371 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);371 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
372 \\ stdout.print("before\n") catch unreachable;372 \\ stdout.print("before\n") catch unreachable;
373 \\ defer stdout.print("defer1\n") catch unreachable;373 \\ defer stdout.print("defer1\n") catch unreachable;
...@@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
380 cases.add("defer with return",380 cases.add("defer with return",
381 \\const io = @import("std").io;381 \\const io = @import("std").io;
382 \\const os = @import("std").os;382 \\const os = @import("std").os;
383 \\pub fn main() -> %void {383 \\pub fn main() %void {
384 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);384 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
385 \\ stdout.print("before\n") catch unreachable;385 \\ stdout.print("before\n") catch unreachable;
386 \\ defer stdout.print("defer1\n") catch unreachable;386 \\ defer stdout.print("defer1\n") catch unreachable;
...@@ -392,41 +392,41 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -392,41 +392,41 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
392 \\}392 \\}
393 , "before\ndefer2\ndefer1\n");393 , "before\ndefer2\ndefer1\n");
394394
395 cases.add("%defer and it fails",395 cases.add("errdefer and it fails",
396 \\const io = @import("std").io;396 \\const io = @import("std").io;
397 \\pub fn main() -> %void {397 \\pub fn main() %void {
398 \\ do_test() catch return;398 \\ do_test() catch return;
399 \\}399 \\}
400 \\fn do_test() -> %void {400 \\fn do_test() %void {
401 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);401 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
402 \\ stdout.print("before\n") catch unreachable;402 \\ stdout.print("before\n") catch unreachable;
403 \\ defer stdout.print("defer1\n") catch unreachable;403 \\ defer stdout.print("defer1\n") catch unreachable;
404 \\ %defer stdout.print("deferErr\n") catch unreachable;404 \\ errdefer stdout.print("deferErr\n") catch unreachable;
405 \\ try its_gonna_fail();405 \\ try its_gonna_fail();
406 \\ defer stdout.print("defer3\n") catch unreachable;406 \\ defer stdout.print("defer3\n") catch unreachable;
407 \\ stdout.print("after\n") catch unreachable;407 \\ stdout.print("after\n") catch unreachable;
408 \\}408 \\}
409 \\error IToldYouItWouldFail;409 \\error IToldYouItWouldFail;
410 \\fn its_gonna_fail() -> %void {410 \\fn its_gonna_fail() %void {
411 \\ return error.IToldYouItWouldFail;411 \\ return error.IToldYouItWouldFail;
412 \\}412 \\}
413 , "before\ndeferErr\ndefer1\n");413 , "before\ndeferErr\ndefer1\n");
414414
415 cases.add("%defer and it passes",415 cases.add("errdefer and it passes",
416 \\const io = @import("std").io;416 \\const io = @import("std").io;
417 \\pub fn main() -> %void {417 \\pub fn main() %void {
418 \\ do_test() catch return;418 \\ do_test() catch return;
419 \\}419 \\}
420 \\fn do_test() -> %void {420 \\fn do_test() %void {
421 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);421 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
422 \\ stdout.print("before\n") catch unreachable;422 \\ stdout.print("before\n") catch unreachable;
423 \\ defer stdout.print("defer1\n") catch unreachable;423 \\ defer stdout.print("defer1\n") catch unreachable;
424 \\ %defer stdout.print("deferErr\n") catch unreachable;424 \\ errdefer stdout.print("deferErr\n") catch unreachable;
425 \\ try its_gonna_pass();425 \\ try its_gonna_pass();
426 \\ defer stdout.print("defer3\n") catch unreachable;426 \\ defer stdout.print("defer3\n") catch unreachable;
427 \\ stdout.print("after\n") catch unreachable;427 \\ stdout.print("after\n") catch unreachable;
428 \\}428 \\}
429 \\fn its_gonna_pass() -> %void { }429 \\fn its_gonna_pass() %void { }
430 , "before\nafter\ndefer3\ndefer1\n");430 , "before\nafter\ndefer3\ndefer1\n");
431431
432 cases.addCase(x: {432 cases.addCase(x: {
...@@ -434,7 +434,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -434,7 +434,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
434 \\const foo_txt = @embedFile("foo.txt");434 \\const foo_txt = @embedFile("foo.txt");
435 \\const io = @import("std").io;435 \\const io = @import("std").io;
436 \\436 \\
437 \\pub fn main() -> %void {437 \\pub fn main() %void {
438 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);438 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
439 \\ stdout.print(foo_txt) catch unreachable;439 \\ stdout.print(foo_txt) catch unreachable;
440 \\}440 \\}
...@@ -452,7 +452,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -452,7 +452,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
452 \\const os = std.os;452 \\const os = std.os;
453 \\const allocator = std.debug.global_allocator;453 \\const allocator = std.debug.global_allocator;
454 \\454 \\
455 \\pub fn main() -> %void {455 \\pub fn main() %void {
456 \\ var args_it = os.args();456 \\ var args_it = os.args();
457 \\ var stdout_file = try io.getStdOut();457 \\ var stdout_file = try io.getStdOut();
458 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);458 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
493 \\const os = std.os;493 \\const os = std.os;
494 \\const allocator = std.debug.global_allocator;494 \\const allocator = std.debug.global_allocator;
495 \\495 \\
496 \\pub fn main() -> %void {496 \\pub fn main() %void {
497 \\ var args_it = os.args();497 \\ var args_it = os.args();
498 \\ var stdout_file = try io.getStdOut();498 \\ var stdout_file = try io.getStdOut();
499 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);499 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
test/compile_errors.zig+459-413
...@@ -1,17 +1,63 @@...@@ -1,17 +1,63 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.CompileErrorContext) {3pub fn addCases(cases: &tests.CompileErrorContext) void {
4 cases.add("function with non-extern enum parameter",
5 \\const Foo = enum { A, B, C };
6 \\export fn entry(foo: Foo) void { }
7 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
8
9 cases.add("function with non-extern struct parameter",
10 \\const Foo = struct {
11 \\ A: i32,
12 \\ B: f32,
13 \\ C: bool,
14 \\};
15 \\export fn entry(foo: Foo) void { }
16 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
17
18 cases.add("function with non-extern union parameter",
19 \\const Foo = union {
20 \\ A: i32,
21 \\ B: f32,
22 \\ C: bool,
23 \\};
24 \\export fn entry(foo: Foo) void { }
25 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
26
27 cases.add("switch on enum with 1 field with no prongs",
28 \\const Foo = enum { M };
29 \\
30 \\export fn entry() void {
31 \\ var f = Foo.M;
32 \\ switch (f) {}
33 \\}
34 , ".tmp_source.zig:5:5: error: enumeration value 'Foo.M' not handled in switch");
35
36 cases.add("shift by negative comptime integer",
37 \\comptime {
38 \\ var a = 1 >> -1;
39 \\}
40 , ".tmp_source.zig:2:18: error: shift by negative value -1");
41
42 cases.add("@panic called at compile time",
43 \\export fn entry() void {
44 \\ comptime {
45 \\ @panic("aoeu");
46 \\ }
47 \\}
48 , ".tmp_source.zig:3:9: error: encountered @panic at compile-time");
49
4 cases.add("wrong return type for main",50 cases.add("wrong return type for main",
5 \\pub fn main() -> f32 { }51 \\pub fn main() f32 { }
6 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");52 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");
753
8 cases.add("double ?? on main return value",54 cases.add("double ?? on main return value",
9 \\pub fn main() -> ??void {55 \\pub fn main() ??void {
10 \\}56 \\}
11 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");57 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");
1258
13 cases.add("bad identifier in function with struct defined inside function which references local const",59 cases.add("bad identifier in function with struct defined inside function which references local const",
14 \\export fn entry() {60 \\export fn entry() void {
15 \\ const BlockKind = u32;61 \\ const BlockKind = u32;
16 \\62 \\
17 \\ const Block = struct {63 \\ const Block = struct {
...@@ -23,7 +69,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -23,7 +69,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23 , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'");69 , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'");
2470
25 cases.add("labeled break not found",71 cases.add("labeled break not found",
26 \\export fn entry() {72 \\export fn entry() void {
27 \\ blah: while (true) {73 \\ blah: while (true) {
28 \\ while (true) {74 \\ while (true) {
29 \\ break :outer;75 \\ break :outer;
...@@ -33,7 +79,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -33,7 +79,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
33 , ".tmp_source.zig:4:13: error: label not found: 'outer'");79 , ".tmp_source.zig:4:13: error: label not found: 'outer'");
3480
35 cases.add("labeled continue not found",81 cases.add("labeled continue not found",
36 \\export fn entry() {82 \\export fn entry() void {
37 \\ var i: usize = 0;83 \\ var i: usize = 0;
38 \\ blah: while (i < 10) : (i += 1) {84 \\ blah: while (i < 10) : (i += 1) {
39 \\ while (true) {85 \\ while (true) {
...@@ -44,17 +90,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -44,17 +90,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
44 , ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'");90 , ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'");
4591
46 cases.add("attempt to use 0 bit type in extern fn",92 cases.add("attempt to use 0 bit type in extern fn",
47 \\extern fn foo(ptr: extern fn(&void));93 \\extern fn foo(ptr: extern fn(&void) void) void;
48 \\94 \\
49 \\export fn entry() {95 \\export fn entry() void {
50 \\ foo(bar);96 \\ foo(bar);
51 \\}97 \\}
52 \\98 \\
53 \\extern fn bar(x: &void) { }99 \\extern fn bar(x: &void) void { }
54 , ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'");100 , ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'");
55101
56 cases.add("implicit semicolon - block statement",102 cases.add("implicit semicolon - block statement",
57 \\export fn entry() {103 \\export fn entry() void {
58 \\ {}104 \\ {}
59 \\ var good = {};105 \\ var good = {};
60 \\ ({})106 \\ ({})
...@@ -63,7 +109,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -63,7 +109,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
63 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");109 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
64110
65 cases.add("implicit semicolon - block expr",111 cases.add("implicit semicolon - block expr",
66 \\export fn entry() {112 \\export fn entry() void {
67 \\ _ = {};113 \\ _ = {};
68 \\ var good = {};114 \\ var good = {};
69 \\ _ = {}115 \\ _ = {}
...@@ -72,7 +118,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -72,7 +118,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
72 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");118 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
73119
74 cases.add("implicit semicolon - comptime statement",120 cases.add("implicit semicolon - comptime statement",
75 \\export fn entry() {121 \\export fn entry() void {
76 \\ comptime {}122 \\ comptime {}
77 \\ var good = {};123 \\ var good = {};
78 \\ comptime ({})124 \\ comptime ({})
...@@ -81,7 +127,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -81,7 +127,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
81 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");127 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
82128
83 cases.add("implicit semicolon - comptime expression",129 cases.add("implicit semicolon - comptime expression",
84 \\export fn entry() {130 \\export fn entry() void {
85 \\ _ = comptime {};131 \\ _ = comptime {};
86 \\ var good = {};132 \\ var good = {};
87 \\ _ = comptime {}133 \\ _ = comptime {}
...@@ -90,7 +136,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -90,7 +136,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
90 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");136 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
91137
92 cases.add("implicit semicolon - defer",138 cases.add("implicit semicolon - defer",
93 \\export fn entry() {139 \\export fn entry() void {
94 \\ defer {}140 \\ defer {}
95 \\ var good = {};141 \\ var good = {};
96 \\ defer ({})142 \\ defer ({})
...@@ -99,7 +145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -99,7 +145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
99 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");145 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
100146
101 cases.add("implicit semicolon - if statement",147 cases.add("implicit semicolon - if statement",
102 \\export fn entry() {148 \\export fn entry() void {
103 \\ if(true) {}149 \\ if(true) {}
104 \\ var good = {};150 \\ var good = {};
105 \\ if(true) ({})151 \\ if(true) ({})
...@@ -108,7 +154,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -108,7 +154,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
108 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");154 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
109155
110 cases.add("implicit semicolon - if expression",156 cases.add("implicit semicolon - if expression",
111 \\export fn entry() {157 \\export fn entry() void {
112 \\ _ = if(true) {};158 \\ _ = if(true) {};
113 \\ var good = {};159 \\ var good = {};
114 \\ _ = if(true) {}160 \\ _ = if(true) {}
...@@ -117,7 +163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -117,7 +163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
117 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");163 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
118164
119 cases.add("implicit semicolon - if-else statement",165 cases.add("implicit semicolon - if-else statement",
120 \\export fn entry() {166 \\export fn entry() void {
121 \\ if(true) {} else {}167 \\ if(true) {} else {}
122 \\ var good = {};168 \\ var good = {};
123 \\ if(true) ({}) else ({})169 \\ if(true) ({}) else ({})
...@@ -126,7 +172,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -126,7 +172,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
126 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");172 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
127173
128 cases.add("implicit semicolon - if-else expression",174 cases.add("implicit semicolon - if-else expression",
129 \\export fn entry() {175 \\export fn entry() void {
130 \\ _ = if(true) {} else {};176 \\ _ = if(true) {} else {};
131 \\ var good = {};177 \\ var good = {};
132 \\ _ = if(true) {} else {}178 \\ _ = if(true) {} else {}
...@@ -135,7 +181,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -135,7 +181,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
135 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");181 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
136182
137 cases.add("implicit semicolon - if-else-if statement",183 cases.add("implicit semicolon - if-else-if statement",
138 \\export fn entry() {184 \\export fn entry() void {
139 \\ if(true) {} else if(true) {}185 \\ if(true) {} else if(true) {}
140 \\ var good = {};186 \\ var good = {};
141 \\ if(true) ({}) else if(true) ({})187 \\ if(true) ({}) else if(true) ({})
...@@ -144,7 +190,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -144,7 +190,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
144 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");190 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
145191
146 cases.add("implicit semicolon - if-else-if expression",192 cases.add("implicit semicolon - if-else-if expression",
147 \\export fn entry() {193 \\export fn entry() void {
148 \\ _ = if(true) {} else if(true) {};194 \\ _ = if(true) {} else if(true) {};
149 \\ var good = {};195 \\ var good = {};
150 \\ _ = if(true) {} else if(true) {}196 \\ _ = if(true) {} else if(true) {}
...@@ -153,7 +199,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -153,7 +199,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
153 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");199 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
154200
155 cases.add("implicit semicolon - if-else-if-else statement",201 cases.add("implicit semicolon - if-else-if-else statement",
156 \\export fn entry() {202 \\export fn entry() void {
157 \\ if(true) {} else if(true) {} else {}203 \\ if(true) {} else if(true) {} else {}
158 \\ var good = {};204 \\ var good = {};
159 \\ if(true) ({}) else if(true) ({}) else ({})205 \\ if(true) ({}) else if(true) ({}) else ({})
...@@ -162,7 +208,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -162,7 +208,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
162 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");208 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
163209
164 cases.add("implicit semicolon - if-else-if-else expression",210 cases.add("implicit semicolon - if-else-if-else expression",
165 \\export fn entry() {211 \\export fn entry() void {
166 \\ _ = if(true) {} else if(true) {} else {};212 \\ _ = if(true) {} else if(true) {} else {};
167 \\ var good = {};213 \\ var good = {};
168 \\ _ = if(true) {} else if(true) {} else {}214 \\ _ = if(true) {} else if(true) {} else {}
...@@ -171,7 +217,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -171,7 +217,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
171 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");217 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
172218
173 cases.add("implicit semicolon - test statement",219 cases.add("implicit semicolon - test statement",
174 \\export fn entry() {220 \\export fn entry() void {
175 \\ if (foo()) |_| {}221 \\ if (foo()) |_| {}
176 \\ var good = {};222 \\ var good = {};
177 \\ if (foo()) |_| ({})223 \\ if (foo()) |_| ({})
...@@ -180,7 +226,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -180,7 +226,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
180 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");226 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
181227
182 cases.add("implicit semicolon - test expression",228 cases.add("implicit semicolon - test expression",
183 \\export fn entry() {229 \\export fn entry() void {
184 \\ _ = if (foo()) |_| {};230 \\ _ = if (foo()) |_| {};
185 \\ var good = {};231 \\ var good = {};
186 \\ _ = if (foo()) |_| {}232 \\ _ = if (foo()) |_| {}
...@@ -189,7 +235,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -189,7 +235,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
189 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");235 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
190236
191 cases.add("implicit semicolon - while statement",237 cases.add("implicit semicolon - while statement",
192 \\export fn entry() {238 \\export fn entry() void {
193 \\ while(true) {}239 \\ while(true) {}
194 \\ var good = {};240 \\ var good = {};
195 \\ while(true) ({})241 \\ while(true) ({})
...@@ -198,7 +244,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -198,7 +244,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
198 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");244 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
199245
200 cases.add("implicit semicolon - while expression",246 cases.add("implicit semicolon - while expression",
201 \\export fn entry() {247 \\export fn entry() void {
202 \\ _ = while(true) {};248 \\ _ = while(true) {};
203 \\ var good = {};249 \\ var good = {};
204 \\ _ = while(true) {}250 \\ _ = while(true) {}
...@@ -207,7 +253,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -207,7 +253,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
207 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");253 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
208254
209 cases.add("implicit semicolon - while-continue statement",255 cases.add("implicit semicolon - while-continue statement",
210 \\export fn entry() {256 \\export fn entry() void {
211 \\ while(true):({}) {}257 \\ while(true):({}) {}
212 \\ var good = {};258 \\ var good = {};
213 \\ while(true):({}) ({})259 \\ while(true):({}) ({})
...@@ -216,7 +262,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -216,7 +262,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
216 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");262 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
217263
218 cases.add("implicit semicolon - while-continue expression",264 cases.add("implicit semicolon - while-continue expression",
219 \\export fn entry() {265 \\export fn entry() void {
220 \\ _ = while(true):({}) {};266 \\ _ = while(true):({}) {};
221 \\ var good = {};267 \\ var good = {};
222 \\ _ = while(true):({}) {}268 \\ _ = while(true):({}) {}
...@@ -225,7 +271,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -225,7 +271,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
225 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");271 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
226272
227 cases.add("implicit semicolon - for statement",273 cases.add("implicit semicolon - for statement",
228 \\export fn entry() {274 \\export fn entry() void {
229 \\ for(foo()) {}275 \\ for(foo()) {}
230 \\ var good = {};276 \\ var good = {};
231 \\ for(foo()) ({})277 \\ for(foo()) ({})
...@@ -234,7 +280,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -234,7 +280,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
234 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");280 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
235281
236 cases.add("implicit semicolon - for expression",282 cases.add("implicit semicolon - for expression",
237 \\export fn entry() {283 \\export fn entry() void {
238 \\ _ = for(foo()) {};284 \\ _ = for(foo()) {};
239 \\ var good = {};285 \\ var good = {};
240 \\ _ = for(foo()) {}286 \\ _ = for(foo()) {}
...@@ -243,60 +289,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -243,60 +289,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
243 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");289 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
244290
245 cases.add("multiple function definitions",291 cases.add("multiple function definitions",
246 \\fn a() {}292 \\fn a() void {}
247 \\fn a() {}293 \\fn a() void {}
248 \\export fn entry() { a(); }294 \\export fn entry() void { a(); }
249 , ".tmp_source.zig:2:1: error: redefinition of 'a'");295 , ".tmp_source.zig:2:1: error: redefinition of 'a'");
250296
251 cases.add("unreachable with return",297 cases.add("unreachable with return",
252 \\fn a() -> noreturn {return;}298 \\fn a() noreturn {return;}
253 \\export fn entry() { a(); }299 \\export fn entry() void { a(); }
254 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");300 , ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'");
255301
256 cases.add("control reaches end of non-void function",302 cases.add("control reaches end of non-void function",
257 \\fn a() -> i32 {}303 \\fn a() i32 {}
258 \\export fn entry() { _ = a(); }304 \\export fn entry() void { _ = a(); }
259 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");305 , ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'");
260306
261 cases.add("undefined function call",307 cases.add("undefined function call",
262 \\export fn a() {308 \\export fn a() void {
263 \\ b();309 \\ b();
264 \\}310 \\}
265 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");311 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
266312
267 cases.add("wrong number of arguments",313 cases.add("wrong number of arguments",
268 \\export fn a() {314 \\export fn a() void {
269 \\ b(1);315 \\ b(1);
270 \\}316 \\}
271 \\fn b(a: i32, b: i32, c: i32) { }317 \\fn b(a: i32, b: i32, c: i32) void { }
272 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");318 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
273319
274 cases.add("invalid type",320 cases.add("invalid type",
275 \\fn a() -> bogus {}321 \\fn a() bogus {}
276 \\export fn entry() { _ = a(); }322 \\export fn entry() void { _ = a(); }
277 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");323 , ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'");
278324
279 cases.add("pointer to unreachable",325 cases.add("pointer to unreachable",
280 \\fn a() -> &noreturn {}326 \\fn a() &noreturn {}
281 \\export fn entry() { _ = a(); }327 \\export fn entry() void { _ = a(); }
282 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");328 , ".tmp_source.zig:1:9: error: pointer to unreachable not allowed");
283329
284 cases.add("unreachable code",330 cases.add("unreachable code",
285 \\export fn a() {331 \\export fn a() void {
286 \\ return;332 \\ return;
287 \\ b();333 \\ b();
288 \\}334 \\}
289 \\335 \\
290 \\fn b() {}336 \\fn b() void {}
291 , ".tmp_source.zig:3:5: error: unreachable code");337 , ".tmp_source.zig:3:5: error: unreachable code");
292338
293 cases.add("bad import",339 cases.add("bad import",
294 \\const bogus = @import("bogus-does-not-exist.zig");340 \\const bogus = @import("bogus-does-not-exist.zig");
295 \\export fn entry() { bogus.bogo(); }341 \\export fn entry() void { bogus.bogo(); }
296 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");342 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
297343
298 cases.add("undeclared identifier",344 cases.add("undeclared identifier",
299 \\export fn a() {345 \\export fn a() void {
300 \\ return346 \\ return
301 \\ b +347 \\ b +
302 \\ c;348 \\ c;
...@@ -306,89 +352,89 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -306,89 +352,89 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
306 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");352 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");
307353
308 cases.add("parameter redeclaration",354 cases.add("parameter redeclaration",
309 \\fn f(a : i32, a : i32) {355 \\fn f(a : i32, a : i32) void {
310 \\}356 \\}
311 \\export fn entry() { f(1, 2); }357 \\export fn entry() void { f(1, 2); }
312 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");358 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
313359
314 cases.add("local variable redeclaration",360 cases.add("local variable redeclaration",
315 \\export fn f() {361 \\export fn f() void {
316 \\ const a : i32 = 0;362 \\ const a : i32 = 0;
317 \\ const a = 0;363 \\ const a = 0;
318 \\}364 \\}
319 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");365 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
320366
321 cases.add("local variable redeclares parameter",367 cases.add("local variable redeclares parameter",
322 \\fn f(a : i32) {368 \\fn f(a : i32) void {
323 \\ const a = 0;369 \\ const a = 0;
324 \\}370 \\}
325 \\export fn entry() { f(1); }371 \\export fn entry() void { f(1); }
326 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");372 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
327373
328 cases.add("variable has wrong type",374 cases.add("variable has wrong type",
329 \\export fn f() -> i32 {375 \\export fn f() i32 {
330 \\ const a = c"a";376 \\ const a = c"a";
331 \\ return a;377 \\ return a;
332 \\}378 \\}
333 , ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'");379 , ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'");
334380
335 cases.add("if condition is bool, not int",381 cases.add("if condition is bool, not int",
336 \\export fn f() {382 \\export fn f() void {
337 \\ if (0) {}383 \\ if (0) {}
338 \\}384 \\}
339 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");385 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
340386
341 cases.add("assign unreachable",387 cases.add("assign unreachable",
342 \\export fn f() {388 \\export fn f() void {
343 \\ const a = return;389 \\ const a = return;
344 \\}390 \\}
345 , ".tmp_source.zig:2:5: error: unreachable code");391 , ".tmp_source.zig:2:5: error: unreachable code");
346392
347 cases.add("unreachable variable",393 cases.add("unreachable variable",
348 \\export fn f() {394 \\export fn f() void {
349 \\ const a: noreturn = {};395 \\ const a: noreturn = {};
350 \\}396 \\}
351 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");397 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
352398
353 cases.add("unreachable parameter",399 cases.add("unreachable parameter",
354 \\fn f(a: noreturn) {}400 \\fn f(a: noreturn) void {}
355 \\export fn entry() { f(); }401 \\export fn entry() void { f(); }
356 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");402 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
357403
358 cases.add("bad assignment target",404 cases.add("bad assignment target",
359 \\export fn f() {405 \\export fn f() void {
360 \\ 3 = 3;406 \\ 3 = 3;
361 \\}407 \\}
362 , ".tmp_source.zig:2:7: error: cannot assign to constant");408 , ".tmp_source.zig:2:7: error: cannot assign to constant");
363409
364 cases.add("assign to constant variable",410 cases.add("assign to constant variable",
365 \\export fn f() {411 \\export fn f() void {
366 \\ const a = 3;412 \\ const a = 3;
367 \\ a = 4;413 \\ a = 4;
368 \\}414 \\}
369 , ".tmp_source.zig:3:7: error: cannot assign to constant");415 , ".tmp_source.zig:3:7: error: cannot assign to constant");
370416
371 cases.add("use of undeclared identifier",417 cases.add("use of undeclared identifier",
372 \\export fn f() {418 \\export fn f() void {
373 \\ b = 3;419 \\ b = 3;
374 \\}420 \\}
375 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");421 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
376422
377 cases.add("const is a statement, not an expression",423 cases.add("const is a statement, not an expression",
378 \\export fn f() {424 \\export fn f() void {
379 \\ (const a = 0);425 \\ (const a = 0);
380 \\}426 \\}
381 , ".tmp_source.zig:2:6: error: invalid token: 'const'");427 , ".tmp_source.zig:2:6: error: invalid token: 'const'");
382428
383 cases.add("array access of undeclared identifier",429 cases.add("array access of undeclared identifier",
384 \\export fn f() {430 \\export fn f() void {
385 \\ i[i] = i[i];431 \\ i[i] = i[i];
386 \\}432 \\}
387 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",433 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
388 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");434 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
389435
390 cases.add("array access of non array",436 cases.add("array access of non array",
391 \\export fn f() {437 \\export fn f() void {
392 \\ var bad : bool = undefined;438 \\ var bad : bool = undefined;
393 \\ bad[bad] = bad[bad];439 \\ bad[bad] = bad[bad];
394 \\}440 \\}
...@@ -396,7 +442,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -396,7 +442,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
396 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");442 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
397443
398 cases.add("array access with non integer index",444 cases.add("array access with non integer index",
399 \\export fn f() {445 \\export fn f() void {
400 \\ var array = "aoeu";446 \\ var array = "aoeu";
401 \\ var bad = false;447 \\ var bad = false;
402 \\ array[bad] = array[bad];448 \\ array[bad] = array[bad];
...@@ -406,37 +452,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -406,37 +452,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
406452
407 cases.add("write to const global variable",453 cases.add("write to const global variable",
408 \\const x : i32 = 99;454 \\const x : i32 = 99;
409 \\fn f() {455 \\fn f() void {
410 \\ x = 1;456 \\ x = 1;
411 \\}457 \\}
412 \\export fn entry() { f(); }458 \\export fn entry() void { f(); }
413 , ".tmp_source.zig:3:7: error: cannot assign to constant");459 , ".tmp_source.zig:3:7: error: cannot assign to constant");
414460
415461
416 cases.add("missing else clause",462 cases.add("missing else clause",
417 \\fn f(b: bool) {463 \\fn f(b: bool) void {
418 \\ const x : i32 = if (b) h: { break :h 1; };464 \\ const x : i32 = if (b) h: { break :h 1; };
419 \\ const y = if (b) h: { break :h i32(1); };465 \\ const y = if (b) h: { break :h i32(1); };
420 \\}466 \\}
421 \\export fn entry() { f(true); }467 \\export fn entry() void { f(true); }
422 , ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",468 , ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
423 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");469 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
424470
425 cases.add("direct struct loop",471 cases.add("direct struct loop",
426 \\const A = struct { a : A, };472 \\const A = struct { a : A, };
427 \\export fn entry() -> usize { return @sizeOf(A); }473 \\export fn entry() usize { return @sizeOf(A); }
428 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");474 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
429475
430 cases.add("indirect struct loop",476 cases.add("indirect struct loop",
431 \\const A = struct { b : B, };477 \\const A = struct { b : B, };
432 \\const B = struct { c : C, };478 \\const B = struct { c : C, };
433 \\const C = struct { a : A, };479 \\const C = struct { a : A, };
434 \\export fn entry() -> usize { return @sizeOf(A); }480 \\export fn entry() usize { return @sizeOf(A); }
435 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");481 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
436482
437 cases.add("invalid struct field",483 cases.add("invalid struct field",
438 \\const A = struct { x : i32, };484 \\const A = struct { x : i32, };
439 \\export fn f() {485 \\export fn f() void {
440 \\ var a : A = undefined;486 \\ var a : A = undefined;
441 \\ a.foo = 1;487 \\ a.foo = 1;
442 \\ const y = a.bar;488 \\ const y = a.bar;
...@@ -468,7 +514,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -468,7 +514,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
468 \\ y : i32,514 \\ y : i32,
469 \\ z : i32,515 \\ z : i32,
470 \\};516 \\};
471 \\export fn f() {517 \\export fn f() void {
472 \\ const a = A {518 \\ const a = A {
473 \\ .z = 1,519 \\ .z = 1,
474 \\ .y = 2,520 \\ .y = 2,
...@@ -484,7 +530,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -484,7 +530,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
484 \\ y : i32,530 \\ y : i32,
485 \\ z : i32,531 \\ z : i32,
486 \\};532 \\};
487 \\export fn f() {533 \\export fn f() void {
488 \\ // we want the error on the '{' not the 'A' because534 \\ // we want the error on the '{' not the 'A' because
489 \\ // the A could be a complicated expression535 \\ // the A could be a complicated expression
490 \\ const a = A {536 \\ const a = A {
...@@ -500,7 +546,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -500,7 +546,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
500 \\ y : i32,546 \\ y : i32,
501 \\ z : i32,547 \\ z : i32,
502 \\};548 \\};
503 \\export fn f() {549 \\export fn f() void {
504 \\ const a = A {550 \\ const a = A {
505 \\ .z = 4,551 \\ .z = 4,
506 \\ .y = 2,552 \\ .y = 2,
...@@ -510,57 +556,57 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -510,57 +556,57 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
510 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");556 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");
511557
512 cases.add("invalid break expression",558 cases.add("invalid break expression",
513 \\export fn f() {559 \\export fn f() void {
514 \\ break;560 \\ break;
515 \\}561 \\}
516 , ".tmp_source.zig:2:5: error: break expression outside loop");562 , ".tmp_source.zig:2:5: error: break expression outside loop");
517563
518 cases.add("invalid continue expression",564 cases.add("invalid continue expression",
519 \\export fn f() {565 \\export fn f() void {
520 \\ continue;566 \\ continue;
521 \\}567 \\}
522 , ".tmp_source.zig:2:5: error: continue expression outside loop");568 , ".tmp_source.zig:2:5: error: continue expression outside loop");
523569
524 cases.add("invalid maybe type",570 cases.add("invalid maybe type",
525 \\export fn f() {571 \\export fn f() void {
526 \\ if (true) |x| { }572 \\ if (true) |x| { }
527 \\}573 \\}
528 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");574 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");
529575
530 cases.add("cast unreachable",576 cases.add("cast unreachable",
531 \\fn f() -> i32 {577 \\fn f() i32 {
532 \\ return i32(return 1);578 \\ return i32(return 1);
533 \\}579 \\}
534 \\export fn entry() { _ = f(); }580 \\export fn entry() void { _ = f(); }
535 , ".tmp_source.zig:2:15: error: unreachable code");581 , ".tmp_source.zig:2:15: error: unreachable code");
536582
537 cases.add("invalid builtin fn",583 cases.add("invalid builtin fn",
538 \\fn f() -> @bogus(foo) {584 \\fn f() @bogus(foo) {
539 \\}585 \\}
540 \\export fn entry() { _ = f(); }586 \\export fn entry() void { _ = f(); }
541 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");587 , ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'");
542588
543 cases.add("top level decl dependency loop",589 cases.add("top level decl dependency loop",
544 \\const a : @typeOf(b) = 0;590 \\const a : @typeOf(b) = 0;
545 \\const b : @typeOf(a) = 0;591 \\const b : @typeOf(a) = 0;
546 \\export fn entry() {592 \\export fn entry() void {
547 \\ const c = a + b;593 \\ const c = a + b;
548 \\}594 \\}
549 , ".tmp_source.zig:1:1: error: 'a' depends on itself");595 , ".tmp_source.zig:1:1: error: 'a' depends on itself");
550596
551 cases.add("noalias on non pointer param",597 cases.add("noalias on non pointer param",
552 \\fn f(noalias x: i32) {}598 \\fn f(noalias x: i32) void {}
553 \\export fn entry() { f(1234); }599 \\export fn entry() void { f(1234); }
554 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");600 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
555601
556 cases.add("struct init syntax for array",602 cases.add("struct init syntax for array",
557 \\const foo = []u16{.x = 1024,};603 \\const foo = []u16{.x = 1024,};
558 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }604 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
559 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");605 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
560606
561 cases.add("type variables must be constant",607 cases.add("type variables must be constant",
562 \\var foo = u8;608 \\var foo = u8;
563 \\export fn entry() -> foo {609 \\export fn entry() foo {
564 \\ return 1;610 \\ return 1;
565 \\}611 \\}
566 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");612 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");
...@@ -570,11 +616,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -570,11 +616,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
570 \\const Foo = struct {};616 \\const Foo = struct {};
571 \\const Bar = struct {};617 \\const Bar = struct {};
572 \\618 \\
573 \\fn f(Foo: i32) {619 \\fn f(Foo: i32) void {
574 \\ var Bar : i32 = undefined;620 \\ var Bar : i32 = undefined;
575 \\}621 \\}
576 \\622 \\
577 \\export fn entry() {623 \\export fn entry() void {
578 \\ f(1234);624 \\ f(1234);
579 \\}625 \\}
580 ,626 ,
...@@ -590,7 +636,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -590,7 +636,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
590 \\ Three,636 \\ Three,
591 \\ Four,637 \\ Four,
592 \\};638 \\};
593 \\fn f(n: Number) -> i32 {639 \\fn f(n: Number) i32 {
594 \\ switch (n) {640 \\ switch (n) {
595 \\ Number.One => 1,641 \\ Number.One => 1,
596 \\ Number.Two => 2,642 \\ Number.Two => 2,
...@@ -598,7 +644,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -598,7 +644,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
598 \\ }644 \\ }
599 \\}645 \\}
600 \\646 \\
601 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }647 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
602 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");648 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
603649
604 cases.add("switch expression - duplicate enumeration prong",650 cases.add("switch expression - duplicate enumeration prong",
...@@ -608,7 +654,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -608,7 +654,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
608 \\ Three,654 \\ Three,
609 \\ Four,655 \\ Four,
610 \\};656 \\};
611 \\fn f(n: Number) -> i32 {657 \\fn f(n: Number) i32 {
612 \\ switch (n) {658 \\ switch (n) {
613 \\ Number.One => 1,659 \\ Number.One => 1,
614 \\ Number.Two => 2,660 \\ Number.Two => 2,
...@@ -618,7 +664,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -618,7 +664,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
618 \\ }664 \\ }
619 \\}665 \\}
620 \\666 \\
621 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }667 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
622 , ".tmp_source.zig:13:15: error: duplicate switch value",668 , ".tmp_source.zig:13:15: error: duplicate switch value",
623 ".tmp_source.zig:10:15: note: other value is here");669 ".tmp_source.zig:10:15: note: other value is here");
624670
...@@ -629,7 +675,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -629,7 +675,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
629 \\ Three,675 \\ Three,
630 \\ Four,676 \\ Four,
631 \\};677 \\};
632 \\fn f(n: Number) -> i32 {678 \\fn f(n: Number) i32 {
633 \\ switch (n) {679 \\ switch (n) {
634 \\ Number.One => 1,680 \\ Number.One => 1,
635 \\ Number.Two => 2,681 \\ Number.Two => 2,
...@@ -640,35 +686,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -640,35 +686,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
640 \\ }686 \\ }
641 \\}687 \\}
642 \\688 \\
643 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }689 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
644 , ".tmp_source.zig:13:15: error: duplicate switch value",690 , ".tmp_source.zig:13:15: error: duplicate switch value",
645 ".tmp_source.zig:10:15: note: other value is here");691 ".tmp_source.zig:10:15: note: other value is here");
646692
647 cases.add("switch expression - multiple else prongs",693 cases.add("switch expression - multiple else prongs",
648 \\fn f(x: u32) {694 \\fn f(x: u32) void {
649 \\ const value: bool = switch (x) {695 \\ const value: bool = switch (x) {
650 \\ 1234 => false,696 \\ 1234 => false,
651 \\ else => true,697 \\ else => true,
652 \\ else => true,698 \\ else => true,
653 \\ };699 \\ };
654 \\}700 \\}
655 \\export fn entry() {701 \\export fn entry() void {
656 \\ f(1234);702 \\ f(1234);
657 \\}703 \\}
658 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");704 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
659705
660 cases.add("switch expression - non exhaustive integer prongs",706 cases.add("switch expression - non exhaustive integer prongs",
661 \\fn foo(x: u8) {707 \\fn foo(x: u8) void {
662 \\ switch (x) {708 \\ switch (x) {
663 \\ 0 => {},709 \\ 0 => {},
664 \\ }710 \\ }
665 \\}711 \\}
666 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }712 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
667 ,713 ,
668 ".tmp_source.zig:2:5: error: switch must handle all possibilities");714 ".tmp_source.zig:2:5: error: switch must handle all possibilities");
669715
670 cases.add("switch expression - duplicate or overlapping integer value",716 cases.add("switch expression - duplicate or overlapping integer value",
671 \\fn foo(x: u8) -> u8 {717 \\fn foo(x: u8) u8 {
672 \\ return switch (x) {718 \\ return switch (x) {
673 \\ 0 ... 100 => u8(0),719 \\ 0 ... 100 => u8(0),
674 \\ 101 ... 200 => 1,720 \\ 101 ... 200 => 1,
...@@ -676,26 +722,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -676,26 +722,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
676 \\ 206 ... 255 => 3,722 \\ 206 ... 255 => 3,
677 \\ };723 \\ };
678 \\}724 \\}
679 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }725 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
680 ,726 ,
681 ".tmp_source.zig:6:9: error: duplicate switch value",727 ".tmp_source.zig:6:9: error: duplicate switch value",
682 ".tmp_source.zig:5:14: note: previous value is here");728 ".tmp_source.zig:5:14: note: previous value is here");
683729
684 cases.add("switch expression - switch on pointer type with no else",730 cases.add("switch expression - switch on pointer type with no else",
685 \\fn foo(x: &u8) {731 \\fn foo(x: &u8) void {
686 \\ switch (x) {732 \\ switch (x) {
687 \\ &y => {},733 \\ &y => {},
688 \\ }734 \\ }
689 \\}735 \\}
690 \\const y: u8 = 100;736 \\const y: u8 = 100;
691 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }737 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
692 ,738 ,
693 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");739 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");
694740
695 cases.add("global variable initializer must be constant expression",741 cases.add("global variable initializer must be constant expression",
696 \\extern fn foo() -> i32;742 \\extern fn foo() i32;
697 \\const x = foo();743 \\const x = foo();
698 \\export fn entry() -> i32 { return x; }744 \\export fn entry() i32 { return x; }
699 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");745 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
700746
701 cases.add("array concatenation with wrong type",747 cases.add("array concatenation with wrong type",
...@@ -703,38 +749,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -703,38 +749,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
703 \\const derp = usize(1234);749 \\const derp = usize(1234);
704 \\const a = derp ++ "foo";750 \\const a = derp ++ "foo";
705 \\751 \\
706 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }752 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
707 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");753 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
708754
709 cases.add("non compile time array concatenation",755 cases.add("non compile time array concatenation",
710 \\fn f() -> []u8 {756 \\fn f() []u8 {
711 \\ return s ++ "foo";757 \\ return s ++ "foo";
712 \\}758 \\}
713 \\var s: [10]u8 = undefined;759 \\var s: [10]u8 = undefined;
714 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }760 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
715 , ".tmp_source.zig:2:12: error: unable to evaluate constant expression");761 , ".tmp_source.zig:2:12: error: unable to evaluate constant expression");
716762
717 cases.add("@cImport with bogus include",763 cases.add("@cImport with bogus include",
718 \\const c = @cImport(@cInclude("bogus.h"));764 \\const c = @cImport(@cInclude("bogus.h"));
719 \\export fn entry() -> usize { return @sizeOf(@typeOf(c.bogo)); }765 \\export fn entry() usize { return @sizeOf(@typeOf(c.bogo)); }
720 , ".tmp_source.zig:1:11: error: C import failed",766 , ".tmp_source.zig:1:11: error: C import failed",
721 ".h:1:10: note: 'bogus.h' file not found");767 ".h:1:10: note: 'bogus.h' file not found");
722768
723 cases.add("address of number literal",769 cases.add("address of number literal",
724 \\const x = 3;770 \\const x = 3;
725 \\const y = &x;771 \\const y = &x;
726 \\fn foo() -> &const i32 { return y; }772 \\fn foo() &const i32 { return y; }
727 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }773 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
728 , ".tmp_source.zig:3:33: error: expected type '&const i32', found '&const (integer literal)'");774 , ".tmp_source.zig:3:30: error: expected type '&const i32', found '&const (integer literal)'");
729775
730 cases.add("integer overflow error",776 cases.add("integer overflow error",
731 \\const x : u8 = 300;777 \\const x : u8 = 300;
732 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }778 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
733 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");779 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
734780
735 cases.add("incompatible number literals",781 cases.add("incompatible number literals",
736 \\const x = 2 == 2.0;782 \\const x = 2 == 2.0;
737 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }783 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
738 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");784 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
739785
740 cases.add("missing function call param",786 cases.add("missing function call param",
...@@ -742,10 +788,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -742,10 +788,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
742 \\ a: i32,788 \\ a: i32,
743 \\ b: i32,789 \\ b: i32,
744 \\790 \\
745 \\ fn member_a(foo: &const Foo) -> i32 {791 \\ fn member_a(foo: &const Foo) i32 {
746 \\ return foo.a;792 \\ return foo.a;
747 \\ }793 \\ }
748 \\ fn member_b(foo: &const Foo) -> i32 {794 \\ fn member_b(foo: &const Foo) i32 {
749 \\ return foo.b;795 \\ return foo.b;
750 \\ }796 \\ }
751 \\};797 \\};
...@@ -756,59 +802,59 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -756,59 +802,59 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
756 \\ Foo.member_b,802 \\ Foo.member_b,
757 \\};803 \\};
758 \\804 \\
759 \\fn f(foo: &const Foo, index: usize) {805 \\fn f(foo: &const Foo, index: usize) void {
760 \\ const result = members[index]();806 \\ const result = members[index]();
761 \\}807 \\}
762 \\808 \\
763 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }809 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
764 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");810 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
765811
766 cases.add("missing function name and param name",812 cases.add("missing function name and param name",
767 \\fn () {}813 \\fn () void {}
768 \\fn f(i32) {}814 \\fn f(i32) void {}
769 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }815 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
770 ,816 ,
771 ".tmp_source.zig:1:1: error: missing function name",817 ".tmp_source.zig:1:1: error: missing function name",
772 ".tmp_source.zig:2:6: error: missing parameter name");818 ".tmp_source.zig:2:6: error: missing parameter name");
773819
774 cases.add("wrong function type",820 cases.add("wrong function type",
775 \\const fns = []fn(){ a, b, c };821 \\const fns = []fn() void { a, b, c };
776 \\fn a() -> i32 {return 0;}822 \\fn a() i32 {return 0;}
777 \\fn b() -> i32 {return 1;}823 \\fn b() i32 {return 1;}
778 \\fn c() -> i32 {return 2;}824 \\fn c() i32 {return 2;}
779 \\export fn entry() -> usize { return @sizeOf(@typeOf(fns)); }825 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
780 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");826 , ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'");
781827
782 cases.add("extern function pointer mismatch",828 cases.add("extern function pointer mismatch",
783 \\const fns = [](fn(i32)->i32){ a, b, c };829 \\const fns = [](fn(i32)i32) { a, b, c };
784 \\pub fn a(x: i32) -> i32 {return x + 0;}830 \\pub fn a(x: i32) i32 {return x + 0;}
785 \\pub fn b(x: i32) -> i32 {return x + 1;}831 \\pub fn b(x: i32) i32 {return x + 1;}
786 \\export fn c(x: i32) -> i32 {return x + 2;}832 \\export fn c(x: i32) i32 {return x + 2;}
787 \\833 \\
788 \\export fn entry() -> usize { return @sizeOf(@typeOf(fns)); }834 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
789 , ".tmp_source.zig:1:37: error: expected type 'fn(i32) -> i32', found 'extern fn(i32) -> i32'");835 , ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'");
790836
791837
792 cases.add("implicit cast from f64 to f32",838 cases.add("implicit cast from f64 to f32",
793 \\const x : f64 = 1.0;839 \\const x : f64 = 1.0;
794 \\const y : f32 = x;840 \\const y : f32 = x;
795 \\841 \\
796 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }842 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
797 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");843 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
798844
799845
800 cases.add("colliding invalid top level functions",846 cases.add("colliding invalid top level functions",
801 \\fn func() -> bogus {}847 \\fn func() bogus {}
802 \\fn func() -> bogus {}848 \\fn func() bogus {}
803 \\export fn entry() -> usize { return @sizeOf(@typeOf(func)); }849 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }
804 ,850 ,
805 ".tmp_source.zig:2:1: error: redefinition of 'func'",851 ".tmp_source.zig:2:1: error: redefinition of 'func'",
806 ".tmp_source.zig:1:14: error: use of undeclared identifier 'bogus'");852 ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
807853
808854
809 cases.add("bogus compile var",855 cases.add("bogus compile var",
810 \\const x = @import("builtin").bogus;856 \\const x = @import("builtin").bogus;
811 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }857 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
812 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");858 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");
813859
814860
...@@ -817,11 +863,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -817,11 +863,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
817 \\ y: [get()]u8,863 \\ y: [get()]u8,
818 \\};864 \\};
819 \\var global_var: usize = 1;865 \\var global_var: usize = 1;
820 \\fn get() -> usize { return global_var; }866 \\fn get() usize { return global_var; }
821 \\867 \\
822 \\export fn entry() -> usize { return @sizeOf(@typeOf(Foo)); }868 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
823 ,869 ,
824 ".tmp_source.zig:5:28: error: unable to evaluate constant expression",870 ".tmp_source.zig:5:25: error: unable to evaluate constant expression",
825 ".tmp_source.zig:2:12: note: called from here",871 ".tmp_source.zig:2:12: note: called from here",
826 ".tmp_source.zig:2:8: note: called from here");872 ".tmp_source.zig:2:8: note: called from here");
827873
...@@ -832,7 +878,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -832,7 +878,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
832 \\};878 \\};
833 \\const x = Foo {.field = 1} + Foo {.field = 2};879 \\const x = Foo {.field = 1} + Foo {.field = 2};
834 \\880 \\
835 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }881 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
836 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");882 , ".tmp_source.zig:4:28: error: invalid operands to binary expression: 'Foo' and 'Foo'");
837883
838884
...@@ -842,78 +888,78 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -842,78 +888,78 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
842 \\const int_x = u32(1) / u32(0);888 \\const int_x = u32(1) / u32(0);
843 \\const float_x = f32(1.0) / f32(0.0);889 \\const float_x = f32(1.0) / f32(0.0);
844 \\890 \\
845 \\export fn entry1() -> usize { return @sizeOf(@typeOf(lit_int_x)); }891 \\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }
846 \\export fn entry2() -> usize { return @sizeOf(@typeOf(lit_float_x)); }892 \\export fn entry2() usize { return @sizeOf(@typeOf(lit_float_x)); }
847 \\export fn entry3() -> usize { return @sizeOf(@typeOf(int_x)); }893 \\export fn entry3() usize { return @sizeOf(@typeOf(int_x)); }
848 \\export fn entry4() -> usize { return @sizeOf(@typeOf(float_x)); }894 \\export fn entry4() usize { return @sizeOf(@typeOf(float_x)); }
849 ,895 ,
850 ".tmp_source.zig:1:21: error: division by zero is undefined",896 ".tmp_source.zig:1:21: error: division by zero",
851 ".tmp_source.zig:2:25: error: division by zero is undefined",897 ".tmp_source.zig:2:25: error: division by zero",
852 ".tmp_source.zig:3:22: error: division by zero is undefined",898 ".tmp_source.zig:3:22: error: division by zero",
853 ".tmp_source.zig:4:26: error: division by zero is undefined");899 ".tmp_source.zig:4:26: error: division by zero");
854900
855901
856 cases.add("normal string with newline",902 cases.add("normal string with newline",
857 \\const foo = "a903 \\const foo = "a
858 \\b";904 \\b";
859 \\905 \\
860 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }906 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
861 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");907 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
862908
863 cases.add("invalid comparison for function pointers",909 cases.add("invalid comparison for function pointers",
864 \\fn foo() {}910 \\fn foo() void {}
865 \\const invalid = foo > foo;911 \\const invalid = foo > foo;
866 \\912 \\
867 \\export fn entry() -> usize { return @sizeOf(@typeOf(invalid)); }913 \\export fn entry() usize { return @sizeOf(@typeOf(invalid)); }
868 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");914 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'");
869915
870 cases.add("generic function instance with non-constant expression",916 cases.add("generic function instance with non-constant expression",
871 \\fn foo(comptime x: i32, y: i32) -> i32 { return x + y; }917 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
872 \\fn test1(a: i32, b: i32) -> i32 {918 \\fn test1(a: i32, b: i32) i32 {
873 \\ return foo(a, b);919 \\ return foo(a, b);
874 \\}920 \\}
875 \\921 \\
876 \\export fn entry() -> usize { return @sizeOf(@typeOf(test1)); }922 \\export fn entry() usize { return @sizeOf(@typeOf(test1)); }
877 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");923 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
878924
879 cases.add("assign null to non-nullable pointer",925 cases.add("assign null to non-nullable pointer",
880 \\const a: &u8 = null;926 \\const a: &u8 = null;
881 \\927 \\
882 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }928 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
883 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");929 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
884930
885 cases.add("indexing an array of size zero",931 cases.add("indexing an array of size zero",
886 \\const array = []u8{};932 \\const array = []u8{};
887 \\export fn foo() {933 \\export fn foo() void {
888 \\ const pointer = &array[0];934 \\ const pointer = &array[0];
889 \\}935 \\}
890 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");936 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
891937
892 cases.add("compile time division by zero",938 cases.add("compile time division by zero",
893 \\const y = foo(0);939 \\const y = foo(0);
894 \\fn foo(x: u32) -> u32 {940 \\fn foo(x: u32) u32 {
895 \\ return 1 / x;941 \\ return 1 / x;
896 \\}942 \\}
897 \\943 \\
898 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }944 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
899 ,945 ,
900 ".tmp_source.zig:3:14: error: division by zero is undefined",946 ".tmp_source.zig:3:14: error: division by zero",
901 ".tmp_source.zig:1:14: note: called from here");947 ".tmp_source.zig:1:14: note: called from here");
902948
903 cases.add("branch on undefined value",949 cases.add("branch on undefined value",
904 \\const x = if (undefined) true else false;950 \\const x = if (undefined) true else false;
905 \\951 \\
906 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }952 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
907 , ".tmp_source.zig:1:15: error: use of undefined value");953 , ".tmp_source.zig:1:15: error: use of undefined value");
908954
909955
910 cases.add("endless loop in function evaluation",956 cases.add("endless loop in function evaluation",
911 \\const seventh_fib_number = fibbonaci(7);957 \\const seventh_fib_number = fibbonaci(7);
912 \\fn fibbonaci(x: i32) -> i32 {958 \\fn fibbonaci(x: i32) i32 {
913 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);959 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
914 \\}960 \\}
915 \\961 \\
916 \\export fn entry() -> usize { return @sizeOf(@typeOf(seventh_fib_number)); }962 \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); }
917 ,963 ,
918 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",964 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
919 ".tmp_source.zig:3:21: note: called from here");965 ".tmp_source.zig:3:21: note: called from here");
...@@ -921,7 +967,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -921,7 +967,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
921 cases.add("@embedFile with bogus file",967 cases.add("@embedFile with bogus file",
922 \\const resource = @embedFile("bogus.txt");968 \\const resource = @embedFile("bogus.txt");
923 \\969 \\
924 \\export fn entry() -> usize { return @sizeOf(@typeOf(resource)); }970 \\export fn entry() usize { return @sizeOf(@typeOf(resource)); }
925 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");971 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
926972
927 cases.add("non-const expression in struct literal outside function",973 cases.add("non-const expression in struct literal outside function",
...@@ -929,9 +975,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -929,9 +975,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
929 \\ x: i32,975 \\ x: i32,
930 \\};976 \\};
931 \\const a = Foo {.x = get_it()};977 \\const a = Foo {.x = get_it()};
932 \\extern fn get_it() -> i32;978 \\extern fn get_it() i32;
933 \\979 \\
934 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }980 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
935 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");981 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
936982
937 cases.add("non-const expression function call with struct return value outside function",983 cases.add("non-const expression function call with struct return value outside function",
...@@ -939,60 +985,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -939,60 +985,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
939 \\ x: i32,985 \\ x: i32,
940 \\};986 \\};
941 \\const a = get_it();987 \\const a = get_it();
942 \\fn get_it() -> Foo {988 \\fn get_it() Foo {
943 \\ global_side_effect = true;989 \\ global_side_effect = true;
944 \\ return Foo {.x = 13};990 \\ return Foo {.x = 13};
945 \\}991 \\}
946 \\var global_side_effect = false;992 \\var global_side_effect = false;
947 \\993 \\
948 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }994 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
949 ,995 ,
950 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",996 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
951 ".tmp_source.zig:4:17: note: called from here");997 ".tmp_source.zig:4:17: note: called from here");
952998
953 cases.add("undeclared identifier error should mark fn as impure",999 cases.add("undeclared identifier error should mark fn as impure",
954 \\export fn foo() {1000 \\export fn foo() void {
955 \\ test_a_thing();1001 \\ test_a_thing();
956 \\}1002 \\}
957 \\fn test_a_thing() {1003 \\fn test_a_thing() void {
958 \\ bad_fn_call();1004 \\ bad_fn_call();
959 \\}1005 \\}
960 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");1006 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
9611007
962 cases.add("illegal comparison of types",1008 cases.add("illegal comparison of types",
963 \\fn bad_eql_1(a: []u8, b: []u8) -> bool {1009 \\fn bad_eql_1(a: []u8, b: []u8) bool {
964 \\ return a == b;1010 \\ return a == b;
965 \\}1011 \\}
966 \\const EnumWithData = union(enum) {1012 \\const EnumWithData = union(enum) {
967 \\ One: void,1013 \\ One: void,
968 \\ Two: i32,1014 \\ Two: i32,
969 \\};1015 \\};
970 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) -> bool {1016 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {
971 \\ return *a == *b;1017 \\ return *a == *b;
972 \\}1018 \\}
973 \\1019 \\
974 \\export fn entry1() -> usize { return @sizeOf(@typeOf(bad_eql_1)); }1020 \\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }
975 \\export fn entry2() -> usize { return @sizeOf(@typeOf(bad_eql_2)); }1021 \\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }
976 ,1022 ,
977 ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",1023 ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
978 ".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'");1024 ".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'");
9791025
980 cases.add("non-const switch number literal",1026 cases.add("non-const switch number literal",
981 \\export fn foo() {1027 \\export fn foo() void {
982 \\ const x = switch (bar()) {1028 \\ const x = switch (bar()) {
983 \\ 1, 2 => 1,1029 \\ 1, 2 => 1,
984 \\ 3, 4 => 2,1030 \\ 3, 4 => 2,
985 \\ else => 3,1031 \\ else => 3,
986 \\ };1032 \\ };
987 \\}1033 \\}
988 \\fn bar() -> i32 {1034 \\fn bar() i32 {
989 \\ return 2;1035 \\ return 2;
990 \\}1036 \\}
991 , ".tmp_source.zig:2:15: error: unable to infer expression type");1037 , ".tmp_source.zig:2:15: error: unable to infer expression type");
9921038
993 cases.add("atomic orderings of cmpxchg - failure stricter than success",1039 cases.add("atomic orderings of cmpxchg - failure stricter than success",
994 \\const AtomicOrder = @import("builtin").AtomicOrder;1040 \\const AtomicOrder = @import("builtin").AtomicOrder;
995 \\export fn f() {1041 \\export fn f() void {
996 \\ var x: i32 = 1234;1042 \\ var x: i32 = 1234;
997 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}1043 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
998 \\}1044 \\}
...@@ -1000,7 +1046,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1000,7 +1046,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10001046
1001 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",1047 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
1002 \\const AtomicOrder = @import("builtin").AtomicOrder;1048 \\const AtomicOrder = @import("builtin").AtomicOrder;
1003 \\export fn f() {1049 \\export fn f() void {
1004 \\ var x: i32 = 1234;1050 \\ var x: i32 = 1234;
1005 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}1051 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
1006 \\}1052 \\}
...@@ -1008,22 +1054,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1008,22 +1054,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10081054
1009 cases.add("negation overflow in function evaluation",1055 cases.add("negation overflow in function evaluation",
1010 \\const y = neg(-128);1056 \\const y = neg(-128);
1011 \\fn neg(x: i8) -> i8 {1057 \\fn neg(x: i8) i8 {
1012 \\ return -x;1058 \\ return -x;
1013 \\}1059 \\}
1014 \\1060 \\
1015 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }1061 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1016 ,1062 ,
1017 ".tmp_source.zig:3:12: error: negation caused overflow",1063 ".tmp_source.zig:3:12: error: negation caused overflow",
1018 ".tmp_source.zig:1:14: note: called from here");1064 ".tmp_source.zig:1:14: note: called from here");
10191065
1020 cases.add("add overflow in function evaluation",1066 cases.add("add overflow in function evaluation",
1021 \\const y = add(65530, 10);1067 \\const y = add(65530, 10);
1022 \\fn add(a: u16, b: u16) -> u16 {1068 \\fn add(a: u16, b: u16) u16 {
1023 \\ return a + b;1069 \\ return a + b;
1024 \\}1070 \\}
1025 \\1071 \\
1026 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }1072 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1027 ,1073 ,
1028 ".tmp_source.zig:3:14: error: operation caused overflow",1074 ".tmp_source.zig:3:14: error: operation caused overflow",
1029 ".tmp_source.zig:1:14: note: called from here");1075 ".tmp_source.zig:1:14: note: called from here");
...@@ -1031,47 +1077,47 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1031,47 +1077,47 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10311077
1032 cases.add("sub overflow in function evaluation",1078 cases.add("sub overflow in function evaluation",
1033 \\const y = sub(10, 20);1079 \\const y = sub(10, 20);
1034 \\fn sub(a: u16, b: u16) -> u16 {1080 \\fn sub(a: u16, b: u16) u16 {
1035 \\ return a - b;1081 \\ return a - b;
1036 \\}1082 \\}
1037 \\1083 \\
1038 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }1084 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1039 ,1085 ,
1040 ".tmp_source.zig:3:14: error: operation caused overflow",1086 ".tmp_source.zig:3:14: error: operation caused overflow",
1041 ".tmp_source.zig:1:14: note: called from here");1087 ".tmp_source.zig:1:14: note: called from here");
10421088
1043 cases.add("mul overflow in function evaluation",1089 cases.add("mul overflow in function evaluation",
1044 \\const y = mul(300, 6000);1090 \\const y = mul(300, 6000);
1045 \\fn mul(a: u16, b: u16) -> u16 {1091 \\fn mul(a: u16, b: u16) u16 {
1046 \\ return a * b;1092 \\ return a * b;
1047 \\}1093 \\}
1048 \\1094 \\
1049 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }1095 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
1050 ,1096 ,
1051 ".tmp_source.zig:3:14: error: operation caused overflow",1097 ".tmp_source.zig:3:14: error: operation caused overflow",
1052 ".tmp_source.zig:1:14: note: called from here");1098 ".tmp_source.zig:1:14: note: called from here");
10531099
1054 cases.add("truncate sign mismatch",1100 cases.add("truncate sign mismatch",
1055 \\fn f() -> i8 {1101 \\fn f() i8 {
1056 \\ const x: u32 = 10;1102 \\ const x: u32 = 10;
1057 \\ return @truncate(i8, x);1103 \\ return @truncate(i8, x);
1058 \\}1104 \\}
1059 \\1105 \\
1060 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }1106 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1061 , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");1107 , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");
10621108
1063 cases.add("try in function with non error return type",1109 cases.add("try in function with non error return type",
1064 \\export fn f() {1110 \\export fn f() void {
1065 \\ try something();1111 \\ try something();
1066 \\}1112 \\}
1067 \\fn something() -> %void { }1113 \\fn something() %void { }
1068 ,1114 ,
1069 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");1115 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");
10701116
1071 cases.add("invalid pointer for var type",1117 cases.add("invalid pointer for var type",
1072 \\extern fn ext() -> usize;1118 \\extern fn ext() usize;
1073 \\var bytes: [ext()]u8 = undefined;1119 \\var bytes: [ext()]u8 = undefined;
1074 \\export fn f() {1120 \\export fn f() void {
1075 \\ for (bytes) |*b, i| {1121 \\ for (bytes) |*b, i| {
1076 \\ *b = u8(i);1122 \\ *b = u8(i);
1077 \\ }1123 \\ }
...@@ -1079,21 +1125,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1079,21 +1125,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1079 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");1125 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
10801126
1081 cases.add("export function with comptime parameter",1127 cases.add("export function with comptime parameter",
1082 \\export fn foo(comptime x: i32, y: i32) -> i32{1128 \\export fn foo(comptime x: i32, y: i32) i32{
1083 \\ return x + y;1129 \\ return x + y;
1084 \\}1130 \\}
1085 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1131 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10861132
1087 cases.add("extern function with comptime parameter",1133 cases.add("extern function with comptime parameter",
1088 \\extern fn foo(comptime x: i32, y: i32) -> i32;1134 \\extern fn foo(comptime x: i32, y: i32) i32;
1089 \\fn f() -> i32 {1135 \\fn f() i32 {
1090 \\ return foo(1, 2);1136 \\ return foo(1, 2);
1091 \\}1137 \\}
1092 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }1138 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1093 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");1139 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10941140
1095 cases.add("convert fixed size array to slice with invalid size",1141 cases.add("convert fixed size array to slice with invalid size",
1096 \\export fn f() {1142 \\export fn f() void {
1097 \\ var array: [5]u8 = undefined;1143 \\ var array: [5]u8 = undefined;
1098 \\ var foo = ([]const u32)(array)[0];1144 \\ var foo = ([]const u32)(array)[0];
1099 \\}1145 \\}
...@@ -1101,12 +1147,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1101,12 +1147,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11011147
1102 cases.add("non-pure function returns type",1148 cases.add("non-pure function returns type",
1103 \\var a: u32 = 0;1149 \\var a: u32 = 0;
1104 \\pub fn List(comptime T: type) -> type {1150 \\pub fn List(comptime T: type) type {
1105 \\ a += 1;1151 \\ a += 1;
1106 \\ return SmallList(T, 8);1152 \\ return SmallList(T, 8);
1107 \\}1153 \\}
1108 \\1154 \\
1109 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {1155 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type {
1110 \\ return struct {1156 \\ return struct {
1111 \\ items: []T,1157 \\ items: []T,
1112 \\ length: usize,1158 \\ length: usize,
...@@ -1114,7 +1160,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1114,7 +1160,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1114 \\ };1160 \\ };
1115 \\}1161 \\}
1116 \\1162 \\
1117 \\export fn function_with_return_type_type() {1163 \\export fn function_with_return_type_type() void {
1118 \\ var list: List(i32) = undefined;1164 \\ var list: List(i32) = undefined;
1119 \\ list.length = 10;1165 \\ list.length = 10;
1120 \\}1166 \\}
...@@ -1123,46 +1169,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1123,46 +1169,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11231169
1124 cases.add("bogus method call on slice",1170 cases.add("bogus method call on slice",
1125 \\var self = "aoeu";1171 \\var self = "aoeu";
1126 \\fn f(m: []const u8) {1172 \\fn f(m: []const u8) void {
1127 \\ m.copy(u8, self[0..], m);1173 \\ m.copy(u8, self[0..], m);
1128 \\}1174 \\}
1129 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }1175 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1130 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");1176 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
11311177
1132 cases.add("wrong number of arguments for method fn call",1178 cases.add("wrong number of arguments for method fn call",
1133 \\const Foo = struct {1179 \\const Foo = struct {
1134 \\ fn method(self: &const Foo, a: i32) {}1180 \\ fn method(self: &const Foo, a: i32) void {}
1135 \\};1181 \\};
1136 \\fn f(foo: &const Foo) {1182 \\fn f(foo: &const Foo) void {
1137 \\1183 \\
1138 \\ foo.method(1, 2);1184 \\ foo.method(1, 2);
1139 \\}1185 \\}
1140 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }1186 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
1141 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");1187 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
11421188
1143 cases.add("assign through constant pointer",1189 cases.add("assign through constant pointer",
1144 \\export fn f() {1190 \\export fn f() void {
1145 \\ var cstr = c"Hat";1191 \\ var cstr = c"Hat";
1146 \\ cstr[0] = 'W';1192 \\ cstr[0] = 'W';
1147 \\}1193 \\}
1148 , ".tmp_source.zig:3:11: error: cannot assign to constant");1194 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11491195
1150 cases.add("assign through constant slice",1196 cases.add("assign through constant slice",
1151 \\export fn f() {1197 \\export fn f() void {
1152 \\ var cstr: []const u8 = "Hat";1198 \\ var cstr: []const u8 = "Hat";
1153 \\ cstr[0] = 'W';1199 \\ cstr[0] = 'W';
1154 \\}1200 \\}
1155 , ".tmp_source.zig:3:11: error: cannot assign to constant");1201 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11561202
1157 cases.add("main function with bogus args type",1203 cases.add("main function with bogus args type",
1158 \\pub fn main(args: [][]bogus) -> %void {}1204 \\pub fn main(args: [][]bogus) %void {}
1159 , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");1205 , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");
11601206
1161 cases.add("for loop missing element param",1207 cases.add("for loop missing element param",
1162 \\fn foo(blah: []u8) {1208 \\fn foo(blah: []u8) void {
1163 \\ for (blah) { }1209 \\ for (blah) { }
1164 \\}1210 \\}
1165 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1211 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1166 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");1212 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
11671213
1168 cases.add("misspelled type with pointer only reference",1214 cases.add("misspelled type with pointer only reference",
...@@ -1189,27 +1235,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1189,27 +1235,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1189 \\ jobject: ?JsonOA,1235 \\ jobject: ?JsonOA,
1190 \\};1236 \\};
1191 \\1237 \\
1192 \\fn foo() {1238 \\fn foo() void {
1193 \\ var jll: JasonList = undefined;1239 \\ var jll: JasonList = undefined;
1194 \\ jll.init(1234);1240 \\ jll.init(1234);
1195 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };1241 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
1196 \\}1242 \\}
1197 \\1243 \\
1198 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1244 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1199 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");1245 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
12001246
1201 cases.add("method call with first arg type primitive",1247 cases.add("method call with first arg type primitive",
1202 \\const Foo = struct {1248 \\const Foo = struct {
1203 \\ x: i32,1249 \\ x: i32,
1204 \\1250 \\
1205 \\ fn init(x: i32) -> Foo {1251 \\ fn init(x: i32) Foo {
1206 \\ return Foo {1252 \\ return Foo {
1207 \\ .x = x,1253 \\ .x = x,
1208 \\ };1254 \\ };
1209 \\ }1255 \\ }
1210 \\};1256 \\};
1211 \\1257 \\
1212 \\export fn f() {1258 \\export fn f() void {
1213 \\ const derp = Foo.init(3);1259 \\ const derp = Foo.init(3);
1214 \\1260 \\
1215 \\ derp.init();1261 \\ derp.init();
...@@ -1221,7 +1267,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1221,7 +1267,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1221 \\ len: usize,1267 \\ len: usize,
1222 \\ allocator: &Allocator,1268 \\ allocator: &Allocator,
1223 \\1269 \\
1224 \\ pub fn init(allocator: &Allocator) -> List {1270 \\ pub fn init(allocator: &Allocator) List {
1225 \\ return List {1271 \\ return List {
1226 \\ .len = 0,1272 \\ .len = 0,
1227 \\ .allocator = allocator,1273 \\ .allocator = allocator,
...@@ -1237,7 +1283,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1237,7 +1283,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1237 \\ field: i32,1283 \\ field: i32,
1238 \\};1284 \\};
1239 \\1285 \\
1240 \\export fn foo() {1286 \\export fn foo() void {
1241 \\ var x = List.init(&global_allocator);1287 \\ var x = List.init(&global_allocator);
1242 \\ x.init();1288 \\ x.init();
1243 \\}1289 \\}
...@@ -1248,14 +1294,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1248,14 +1294,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1248 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;1294 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
1249 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);1295 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
1250 \\1296 \\
1251 \\export fn entry() -> usize { return @sizeOf(@typeOf(block_aligned_stuff)); }1297 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
1252 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");1298 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
12531299
1254 cases.addCase(x: {1300 cases.addCase(x: {
1255 const tc = cases.create("multiple files with private function error",1301 const tc = cases.create("multiple files with private function error",
1256 \\const foo = @import("foo.zig");1302 \\const foo = @import("foo.zig");
1257 \\1303 \\
1258 \\export fn callPrivFunction() {1304 \\export fn callPrivFunction() void {
1259 \\ foo.privateFunction();1305 \\ foo.privateFunction();
1260 \\}1306 \\}
1261 ,1307 ,
...@@ -1263,7 +1309,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1263,7 +1309,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1263 "foo.zig:1:1: note: declared here");1309 "foo.zig:1:1: note: declared here");
12641310
1265 tc.addSourceFile("foo.zig",1311 tc.addSourceFile("foo.zig",
1266 \\fn privateFunction() { }1312 \\fn privateFunction() void { }
1267 );1313 );
12681314
1269 break :x tc;1315 break :x tc;
...@@ -1273,21 +1319,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1273,21 +1319,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1273 \\const zero: i32 = 0;1319 \\const zero: i32 = 0;
1274 \\const a = zero{1};1320 \\const a = zero{1};
1275 \\1321 \\
1276 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }1322 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
1277 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");1323 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
12781324
1279 cases.add("assign to constant field",1325 cases.add("assign to constant field",
1280 \\const Foo = struct {1326 \\const Foo = struct {
1281 \\ field: i32,1327 \\ field: i32,
1282 \\};1328 \\};
1283 \\export fn derp() {1329 \\export fn derp() void {
1284 \\ const f = Foo {.field = 1234,};1330 \\ const f = Foo {.field = 1234,};
1285 \\ f.field = 0;1331 \\ f.field = 0;
1286 \\}1332 \\}
1287 , ".tmp_source.zig:6:13: error: cannot assign to constant");1333 , ".tmp_source.zig:6:13: error: cannot assign to constant");
12881334
1289 cases.add("return from defer expression",1335 cases.add("return from defer expression",
1290 \\pub fn testTrickyDefer() -> %void {1336 \\pub fn testTrickyDefer() %void {
1291 \\ defer canFail() catch {};1337 \\ defer canFail() catch {};
1292 \\1338 \\
1293 \\ defer try canFail();1339 \\ defer try canFail();
...@@ -1295,31 +1341,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1295,31 +1341,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1295 \\ const a = maybeInt() ?? return;1341 \\ const a = maybeInt() ?? return;
1296 \\}1342 \\}
1297 \\1343 \\
1298 \\fn canFail() -> %void { }1344 \\fn canFail() %void { }
1299 \\1345 \\
1300 \\pub fn maybeInt() -> ?i32 {1346 \\pub fn maybeInt() ?i32 {
1301 \\ return 0;1347 \\ return 0;
1302 \\}1348 \\}
1303 \\1349 \\
1304 \\export fn entry() -> usize { return @sizeOf(@typeOf(testTrickyDefer)); }1350 \\export fn entry() usize { return @sizeOf(@typeOf(testTrickyDefer)); }
1305 , ".tmp_source.zig:4:11: error: cannot return from defer expression");1351 , ".tmp_source.zig:4:11: error: cannot return from defer expression");
13061352
1307 cases.add("attempt to access var args out of bounds",1353 cases.add("attempt to access var args out of bounds",
1308 \\fn add(args: ...) -> i32 {1354 \\fn add(args: ...) i32 {
1309 \\ return args[0] + args[1];1355 \\ return args[0] + args[1];
1310 \\}1356 \\}
1311 \\1357 \\
1312 \\fn foo() -> i32 {1358 \\fn foo() i32 {
1313 \\ return add(i32(1234));1359 \\ return add(i32(1234));
1314 \\}1360 \\}
1315 \\1361 \\
1316 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1362 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1317 ,1363 ,
1318 ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",1364 ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",
1319 ".tmp_source.zig:6:15: note: called from here");1365 ".tmp_source.zig:6:15: note: called from here");
13201366
1321 cases.add("pass integer literal to var args",1367 cases.add("pass integer literal to var args",
1322 \\fn add(args: ...) -> i32 {1368 \\fn add(args: ...) i32 {
1323 \\ var sum = i32(0);1369 \\ var sum = i32(0);
1324 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {1370 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
1325 \\ sum += args[i];1371 \\ sum += args[i];
...@@ -1327,34 +1373,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1327,34 +1373,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1327 \\ return sum;1373 \\ return sum;
1328 \\}1374 \\}
1329 \\1375 \\
1330 \\fn bar() -> i32 {1376 \\fn bar() i32 {
1331 \\ return add(1, 2, 3, 4);1377 \\ return add(1, 2, 3, 4);
1332 \\}1378 \\}
1333 \\1379 \\
1334 \\export fn entry() -> usize { return @sizeOf(@typeOf(bar)); }1380 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
1335 , ".tmp_source.zig:10:16: error: parameter of type '(integer literal)' requires comptime");1381 , ".tmp_source.zig:10:16: error: parameter of type '(integer literal)' requires comptime");
13361382
1337 cases.add("assign too big number to u16",1383 cases.add("assign too big number to u16",
1338 \\export fn foo() {1384 \\export fn foo() void {
1339 \\ var vga_mem: u16 = 0xB8000;1385 \\ var vga_mem: u16 = 0xB8000;
1340 \\}1386 \\}
1341 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");1387 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13421388
1343 cases.add("global variable alignment non power of 2",1389 cases.add("global variable alignment non power of 2",
1344 \\const some_data: [100]u8 align(3) = undefined;1390 \\const some_data: [100]u8 align(3) = undefined;
1345 \\export fn entry() -> usize { return @sizeOf(@typeOf(some_data)); }1391 \\export fn entry() usize { return @sizeOf(@typeOf(some_data)); }
1346 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");1392 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
13471393
1348 cases.add("function alignment non power of 2",1394 cases.add("function alignment non power of 2",
1349 \\extern fn foo() align(3);1395 \\extern fn foo() align(3) void;
1350 \\export fn entry() { return foo(); }1396 \\export fn entry() void { return foo(); }
1351 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");1397 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13521398
1353 cases.add("compile log",1399 cases.add("compile log",
1354 \\export fn foo() {1400 \\export fn foo() void {
1355 \\ comptime bar(12, "hi");1401 \\ comptime bar(12, "hi");
1356 \\}1402 \\}
1357 \\fn bar(a: i32, b: []const u8) {1403 \\fn bar(a: i32, b: []const u8) void {
1358 \\ @compileLog("begin");1404 \\ @compileLog("begin");
1359 \\ @compileLog("a", a, "b", b);1405 \\ @compileLog("a", a, "b", b);
1360 \\ @compileLog("end");1406 \\ @compileLog("end");
...@@ -1374,15 +1420,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1374,15 +1420,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1374 \\ c: u2,1420 \\ c: u2,
1375 \\};1421 \\};
1376 \\1422 \\
1377 \\fn foo(bit_field: &const BitField) -> u3 {1423 \\fn foo(bit_field: &const BitField) u3 {
1378 \\ return bar(&bit_field.b);1424 \\ return bar(&bit_field.b);
1379 \\}1425 \\}
1380 \\1426 \\
1381 \\fn bar(x: &const u3) -> u3 {1427 \\fn bar(x: &const u3) u3 {
1382 \\ return *x;1428 \\ return *x;
1383 \\}1429 \\}
1384 \\1430 \\
1385 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1431 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1386 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");1432 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
13871433
1388 cases.add("referring to a struct that is invalid",1434 cases.add("referring to a struct that is invalid",
...@@ -1390,11 +1436,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1390,11 +1436,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1390 \\ Type: u8,1436 \\ Type: u8,
1391 \\};1437 \\};
1392 \\1438 \\
1393 \\export fn foo() {1439 \\export fn foo() void {
1394 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);1440 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
1395 \\}1441 \\}
1396 \\1442 \\
1397 \\fn assert(ok: bool) {1443 \\fn assert(ok: bool) void {
1398 \\ if (!ok) unreachable;1444 \\ if (!ok) unreachable;
1399 \\}1445 \\}
1400 ,1446 ,
...@@ -1402,92 +1448,92 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1402,92 +1448,92 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1402 ".tmp_source.zig:6:20: note: called from here");1448 ".tmp_source.zig:6:20: note: called from here");
14031449
1404 cases.add("control flow uses comptime var at runtime",1450 cases.add("control flow uses comptime var at runtime",
1405 \\export fn foo() {1451 \\export fn foo() void {
1406 \\ comptime var i = 0;1452 \\ comptime var i = 0;
1407 \\ while (i < 5) : (i += 1) {1453 \\ while (i < 5) : (i += 1) {
1408 \\ bar();1454 \\ bar();
1409 \\ }1455 \\ }
1410 \\}1456 \\}
1411 \\1457 \\
1412 \\fn bar() { }1458 \\fn bar() void { }
1413 ,1459 ,
1414 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",1460 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
1415 ".tmp_source.zig:3:24: note: compile-time variable assigned here");1461 ".tmp_source.zig:3:24: note: compile-time variable assigned here");
14161462
1417 cases.add("ignored return value",1463 cases.add("ignored return value",
1418 \\export fn foo() {1464 \\export fn foo() void {
1419 \\ bar();1465 \\ bar();
1420 \\}1466 \\}
1421 \\fn bar() -> i32 { return 0; }1467 \\fn bar() i32 { return 0; }
1422 , ".tmp_source.zig:2:8: error: expression value is ignored");1468 , ".tmp_source.zig:2:8: error: expression value is ignored");
14231469
1424 cases.add("ignored assert-err-ok return value",1470 cases.add("ignored assert-err-ok return value",
1425 \\export fn foo() {1471 \\export fn foo() void {
1426 \\ bar() catch unreachable;1472 \\ bar() catch unreachable;
1427 \\}1473 \\}
1428 \\fn bar() -> %i32 { return 0; }1474 \\fn bar() %i32 { return 0; }
1429 , ".tmp_source.zig:2:11: error: expression value is ignored");1475 , ".tmp_source.zig:2:11: error: expression value is ignored");
14301476
1431 cases.add("ignored statement value",1477 cases.add("ignored statement value",
1432 \\export fn foo() {1478 \\export fn foo() void {
1433 \\ 1;1479 \\ 1;
1434 \\}1480 \\}
1435 , ".tmp_source.zig:2:5: error: expression value is ignored");1481 , ".tmp_source.zig:2:5: error: expression value is ignored");
14361482
1437 cases.add("ignored comptime statement value",1483 cases.add("ignored comptime statement value",
1438 \\export fn foo() {1484 \\export fn foo() void {
1439 \\ comptime {1;}1485 \\ comptime {1;}
1440 \\}1486 \\}
1441 , ".tmp_source.zig:2:15: error: expression value is ignored");1487 , ".tmp_source.zig:2:15: error: expression value is ignored");
14421488
1443 cases.add("ignored comptime value",1489 cases.add("ignored comptime value",
1444 \\export fn foo() {1490 \\export fn foo() void {
1445 \\ comptime 1;1491 \\ comptime 1;
1446 \\}1492 \\}
1447 , ".tmp_source.zig:2:5: error: expression value is ignored");1493 , ".tmp_source.zig:2:5: error: expression value is ignored");
14481494
1449 cases.add("ignored defered statement value",1495 cases.add("ignored defered statement value",
1450 \\export fn foo() {1496 \\export fn foo() void {
1451 \\ defer {1;}1497 \\ defer {1;}
1452 \\}1498 \\}
1453 , ".tmp_source.zig:2:12: error: expression value is ignored");1499 , ".tmp_source.zig:2:12: error: expression value is ignored");
14541500
1455 cases.add("ignored defered function call",1501 cases.add("ignored defered function call",
1456 \\export fn foo() {1502 \\export fn foo() void {
1457 \\ defer bar();1503 \\ defer bar();
1458 \\}1504 \\}
1459 \\fn bar() -> %i32 { return 0; }1505 \\fn bar() %i32 { return 0; }
1460 , ".tmp_source.zig:2:14: error: expression value is ignored");1506 , ".tmp_source.zig:2:14: error: expression value is ignored");
14611507
1462 cases.add("dereference an array",1508 cases.add("dereference an array",
1463 \\var s_buffer: [10]u8 = undefined;1509 \\var s_buffer: [10]u8 = undefined;
1464 \\pub fn pass(in: []u8) -> []u8 {1510 \\pub fn pass(in: []u8) []u8 {
1465 \\ var out = &s_buffer;1511 \\ var out = &s_buffer;
1466 \\ *out[0] = in[0];1512 \\ *out[0] = in[0];
1467 \\ return (*out)[0..1];1513 \\ return (*out)[0..1];
1468 \\}1514 \\}
1469 \\1515 \\
1470 \\export fn entry() -> usize { return @sizeOf(@typeOf(pass)); }1516 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
1471 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");1517 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
14721518
1473 cases.add("pass const ptr to mutable ptr fn",1519 cases.add("pass const ptr to mutable ptr fn",
1474 \\fn foo() -> bool {1520 \\fn foo() bool {
1475 \\ const a = ([]const u8)("a");1521 \\ const a = ([]const u8)("a");
1476 \\ const b = &a;1522 \\ const b = &a;
1477 \\ return ptrEql(b, b);1523 \\ return ptrEql(b, b);
1478 \\}1524 \\}
1479 \\fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {1525 \\fn ptrEql(a: &[]const u8, b: &[]const u8) bool {
1480 \\ return true;1526 \\ return true;
1481 \\}1527 \\}
1482 \\1528 \\
1483 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1529 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1484 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");1530 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");
14851531
1486 cases.addCase(x: {1532 cases.addCase(x: {
1487 const tc = cases.create("export collision",1533 const tc = cases.create("export collision",
1488 \\const foo = @import("foo.zig");1534 \\const foo = @import("foo.zig");
1489 \\1535 \\
1490 \\export fn bar() -> usize {1536 \\export fn bar() usize {
1491 \\ return foo.baz;1537 \\ return foo.baz;
1492 \\}1538 \\}
1493 ,1539 ,
...@@ -1495,7 +1541,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1495,7 +1541,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1495 ".tmp_source.zig:3:8: note: other symbol here");1541 ".tmp_source.zig:3:8: note: other symbol here");
14961542
1497 tc.addSourceFile("foo.zig",1543 tc.addSourceFile("foo.zig",
1498 \\export fn bar() {}1544 \\export fn bar() void {}
1499 \\pub const baz = 1234;1545 \\pub const baz = 1234;
1500 );1546 );
15011547
...@@ -1504,20 +1550,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1504,20 +1550,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15041550
1505 cases.add("pass non-copyable type by value to function",1551 cases.add("pass non-copyable type by value to function",
1506 \\const Point = struct { x: i32, y: i32, };1552 \\const Point = struct { x: i32, y: i32, };
1507 \\fn foo(p: Point) { }1553 \\fn foo(p: Point) void { }
1508 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1554 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1509 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");1555 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
15101556
1511 cases.add("implicit cast from array to mutable slice",1557 cases.add("implicit cast from array to mutable slice",
1512 \\var global_array: [10]i32 = undefined;1558 \\var global_array: [10]i32 = undefined;
1513 \\fn foo(param: []i32) {}1559 \\fn foo(param: []i32) void {}
1514 \\export fn entry() {1560 \\export fn entry() void {
1515 \\ foo(global_array);1561 \\ foo(global_array);
1516 \\}1562 \\}
1517 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");1563 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
15181564
1519 cases.add("ptrcast to non-pointer",1565 cases.add("ptrcast to non-pointer",
1520 \\export fn entry(a: &i32) -> usize {1566 \\export fn entry(a: &i32) usize {
1521 \\ return @ptrCast(usize, a);1567 \\ return @ptrCast(usize, a);
1522 \\}1568 \\}
1523 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");1569 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
...@@ -1525,10 +1571,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1525,10 +1571,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1525 cases.add("too many error values to cast to small integer",1571 cases.add("too many error values to cast to small integer",
1526 \\error A; error B; error C; error D; error E; error F; error G; error H;1572 \\error A; error B; error C; error D; error E; error F; error G; error H;
1527 \\const u2 = @IntType(false, 2);1573 \\const u2 = @IntType(false, 2);
1528 \\fn foo(e: error) -> u2 {1574 \\fn foo(e: error) u2 {
1529 \\ return u2(e);1575 \\ return u2(e);
1530 \\}1576 \\}
1531 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }1577 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
1532 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");1578 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");
15331579
1534 cases.add("asm at compile time",1580 cases.add("asm at compile time",
...@@ -1536,7 +1582,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1536,7 +1582,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1536 \\ doSomeAsm();1582 \\ doSomeAsm();
1537 \\}1583 \\}
1538 \\1584 \\
1539 \\fn doSomeAsm() {1585 \\fn doSomeAsm() void {
1540 \\ asm volatile (1586 \\ asm volatile (
1541 \\ \\.globl aoeu;1587 \\ \\.globl aoeu;
1542 \\ \\.type aoeu, @function;1588 \\ \\.type aoeu, @function;
...@@ -1547,13 +1593,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1547,13 +1593,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15471593
1548 cases.add("invalid member of builtin enum",1594 cases.add("invalid member of builtin enum",
1549 \\const builtin = @import("builtin");1595 \\const builtin = @import("builtin");
1550 \\export fn entry() {1596 \\export fn entry() void {
1551 \\ const foo = builtin.Arch.x86;1597 \\ const foo = builtin.Arch.x86;
1552 \\}1598 \\}
1553 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");1599 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");
15541600
1555 cases.add("int to ptr of 0 bits",1601 cases.add("int to ptr of 0 bits",
1556 \\export fn foo() {1602 \\export fn foo() void {
1557 \\ var x: usize = 0x1000;1603 \\ var x: usize = 0x1000;
1558 \\ var y: &void = @intToPtr(&void, x);1604 \\ var y: &void = @intToPtr(&void, x);
1559 \\}1605 \\}
...@@ -1561,25 +1607,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1561,25 +1607,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15611607
1562 cases.add("@fieldParentPtr - non struct",1608 cases.add("@fieldParentPtr - non struct",
1563 \\const Foo = i32;1609 \\const Foo = i32;
1564 \\export fn foo(a: &i32) -> &Foo {1610 \\export fn foo(a: &i32) &Foo {
1565 \\ return @fieldParentPtr(Foo, "a", a);1611 \\ return @fieldParentPtr(Foo, "a", a);
1566 \\}1612 \\}
1567 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");1613 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
15681614
1569 cases.add("@fieldParentPtr - bad field name",1615 cases.add("@fieldParentPtr - bad field name",
1570 \\const Foo = struct {1616 \\const Foo = extern struct {
1571 \\ derp: i32,1617 \\ derp: i32,
1572 \\};1618 \\};
1573 \\export fn foo(a: &i32) -> &Foo {1619 \\export fn foo(a: &i32) &Foo {
1574 \\ return @fieldParentPtr(Foo, "a", a);1620 \\ return @fieldParentPtr(Foo, "a", a);
1575 \\}1621 \\}
1576 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");1622 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
15771623
1578 cases.add("@fieldParentPtr - field pointer is not pointer",1624 cases.add("@fieldParentPtr - field pointer is not pointer",
1579 \\const Foo = struct {1625 \\const Foo = extern struct {
1580 \\ a: i32,1626 \\ a: i32,
1581 \\};1627 \\};
1582 \\export fn foo(a: i32) -> &Foo {1628 \\export fn foo(a: i32) &Foo {
1583 \\ return @fieldParentPtr(Foo, "a", a);1629 \\ return @fieldParentPtr(Foo, "a", a);
1584 \\}1630 \\}
1585 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");1631 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
...@@ -1611,7 +1657,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1611,7 +1657,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16111657
1612 cases.add("@offsetOf - non struct",1658 cases.add("@offsetOf - non struct",
1613 \\const Foo = i32;1659 \\const Foo = i32;
1614 \\export fn foo() -> usize {1660 \\export fn foo() usize {
1615 \\ return @offsetOf(Foo, "a");1661 \\ return @offsetOf(Foo, "a");
1616 \\}1662 \\}
1617 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");1663 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");
...@@ -1620,7 +1666,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1620,7 +1666,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1620 \\const Foo = struct {1666 \\const Foo = struct {
1621 \\ derp: i32,1667 \\ derp: i32,
1622 \\};1668 \\};
1623 \\export fn foo() -> usize {1669 \\export fn foo() usize {
1624 \\ return @offsetOf(Foo, "a");1670 \\ return @offsetOf(Foo, "a");
1625 \\}1671 \\}
1626 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");1672 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");
...@@ -1630,21 +1676,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1630,21 +1676,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1630 , "error: no member named 'main' in '");1676 , "error: no member named 'main' in '");
16311677
1632 cases.addExe("private main fn",1678 cases.addExe("private main fn",
1633 \\fn main() {}1679 \\fn main() void {}
1634 ,1680 ,
1635 "error: 'main' is private",1681 "error: 'main' is private",
1636 ".tmp_source.zig:1:1: note: declared here");1682 ".tmp_source.zig:1:1: note: declared here");
16371683
1638 cases.add("setting a section on an extern variable",1684 cases.add("setting a section on an extern variable",
1639 \\extern var foo: i32 section(".text2");1685 \\extern var foo: i32 section(".text2");
1640 \\export fn entry() -> i32 {1686 \\export fn entry() i32 {
1641 \\ return foo;1687 \\ return foo;
1642 \\}1688 \\}
1643 ,1689 ,
1644 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");1690 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");
16451691
1646 cases.add("setting a section on a local variable",1692 cases.add("setting a section on a local variable",
1647 \\export fn entry() -> i32 {1693 \\export fn entry() i32 {
1648 \\ var foo: i32 section(".text2") = 1234;1694 \\ var foo: i32 section(".text2") = 1234;
1649 \\ return foo;1695 \\ return foo;
1650 \\}1696 \\}
...@@ -1652,15 +1698,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1652,15 +1698,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1652 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");1698 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");
16531699
1654 cases.add("setting a section on an extern fn",1700 cases.add("setting a section on an extern fn",
1655 \\extern fn foo() section(".text2");1701 \\extern fn foo() section(".text2") void;
1656 \\export fn entry() {1702 \\export fn entry() void {
1657 \\ foo();1703 \\ foo();
1658 \\}1704 \\}
1659 ,1705 ,
1660 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");1706 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");
16611707
1662 cases.add("returning address of local variable - simple",1708 cases.add("returning address of local variable - simple",
1663 \\export fn foo() -> &i32 {1709 \\export fn foo() &i32 {
1664 \\ var a: i32 = undefined;1710 \\ var a: i32 = undefined;
1665 \\ return &a;1711 \\ return &a;
1666 \\}1712 \\}
...@@ -1668,7 +1714,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1668,7 +1714,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1668 ".tmp_source.zig:3:13: error: function returns address of local variable");1714 ".tmp_source.zig:3:13: error: function returns address of local variable");
16691715
1670 cases.add("returning address of local variable - phi",1716 cases.add("returning address of local variable - phi",
1671 \\export fn foo(c: bool) -> &i32 {1717 \\export fn foo(c: bool) &i32 {
1672 \\ var a: i32 = undefined;1718 \\ var a: i32 = undefined;
1673 \\ var b: i32 = undefined;1719 \\ var b: i32 = undefined;
1674 \\ return if (c) &a else &b;1720 \\ return if (c) &a else &b;
...@@ -1677,13 +1723,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1677,13 +1723,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1677 ".tmp_source.zig:4:12: error: function returns address of local variable");1723 ".tmp_source.zig:4:12: error: function returns address of local variable");
16781724
1679 cases.add("inner struct member shadowing outer struct member",1725 cases.add("inner struct member shadowing outer struct member",
1680 \\fn A() -> type {1726 \\fn A() type {
1681 \\ return struct {1727 \\ return struct {
1682 \\ b: B(),1728 \\ b: B(),
1683 \\1729 \\
1684 \\ const Self = this;1730 \\ const Self = this;
1685 \\1731 \\
1686 \\ fn B() -> type {1732 \\ fn B() type {
1687 \\ return struct {1733 \\ return struct {
1688 \\ const Self = this;1734 \\ const Self = this;
1689 \\ };1735 \\ };
...@@ -1693,7 +1739,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1693,7 +1739,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1693 \\comptime {1739 \\comptime {
1694 \\ assert(A().B().Self != A().Self);1740 \\ assert(A().B().Self != A().Self);
1695 \\}1741 \\}
1696 \\fn assert(ok: bool) {1742 \\fn assert(ok: bool) void {
1697 \\ if (!ok) unreachable;1743 \\ if (!ok) unreachable;
1698 \\}1744 \\}
1699 ,1745 ,
...@@ -1701,87 +1747,87 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1701,87 +1747,87 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1701 ".tmp_source.zig:5:9: note: previous definition is here");1747 ".tmp_source.zig:5:9: note: previous definition is here");
17021748
1703 cases.add("while expected bool, got nullable",1749 cases.add("while expected bool, got nullable",
1704 \\export fn foo() {1750 \\export fn foo() void {
1705 \\ while (bar()) {}1751 \\ while (bar()) {}
1706 \\}1752 \\}
1707 \\fn bar() -> ?i32 { return 1; }1753 \\fn bar() ?i32 { return 1; }
1708 ,1754 ,
1709 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");1755 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");
17101756
1711 cases.add("while expected bool, got error union",1757 cases.add("while expected bool, got error union",
1712 \\export fn foo() {1758 \\export fn foo() void {
1713 \\ while (bar()) {}1759 \\ while (bar()) {}
1714 \\}1760 \\}
1715 \\fn bar() -> %i32 { return 1; }1761 \\fn bar() %i32 { return 1; }
1716 ,1762 ,
1717 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");1763 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");
17181764
1719 cases.add("while expected nullable, got bool",1765 cases.add("while expected nullable, got bool",
1720 \\export fn foo() {1766 \\export fn foo() void {
1721 \\ while (bar()) |x| {}1767 \\ while (bar()) |x| {}
1722 \\}1768 \\}
1723 \\fn bar() -> bool { return true; }1769 \\fn bar() bool { return true; }
1724 ,1770 ,
1725 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");1771 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");
17261772
1727 cases.add("while expected nullable, got error union",1773 cases.add("while expected nullable, got error union",
1728 \\export fn foo() {1774 \\export fn foo() void {
1729 \\ while (bar()) |x| {}1775 \\ while (bar()) |x| {}
1730 \\}1776 \\}
1731 \\fn bar() -> %i32 { return 1; }1777 \\fn bar() %i32 { return 1; }
1732 ,1778 ,
1733 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");1779 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");
17341780
1735 cases.add("while expected error union, got bool",1781 cases.add("while expected error union, got bool",
1736 \\export fn foo() {1782 \\export fn foo() void {
1737 \\ while (bar()) |x| {} else |err| {}1783 \\ while (bar()) |x| {} else |err| {}
1738 \\}1784 \\}
1739 \\fn bar() -> bool { return true; }1785 \\fn bar() bool { return true; }
1740 ,1786 ,
1741 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");1787 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");
17421788
1743 cases.add("while expected error union, got nullable",1789 cases.add("while expected error union, got nullable",
1744 \\export fn foo() {1790 \\export fn foo() void {
1745 \\ while (bar()) |x| {} else |err| {}1791 \\ while (bar()) |x| {} else |err| {}
1746 \\}1792 \\}
1747 \\fn bar() -> ?i32 { return 1; }1793 \\fn bar() ?i32 { return 1; }
1748 ,1794 ,
1749 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");1795 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");
17501796
1751 cases.add("inline fn calls itself indirectly",1797 cases.add("inline fn calls itself indirectly",
1752 \\export fn foo() {1798 \\export fn foo() void {
1753 \\ bar();1799 \\ bar();
1754 \\}1800 \\}
1755 \\inline fn bar() {1801 \\inline fn bar() void {
1756 \\ baz();1802 \\ baz();
1757 \\ quux();1803 \\ quux();
1758 \\}1804 \\}
1759 \\inline fn baz() {1805 \\inline fn baz() void {
1760 \\ bar();1806 \\ bar();
1761 \\ quux();1807 \\ quux();
1762 \\}1808 \\}
1763 \\extern fn quux();1809 \\extern fn quux() void;
1764 ,1810 ,
1765 ".tmp_source.zig:4:8: error: unable to inline function");1811 ".tmp_source.zig:4:8: error: unable to inline function");
17661812
1767 cases.add("save reference to inline function",1813 cases.add("save reference to inline function",
1768 \\export fn foo() {1814 \\export fn foo() void {
1769 \\ quux(@ptrToInt(bar));1815 \\ quux(@ptrToInt(bar));
1770 \\}1816 \\}
1771 \\inline fn bar() { }1817 \\inline fn bar() void { }
1772 \\extern fn quux(usize);1818 \\extern fn quux(usize) void;
1773 ,1819 ,
1774 ".tmp_source.zig:4:8: error: unable to inline function");1820 ".tmp_source.zig:4:8: error: unable to inline function");
17751821
1776 cases.add("signed integer division",1822 cases.add("signed integer division",
1777 \\export fn foo(a: i32, b: i32) -> i32 {1823 \\export fn foo(a: i32, b: i32) i32 {
1778 \\ return a / b;1824 \\ return a / b;
1779 \\}1825 \\}
1780 ,1826 ,
1781 ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");1827 ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");
17821828
1783 cases.add("signed integer remainder division",1829 cases.add("signed integer remainder division",
1784 \\export fn foo(a: i32, b: i32) -> i32 {1830 \\export fn foo(a: i32, b: i32) i32 {
1785 \\ return a % b;1831 \\ return a % b;
1786 \\}1832 \\}
1787 ,1833 ,
...@@ -1802,7 +1848,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1802,7 +1848,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1802 \\ const c = a / b;1848 \\ const c = a / b;
1803 \\}1849 \\}
1804 ,1850 ,
1805 ".tmp_source.zig:4:17: error: division by zero is undefined");1851 ".tmp_source.zig:4:17: error: division by zero");
18061852
1807 cases.add("compile-time remainder division by zero",1853 cases.add("compile-time remainder division by zero",
1808 \\comptime {1854 \\comptime {
...@@ -1811,7 +1857,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1811,7 +1857,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1811 \\ const c = a % b;1857 \\ const c = a % b;
1812 \\}1858 \\}
1813 ,1859 ,
1814 ".tmp_source.zig:4:17: error: division by zero is undefined");1860 ".tmp_source.zig:4:17: error: division by zero");
18151861
1816 cases.add("compile-time integer cast truncates bits",1862 cases.add("compile-time integer cast truncates bits",
1817 \\comptime {1863 \\comptime {
...@@ -1821,17 +1867,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1821,17 +1867,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1821 ,1867 ,
1822 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");1868 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
18231869
1824 cases.add("@setDebugSafety twice for same scope",1870 cases.add("@setRuntimeSafety twice for same scope",
1825 \\export fn foo() {1871 \\export fn foo() void {
1826 \\ @setDebugSafety(this, false);1872 \\ @setRuntimeSafety(false);
1827 \\ @setDebugSafety(this, false);1873 \\ @setRuntimeSafety(false);
1828 \\}1874 \\}
1829 ,1875 ,
1830 ".tmp_source.zig:3:5: error: debug safety set twice for same scope",1876 ".tmp_source.zig:3:5: error: runtime safety set twice for same scope",
1831 ".tmp_source.zig:2:5: note: first set here");1877 ".tmp_source.zig:2:5: note: first set here");
18321878
1833 cases.add("@setFloatMode twice for same scope",1879 cases.add("@setFloatMode twice for same scope",
1834 \\export fn foo() {1880 \\export fn foo() void {
1835 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);1881 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
1836 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);1882 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
1837 \\}1883 \\}
...@@ -1840,14 +1886,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1840,14 +1886,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1840 ".tmp_source.zig:2:5: note: first set here");1886 ".tmp_source.zig:2:5: note: first set here");
18411887
1842 cases.add("array access of type",1888 cases.add("array access of type",
1843 \\export fn foo() {1889 \\export fn foo() void {
1844 \\ var b: u8[40] = undefined;1890 \\ var b: u8[40] = undefined;
1845 \\}1891 \\}
1846 ,1892 ,
1847 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");1893 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");
18481894
1849 cases.add("cannot break out of defer expression",1895 cases.add("cannot break out of defer expression",
1850 \\export fn foo() {1896 \\export fn foo() void {
1851 \\ while (true) {1897 \\ while (true) {
1852 \\ defer {1898 \\ defer {
1853 \\ break;1899 \\ break;
...@@ -1858,7 +1904,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1858,7 +1904,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1858 ".tmp_source.zig:4:13: error: cannot break out of defer expression");1904 ".tmp_source.zig:4:13: error: cannot break out of defer expression");
18591905
1860 cases.add("cannot continue out of defer expression",1906 cases.add("cannot continue out of defer expression",
1861 \\export fn foo() {1907 \\export fn foo() void {
1862 \\ while (true) {1908 \\ while (true) {
1863 \\ defer {1909 \\ defer {
1864 \\ continue;1910 \\ continue;
...@@ -1869,24 +1915,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1869,24 +1915,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1869 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");1915 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");
18701916
1871 cases.add("calling a var args function only known at runtime",1917 cases.add("calling a var args function only known at runtime",
1872 \\var foos = []fn(...) { foo1, foo2 };1918 \\var foos = []fn(...) void { foo1, foo2 };
1873 \\1919 \\
1874 \\fn foo1(args: ...) {}1920 \\fn foo1(args: ...) void {}
1875 \\fn foo2(args: ...) {}1921 \\fn foo2(args: ...) void {}
1876 \\1922 \\
1877 \\pub fn main() -> %void {1923 \\pub fn main() %void {
1878 \\ foos[0]();1924 \\ foos[0]();
1879 \\}1925 \\}
1880 ,1926 ,
1881 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");1927 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");
18821928
1883 cases.add("calling a generic function only known at runtime",1929 cases.add("calling a generic function only known at runtime",
1884 \\var foos = []fn(var) { foo1, foo2 };1930 \\var foos = []fn(var) void { foo1, foo2 };
1885 \\1931 \\
1886 \\fn foo1(arg: var) {}1932 \\fn foo1(arg: var) void {}
1887 \\fn foo2(arg: var) {}1933 \\fn foo2(arg: var) void {}
1888 \\1934 \\
1889 \\pub fn main() -> %void {1935 \\pub fn main() %void {
1890 \\ foos[0](true);1936 \\ foos[0](true);
1891 \\}1937 \\}
1892 ,1938 ,
...@@ -1898,7 +1944,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1898,7 +1944,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1898 \\const bar = baz + foo;1944 \\const bar = baz + foo;
1899 \\const baz = 1;1945 \\const baz = 1;
1900 \\1946 \\
1901 \\export fn entry() -> i32 {1947 \\export fn entry() i32 {
1902 \\ return bar;1948 \\ return bar;
1903 \\}1949 \\}
1904 ,1950 ,
...@@ -1913,7 +1959,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1913,7 +1959,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1913 \\1959 \\
1914 \\var foo: Foo = undefined;1960 \\var foo: Foo = undefined;
1915 \\1961 \\
1916 \\export fn entry() -> usize {1962 \\export fn entry() usize {
1917 \\ return @sizeOf(@typeOf(foo.x));1963 \\ return @sizeOf(@typeOf(foo.x));
1918 \\}1964 \\}
1919 ,1965 ,
...@@ -1934,14 +1980,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1934,14 +1980,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1934 ".tmp_source.zig:2:15: error: float literal out of range of any type");1980 ".tmp_source.zig:2:15: error: float literal out of range of any type");
19351981
1936 cases.add("explicit cast float literal to integer when there is a fraction component",1982 cases.add("explicit cast float literal to integer when there is a fraction component",
1937 \\export fn entry() -> i32 {1983 \\export fn entry() i32 {
1938 \\ return i32(12.34);1984 \\ return i32(12.34);
1939 \\}1985 \\}
1940 ,1986 ,
1941 ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");1987 ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");
19421988
1943 cases.add("non pointer given to @ptrToInt",1989 cases.add("non pointer given to @ptrToInt",
1944 \\export fn entry(x: i32) -> usize {1990 \\export fn entry(x: i32) usize {
1945 \\ return @ptrToInt(x);1991 \\ return @ptrToInt(x);
1946 \\}1992 \\}
1947 ,1993 ,
...@@ -1962,14 +2008,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1962,14 +2008,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1962 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");2008 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");
19632009
1964 cases.add("shifting without int type or comptime known",2010 cases.add("shifting without int type or comptime known",
1965 \\export fn entry(x: u8) -> u8 {2011 \\export fn entry(x: u8) u8 {
1966 \\ return 0x11 << x;2012 \\ return 0x11 << x;
1967 \\}2013 \\}
1968 ,2014 ,
1969 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");2015 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");
19702016
1971 cases.add("shifting RHS is log2 of LHS int bit width",2017 cases.add("shifting RHS is log2 of LHS int bit width",
1972 \\export fn entry(x: u8, y: u8) -> u8 {2018 \\export fn entry(x: u8, y: u8) u8 {
1973 \\ return x << y;2019 \\ return x << y;
1974 \\}2020 \\}
1975 ,2021 ,
...@@ -1977,7 +2023,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1977,7 +2023,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19772023
1978 cases.add("globally shadowing a primitive type",2024 cases.add("globally shadowing a primitive type",
1979 \\const u16 = @intType(false, 8);2025 \\const u16 = @intType(false, 8);
1980 \\export fn entry() {2026 \\export fn entry() void {
1981 \\ const a: u16 = 300;2027 \\ const a: u16 = 300;
1982 \\}2028 \\}
1983 ,2029 ,
...@@ -1989,12 +2035,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -1989,12 +2035,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
1989 \\ b: u32,2035 \\ b: u32,
1990 \\};2036 \\};
1991 \\2037 \\
1992 \\export fn entry() {2038 \\export fn entry() void {
1993 \\ var foo = Foo { .a = 1, .b = 10 };2039 \\ var foo = Foo { .a = 1, .b = 10 };
1994 \\ bar(&foo.b);2040 \\ bar(&foo.b);
1995 \\}2041 \\}
1996 \\2042 \\
1997 \\fn bar(x: &u32) {2043 \\fn bar(x: &u32) void {
1998 \\ *x += 1;2044 \\ *x += 1;
1999 \\}2045 \\}
2000 ,2046 ,
...@@ -2006,20 +2052,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2006,20 +2052,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2006 \\ b: u32,2052 \\ b: u32,
2007 \\};2053 \\};
2008 \\2054 \\
2009 \\export fn entry() {2055 \\export fn entry() void {
2010 \\ var foo = Foo { .a = 1, .b = 10 };2056 \\ var foo = Foo { .a = 1, .b = 10 };
2011 \\ foo.b += 1;2057 \\ foo.b += 1;
2012 \\ bar((&foo.b)[0..1]);2058 \\ bar((&foo.b)[0..1]);
2013 \\}2059 \\}
2014 \\2060 \\
2015 \\fn bar(x: []u32) {2061 \\fn bar(x: []u32) void {
2016 \\ x[0] += 1;2062 \\ x[0] += 1;
2017 \\}2063 \\}
2018 ,2064 ,
2019 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");2065 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
20202066
2021 cases.add("increase pointer alignment in @ptrCast",2067 cases.add("increase pointer alignment in @ptrCast",
2022 \\export fn entry() -> u32 {2068 \\export fn entry() u32 {
2023 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};2069 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
2024 \\ const ptr = @ptrCast(&u32, &bytes[0]);2070 \\ const ptr = @ptrCast(&u32, &bytes[0]);
2025 \\ return *ptr;2071 \\ return *ptr;
...@@ -2030,7 +2076,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2030,7 +2076,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2030 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");2076 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");
20312077
2032 cases.add("increase pointer alignment in slice resize",2078 cases.add("increase pointer alignment in slice resize",
2033 \\export fn entry() -> u32 {2079 \\export fn entry() u32 {
2034 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};2080 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
2035 \\ return ([]u32)(bytes[0..])[0];2081 \\ return ([]u32)(bytes[0..])[0];
2036 \\}2082 \\}
...@@ -2040,26 +2086,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2040,26 +2086,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2040 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");2086 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");
20412087
2042 cases.add("@alignCast expects pointer or slice",2088 cases.add("@alignCast expects pointer or slice",
2043 \\export fn entry() {2089 \\export fn entry() void {
2044 \\ @alignCast(4, u32(3));2090 \\ @alignCast(4, u32(3));
2045 \\}2091 \\}
2046 ,2092 ,
2047 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");2093 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");
20482094
2049 cases.add("passing an under-aligned function pointer",2095 cases.add("passing an under-aligned function pointer",
2050 \\export fn entry() {2096 \\export fn entry() void {
2051 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);2097 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
2052 \\}2098 \\}
2053 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {2099 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) i32, answer: i32) void {
2054 \\ if (ptr() != answer) unreachable;2100 \\ if (ptr() != answer) unreachable;
2055 \\}2101 \\}
2056 \\fn alignedSmall() align(4) -> i32 { return 1234; }2102 \\fn alignedSmall() align(4) i32 { return 1234; }
2057 ,2103 ,
2058 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) -> i32', found 'fn() align(4) -> i32'");2104 ".tmp_source.zig:2:35: error: expected type 'fn() align(8) i32', found 'fn() align(4) i32'");
20592105
2060 cases.add("passing a not-aligned-enough pointer to cmpxchg",2106 cases.add("passing a not-aligned-enough pointer to cmpxchg",
2061 \\const AtomicOrder = @import("builtin").AtomicOrder;2107 \\const AtomicOrder = @import("builtin").AtomicOrder;
2062 \\export fn entry() -> bool {2108 \\export fn entry() bool {
2063 \\ var x: i32 align(1) = 1234;2109 \\ var x: i32 align(1) = 1234;
2064 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}2110 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
2065 \\ return x == 5678;2111 \\ return x == 5678;
...@@ -2078,7 +2124,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2078,7 +2124,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2078 \\comptime {2124 \\comptime {
2079 \\ foo();2125 \\ foo();
2080 \\}2126 \\}
2081 \\fn foo() {2127 \\fn foo() void {
2082 \\ @setEvalBranchQuota(1001);2128 \\ @setEvalBranchQuota(1001);
2083 \\}2129 \\}
2084 ,2130 ,
...@@ -2088,8 +2134,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2088,8 +2134,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20882134
2089 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",2135 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",
2090 \\const Derp = @OpaqueType();2136 \\const Derp = @OpaqueType();
2091 \\extern fn bar(d: &Derp);2137 \\extern fn bar(d: &Derp) void;
2092 \\export fn foo() {2138 \\export fn foo() void {
2093 \\ const x = u8(1);2139 \\ const x = u8(1);
2094 \\ bar(@ptrCast(&c_void, &x));2140 \\ bar(@ptrCast(&c_void, &x));
2095 \\}2141 \\}
...@@ -2099,7 +2145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2099,7 +2145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2099 cases.add("non-const variables of things that require const variables",2145 cases.add("non-const variables of things that require const variables",
2100 \\const Opaque = @OpaqueType();2146 \\const Opaque = @OpaqueType();
2101 \\2147 \\
2102 \\export fn entry(opaque: &Opaque) {2148 \\export fn entry(opaque: &Opaque) void {
2103 \\ var m2 = &2;2149 \\ var m2 = &2;
2104 \\ const y: u32 = *m2;2150 \\ const y: u32 = *m2;
2105 \\2151 \\
...@@ -2117,7 +2163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2117,7 +2163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2117 \\}2163 \\}
2118 \\2164 \\
2119 \\const Foo = struct {2165 \\const Foo = struct {
2120 \\ fn bar(self: &const Foo) {}2166 \\ fn bar(self: &const Foo) void {}
2121 \\};2167 \\};
2122 ,2168 ,
2123 ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",2169 ".tmp_source.zig:4:4: error: variable of type '&const (integer literal)' must be const or comptime",
...@@ -2129,11 +2175,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2129,11 +2175,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2129 ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",2175 ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",
2130 ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",2176 ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",
2131 ".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",2177 ".tmp_source.zig:14:4: error: variable of type '(namespace)' must be const or comptime",
2132 ".tmp_source.zig:15:4: error: variable of type '(bound fn(&const Foo))' must be const or comptime",2178 ".tmp_source.zig:15:4: error: variable of type '(bound fn(&const Foo) void)' must be const or comptime",
2133 ".tmp_source.zig:17:4: error: unreachable code");2179 ".tmp_source.zig:17:4: error: unreachable code");
21342180
2135 cases.add("wrong types given to atomic order args in cmpxchg",2181 cases.add("wrong types given to atomic order args in cmpxchg",
2136 \\export fn entry() {2182 \\export fn entry() void {
2137 \\ var x: i32 = 1234;2183 \\ var x: i32 = 1234;
2138 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}2184 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}
2139 \\}2185 \\}
...@@ -2141,7 +2187,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2141,7 +2187,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2141 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");2187 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");
21422188
2143 cases.add("wrong types given to @export",2189 cases.add("wrong types given to @export",
2144 \\extern fn entry() { }2190 \\extern fn entry() void { }
2145 \\comptime {2191 \\comptime {
2146 \\ @export("entry", entry, u32(1234));2192 \\ @export("entry", entry, u32(1234));
2147 \\}2193 \\}
...@@ -2166,7 +2212,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2166,7 +2212,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2166 \\ },2212 \\ },
2167 \\};2213 \\};
2168 \\2214 \\
2169 \\export fn entry() {2215 \\export fn entry() void {
2170 \\ const a = MdNode.Header {2216 \\ const a = MdNode.Header {
2171 \\ .text = MdText.init(&std.debug.global_allocator),2217 \\ .text = MdText.init(&std.debug.global_allocator),
2172 \\ .weight = HeaderWeight.H1,2218 \\ .weight = HeaderWeight.H1,
...@@ -2183,24 +2229,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2183,24 +2229,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2183 ".tmp_source.zig:2:5: error: @setAlignStack outside function");2229 ".tmp_source.zig:2:5: error: @setAlignStack outside function");
21842230
2185 cases.add("@setAlignStack in naked function",2231 cases.add("@setAlignStack in naked function",
2186 \\export nakedcc fn entry() {2232 \\export nakedcc fn entry() void {
2187 \\ @setAlignStack(16);2233 \\ @setAlignStack(16);
2188 \\}2234 \\}
2189 ,2235 ,
2190 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");2236 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");
21912237
2192 cases.add("@setAlignStack in inline function",2238 cases.add("@setAlignStack in inline function",
2193 \\export fn entry() {2239 \\export fn entry() void {
2194 \\ foo();2240 \\ foo();
2195 \\}2241 \\}
2196 \\inline fn foo() {2242 \\inline fn foo() void {
2197 \\ @setAlignStack(16);2243 \\ @setAlignStack(16);
2198 \\}2244 \\}
2199 ,2245 ,
2200 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");2246 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");
22012247
2202 cases.add("@setAlignStack set twice",2248 cases.add("@setAlignStack set twice",
2203 \\export fn entry() {2249 \\export fn entry() void {
2204 \\ @setAlignStack(16);2250 \\ @setAlignStack(16);
2205 \\ @setAlignStack(16);2251 \\ @setAlignStack(16);
2206 \\}2252 \\}
...@@ -2209,7 +2255,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2209,7 +2255,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2209 ".tmp_source.zig:2:5: note: first set here");2255 ".tmp_source.zig:2:5: note: first set here");
22102256
2211 cases.add("@setAlignStack too big",2257 cases.add("@setAlignStack too big",
2212 \\export fn entry() {2258 \\export fn entry() void {
2213 \\ @setAlignStack(511 + 1);2259 \\ @setAlignStack(511 + 1);
2214 \\}2260 \\}
2215 ,2261 ,
...@@ -2218,14 +2264,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2218,14 +2264,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2218 cases.add("storing runtime value in compile time variable then using it",2264 cases.add("storing runtime value in compile time variable then using it",
2219 \\const Mode = @import("builtin").Mode;2265 \\const Mode = @import("builtin").Mode;
2220 \\2266 \\
2221 \\fn Free(comptime filename: []const u8) -> TestCase {2267 \\fn Free(comptime filename: []const u8) TestCase {
2222 \\ return TestCase {2268 \\ return TestCase {
2223 \\ .filename = filename,2269 \\ .filename = filename,
2224 \\ .problem_type = ProblemType.Free,2270 \\ .problem_type = ProblemType.Free,
2225 \\ };2271 \\ };
2226 \\}2272 \\}
2227 \\2273 \\
2228 \\fn LibC(comptime filename: []const u8) -> TestCase {2274 \\fn LibC(comptime filename: []const u8) TestCase {
2229 \\ return TestCase {2275 \\ return TestCase {
2230 \\ .filename = filename,2276 \\ .filename = filename,
2231 \\ .problem_type = ProblemType.LinkLibC,2277 \\ .problem_type = ProblemType.LinkLibC,
...@@ -2242,7 +2288,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2242,7 +2288,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2242 \\ LinkLibC,2288 \\ LinkLibC,
2243 \\};2289 \\};
2244 \\2290 \\
2245 \\export fn entry() {2291 \\export fn entry() void {
2246 \\ const tests = []TestCase {2292 \\ const tests = []TestCase {
2247 \\ Free("001"),2293 \\ Free("001"),
2248 \\ Free("002"),2294 \\ Free("002"),
...@@ -2263,34 +2309,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2263,34 +2309,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2263 cases.add("field access of opaque type",2309 cases.add("field access of opaque type",
2264 \\const MyType = @OpaqueType();2310 \\const MyType = @OpaqueType();
2265 \\2311 \\
2266 \\export fn entry() -> bool {2312 \\export fn entry() bool {
2267 \\ var x: i32 = 1;2313 \\ var x: i32 = 1;
2268 \\ return bar(@ptrCast(&MyType, &x));2314 \\ return bar(@ptrCast(&MyType, &x));
2269 \\}2315 \\}
2270 \\2316 \\
2271 \\fn bar(x: &MyType) -> bool {2317 \\fn bar(x: &MyType) bool {
2272 \\ return x.blah;2318 \\ return x.blah;
2273 \\}2319 \\}
2274 ,2320 ,
2275 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");2321 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
22762322
2277 cases.add("carriage return special case",2323 cases.add("carriage return special case",
2278 "fn test() -> bool {\r\n" ++2324 "fn test() bool {\r\n" ++
2279 " true\r\n" ++2325 " true\r\n" ++
2280 "}\r\n"2326 "}\r\n"
2281 ,2327 ,
2282 ".tmp_source.zig:1:20: error: invalid carriage return, only '\\n' line endings are supported");2328 ".tmp_source.zig:1:17: error: invalid carriage return, only '\\n' line endings are supported");
22832329
2284 cases.add("non-printable invalid character",2330 cases.add("non-printable invalid character",
2285 "\xff\xfe" ++2331 "\xff\xfe" ++
2286 \\fn test() -> bool {\r2332 \\fn test() bool {\r
2287 \\ true\r2333 \\ true\r
2288 \\}2334 \\}
2289 ,2335 ,
2290 ".tmp_source.zig:1:1: error: invalid character: '\\xff'");2336 ".tmp_source.zig:1:1: error: invalid character: '\\xff'");
22912337
2292 cases.add("non-printable invalid character with escape alternative",2338 cases.add("non-printable invalid character with escape alternative",
2293 "fn test() -> bool {\n" ++2339 "fn test() bool {\n" ++
2294 "\ttrue\n" ++2340 "\ttrue\n" ++
2295 "}\n"2341 "}\n"
2296 ,2342 ,
...@@ -2307,9 +2353,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2307,9 +2353,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2307 \\comptime {2353 \\comptime {
2308 \\ _ = @ArgType(@typeOf(add), 2);2354 \\ _ = @ArgType(@typeOf(add), 2);
2309 \\}2355 \\}
2310 \\fn add(a: i32, b: i32) -> i32 { return a + b; }2356 \\fn add(a: i32, b: i32) i32 { return a + b; }
2311 ,2357 ,
2312 ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) -> i32' has 2 arguments");2358 ".tmp_source.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments");
23132359
2314 cases.add("@memberType on unsupported type",2360 cases.add("@memberType on unsupported type",
2315 \\comptime {2361 \\comptime {
...@@ -2374,17 +2420,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2374,17 +2420,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2374 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");2420 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23752421
2376 cases.add("calling var args extern function, passing array instead of pointer",2422 cases.add("calling var args extern function, passing array instead of pointer",
2377 \\export fn entry() {2423 \\export fn entry() void {
2378 \\ foo("hello");2424 \\ foo("hello");
2379 \\}2425 \\}
2380 \\pub extern fn foo(format: &const u8, ...);2426 \\pub extern fn foo(format: &const u8, ...) void;
2381 ,2427 ,
2382 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");2428 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
23832429
2384 cases.add("constant inside comptime function has compile error",2430 cases.add("constant inside comptime function has compile error",
2385 \\const ContextAllocator = MemoryPool(usize);2431 \\const ContextAllocator = MemoryPool(usize);
2386 \\2432 \\
2387 \\pub fn MemoryPool(comptime T: type) -> type {2433 \\pub fn MemoryPool(comptime T: type) type {
2388 \\ const free_list_t = @compileError("aoeu");2434 \\ const free_list_t = @compileError("aoeu");
2389 \\2435 \\
2390 \\ return struct {2436 \\ return struct {
...@@ -2392,7 +2438,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2392,7 +2438,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2392 \\ };2438 \\ };
2393 \\}2439 \\}
2394 \\2440 \\
2395 \\export fn entry() {2441 \\export fn entry() void {
2396 \\ var allocator: ContextAllocator = undefined;2442 \\ var allocator: ContextAllocator = undefined;
2397 \\}2443 \\}
2398 ,2444 ,
...@@ -2409,7 +2455,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2409,7 +2455,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2409 \\ Five,2455 \\ Five,
2410 \\};2456 \\};
2411 \\2457 \\
2412 \\export fn entry() {2458 \\export fn entry() void {
2413 \\ var x = Small.One;2459 \\ var x = Small.One;
2414 \\}2460 \\}
2415 ,2461 ,
...@@ -2422,7 +2468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2422,7 +2468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2422 \\ Three,2468 \\ Three,
2423 \\};2469 \\};
2424 \\2470 \\
2425 \\export fn entry() {2471 \\export fn entry() void {
2426 \\ var x = Small.One;2472 \\ var x = Small.One;
2427 \\}2473 \\}
2428 ,2474 ,
...@@ -2436,7 +2482,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2436,7 +2482,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2436 \\ Four,2482 \\ Four,
2437 \\};2483 \\};
2438 \\2484 \\
2439 \\export fn entry() {2485 \\export fn entry() void {
2440 \\ var x: u2 = Small.Two;2486 \\ var x: u2 = Small.Two;
2441 \\}2487 \\}
2442 ,2488 ,
...@@ -2450,7 +2496,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2450,7 +2496,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2450 \\ Four,2496 \\ Four,
2451 \\};2497 \\};
2452 \\2498 \\
2453 \\export fn entry() {2499 \\export fn entry() void {
2454 \\ var x = u3(Small.Two);2500 \\ var x = u3(Small.Two);
2455 \\}2501 \\}
2456 ,2502 ,
...@@ -2464,7 +2510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2464,7 +2510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2464 \\ Four,2510 \\ Four,
2465 \\};2511 \\};
2466 \\2512 \\
2467 \\export fn entry() {2513 \\export fn entry() void {
2468 \\ var y = u3(3);2514 \\ var y = u3(3);
2469 \\ var x = Small(y);2515 \\ var x = Small(y);
2470 \\}2516 \\}
...@@ -2479,7 +2525,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2479,7 +2525,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2479 \\ Four,2525 \\ Four,
2480 \\};2526 \\};
2481 \\2527 \\
2482 \\export fn entry() {2528 \\export fn entry() void {
2483 \\ var y = Small.Two;2529 \\ var y = Small.Two;
2484 \\}2530 \\}
2485 ,2531 ,
...@@ -2489,7 +2535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2489,7 +2535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2489 \\const MultipleChoice = struct {2535 \\const MultipleChoice = struct {
2490 \\ A: i32 = 20,2536 \\ A: i32 = 20,
2491 \\};2537 \\};
2492 \\export fn entry() {2538 \\export fn entry() void {
2493 \\ var x: MultipleChoice = undefined;2539 \\ var x: MultipleChoice = undefined;
2494 \\}2540 \\}
2495 ,2541 ,
...@@ -2499,7 +2545,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2499,7 +2545,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2499 \\const MultipleChoice = union {2545 \\const MultipleChoice = union {
2500 \\ A: i32 = 20,2546 \\ A: i32 = 20,
2501 \\};2547 \\};
2502 \\export fn entry() {2548 \\export fn entry() void {
2503 \\ var x: MultipleChoice = undefined;2549 \\ var x: MultipleChoice = undefined;
2504 \\}2550 \\}
2505 ,2551 ,
...@@ -2508,7 +2554,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2508,7 +2554,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25082554
2509 cases.add("enum with 0 fields",2555 cases.add("enum with 0 fields",
2510 \\const Foo = enum {};2556 \\const Foo = enum {};
2511 \\export fn entry() -> usize {2557 \\export fn entry() usize {
2512 \\ return @sizeOf(Foo);2558 \\ return @sizeOf(Foo);
2513 \\}2559 \\}
2514 ,2560 ,
...@@ -2516,7 +2562,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2516,7 +2562,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25162562
2517 cases.add("union with 0 fields",2563 cases.add("union with 0 fields",
2518 \\const Foo = union {};2564 \\const Foo = union {};
2519 \\export fn entry() -> usize {2565 \\export fn entry() usize {
2520 \\ return @sizeOf(Foo);2566 \\ return @sizeOf(Foo);
2521 \\}2567 \\}
2522 ,2568 ,
...@@ -2530,7 +2576,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2530,7 +2576,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2530 \\ D = 1000,2576 \\ D = 1000,
2531 \\ E = 60,2577 \\ E = 60,
2532 \\};2578 \\};
2533 \\export fn entry() {2579 \\export fn entry() void {
2534 \\ var x = MultipleChoice.C;2580 \\ var x = MultipleChoice.C;
2535 \\}2581 \\}
2536 ,2582 ,
...@@ -2547,7 +2593,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2547,7 +2593,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2547 \\ A: i32,2593 \\ A: i32,
2548 \\ B: f64,2594 \\ B: f64,
2549 \\};2595 \\};
2550 \\export fn entry() -> usize {2596 \\export fn entry() usize {
2551 \\ return @sizeOf(Payload);2597 \\ return @sizeOf(Payload);
2552 \\}2598 \\}
2553 ,2599 ,
...@@ -2558,7 +2604,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2558,7 +2604,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2558 \\const Foo = union {2604 \\const Foo = union {
2559 \\ A: i32,2605 \\ A: i32,
2560 \\};2606 \\};
2561 \\export fn entry() {2607 \\export fn entry() void {
2562 \\ const x = @TagType(Foo);2608 \\ const x = @TagType(Foo);
2563 \\}2609 \\}
2564 ,2610 ,
...@@ -2569,7 +2615,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2569,7 +2615,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2569 \\const Foo = union(enum(f32)) {2615 \\const Foo = union(enum(f32)) {
2570 \\ A: i32,2616 \\ A: i32,
2571 \\};2617 \\};
2572 \\export fn entry() {2618 \\export fn entry() void {
2573 \\ const x = @TagType(Foo);2619 \\ const x = @TagType(Foo);
2574 \\}2620 \\}
2575 ,2621 ,
...@@ -2579,7 +2625,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2579,7 +2625,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2579 \\const Foo = union(u32) {2625 \\const Foo = union(u32) {
2580 \\ A: i32,2626 \\ A: i32,
2581 \\};2627 \\};
2582 \\export fn entry() {2628 \\export fn entry() void {
2583 \\ const x = @TagType(Foo);2629 \\ const x = @TagType(Foo);
2584 \\}2630 \\}
2585 ,2631 ,
...@@ -2593,7 +2639,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2593,7 +2639,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2593 \\ D = 1000,2639 \\ D = 1000,
2594 \\ E = 60,2640 \\ E = 60,
2595 \\};2641 \\};
2596 \\export fn entry() {2642 \\export fn entry() void {
2597 \\ var x = MultipleChoice { .C = {} };2643 \\ var x = MultipleChoice { .C = {} };
2598 \\}2644 \\}
2599 ,2645 ,
...@@ -2612,7 +2658,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2612,7 +2658,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2612 \\ C: bool,2658 \\ C: bool,
2613 \\ D: bool,2659 \\ D: bool,
2614 \\};2660 \\};
2615 \\export fn entry() {2661 \\export fn entry() void {
2616 \\ var a = Payload {.A = 1234};2662 \\ var a = Payload {.A = 1234};
2617 \\}2663 \\}
2618 ,2664 ,
...@@ -2625,7 +2671,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2625,7 +2671,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2625 \\ B,2671 \\ B,
2626 \\ C,2672 \\ C,
2627 \\};2673 \\};
2628 \\export fn entry() {2674 \\export fn entry() void {
2629 \\ var b = Letter.B;2675 \\ var b = Letter.B;
2630 \\}2676 \\}
2631 ,2677 ,
...@@ -2636,7 +2682,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2636,7 +2682,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2636 \\const Letter = struct {2682 \\const Letter = struct {
2637 \\ A,2683 \\ A,
2638 \\};2684 \\};
2639 \\export fn entry() {2685 \\export fn entry() void {
2640 \\ var a = Letter { .A = {} };2686 \\ var a = Letter { .A = {} };
2641 \\}2687 \\}
2642 ,2688 ,
...@@ -2646,7 +2692,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2646,7 +2692,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2646 \\const Letter = extern union {2692 \\const Letter = extern union {
2647 \\ A,2693 \\ A,
2648 \\};2694 \\};
2649 \\export fn entry() {2695 \\export fn entry() void {
2650 \\ var a = Letter { .A = {} };2696 \\ var a = Letter { .A = {} };
2651 \\}2697 \\}
2652 ,2698 ,
...@@ -2663,7 +2709,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2663,7 +2709,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2663 \\ B: f64,2709 \\ B: f64,
2664 \\ C: bool,2710 \\ C: bool,
2665 \\};2711 \\};
2666 \\export fn entry() {2712 \\export fn entry() void {
2667 \\ var a = Payload { .A = 1234 };2713 \\ var a = Payload { .A = 1234 };
2668 \\}2714 \\}
2669 ,2715 ,
...@@ -2680,7 +2726,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2680,7 +2726,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2680 \\ B: f64,2726 \\ B: f64,
2681 \\ C: bool,2727 \\ C: bool,
2682 \\};2728 \\};
2683 \\export fn entry() {2729 \\export fn entry() void {
2684 \\ var a = Payload { .A = 1234 };2730 \\ var a = Payload { .A = 1234 };
2685 \\}2731 \\}
2686 ,2732 ,
...@@ -2692,11 +2738,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2692,11 +2738,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2692 \\ B: f64,2738 \\ B: f64,
2693 \\ C: bool,2739 \\ C: bool,
2694 \\};2740 \\};
2695 \\export fn entry() {2741 \\export fn entry() void {
2696 \\ const a = Payload { .A = 1234 };2742 \\ const a = Payload { .A = 1234 };
2697 \\ foo(a);2743 \\ foo(a);
2698 \\}2744 \\}
2699 \\fn foo(a: &const Payload) {2745 \\fn foo(a: &const Payload) void {
2700 \\ switch (*a) {2746 \\ switch (*a) {
2701 \\ Payload.A => {},2747 \\ Payload.A => {},
2702 \\ else => unreachable,2748 \\ else => unreachable,
...@@ -2711,7 +2757,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2711,7 +2757,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2711 \\ A = 10,2757 \\ A = 10,
2712 \\ B = 11,2758 \\ B = 11,
2713 \\};2759 \\};
2714 \\export fn entry() {2760 \\export fn entry() void {
2715 \\ var x = Foo(0);2761 \\ var x = Foo(0);
2716 \\}2762 \\}
2717 ,2763 ,
...@@ -2725,7 +2771,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2725,7 +2771,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2725 \\ B,2771 \\ B,
2726 \\ C,2772 \\ C,
2727 \\};2773 \\};
2728 \\export fn entry() {2774 \\export fn entry() void {
2729 \\ var x: Value = Letter.A;2775 \\ var x: Value = Letter.A;
2730 \\}2776 \\}
2731 ,2777 ,
...@@ -2739,10 +2785,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {...@@ -2739,10 +2785,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2739 \\ B,2785 \\ B,
2740 \\ C,2786 \\ C,
2741 \\};2787 \\};
2742 \\export fn entry() {2788 \\export fn entry() void {
2743 \\ foo(Letter.A);2789 \\ foo(Letter.A);
2744 \\}2790 \\}
2745 \\fn foo(l: Letter) {2791 \\fn foo(l: Letter) void {
2746 \\ var x: Value = l;2792 \\ var x: Value = l;
2747 \\}2793 \\}
2748 ,2794 ,
test/debug_safety.zig deleted-286
...@@ -1,286 +0,0 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.CompareOutputContext) {
4 cases.addDebugSafety("calling panic",
5 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\pub fn main() -> %void {
9 \\ @panic("oh no");
10 \\}
11 );
12
13 cases.addDebugSafety("out of bounds slice access",
14 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
15 \\ @import("std").os.exit(126);
16 \\}
17 \\pub fn main() -> %void {
18 \\ const a = []i32{1, 2, 3, 4};
19 \\ baz(bar(a));
20 \\}
21 \\fn bar(a: []const i32) -> i32 {
22 \\ return a[4];
23 \\}
24 \\fn baz(a: i32) { }
25 );
26
27 cases.addDebugSafety("integer addition overflow",
28 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
29 \\ @import("std").os.exit(126);
30 \\}
31 \\error Whatever;
32 \\pub fn main() -> %void {
33 \\ const x = add(65530, 10);
34 \\ if (x == 0) return error.Whatever;
35 \\}
36 \\fn add(a: u16, b: u16) -> u16 {
37 \\ return a + b;
38 \\}
39 );
40
41 cases.addDebugSafety("integer subtraction overflow",
42 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
43 \\ @import("std").os.exit(126);
44 \\}
45 \\error Whatever;
46 \\pub fn main() -> %void {
47 \\ const x = sub(10, 20);
48 \\ if (x == 0) return error.Whatever;
49 \\}
50 \\fn sub(a: u16, b: u16) -> u16 {
51 \\ return a - b;
52 \\}
53 );
54
55 cases.addDebugSafety("integer multiplication overflow",
56 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
57 \\ @import("std").os.exit(126);
58 \\}
59 \\error Whatever;
60 \\pub fn main() -> %void {
61 \\ const x = mul(300, 6000);
62 \\ if (x == 0) return error.Whatever;
63 \\}
64 \\fn mul(a: u16, b: u16) -> u16 {
65 \\ return a * b;
66 \\}
67 );
68
69 cases.addDebugSafety("integer negation overflow",
70 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
71 \\ @import("std").os.exit(126);
72 \\}
73 \\error Whatever;
74 \\pub fn main() -> %void {
75 \\ const x = neg(-32768);
76 \\ if (x == 32767) return error.Whatever;
77 \\}
78 \\fn neg(a: i16) -> i16 {
79 \\ return -a;
80 \\}
81 );
82
83 cases.addDebugSafety("signed integer division overflow",
84 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
85 \\ @import("std").os.exit(126);
86 \\}
87 \\error Whatever;
88 \\pub fn main() -> %void {
89 \\ const x = div(-32768, -1);
90 \\ if (x == 32767) return error.Whatever;
91 \\}
92 \\fn div(a: i16, b: i16) -> i16 {
93 \\ return @divTrunc(a, b);
94 \\}
95 );
96
97 cases.addDebugSafety("signed shift left overflow",
98 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
99 \\ @import("std").os.exit(126);
100 \\}
101 \\error Whatever;
102 \\pub fn main() -> %void {
103 \\ const x = shl(-16385, 1);
104 \\ if (x == 0) return error.Whatever;
105 \\}
106 \\fn shl(a: i16, b: u4) -> i16 {
107 \\ return @shlExact(a, b);
108 \\}
109 );
110
111 cases.addDebugSafety("unsigned shift left overflow",
112 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
113 \\ @import("std").os.exit(126);
114 \\}
115 \\error Whatever;
116 \\pub fn main() -> %void {
117 \\ const x = shl(0b0010111111111111, 3);
118 \\ if (x == 0) return error.Whatever;
119 \\}
120 \\fn shl(a: u16, b: u4) -> u16 {
121 \\ return @shlExact(a, b);
122 \\}
123 );
124
125 cases.addDebugSafety("signed shift right overflow",
126 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
127 \\ @import("std").os.exit(126);
128 \\}
129 \\error Whatever;
130 \\pub fn main() -> %void {
131 \\ const x = shr(-16385, 1);
132 \\ if (x == 0) return error.Whatever;
133 \\}
134 \\fn shr(a: i16, b: u4) -> i16 {
135 \\ return @shrExact(a, b);
136 \\}
137 );
138
139 cases.addDebugSafety("unsigned shift right overflow",
140 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
141 \\ @import("std").os.exit(126);
142 \\}
143 \\error Whatever;
144 \\pub fn main() -> %void {
145 \\ const x = shr(0b0010111111111111, 3);
146 \\ if (x == 0) return error.Whatever;
147 \\}
148 \\fn shr(a: u16, b: u4) -> u16 {
149 \\ return @shrExact(a, b);
150 \\}
151 );
152
153 cases.addDebugSafety("integer division by zero",
154 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
155 \\ @import("std").os.exit(126);
156 \\}
157 \\error Whatever;
158 \\pub fn main() -> %void {
159 \\ const x = div0(999, 0);
160 \\}
161 \\fn div0(a: i32, b: i32) -> i32 {
162 \\ return @divTrunc(a, b);
163 \\}
164 );
165
166 cases.addDebugSafety("exact division failure",
167 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
168 \\ @import("std").os.exit(126);
169 \\}
170 \\error Whatever;
171 \\pub fn main() -> %void {
172 \\ const x = divExact(10, 3);
173 \\ if (x == 0) return error.Whatever;
174 \\}
175 \\fn divExact(a: i32, b: i32) -> i32 {
176 \\ return @divExact(a, b);
177 \\}
178 );
179
180 cases.addDebugSafety("cast []u8 to bigger slice of wrong size",
181 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
182 \\ @import("std").os.exit(126);
183 \\}
184 \\error Whatever;
185 \\pub fn main() -> %void {
186 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
187 \\ if (x.len == 0) return error.Whatever;
188 \\}
189 \\fn widenSlice(slice: []align(1) const u8) -> []align(1) const i32 {
190 \\ return ([]align(1) const i32)(slice);
191 \\}
192 );
193
194 cases.addDebugSafety("value does not fit in shortening cast",
195 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
196 \\ @import("std").os.exit(126);
197 \\}
198 \\error Whatever;
199 \\pub fn main() -> %void {
200 \\ const x = shorten_cast(200);
201 \\ if (x == 0) return error.Whatever;
202 \\}
203 \\fn shorten_cast(x: i32) -> i8 {
204 \\ return i8(x);
205 \\}
206 );
207
208 cases.addDebugSafety("signed integer not fitting in cast to unsigned integer",
209 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
210 \\ @import("std").os.exit(126);
211 \\}
212 \\error Whatever;
213 \\pub fn main() -> %void {
214 \\ const x = unsigned_cast(-10);
215 \\ if (x == 0) return error.Whatever;
216 \\}
217 \\fn unsigned_cast(x: i32) -> u32 {
218 \\ return u32(x);
219 \\}
220 );
221
222 cases.addDebugSafety("unwrap error",
223 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
224 \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
225 \\ @import("std").os.exit(126); // good
226 \\ }
227 \\ @import("std").os.exit(0); // test failed
228 \\}
229 \\error Whatever;
230 \\pub fn main() -> %void {
231 \\ bar() catch unreachable;
232 \\}
233 \\fn bar() -> %void {
234 \\ return error.Whatever;
235 \\}
236 );
237
238 cases.addDebugSafety("cast integer to error and no code matches",
239 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
240 \\ @import("std").os.exit(126);
241 \\}
242 \\pub fn main() -> %void {
243 \\ _ = bar(9999);
244 \\}
245 \\fn bar(x: u32) -> error {
246 \\ return error(x);
247 \\}
248 );
249
250 cases.addDebugSafety("@alignCast misaligned",
251 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
252 \\ @import("std").os.exit(126);
253 \\}
254 \\error Wrong;
255 \\pub fn main() -> %void {
256 \\ var array align(4) = []u32{0x11111111, 0x11111111};
257 \\ const bytes = ([]u8)(array[0..]);
258 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
259 \\}
260 \\fn foo(bytes: []u8) -> u32 {
261 \\ const slice4 = bytes[1..5];
262 \\ const int_slice = ([]u32)(@alignCast(4, slice4));
263 \\ return int_slice[0];
264 \\}
265 );
266
267 cases.addDebugSafety("bad union field access",
268 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
269 \\ @import("std").os.exit(126);
270 \\}
271 \\
272 \\const Foo = union {
273 \\ float: f32,
274 \\ int: u32,
275 \\};
276 \\
277 \\pub fn main() -> %void {
278 \\ var f = Foo { .int = 42 };
279 \\ bar(&f);
280 \\}
281 \\
282 \\fn bar(f: &Foo) {
283 \\ f.float = 12.34;
284 \\}
285 );
286}
test/gen_h.zig created+69
...@@ -0,0 +1,69 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.GenHContext) void {
4 cases.add("declare enum",
5 \\const Foo = extern enum { A, B, C };
6 \\export fn entry(foo: Foo) void { }
7 ,
8 \\enum Foo {
9 \\ A = 0,
10 \\ B = 1,
11 \\ C = 2
12 \\};
13 \\
14 \\TEST_EXPORT void entry(enum Foo foo);
15 \\
16 );
17
18 cases.add("declare struct",
19 \\const Foo = extern struct {
20 \\ A: i32,
21 \\ B: f32,
22 \\ C: bool,
23 \\};
24 \\export fn entry(foo: Foo) void { }
25 ,
26 \\struct Foo {
27 \\ int32_t A;
28 \\ float B;
29 \\ bool C;
30 \\};
31 \\
32 \\TEST_EXPORT void entry(struct Foo foo);
33 \\
34 );
35
36 cases.add("declare union",
37 \\const Foo = extern union {
38 \\ A: i32,
39 \\ B: f32,
40 \\ C: bool,
41 \\};
42 \\export fn entry(foo: Foo) void { }
43 ,
44 \\union Foo {
45 \\ int32_t A;
46 \\ float B;
47 \\ bool C;
48 \\};
49 \\
50 \\TEST_EXPORT void entry(union Foo foo);
51 \\
52 );
53
54 cases.add("array field-type",
55 \\const Foo = extern struct {
56 \\ A: [2]i32,
57 \\ B: [4]&u32,
58 \\};
59 \\export fn entry(foo: Foo, bar: [3]u8) void { }
60 ,
61 \\struct Foo {
62 \\ int32_t A[2];
63 \\ uint32_t * B[4];
64 \\};
65 \\
66 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);
67 \\
68 );
69}
test/runtime_safety.zig created+286
...@@ -0,0 +1,286 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.CompareOutputContext) void {
4 cases.addRuntimeSafety("calling panic",
5 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\pub fn main() %void {
9 \\ @panic("oh no");
10 \\}
11 );
12
13 cases.addRuntimeSafety("out of bounds slice access",
14 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
15 \\ @import("std").os.exit(126);
16 \\}
17 \\pub fn main() %void {
18 \\ const a = []i32{1, 2, 3, 4};
19 \\ baz(bar(a));
20 \\}
21 \\fn bar(a: []const i32) i32 {
22 \\ return a[4];
23 \\}
24 \\fn baz(a: i32) void { }
25 );
26
27 cases.addRuntimeSafety("integer addition overflow",
28 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
29 \\ @import("std").os.exit(126);
30 \\}
31 \\error Whatever;
32 \\pub fn main() %void {
33 \\ const x = add(65530, 10);
34 \\ if (x == 0) return error.Whatever;
35 \\}
36 \\fn add(a: u16, b: u16) u16 {
37 \\ return a + b;
38 \\}
39 );
40
41 cases.addRuntimeSafety("integer subtraction overflow",
42 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
43 \\ @import("std").os.exit(126);
44 \\}
45 \\error Whatever;
46 \\pub fn main() %void {
47 \\ const x = sub(10, 20);
48 \\ if (x == 0) return error.Whatever;
49 \\}
50 \\fn sub(a: u16, b: u16) u16 {
51 \\ return a - b;
52 \\}
53 );
54
55 cases.addRuntimeSafety("integer multiplication overflow",
56 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
57 \\ @import("std").os.exit(126);
58 \\}
59 \\error Whatever;
60 \\pub fn main() %void {
61 \\ const x = mul(300, 6000);
62 \\ if (x == 0) return error.Whatever;
63 \\}
64 \\fn mul(a: u16, b: u16) u16 {
65 \\ return a * b;
66 \\}
67 );
68
69 cases.addRuntimeSafety("integer negation overflow",
70 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
71 \\ @import("std").os.exit(126);
72 \\}
73 \\error Whatever;
74 \\pub fn main() %void {
75 \\ const x = neg(-32768);
76 \\ if (x == 32767) return error.Whatever;
77 \\}
78 \\fn neg(a: i16) i16 {
79 \\ return -a;
80 \\}
81 );
82
83 cases.addRuntimeSafety("signed integer division overflow",
84 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
85 \\ @import("std").os.exit(126);
86 \\}
87 \\error Whatever;
88 \\pub fn main() %void {
89 \\ const x = div(-32768, -1);
90 \\ if (x == 32767) return error.Whatever;
91 \\}
92 \\fn div(a: i16, b: i16) i16 {
93 \\ return @divTrunc(a, b);
94 \\}
95 );
96
97 cases.addRuntimeSafety("signed shift left overflow",
98 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
99 \\ @import("std").os.exit(126);
100 \\}
101 \\error Whatever;
102 \\pub fn main() %void {
103 \\ const x = shl(-16385, 1);
104 \\ if (x == 0) return error.Whatever;
105 \\}
106 \\fn shl(a: i16, b: u4) i16 {
107 \\ return @shlExact(a, b);
108 \\}
109 );
110
111 cases.addRuntimeSafety("unsigned shift left overflow",
112 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
113 \\ @import("std").os.exit(126);
114 \\}
115 \\error Whatever;
116 \\pub fn main() %void {
117 \\ const x = shl(0b0010111111111111, 3);
118 \\ if (x == 0) return error.Whatever;
119 \\}
120 \\fn shl(a: u16, b: u4) u16 {
121 \\ return @shlExact(a, b);
122 \\}
123 );
124
125 cases.addRuntimeSafety("signed shift right overflow",
126 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
127 \\ @import("std").os.exit(126);
128 \\}
129 \\error Whatever;
130 \\pub fn main() %void {
131 \\ const x = shr(-16385, 1);
132 \\ if (x == 0) return error.Whatever;
133 \\}
134 \\fn shr(a: i16, b: u4) i16 {
135 \\ return @shrExact(a, b);
136 \\}
137 );
138
139 cases.addRuntimeSafety("unsigned shift right overflow",
140 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
141 \\ @import("std").os.exit(126);
142 \\}
143 \\error Whatever;
144 \\pub fn main() %void {
145 \\ const x = shr(0b0010111111111111, 3);
146 \\ if (x == 0) return error.Whatever;
147 \\}
148 \\fn shr(a: u16, b: u4) u16 {
149 \\ return @shrExact(a, b);
150 \\}
151 );
152
153 cases.addRuntimeSafety("integer division by zero",
154 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
155 \\ @import("std").os.exit(126);
156 \\}
157 \\error Whatever;
158 \\pub fn main() %void {
159 \\ const x = div0(999, 0);
160 \\}
161 \\fn div0(a: i32, b: i32) i32 {
162 \\ return @divTrunc(a, b);
163 \\}
164 );
165
166 cases.addRuntimeSafety("exact division failure",
167 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
168 \\ @import("std").os.exit(126);
169 \\}
170 \\error Whatever;
171 \\pub fn main() %void {
172 \\ const x = divExact(10, 3);
173 \\ if (x == 0) return error.Whatever;
174 \\}
175 \\fn divExact(a: i32, b: i32) i32 {
176 \\ return @divExact(a, b);
177 \\}
178 );
179
180 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
181 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
182 \\ @import("std").os.exit(126);
183 \\}
184 \\error Whatever;
185 \\pub fn main() %void {
186 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
187 \\ if (x.len == 0) return error.Whatever;
188 \\}
189 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
190 \\ return ([]align(1) const i32)(slice);
191 \\}
192 );
193
194 cases.addRuntimeSafety("value does not fit in shortening cast",
195 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
196 \\ @import("std").os.exit(126);
197 \\}
198 \\error Whatever;
199 \\pub fn main() %void {
200 \\ const x = shorten_cast(200);
201 \\ if (x == 0) return error.Whatever;
202 \\}
203 \\fn shorten_cast(x: i32) i8 {
204 \\ return i8(x);
205 \\}
206 );
207
208 cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
209 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
210 \\ @import("std").os.exit(126);
211 \\}
212 \\error Whatever;
213 \\pub fn main() %void {
214 \\ const x = unsigned_cast(-10);
215 \\ if (x == 0) return error.Whatever;
216 \\}
217 \\fn unsigned_cast(x: i32) u32 {
218 \\ return u32(x);
219 \\}
220 );
221
222 cases.addRuntimeSafety("unwrap error",
223 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
224 \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
225 \\ @import("std").os.exit(126); // good
226 \\ }
227 \\ @import("std").os.exit(0); // test failed
228 \\}
229 \\error Whatever;
230 \\pub fn main() %void {
231 \\ bar() catch unreachable;
232 \\}
233 \\fn bar() %void {
234 \\ return error.Whatever;
235 \\}
236 );
237
238 cases.addRuntimeSafety("cast integer to error and no code matches",
239 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
240 \\ @import("std").os.exit(126);
241 \\}
242 \\pub fn main() %void {
243 \\ _ = bar(9999);
244 \\}
245 \\fn bar(x: u32) error {
246 \\ return error(x);
247 \\}
248 );
249
250 cases.addRuntimeSafety("@alignCast misaligned",
251 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
252 \\ @import("std").os.exit(126);
253 \\}
254 \\error Wrong;
255 \\pub fn main() %void {
256 \\ var array align(4) = []u32{0x11111111, 0x11111111};
257 \\ const bytes = ([]u8)(array[0..]);
258 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
259 \\}
260 \\fn foo(bytes: []u8) u32 {
261 \\ const slice4 = bytes[1..5];
262 \\ const int_slice = ([]u32)(@alignCast(4, slice4));
263 \\ return int_slice[0];
264 \\}
265 );
266
267 cases.addRuntimeSafety("bad union field access",
268 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
269 \\ @import("std").os.exit(126);
270 \\}
271 \\
272 \\const Foo = union {
273 \\ float: f32,
274 \\ int: u32,
275 \\};
276 \\
277 \\pub fn main() %void {
278 \\ var f = Foo { .int = 42 };
279 \\ bar(&f);
280 \\}
281 \\
282 \\fn bar(f: &Foo) void {
283 \\ f.float = 12.34;
284 \\}
285 );
286}
test/standalone/brace_expansion/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 const main = b.addTest("main.zig");4 const main = b.addTest("main.zig");
5 main.setBuildMode(b.standardReleaseOptions());5 main.setBuildMode(b.standardReleaseOptions());
66
test/standalone/brace_expansion/main.zig+8-10
...@@ -19,7 +19,7 @@ const Token = union(enum) {...@@ -19,7 +19,7 @@ const Token = union(enum) {
1919
20var global_allocator: &mem.Allocator = undefined;20var global_allocator: &mem.Allocator = undefined;
2121
22fn tokenize(input:[] const u8) -> %ArrayList(Token) {22fn tokenize(input:[] const u8) %ArrayList(Token) {
23 const State = enum {23 const State = enum {
24 Start,24 Start,
25 Word,25 Word,
...@@ -71,7 +71,7 @@ const Node = union(enum) {...@@ -71,7 +71,7 @@ const Node = union(enum) {
71 Combine: []Node,71 Combine: []Node,
72};72};
7373
74fn parse(tokens: &const ArrayList(Token), token_index: &usize) -> %Node {74fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
75 const first_token = tokens.items[*token_index];75 const first_token = tokens.items[*token_index];
76 *token_index += 1;76 *token_index += 1;
7777
...@@ -107,7 +107,7 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) -> %Node {...@@ -107,7 +107,7 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) -> %Node {
107 }107 }
108}108}
109109
110fn expandString(input: []const u8, output: &Buffer) -> %void {110fn expandString(input: []const u8, output: &Buffer) %void {
111 const tokens = try tokenize(input);111 const tokens = try tokenize(input);
112 if (tokens.len == 1) {112 if (tokens.len == 1) {
113 return output.resize(0);113 return output.resize(0);
...@@ -135,9 +135,7 @@ fn expandString(input: []const u8, output: &Buffer) -> %void {...@@ -135,9 +135,7 @@ fn expandString(input: []const u8, output: &Buffer) -> %void {
135 }135 }
136}136}
137137
138const ListOfBuffer0 = ArrayList(Buffer); // TODO this is working around a compiler bug, fix and delete this138fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
139
140fn expandNode(node: &const Node, output: &ListOfBuffer0) -> %void {
141 assert(output.len == 0);139 assert(output.len == 0);
142 switch (*node) {140 switch (*node) {
143 Node.Scalar => |scalar| {141 Node.Scalar => |scalar| {
...@@ -174,7 +172,7 @@ fn expandNode(node: &const Node, output: &ListOfBuffer0) -> %void {...@@ -174,7 +172,7 @@ fn expandNode(node: &const Node, output: &ListOfBuffer0) -> %void {
174 }172 }
175}173}
176174
177pub fn main() -> %void {175pub fn main() %void {
178 var stdin_file = try io.getStdIn();176 var stdin_file = try io.getStdIn();
179 var stdout_file = try io.getStdOut();177 var stdout_file = try io.getStdOut();
180178
...@@ -210,11 +208,11 @@ test "invalid inputs" {...@@ -210,11 +208,11 @@ test "invalid inputs" {
210 expectError("\n", error.InvalidInput);208 expectError("\n", error.InvalidInput);
211}209}
212210
213fn expectError(test_input: []const u8, expected_err: error) {211fn expectError(test_input: []const u8, expected_err: error) void {
214 var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;212 var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;
215 defer output_buf.deinit();213 defer output_buf.deinit();
216214
217 if (expandString("}ABC", &output_buf)) {215 if (expandString(test_input, &output_buf)) {
218 unreachable;216 unreachable;
219 } else |err| {217 } else |err| {
220 assert(expected_err == err);218 assert(expected_err == err);
...@@ -244,7 +242,7 @@ test "valid inputs" {...@@ -244,7 +242,7 @@ test "valid inputs" {
244 expectExpansion("a{b}", "ab");242 expectExpansion("a{b}", "ab");
245}243}
246244
247fn expectExpansion(test_input: []const u8, expected_result: []const u8) {245fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {
248 var result = Buffer.initSize(global_allocator, 0) catch unreachable;246 var result = Buffer.initSize(global_allocator, 0) catch unreachable;
249 defer result.deinit();247 defer result.deinit();
250248
test/standalone/issue_339/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 const obj = b.addObject("test", "test.zig");4 const obj = b.addObject("test", "test.zig");
55
6 const test_step = b.step("test", "Test the program");6 const test_step = b.step("test", "Test the program");
test/standalone/issue_339/test.zig+3-3
...@@ -1,8 +1,8 @@...@@ -1,8 +1,8 @@
1const StackTrace = @import("builtin").StackTrace;1const StackTrace = @import("builtin").StackTrace;
2pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) -> noreturn { @breakpoint(); while (true) {} }2pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) noreturn { @breakpoint(); while (true) {} }
33
4fn bar() -> %void {}4fn bar() %void {}
55
6export fn foo() {6export fn foo() void {
7 bar() catch unreachable;7 bar() catch unreachable;
8}8}
test/standalone/pkg_import/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 const exe = b.addExecutable("test", "test.zig");4 const exe = b.addExecutable("test", "test.zig");
5 exe.addPackagePath("my_pkg", "pkg.zig");5 exe.addPackagePath("my_pkg", "pkg.zig");
66
test/standalone/pkg_import/pkg.zig+1-1
...@@ -1 +1 @@...@@ -1 +1 @@
1pub fn add(a: i32, b: i32) -> i32 { return a + b; }1pub fn add(a: i32, b: i32) i32 { return a + b; }
test/standalone/pkg_import/test.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const my_pkg = @import("my_pkg");1const my_pkg = @import("my_pkg");
2const assert = @import("std").debug.assert;2const assert = @import("std").debug.assert;
33
4pub fn main() -> %void {4pub fn main() %void {
5 assert(my_pkg.add(10, 20) == 30);5 assert(my_pkg.add(10, 20) == 30);
6}6}
test/standalone/use_alias/build.zig+1-1
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const Builder = @import("std").build.Builder;1const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {3pub fn build(b: &Builder) %void {
4 b.addCIncludePath(".");4 b.addCIncludePath(".");
55
6 const main = b.addTest("main.zig");6 const main = b.addTest("main.zig");
test/tests.zig+206-57
...@@ -17,8 +17,9 @@ const compare_output = @import("compare_output.zig");...@@ -17,8 +17,9 @@ const compare_output = @import("compare_output.zig");
17const build_examples = @import("build_examples.zig");17const build_examples = @import("build_examples.zig");
18const compile_errors = @import("compile_errors.zig");18const compile_errors = @import("compile_errors.zig");
19const assemble_and_link = @import("assemble_and_link.zig");19const assemble_and_link = @import("assemble_and_link.zig");
20const debug_safety = @import("debug_safety.zig");20const runtime_safety = @import("runtime_safety.zig");
21const translate_c = @import("translate_c.zig");21const translate_c = @import("translate_c.zig");
22const gen_h = @import("gen_h.zig");
2223
23const TestTarget = struct {24const TestTarget = struct {
24 os: builtin.Os,25 os: builtin.Os,
...@@ -49,7 +50,7 @@ error CompilationIncorrectlySucceeded;...@@ -49,7 +50,7 @@ error CompilationIncorrectlySucceeded;
4950
50const max_stdout_size = 1 * 1024 * 1024; // 1 MB51const max_stdout_size = 1 * 1024 * 1024; // 1 MB
5152
52pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {53pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
53 const cases = b.allocator.create(CompareOutputContext) catch unreachable;54 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
54 *cases = CompareOutputContext {55 *cases = CompareOutputContext {
55 .b = b,56 .b = b,
...@@ -63,21 +64,21 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) -> &bu...@@ -63,21 +64,21 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) -> &bu
63 return cases.step;64 return cases.step;
64}65}
6566
66pub fn addDebugSafetyTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {67pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
67 const cases = b.allocator.create(CompareOutputContext) catch unreachable;68 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
68 *cases = CompareOutputContext {69 *cases = CompareOutputContext {
69 .b = b,70 .b = b,
70 .step = b.step("test-debug-safety", "Run the debug safety tests"),71 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
71 .test_index = 0,72 .test_index = 0,
72 .test_filter = test_filter,73 .test_filter = test_filter,
73 };74 };
7475
75 debug_safety.addCases(cases);76 runtime_safety.addCases(cases);
7677
77 return cases.step;78 return cases.step;
78}79}
7980
80pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {81pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
81 const cases = b.allocator.create(CompileErrorContext) catch unreachable;82 const cases = b.allocator.create(CompileErrorContext) catch unreachable;
82 *cases = CompileErrorContext {83 *cases = CompileErrorContext {
83 .b = b,84 .b = b,
...@@ -91,7 +92,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui...@@ -91,7 +92,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui
91 return cases.step;92 return cases.step;
92}93}
9394
94pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {95pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
95 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;96 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
96 *cases = BuildExamplesContext {97 *cases = BuildExamplesContext {
97 .b = b,98 .b = b,
...@@ -105,7 +106,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui...@@ -105,7 +106,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui
105 return cases.step;106 return cases.step;
106}107}
107108
108pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {109pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
109 const cases = b.allocator.create(CompareOutputContext) catch unreachable;110 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
110 *cases = CompareOutputContext {111 *cases = CompareOutputContext {
111 .b = b,112 .b = b,
...@@ -119,11 +120,11 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &...@@ -119,11 +120,11 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &
119 return cases.step;120 return cases.step;
120}121}
121122
122pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {123pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
123 const cases = b.allocator.create(TranslateCContext) catch unreachable;124 const cases = b.allocator.create(TranslateCContext) catch unreachable;
124 *cases = TranslateCContext {125 *cases = TranslateCContext {
125 .b = b,126 .b = b,
126 .step = b.step("test-translate-c", "Run the C header file parsing tests"),127 .step = b.step("test-translate-c", "Run the C transation tests"),
127 .test_index = 0,128 .test_index = 0,
128 .test_filter = test_filter,129 .test_filter = test_filter,
129 };130 };
...@@ -133,8 +134,23 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) -> &build...@@ -133,8 +134,23 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) -> &build
133 return cases.step;134 return cases.step;
134}135}
135136
137pub fn addGenHTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
138 const cases = b.allocator.create(GenHContext) catch unreachable;
139 *cases = GenHContext {
140 .b = b,
141 .step = b.step("test-gen-h", "Run the C header file generation tests"),
142 .test_index = 0,
143 .test_filter = test_filter,
144 };
145
146 gen_h.addCases(cases);
147
148 return cases.step;
149}
150
151
136pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,152pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,
137 name:[] const u8, desc: []const u8, with_lldb: bool) -> &build.Step153 name:[] const u8, desc: []const u8, with_lldb: bool) &build.Step
138{154{
139 const step = b.step(b.fmt("test-{}", name), desc);155 const step = b.step(b.fmt("test-{}", name), desc);
140 for (test_targets) |test_target| {156 for (test_targets) |test_target| {
...@@ -176,7 +192,7 @@ pub const CompareOutputContext = struct {...@@ -176,7 +192,7 @@ pub const CompareOutputContext = struct {
176 const Special = enum {192 const Special = enum {
177 None,193 None,
178 Asm,194 Asm,
179 DebugSafety,195 RuntimeSafety,
180 };196 };
181197
182 const TestCase = struct {198 const TestCase = struct {
...@@ -192,14 +208,14 @@ pub const CompareOutputContext = struct {...@@ -192,14 +208,14 @@ pub const CompareOutputContext = struct {
192 source: []const u8,208 source: []const u8,
193 };209 };
194210
195 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) {211 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
196 self.sources.append(SourceFile {212 self.sources.append(SourceFile {
197 .filename = filename,213 .filename = filename,
198 .source = source,214 .source = source,
199 }) catch unreachable;215 }) catch unreachable;
200 }216 }
201217
202 pub fn setCommandLineArgs(self: &TestCase, args: []const []const u8) {218 pub fn setCommandLineArgs(self: &TestCase, args: []const []const u8) void {
203 self.cli_args = args;219 self.cli_args = args;
204 }220 }
205 };221 };
...@@ -215,7 +231,7 @@ pub const CompareOutputContext = struct {...@@ -215,7 +231,7 @@ pub const CompareOutputContext = struct {
215231
216 pub fn create(context: &CompareOutputContext, exe_path: []const u8,232 pub fn create(context: &CompareOutputContext, exe_path: []const u8,
217 name: []const u8, expected_output: []const u8,233 name: []const u8, expected_output: []const u8,
218 cli_args: []const []const u8) -> &RunCompareOutputStep234 cli_args: []const []const u8) &RunCompareOutputStep
219 {235 {
220 const allocator = context.b.allocator;236 const allocator = context.b.allocator;
221 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;237 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
...@@ -232,7 +248,7 @@ pub const CompareOutputContext = struct {...@@ -232,7 +248,7 @@ pub const CompareOutputContext = struct {
232 return ptr;248 return ptr;
233 }249 }
234250
235 fn make(step: &build.Step) -> %void {251 fn make(step: &build.Step) %void {
236 const self = @fieldParentPtr(RunCompareOutputStep, "step", step);252 const self = @fieldParentPtr(RunCompareOutputStep, "step", step);
237 const b = self.context.b;253 const b = self.context.b;
238254
...@@ -298,7 +314,7 @@ pub const CompareOutputContext = struct {...@@ -298,7 +314,7 @@ pub const CompareOutputContext = struct {
298 }314 }
299 };315 };
300316
301 const DebugSafetyRunStep = struct {317 const RuntimeSafetyRunStep = struct {
302 step: build.Step,318 step: build.Step,
303 context: &CompareOutputContext,319 context: &CompareOutputContext,
304 exe_path: []const u8,320 exe_path: []const u8,
...@@ -306,23 +322,23 @@ pub const CompareOutputContext = struct {...@@ -306,23 +322,23 @@ pub const CompareOutputContext = struct {
306 test_index: usize,322 test_index: usize,
307323
308 pub fn create(context: &CompareOutputContext, exe_path: []const u8,324 pub fn create(context: &CompareOutputContext, exe_path: []const u8,
309 name: []const u8) -> &DebugSafetyRunStep325 name: []const u8) &RuntimeSafetyRunStep
310 {326 {
311 const allocator = context.b.allocator;327 const allocator = context.b.allocator;
312 const ptr = allocator.create(DebugSafetyRunStep) catch unreachable;328 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
313 *ptr = DebugSafetyRunStep {329 *ptr = RuntimeSafetyRunStep {
314 .context = context,330 .context = context,
315 .exe_path = exe_path,331 .exe_path = exe_path,
316 .name = name,332 .name = name,
317 .test_index = context.test_index,333 .test_index = context.test_index,
318 .step = build.Step.init("DebugSafetyRun", allocator, make),334 .step = build.Step.init("RuntimeSafetyRun", allocator, make),
319 };335 };
320 context.test_index += 1;336 context.test_index += 1;
321 return ptr;337 return ptr;
322 }338 }
323339
324 fn make(step: &build.Step) -> %void {340 fn make(step: &build.Step) %void {
325 const self = @fieldParentPtr(DebugSafetyRunStep, "step", step);341 const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
326 const b = self.context.b;342 const b = self.context.b;
327343
328 const full_exe_path = b.pathFromRoot(self.exe_path);344 const full_exe_path = b.pathFromRoot(self.exe_path);
...@@ -367,7 +383,7 @@ pub const CompareOutputContext = struct {...@@ -367,7 +383,7 @@ pub const CompareOutputContext = struct {
367 };383 };
368384
369 pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8,385 pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8,
370 expected_output: []const u8, special: Special) -> TestCase386 expected_output: []const u8, special: Special) TestCase
371 {387 {
372 var tc = TestCase {388 var tc = TestCase {
373 .name = name,389 .name = name,
...@@ -383,33 +399,33 @@ pub const CompareOutputContext = struct {...@@ -383,33 +399,33 @@ pub const CompareOutputContext = struct {
383 }399 }
384400
385 pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8,401 pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8,
386 expected_output: []const u8) -> TestCase402 expected_output: []const u8) TestCase
387 {403 {
388 return createExtra(self, name, source, expected_output, Special.None);404 return createExtra(self, name, source, expected_output, Special.None);
389 }405 }
390406
391 pub fn addC(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) {407 pub fn addC(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
392 var tc = self.create(name, source, expected_output);408 var tc = self.create(name, source, expected_output);
393 tc.link_libc = true;409 tc.link_libc = true;
394 self.addCase(tc);410 self.addCase(tc);
395 }411 }
396412
397 pub fn add(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) {413 pub fn add(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
398 const tc = self.create(name, source, expected_output);414 const tc = self.create(name, source, expected_output);
399 self.addCase(tc);415 self.addCase(tc);
400 }416 }
401417
402 pub fn addAsm(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) {418 pub fn addAsm(self: &CompareOutputContext, name: []const u8, source: []const u8, expected_output: []const u8) void {
403 const tc = self.createExtra(name, source, expected_output, Special.Asm);419 const tc = self.createExtra(name, source, expected_output, Special.Asm);
404 self.addCase(tc);420 self.addCase(tc);
405 }421 }
406422
407 pub fn addDebugSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) {423 pub fn addRuntimeSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) void {
408 const tc = self.createExtra(name, source, undefined, Special.DebugSafety);424 const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
409 self.addCase(tc);425 self.addCase(tc);
410 }426 }
411427
412 pub fn addCase(self: &CompareOutputContext, case: &const TestCase) {428 pub fn addCase(self: &CompareOutputContext, case: &const TestCase) void {
413 const b = self.b;429 const b = self.b;
414430
415 const root_src = os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename) catch unreachable;431 const root_src = os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename) catch unreachable;
...@@ -465,7 +481,7 @@ pub const CompareOutputContext = struct {...@@ -465,7 +481,7 @@ pub const CompareOutputContext = struct {
465 self.step.dependOn(&run_and_cmp_output.step);481 self.step.dependOn(&run_and_cmp_output.step);
466 }482 }
467 },483 },
468 Special.DebugSafety => {484 Special.RuntimeSafety => {
469 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;485 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
470 if (self.test_filter) |filter| {486 if (self.test_filter) |filter| {
471 if (mem.indexOf(u8, annotated_case_name, filter) == null)487 if (mem.indexOf(u8, annotated_case_name, filter) == null)
...@@ -483,7 +499,7 @@ pub const CompareOutputContext = struct {...@@ -483,7 +499,7 @@ pub const CompareOutputContext = struct {
483 exe.step.dependOn(&write_src.step);499 exe.step.dependOn(&write_src.step);
484 }500 }
485501
486 const run_and_cmp_output = DebugSafetyRunStep.create(self, exe.getOutputPath(), annotated_case_name);502 const run_and_cmp_output = RuntimeSafetyRunStep.create(self, exe.getOutputPath(), annotated_case_name);
487 run_and_cmp_output.step.dependOn(&exe.step);503 run_and_cmp_output.step.dependOn(&exe.step);
488504
489 self.step.dependOn(&run_and_cmp_output.step);505 self.step.dependOn(&run_and_cmp_output.step);
...@@ -510,14 +526,14 @@ pub const CompileErrorContext = struct {...@@ -510,14 +526,14 @@ pub const CompileErrorContext = struct {
510 source: []const u8,526 source: []const u8,
511 };527 };
512528
513 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) {529 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
514 self.sources.append(SourceFile {530 self.sources.append(SourceFile {
515 .filename = filename,531 .filename = filename,
516 .source = source,532 .source = source,
517 }) catch unreachable;533 }) catch unreachable;
518 }534 }
519535
520 pub fn addExpectedError(self: &TestCase, text: []const u8) {536 pub fn addExpectedError(self: &TestCase, text: []const u8) void {
521 self.expected_errors.append(text) catch unreachable;537 self.expected_errors.append(text) catch unreachable;
522 }538 }
523 };539 };
...@@ -531,7 +547,7 @@ pub const CompileErrorContext = struct {...@@ -531,7 +547,7 @@ pub const CompileErrorContext = struct {
531 build_mode: Mode,547 build_mode: Mode,
532548
533 pub fn create(context: &CompileErrorContext, name: []const u8,549 pub fn create(context: &CompileErrorContext, name: []const u8,
534 case: &const TestCase, build_mode: Mode) -> &CompileCmpOutputStep550 case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep
535 {551 {
536 const allocator = context.b.allocator;552 const allocator = context.b.allocator;
537 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;553 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
...@@ -547,7 +563,7 @@ pub const CompileErrorContext = struct {...@@ -547,7 +563,7 @@ pub const CompileErrorContext = struct {
547 return ptr;563 return ptr;
548 }564 }
549565
550 fn make(step: &build.Step) -> %void {566 fn make(step: &build.Step) %void {
551 const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);567 const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
552 const b = self.context.b;568 const b = self.context.b;
553569
...@@ -645,7 +661,7 @@ pub const CompileErrorContext = struct {...@@ -645,7 +661,7 @@ pub const CompileErrorContext = struct {
645 }661 }
646 };662 };
647663
648 fn printInvocation(args: []const []const u8) {664 fn printInvocation(args: []const []const u8) void {
649 for (args) |arg| {665 for (args) |arg| {
650 warn("{} ", arg);666 warn("{} ", arg);
651 }667 }
...@@ -653,7 +669,7 @@ pub const CompileErrorContext = struct {...@@ -653,7 +669,7 @@ pub const CompileErrorContext = struct {
653 }669 }
654670
655 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,671 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,
656 expected_lines: ...) -> &TestCase672 expected_lines: ...) &TestCase
657 {673 {
658 const tc = self.b.allocator.create(TestCase) catch unreachable;674 const tc = self.b.allocator.create(TestCase) catch unreachable;
659 *tc = TestCase {675 *tc = TestCase {
...@@ -671,24 +687,24 @@ pub const CompileErrorContext = struct {...@@ -671,24 +687,24 @@ pub const CompileErrorContext = struct {
671 return tc;687 return tc;
672 }688 }
673689
674 pub fn addC(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {690 pub fn addC(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
675 var tc = self.create(name, source, expected_lines);691 var tc = self.create(name, source, expected_lines);
676 tc.link_libc = true;692 tc.link_libc = true;
677 self.addCase(tc);693 self.addCase(tc);
678 }694 }
679695
680 pub fn addExe(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {696 pub fn addExe(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
681 var tc = self.create(name, source, expected_lines);697 var tc = self.create(name, source, expected_lines);
682 tc.is_exe = true;698 tc.is_exe = true;
683 self.addCase(tc);699 self.addCase(tc);
684 }700 }
685701
686 pub fn add(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) {702 pub fn add(self: &CompileErrorContext, name: []const u8, source: []const u8, expected_lines: ...) void {
687 const tc = self.create(name, source, expected_lines);703 const tc = self.create(name, source, expected_lines);
688 self.addCase(tc);704 self.addCase(tc);
689 }705 }
690706
691 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) {707 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {
692 const b = self.b;708 const b = self.b;
693709
694 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {710 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
...@@ -717,15 +733,15 @@ pub const BuildExamplesContext = struct {...@@ -717,15 +733,15 @@ pub const BuildExamplesContext = struct {
717 test_index: usize,733 test_index: usize,
718 test_filter: ?[]const u8,734 test_filter: ?[]const u8,
719735
720 pub fn addC(self: &BuildExamplesContext, root_src: []const u8) {736 pub fn addC(self: &BuildExamplesContext, root_src: []const u8) void {
721 self.addAllArgs(root_src, true);737 self.addAllArgs(root_src, true);
722 }738 }
723739
724 pub fn add(self: &BuildExamplesContext, root_src: []const u8) {740 pub fn add(self: &BuildExamplesContext, root_src: []const u8) void {
725 self.addAllArgs(root_src, false);741 self.addAllArgs(root_src, false);
726 }742 }
727743
728 pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) {744 pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) void {
729 const b = self.b;745 const b = self.b;
730746
731 const annotated_case_name = b.fmt("build {} (Debug)", build_file);747 const annotated_case_name = b.fmt("build {} (Debug)", build_file);
...@@ -756,7 +772,7 @@ pub const BuildExamplesContext = struct {...@@ -756,7 +772,7 @@ pub const BuildExamplesContext = struct {
756 self.step.dependOn(&log_step.step);772 self.step.dependOn(&log_step.step);
757 }773 }
758774
759 pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) {775 pub fn addAllArgs(self: &BuildExamplesContext, root_src: []const u8, link_libc: bool) void {
760 const b = self.b;776 const b = self.b;
761777
762 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {778 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
...@@ -798,14 +814,14 @@ pub const TranslateCContext = struct {...@@ -798,14 +814,14 @@ pub const TranslateCContext = struct {
798 source: []const u8,814 source: []const u8,
799 };815 };
800816
801 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) {817 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
802 self.sources.append(SourceFile {818 self.sources.append(SourceFile {
803 .filename = filename,819 .filename = filename,
804 .source = source,820 .source = source,
805 }) catch unreachable;821 }) catch unreachable;
806 }822 }
807823
808 pub fn addExpectedLine(self: &TestCase, text: []const u8) {824 pub fn addExpectedLine(self: &TestCase, text: []const u8) void {
809 self.expected_lines.append(text) catch unreachable;825 self.expected_lines.append(text) catch unreachable;
810 }826 }
811 };827 };
...@@ -817,7 +833,7 @@ pub const TranslateCContext = struct {...@@ -817,7 +833,7 @@ pub const TranslateCContext = struct {
817 test_index: usize,833 test_index: usize,
818 case: &const TestCase,834 case: &const TestCase,
819835
820 pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) -> &TranslateCCmpOutputStep {836 pub fn create(context: &TranslateCContext, name: []const u8, case: &const TestCase) &TranslateCCmpOutputStep {
821 const allocator = context.b.allocator;837 const allocator = context.b.allocator;
822 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;838 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
823 *ptr = TranslateCCmpOutputStep {839 *ptr = TranslateCCmpOutputStep {
...@@ -831,7 +847,7 @@ pub const TranslateCContext = struct {...@@ -831,7 +847,7 @@ pub const TranslateCContext = struct {
831 return ptr;847 return ptr;
832 }848 }
833849
834 fn make(step: &build.Step) -> %void {850 fn make(step: &build.Step) %void {
835 const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);851 const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
836 const b = self.context.b;852 const b = self.context.b;
837853
...@@ -918,7 +934,7 @@ pub const TranslateCContext = struct {...@@ -918,7 +934,7 @@ pub const TranslateCContext = struct {
918 }934 }
919 };935 };
920936
921 fn printInvocation(args: []const []const u8) {937 fn printInvocation(args: []const []const u8) void {
922 for (args) |arg| {938 for (args) |arg| {
923 warn("{} ", arg);939 warn("{} ", arg);
924 }940 }
...@@ -926,7 +942,7 @@ pub const TranslateCContext = struct {...@@ -926,7 +942,7 @@ pub const TranslateCContext = struct {
926 }942 }
927943
928 pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8,944 pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8,
929 source: []const u8, expected_lines: ...) -> &TestCase945 source: []const u8, expected_lines: ...) &TestCase
930 {946 {
931 const tc = self.b.allocator.create(TestCase) catch unreachable;947 const tc = self.b.allocator.create(TestCase) catch unreachable;
932 *tc = TestCase {948 *tc = TestCase {
...@@ -943,22 +959,22 @@ pub const TranslateCContext = struct {...@@ -943,22 +959,22 @@ pub const TranslateCContext = struct {
943 return tc;959 return tc;
944 }960 }
945961
946 pub fn add(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) {962 pub fn add(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
947 const tc = self.create(false, "source.h", name, source, expected_lines);963 const tc = self.create(false, "source.h", name, source, expected_lines);
948 self.addCase(tc);964 self.addCase(tc);
949 }965 }
950966
951 pub fn addC(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) {967 pub fn addC(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
952 const tc = self.create(false, "source.c", name, source, expected_lines);968 const tc = self.create(false, "source.c", name, source, expected_lines);
953 self.addCase(tc);969 self.addCase(tc);
954 }970 }
955971
956 pub fn addAllowWarnings(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) {972 pub fn addAllowWarnings(self: &TranslateCContext, name: []const u8, source: []const u8, expected_lines: ...) void {
957 const tc = self.create(true, "source.h", name, source, expected_lines);973 const tc = self.create(true, "source.h", name, source, expected_lines);
958 self.addCase(tc);974 self.addCase(tc);
959 }975 }
960976
961 pub fn addCase(self: &TranslateCContext, case: &const TestCase) {977 pub fn addCase(self: &TranslateCContext, case: &const TestCase) void {
962 const b = self.b;978 const b = self.b;
963979
964 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;980 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
...@@ -977,3 +993,136 @@ pub const TranslateCContext = struct {...@@ -977,3 +993,136 @@ pub const TranslateCContext = struct {
977 }993 }
978 }994 }
979};995};
996
997pub const GenHContext = struct {
998 b: &build.Builder,
999 step: &build.Step,
1000 test_index: usize,
1001 test_filter: ?[]const u8,
1002
1003 const TestCase = struct {
1004 name: []const u8,
1005 sources: ArrayList(SourceFile),
1006 expected_lines: ArrayList([]const u8),
1007
1008 const SourceFile = struct {
1009 filename: []const u8,
1010 source: []const u8,
1011 };
1012
1013 pub fn addSourceFile(self: &TestCase, filename: []const u8, source: []const u8) void {
1014 self.sources.append(SourceFile {
1015 .filename = filename,
1016 .source = source,
1017 }) catch unreachable;
1018 }
1019
1020 pub fn addExpectedLine(self: &TestCase, text: []const u8) void {
1021 self.expected_lines.append(text) catch unreachable;
1022 }
1023 };
1024
1025 const GenHCmpOutputStep = struct {
1026 step: build.Step,
1027 context: &GenHContext,
1028 h_path: []const u8,
1029 name: []const u8,
1030 test_index: usize,
1031 case: &const TestCase,
1032
1033 pub fn create(context: &GenHContext, h_path: []const u8, name: []const u8, case: &const TestCase) &GenHCmpOutputStep {
1034 const allocator = context.b.allocator;
1035 const ptr = allocator.create(GenHCmpOutputStep) catch unreachable;
1036 *ptr = GenHCmpOutputStep {
1037 .step = build.Step.init("ParseCCmpOutput", allocator, make),
1038 .context = context,
1039 .h_path = h_path,
1040 .name = name,
1041 .test_index = context.test_index,
1042 .case = case,
1043 };
1044 context.test_index += 1;
1045 return ptr;
1046 }
1047
1048 fn make(step: &build.Step) %void {
1049 const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
1050 const b = self.context.b;
1051
1052 warn("Test {}/{} {}...", self.test_index+1, self.context.test_index, self.name);
1053
1054 const full_h_path = b.pathFromRoot(self.h_path);
1055 const actual_h = try io.readFileAlloc(full_h_path, b.allocator);
1056
1057 for (self.case.expected_lines.toSliceConst()) |expected_line| {
1058 if (mem.indexOf(u8, actual_h, expected_line) == null) {
1059 warn(
1060 \\
1061 \\========= Expected this output: ================
1062 \\{}
1063 \\================================================
1064 \\{}
1065 \\
1066 , expected_line, actual_h);
1067 return error.TestFailed;
1068 }
1069 }
1070 warn("OK\n");
1071 }
1072 };
1073
1074 fn printInvocation(args: []const []const u8) void {
1075 for (args) |arg| {
1076 warn("{} ", arg);
1077 }
1078 warn("\n");
1079 }
1080
1081 pub fn create(self: &GenHContext, filename: []const u8, name: []const u8,
1082 source: []const u8, expected_lines: ...) &TestCase
1083 {
1084 const tc = self.b.allocator.create(TestCase) catch unreachable;
1085 *tc = TestCase {
1086 .name = name,
1087 .sources = ArrayList(TestCase.SourceFile).init(self.b.allocator),
1088 .expected_lines = ArrayList([]const u8).init(self.b.allocator),
1089 };
1090 tc.addSourceFile(filename, source);
1091 comptime var arg_i = 0;
1092 inline while (arg_i < expected_lines.len) : (arg_i += 1) {
1093 tc.addExpectedLine(expected_lines[arg_i]);
1094 }
1095 return tc;
1096 }
1097
1098 pub fn add(self: &GenHContext, name: []const u8, source: []const u8, expected_lines: ...) void {
1099 const tc = self.create("test.zig", name, source, expected_lines);
1100 self.addCase(tc);
1101 }
1102
1103 pub fn addCase(self: &GenHContext, case: &const TestCase) void {
1104 const b = self.b;
1105 const root_src = os.path.join(b.allocator, b.cache_root, case.sources.items[0].filename) catch unreachable;
1106
1107 const mode = builtin.Mode.Debug;
1108 const annotated_case_name = fmt.allocPrint(self.b.allocator, "gen-h {} ({})", case.name, @tagName(mode)) catch unreachable;
1109 if (self.test_filter) |filter| {
1110 if (mem.indexOf(u8, annotated_case_name, filter) == null)
1111 return;
1112 }
1113
1114 const obj = b.addObject("test", root_src);
1115 obj.setBuildMode(mode);
1116
1117 for (case.sources.toSliceConst()) |src_file| {
1118 const expanded_src_path = os.path.join(b.allocator, b.cache_root, src_file.filename) catch unreachable;
1119 const write_src = b.addWriteFile(expanded_src_path, src_file.source);
1120 obj.step.dependOn(&write_src.step);
1121 }
1122
1123 const cmp_h = GenHCmpOutputStep.create(self, obj.getOutputHPath(), annotated_case_name, case);
1124 cmp_h.step.dependOn(&obj.step);
1125
1126 self.step.dependOn(&cmp_h.step);
1127 }
1128};
test/translate_c.zig+66-66
...@@ -1,6 +1,6 @@...@@ -1,6 +1,6 @@
1const tests = @import("tests.zig");1const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.TranslateCContext) {3pub fn addCases(cases: &tests.TranslateCContext) void {
4 cases.addAllowWarnings("simple data types",4 cases.addAllowWarnings("simple data types",
5 \\#include <stdint.h>5 \\#include <stdint.h>
6 \\int foo(char a, unsigned char b, signed char c);6 \\int foo(char a, unsigned char b, signed char c);
...@@ -8,17 +8,17 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -8,17 +8,17 @@ pub fn addCases(cases: &tests.TranslateCContext) {
8 \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);8 \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
9 \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);9 \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);
10 ,10 ,
11 \\pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;11 \\pub extern fn foo(a: u8, b: u8, c: i8) c_int;
12 ,12 ,
13 \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64);13 \\pub extern fn bar(a: u8, b: u16, c: u32, d: u64) void;
14 ,14 ,
15 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64);15 \\pub extern fn baz(a: i8, b: i16, c: i32, d: i64) void;
16 );16 );
1717
18 cases.add("noreturn attribute",18 cases.add("noreturn attribute",
19 \\void foo(void) __attribute__((noreturn));19 \\void foo(void) __attribute__((noreturn));
20 ,20 ,
21 \\pub extern fn foo() -> noreturn;21 \\pub extern fn foo() noreturn;
22 );22 );
2323
24 cases.addC("simple function",24 cases.addC("simple function",
...@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
26 \\ return a < 0 ? -a : a;26 \\ return a < 0 ? -a : a;
27 \\}27 \\}
28 ,28 ,
29 \\export fn abs(a: c_int) -> c_int {29 \\export fn abs(a: c_int) c_int {
30 \\ return if (a < 0) -a else a;30 \\ return if (a < 0) -a else a;
31 \\}31 \\}
32 );32 );
...@@ -56,7 +56,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -56,7 +56,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
56 cases.add("restrict -> noalias",56 cases.add("restrict -> noalias",
57 \\void foo(void *restrict bar, void *restrict);57 \\void foo(void *restrict bar, void *restrict);
58 ,58 ,
59 \\pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void);59 \\pub extern fn foo(noalias bar: ?&c_void, noalias arg1: ?&c_void) void;
60 );60 );
6161
62 cases.add("simple struct",62 cases.add("simple struct",
...@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
98 ,98 ,
99 \\pub const BarB = enum_Bar.B;99 \\pub const BarB = enum_Bar.B;
100 ,100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar));101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar)) void;
102 ,102 ,
103 \\pub const Foo = struct_Foo;103 \\pub const Foo = struct_Foo;
104 ,104 ,
...@@ -108,7 +108,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -108,7 +108,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
108 cases.add("constant size array",108 cases.add("constant size array",
109 \\void func(int array[20]);109 \\void func(int array[20]);
110 ,110 ,
111 \\pub extern fn func(array: ?&c_int);111 \\pub extern fn func(array: ?&c_int) void;
112 );112 );
113113
114 cases.add("self referential struct with function pointer",114 cases.add("self referential struct with function pointer",
...@@ -117,7 +117,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -117,7 +117,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
117 \\};117 \\};
118 ,118 ,
119 \\pub const struct_Foo = extern struct {119 \\pub const struct_Foo = extern struct {
120 \\ derp: ?extern fn(?&struct_Foo),120 \\ derp: ?extern fn(?&struct_Foo) void,
121 \\};121 \\};
122 ,122 ,
123 \\pub const Foo = struct_Foo;123 \\pub const Foo = struct_Foo;
...@@ -129,7 +129,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -129,7 +129,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
129 ,129 ,
130 \\pub const struct_Foo = @OpaqueType();130 \\pub const struct_Foo = @OpaqueType();
131 ,131 ,
132 \\pub extern fn some_func(foo: ?&struct_Foo, x: c_int) -> ?&struct_Foo;132 \\pub extern fn some_func(foo: ?&struct_Foo, x: c_int) ?&struct_Foo;
133 ,133 ,
134 \\pub const Foo = struct_Foo;134 \\pub const Foo = struct_Foo;
135 );135 );
...@@ -190,7 +190,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -190,7 +190,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
190 ,190 ,
191 \\pub const Foo = c_void;191 \\pub const Foo = c_void;
192 ,192 ,
193 \\pub extern fn fun(a: ?&Foo) -> Foo;193 \\pub extern fn fun(a: ?&Foo) Foo;
194 );194 );
195195
196 cases.add("generate inline func for #define global extern fn",196 cases.add("generate inline func for #define global extern fn",
...@@ -200,15 +200,15 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -200,15 +200,15 @@ pub fn addCases(cases: &tests.TranslateCContext) {
200 \\extern char (*fn_ptr2)(int, float);200 \\extern char (*fn_ptr2)(int, float);
201 \\#define bar fn_ptr2201 \\#define bar fn_ptr2
202 ,202 ,
203 \\pub extern var fn_ptr: ?extern fn();203 \\pub extern var fn_ptr: ?extern fn() void;
204 ,204 ,
205 \\pub inline fn foo() {205 \\pub inline fn foo() void {
206 \\ return (??fn_ptr)();206 \\ return (??fn_ptr)();
207 \\}207 \\}
208 ,208 ,
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) u8;
210 ,210 ,
211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {211 \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
212 \\ return (??fn_ptr2)(arg0, arg1);212 \\ return (??fn_ptr2)(arg0, arg1);
213 \\}213 \\}
214 );214 );
...@@ -222,7 +222,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -222,7 +222,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
222 cases.add("__cdecl doesn't mess up function pointers",222 cases.add("__cdecl doesn't mess up function pointers",
223 \\void foo(void (__cdecl *fn_ptr)(void));223 \\void foo(void (__cdecl *fn_ptr)(void));
224 ,224 ,
225 \\pub extern fn foo(fn_ptr: ?extern fn());225 \\pub extern fn foo(fn_ptr: ?extern fn() void) void;
226 );226 );
227227
228 cases.add("comment after integer literal",228 cases.add("comment after integer literal",
...@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
325 \\ return a;325 \\ return a;
326 \\}326 \\}
327 ,327 ,
328 \\pub export fn foo1(_arg_a: c_uint) -> c_uint {328 \\pub export fn foo1(_arg_a: c_uint) c_uint {
329 \\ var a = _arg_a;329 \\ var a = _arg_a;
330 \\ a +%= 1;330 \\ a +%= 1;
331 \\ return a;331 \\ return a;
332 \\}332 \\}
333 \\pub export fn foo2(_arg_a: c_int) -> c_int {333 \\pub export fn foo2(_arg_a: c_int) c_int {
334 \\ var a = _arg_a;334 \\ var a = _arg_a;
335 \\ a += 1;335 \\ a += 1;
336 \\ return a;336 \\ return a;
...@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
346 \\ return i;346 \\ return i;
347 \\}347 \\}
348 ,348 ,
349 \\pub export fn log2(_arg_a: c_uint) -> c_int {349 \\pub export fn log2(_arg_a: c_uint) c_int {
350 \\ var a = _arg_a;350 \\ var a = _arg_a;
351 \\ var i: c_int = 0;351 \\ var i: c_int = 0;
352 \\ while (a > c_uint(0)) {352 \\ while (a > c_uint(0)) {
...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
367 \\ return a;367 \\ return a;
368 \\}368 \\}
369 ,369 ,
370 \\pub export fn max(a: c_int, b: c_int) -> c_int {370 \\pub export fn max(a: c_int, b: c_int) c_int {
371 \\ if (a < b) return b;371 \\ if (a < b) return b;
372 \\ if (a < b) return b else return a;372 \\ if (a < b) return b else return a;
373 \\}373 \\}
...@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
382 \\ return a;382 \\ return a;
383 \\}383 \\}
384 ,384 ,
385 \\pub export fn max(a: c_int, b: c_int) -> c_int {385 \\pub export fn max(a: c_int, b: c_int) c_int {
386 \\ if (a == b) return a;386 \\ if (a == b) return a;
387 \\ if (a != b) return b;387 \\ if (a != b) return b;
388 \\ return a;388 \\ return a;
...@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
407 \\ c = a % b;407 \\ c = a % b;
408 \\}408 \\}
409 ,409 ,
410 \\pub export fn s(a: c_int, b: c_int) -> c_int {410 \\pub export fn s(a: c_int, b: c_int) c_int {
411 \\ var c: c_int = undefined;411 \\ var c: c_int = undefined;
412 \\ c = (a + b);412 \\ c = (a + b);
413 \\ c = (a - b);413 \\ c = (a - b);
...@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
415 \\ c = @divTrunc(a, b);415 \\ c = @divTrunc(a, b);
416 \\ c = @rem(a, b);416 \\ c = @rem(a, b);
417 \\}417 \\}
418 \\pub export fn u(a: c_uint, b: c_uint) -> c_uint {418 \\pub export fn u(a: c_uint, b: c_uint) c_uint {
419 \\ var c: c_uint = undefined;419 \\ var c: c_uint = undefined;
420 \\ c = (a +% b);420 \\ c = (a +% b);
421 \\ c = (a -% b);421 \\ c = (a -% b);
...@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
430 \\ return (a & b) ^ (a | b);430 \\ return (a & b) ^ (a | b);
431 \\}431 \\}
432 ,432 ,
433 \\pub export fn max(a: c_int, b: c_int) -> c_int {433 \\pub export fn max(a: c_int, b: c_int) c_int {
434 \\ return (a & b) ^ (a | b);434 \\ return (a & b) ^ (a | b);
435 \\}435 \\}
436 );436 );
...@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
444 \\ return a;444 \\ return a;
445 \\}445 \\}
446 ,446 ,
447 \\pub export fn max(a: c_int, b: c_int) -> c_int {447 \\pub export fn max(a: c_int, b: c_int) c_int {
448 \\ if ((a < b) or (a == b)) return b;448 \\ if ((a < b) or (a == b)) return b;
449 \\ if ((a >= b) and (a == b)) return a;449 \\ if ((a >= b) and (a == b)) return a;
450 \\ return a;450 \\ return a;
...@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
458 \\ a = tmp;458 \\ a = tmp;
459 \\}459 \\}
460 ,460 ,
461 \\pub export fn max(_arg_a: c_int) -> c_int {461 \\pub export fn max(_arg_a: c_int) c_int {
462 \\ var a = _arg_a;462 \\ var a = _arg_a;
463 \\ var tmp: c_int = undefined;463 \\ var tmp: c_int = undefined;
464 \\ tmp = a;464 \\ tmp = a;
...@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
472 \\ c = b = a;472 \\ c = b = a;
473 \\}473 \\}
474 ,474 ,
475 \\pub export fn max(a: c_int) {475 \\pub export fn max(a: c_int) void {
476 \\ var b: c_int = undefined;476 \\ var b: c_int = undefined;
477 \\ var c: c_int = undefined;477 \\ var c: c_int = undefined;
478 \\ c = x: {478 \\ c = x: {
...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
493 \\ return i;493 \\ return i;
494 \\}494 \\}
495 ,495 ,
496 \\pub export fn log2(_arg_a: u32) -> c_int {496 \\pub export fn log2(_arg_a: u32) c_int {
497 \\ var a = _arg_a;497 \\ var a = _arg_a;
498 \\ var i: c_int = 0;498 \\ var i: c_int = 0;
499 \\ while (a > c_uint(0)) {499 \\ while (a > c_uint(0)) {
...@@ -517,8 +517,8 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -517,8 +517,8 @@ pub fn addCases(cases: &tests.TranslateCContext) {
517 \\static void bar(void) { }517 \\static void bar(void) { }
518 \\void foo(void) { bar(); }518 \\void foo(void) { bar(); }
519 ,519 ,
520 \\pub fn bar() {}520 \\pub fn bar() void {}
521 \\pub export fn foo() {521 \\pub export fn foo() void {
522 \\ bar();522 \\ bar();
523 \\}523 \\}
524 );524 );
...@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
534 \\pub const struct_Foo = extern struct {534 \\pub const struct_Foo = extern struct {
535 \\ field: c_int,535 \\ field: c_int,
536 \\};536 \\};
537 \\pub export fn read_field(foo: ?&struct_Foo) -> c_int {537 \\pub export fn read_field(foo: ?&struct_Foo) c_int {
538 \\ return (??foo).field;538 \\ return (??foo).field;
539 \\}539 \\}
540 );540 );
...@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
544 \\ ;;;;;544 \\ ;;;;;
545 \\}545 \\}
546 ,546 ,
547 \\pub export fn foo() {}547 \\pub export fn foo() void {}
548 );548 );
549549
550 cases.add("undefined array global",550 cases.add("undefined array global",
...@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
560 \\}560 \\}
561 ,561 ,
562 \\pub var array: [100]c_int = undefined;562 \\pub var array: [100]c_int = undefined;
563 \\pub export fn foo(index: c_int) -> c_int {563 \\pub export fn foo(index: c_int) c_int {
564 \\ return array[index];564 \\ return array[index];
565 \\}565 \\}
566 );566 );
...@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
571 \\ return (int)a;571 \\ return (int)a;
572 \\}572 \\}
573 ,573 ,
574 \\pub export fn float_to_int(a: f32) -> c_int {574 \\pub export fn float_to_int(a: f32) c_int {
575 \\ return c_int(a);575 \\ return c_int(a);
576 \\}576 \\}
577 );577 );
...@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
581 \\ return x;581 \\ return x;
582 \\}582 \\}
583 ,583 ,
584 \\pub export fn foo(x: ?&c_ushort) -> ?&c_void {584 \\pub export fn foo(x: ?&c_ushort) ?&c_void {
585 \\ return @ptrCast(?&c_void, x);585 \\ return @ptrCast(?&c_void, x);
586 \\}586 \\}
587 );587 );
...@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
592 \\ return sizeof(int);592 \\ return sizeof(int);
593 \\}593 \\}
594 ,594 ,
595 \\pub export fn size_of() -> usize {595 \\pub export fn size_of() usize {
596 \\ return @sizeOf(c_int);596 \\ return @sizeOf(c_int);
597 \\}597 \\}
598 );598 );
...@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
602 \\ return 0;602 \\ return 0;
603 \\}603 \\}
604 ,604 ,
605 \\pub export fn foo() -> ?&c_int {605 \\pub export fn foo() ?&c_int {
606 \\ return null;606 \\ return null;
607 \\}607 \\}
608 );608 );
...@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
612 \\ return 1, 2;612 \\ return 1, 2;
613 \\}613 \\}
614 ,614 ,
615 \\pub export fn foo() -> c_int {615 \\pub export fn foo() c_int {
616 \\ return x: {616 \\ return x: {
617 \\ _ = 1;617 \\ _ = 1;
618 \\ break :x 2;618 \\ break :x 2;
...@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
625 \\ return (1 << 2) >> 1;625 \\ return (1 << 2) >> 1;
626 \\}626 \\}
627 ,627 ,
628 \\pub export fn foo() -> c_int {628 \\pub export fn foo() c_int {
629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
630 \\}630 \\}
631 );631 );
...@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
643 \\ a <<= (a <<= 1);643 \\ a <<= (a <<= 1);
644 \\}644 \\}
645 ,645 ,
646 \\pub export fn foo() {646 \\pub export fn foo() void {
647 \\ var a: c_int = 0;647 \\ var a: c_int = 0;
648 \\ a += x: {648 \\ a += x: {
649 \\ const _ref = &a;649 \\ const _ref = &a;
...@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
701 \\ a <<= (a <<= 1);701 \\ a <<= (a <<= 1);
702 \\}702 \\}
703 ,703 ,
704 \\pub export fn foo() {704 \\pub export fn foo() void {
705 \\ var a: c_uint = c_uint(0);705 \\ var a: c_uint = c_uint(0);
706 \\ a +%= x: {706 \\ a +%= x: {
707 \\ const _ref = &a;707 \\ const _ref = &a;
...@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
771 \\ u = u--;771 \\ u = u--;
772 \\}772 \\}
773 ,773 ,
774 \\pub export fn foo() {774 \\pub export fn foo() void {
775 \\ var i: c_int = 0;775 \\ var i: c_int = 0;
776 \\ var u: c_uint = c_uint(0);776 \\ var u: c_uint = c_uint(0);
777 \\ i += 1;777 \\ i += 1;
...@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
819 \\ u = --u;819 \\ u = --u;
820 \\}820 \\}
821 ,821 ,
822 \\pub export fn foo() {822 \\pub export fn foo() void {
823 \\ var i: c_int = 0;823 \\ var i: c_int = 0;
824 \\ var u: c_uint = c_uint(0);824 \\ var u: c_uint = c_uint(0);
825 \\ i += 1;825 \\ i += 1;
...@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
862 \\ while (b != 0);862 \\ while (b != 0);
863 \\}863 \\}
864 ,864 ,
865 \\pub export fn foo() {865 \\pub export fn foo() void {
866 \\ var a: c_int = 2;866 \\ var a: c_int = 2;
867 \\ while (true) {867 \\ while (true) {
868 \\ a -= 1;868 \\ a -= 1;
...@@ -886,10 +886,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -886,10 +886,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
886 \\ baz();886 \\ baz();
887 \\}887 \\}
888 ,888 ,
889 \\pub export fn foo() {}889 \\pub export fn foo() void {}
890 \\pub export fn baz() {}890 \\pub export fn baz() void {}
891 \\pub export fn bar() {891 \\pub export fn bar() void {
892 \\ var f: ?extern fn() = foo;892 \\ var f: ?extern fn() void = foo;
893 \\ (??f)();893 \\ (??f)();
894 \\ (??f)();894 \\ (??f)();
895 \\ baz();895 \\ baz();
...@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
901 \\ *x = 1;901 \\ *x = 1;
902 \\}902 \\}
903 ,903 ,
904 \\pub export fn foo(x: ?&c_int) {904 \\pub export fn foo(x: ?&c_int) void {
905 \\ (*??x) = 1;905 \\ (*??x) = 1;
906 \\}906 \\}
907 );907 );
...@@ -927,7 +927,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -927,7 +927,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
927 \\ return *ptr;927 \\ return *ptr;
928 \\}928 \\}
929 ,929 ,
930 \\pub fn foo() -> c_int {930 \\pub fn foo() c_int {
931 \\ var x: c_int = 1234;931 \\ var x: c_int = 1234;
932 \\ var ptr: ?&c_int = &x;932 \\ var ptr: ?&c_int = &x;
933 \\ return *??ptr;933 \\ return *??ptr;
...@@ -939,7 +939,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -939,7 +939,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
939 \\ return "bar";939 \\ return "bar";
940 \\}940 \\}
941 ,941 ,
942 \\pub fn foo() -> ?&const u8 {942 \\pub fn foo() ?&const u8 {
943 \\ return c"bar";943 \\ return c"bar";
944 \\}944 \\}
945 );945 );
...@@ -949,7 +949,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -949,7 +949,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
949 \\ return;949 \\ return;
950 \\}950 \\}
951 ,951 ,
952 \\pub fn foo() {952 \\pub fn foo() void {
953 \\ return;953 \\ return;
954 \\}954 \\}
955 );955 );
...@@ -959,7 +959,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -959,7 +959,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
959 \\ for (int i = 0; i < 10; i += 1) { }959 \\ for (int i = 0; i < 10; i += 1) { }
960 \\}960 \\}
961 ,961 ,
962 \\pub fn foo() {962 \\pub fn foo() void {
963 \\ {963 \\ {
964 \\ var i: c_int = 0;964 \\ var i: c_int = 0;
965 \\ while (i < 10) : (i += 1) {};965 \\ while (i < 10) : (i += 1) {};
...@@ -972,7 +972,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -972,7 +972,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
972 \\ for (;;) { }972 \\ for (;;) { }
973 \\}973 \\}
974 ,974 ,
975 \\pub fn foo() {975 \\pub fn foo() void {
976 \\ while (true) {};976 \\ while (true) {};
977 \\}977 \\}
978 );978 );
...@@ -984,7 +984,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -984,7 +984,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
984 \\ }984 \\ }
985 \\}985 \\}
986 ,986 ,
987 \\pub fn foo() {987 \\pub fn foo() void {
988 \\ while (true) {988 \\ while (true) {
989 \\ break;989 \\ break;
990 \\ };990 \\ };
...@@ -998,7 +998,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -998,7 +998,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
998 \\ }998 \\ }
999 \\}999 \\}
1000 ,1000 ,
1001 \\pub fn foo() {1001 \\pub fn foo() void {
1002 \\ while (true) {1002 \\ while (true) {
1003 \\ continue;1003 \\ continue;
1004 \\ };1004 \\ };
...@@ -1021,9 +1021,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1021,9 +1021,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1021 ,1021 ,
1022 \\pub const GLbitfield = c_uint;1022 \\pub const GLbitfield = c_uint;
1023 ,1023 ,
1024 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield);1024 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield) void;
1025 ,1025 ,
1026 \\pub const OpenGLProc = ?extern fn();1026 \\pub const OpenGLProc = ?extern fn() void;
1027 ,1027 ,
1028 \\pub const union_OpenGLProcs = extern union {1028 \\pub const union_OpenGLProcs = extern union {
1029 \\ ptr: [1]OpenGLProc,1029 \\ ptr: [1]OpenGLProc,
...@@ -1036,7 +1036,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1036,7 +1036,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1036 ,1036 ,
1037 \\pub const glClearPFN = PFNGLCLEARPROC;1037 \\pub const glClearPFN = PFNGLCLEARPROC;
1038 ,1038 ,
1039 \\pub inline fn glClearUnion(arg0: GLbitfield) {1039 \\pub inline fn glClearUnion(arg0: GLbitfield) void {
1040 \\ return (??glProcs.gl.Clear)(arg0);1040 \\ return (??glProcs.gl.Clear)(arg0);
1041 \\}1041 \\}
1042 ,1042 ,
...@@ -1053,7 +1053,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1053,7 +1053,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1053 \\ return x;1053 \\ return x;
1054 \\}1054 \\}
1055 ,1055 ,
1056 \\pub fn foo() -> c_int {1056 \\pub fn foo() c_int {
1057 \\ var x: c_int = 1;1057 \\ var x: c_int = 1;
1058 \\ {1058 \\ {
1059 \\ var x_0: c_int = 2;1059 \\ var x_0: c_int = 2;
...@@ -1068,7 +1068,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1068,7 +1068,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1068 \\ return (float *)a;1068 \\ return (float *)a;
1069 \\}1069 \\}
1070 ,1070 ,
1071 \\fn ptrcast(a: ?&c_int) -> ?&f32 {1071 \\fn ptrcast(a: ?&c_int) ?&f32 {
1072 \\ return @ptrCast(?&f32, a);1072 \\ return @ptrCast(?&f32, a);
1073 \\}1073 \\}
1074 );1074 );
...@@ -1078,7 +1078,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1078,7 +1078,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1078 \\ return ~x;1078 \\ return ~x;
1079 \\}1079 \\}
1080 ,1080 ,
1081 \\pub fn foo(x: c_int) -> c_int {1081 \\pub fn foo(x: c_int) c_int {
1082 \\ return ~x;1082 \\ return ~x;
1083 \\}1083 \\}
1084 );1084 );
...@@ -1088,7 +1088,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1088,7 +1088,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1088 \\ return u32;1088 \\ return u32;
1089 \\}1089 \\}
1090 ,1090 ,
1091 \\pub fn foo(u32_0: c_int) -> c_int {1091 \\pub fn foo(u32_0: c_int) c_int {
1092 \\ return u32_0;1092 \\ return u32_0;
1093 \\}1093 \\}
1094 );1094 );
...@@ -1104,7 +1104,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1104,7 +1104,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1104 \\ static const char v2[] = "2.2.2";1104 \\ static const char v2[] = "2.2.2";
1105 \\}1105 \\}
1106 ,1106 ,
1107 \\pub fn foo() {1107 \\pub fn foo() void {
1108 \\ const v2: &const u8 = c"2.2.2";1108 \\ const v2: &const u8 = c"2.2.2";
1109 \\}1109 \\}
1110 );1110 );
...@@ -1124,7 +1124,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {...@@ -1124,7 +1124,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
1124 \\ }1124 \\ }
1125 \\}1125 \\}
1126 ,1126 ,
1127 \\pub fn if_int(i: c_int) -> c_int {1127 \\pub fn if_int(i: c_int) c_int {
1128 \\ {1128 \\ {
1129 \\ const _tmp = i;1129 \\ const _tmp = i;
1130 \\ if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) {1130 \\ if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) {