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.
55
66[ziglang.org](http://ziglang.org)
77
8[Documentation](http://ziglang.org/documentation/master/)
9
108## Feature Highlights
119
1210 * 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.
200198```
201199./stage2/bin/zig build --build-file ../build.zig install -Drelease-fast
202200```
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;
1010const Buffer = std.Buffer;
1111const io = std.io;
1212
13pub fn build(b: &Builder) -> %void {
13pub fn build(b: &Builder) %void {
1414 const mode = b.standardReleaseOptions();
1515
1616 var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
......@@ -116,11 +116,12 @@ pub fn build(b: &Builder) -> %void {
116116 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
117117 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
118118 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));
120120 test_step.dependOn(tests.addTranslateCTests(b, test_filter));
121 test_step.dependOn(tests.addGenHTests(b, test_filter));
121122}
122123
123fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
124fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) void {
124125 for (dep.libdirs.toSliceConst()) |lib_dir| {
125126 lib_exe_obj.addLibPath(lib_dir);
126127 }
......@@ -135,7 +136,7 @@ fn dependOnLib(lib_exe_obj: &std.build.LibExeObjStep, dep: &const LibraryDep) {
135136 }
136137}
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 {
139140 const lib_prefix = if (lib_exe_obj.target.isWindows()) "" else "lib";
140141 lib_exe_obj.addObjectFile(os.path.join(b.allocator, cmake_binary_dir, "zig_cpp",
141142 b.fmt("{}{}{}", lib_prefix, lib_name, lib_exe_obj.target.libFileExt())) catch unreachable);
......@@ -148,7 +149,7 @@ const LibraryDep = struct {
148149 includes: ArrayList([]const u8),
149150};
150151
151fn findLLVM(b: &Builder, llvm_config_exe: []const u8) -> %LibraryDep {
152fn findLLVM(b: &Builder, llvm_config_exe: []const u8) %LibraryDep {
152153 const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
153154 const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
154155 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 {
196197 return result;
197198}
198199
199pub fn installStdLib(b: &Builder, stdlib_files: []const u8) {
200pub fn installStdLib(b: &Builder, stdlib_files: []const u8) void {
200201 var it = mem.split(stdlib_files, ";");
201202 while (it.next()) |stdlib_file| {
202203 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) {
205206 }
206207}
207208
208pub fn installCHeaders(b: &Builder, c_header_files: []const u8) {
209pub fn installCHeaders(b: &Builder, c_header_files: []const u8) void {
209210 var it = mem.split(c_header_files, ";");
210211 while (it.next()) |c_header_file| {
211212 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) {
214215 }
215216}
216217
217fn nextValue(index: &usize, build_info: []const u8) -> []const u8 {
218fn nextValue(index: &usize, build_info: []const u8) []const u8 {
218219 const start = *index;
219220 while (true) : (*index += 1) {
220221 switch (build_info[*index]) {
ci/appveyor/after_build.bat+1
......@@ -8,6 +8,7 @@ SET "RELEASEDIR=zig-%ZIGVERSION%"
88mkdir "%RELEASEDIR%"
99move build-msvc-release\bin\zig.exe "%RELEASEDIR%"
1010move build-msvc-release\lib "%RELEASEDIR%"
11move zig-cache\langref.html "%RELEASEDIR%"
1112
1213SET "RELEASEZIP=zig-%ZIGVERSION%.zip"
1314
doc/docgen.zig+490-59
......@@ -1,14 +1,18 @@
1const builtin = @import("builtin");
12const std = @import("std");
23const io = std.io;
34const os = std.os;
45const warn = std.debug.warn;
56const mem = std.mem;
7const assert = std.debug.assert;
68
79const max_doc_file_size = 10 * 1024 * 1024;
810
911const 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 {
1216 // TODO use a more general purpose allocator here
1317 var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
1418 defer inc_allocator.deinit();
......@@ -43,6 +47,15 @@ pub fn main() -> %void {
4347 var tokenizer = Tokenizer.init(in_file_name, input_file_bytes);
4448 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 }
4659 try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
4760 try buffered_out_stream.flush();
4861}
......@@ -68,6 +81,7 @@ const Tokenizer = struct {
6881 index: usize,
6982 state: State,
7083 source_file_name: []const u8,
84 code_node_count: usize,
7185
7286 const State = enum {
7387 Start,
......@@ -77,16 +91,17 @@ const Tokenizer = struct {
7791 Eof,
7892 };
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 {
8195 return Tokenizer {
8296 .buffer = buffer,
8397 .index = 0,
8498 .state = State.Start,
8599 .source_file_name = source_file_name,
100 .code_node_count = 0,
86101 };
87102 }
88103
89 fn next(self: &Tokenizer) -> Token {
104 fn next(self: &Tokenizer) Token {
90105 var result = Token {
91106 .id = Token.Id.Eof,
92107 .start = self.index,
......@@ -178,7 +193,7 @@ const Tokenizer = struct {
178193 line_end: usize,
179194 };
180195
181 fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {
196 fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
182197 var loc = Location {
183198 .line = 0,
184199 .column = 0,
......@@ -205,7 +220,7 @@ const Tokenizer = struct {
205220
206221error 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 {
209224 const loc = tokenizer.getTokenLocation(token);
210225 warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args);
211226 if (loc.line_start <= loc.line_end) {
......@@ -228,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const
228243 return error.ParseError;
229244}
230245
231fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) -> %void {
246fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) %void {
232247 if (token.id != id) {
233248 return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
234249 }
235250}
236251
237fn eatToken(tokenizer: &Tokenizer, id: Token.Id) -> %Token {
252fn eatToken(tokenizer: &Tokenizer, id: Token.Id) %Token {
238253 const token = tokenizer.next();
239254 try assertToken(tokenizer, token, id);
240255 return token;
......@@ -251,24 +266,43 @@ const SeeAlsoItem = struct {
251266 token: Token,
252267};
253268
269const ExpectedOutcome = enum {
270 Succeed,
271 Fail,
272};
273
254274const Code = struct {
255275 id: Id,
256276 name: []const u8,
257277 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) {
260285 Test,
261 Exe,
262 Error,
286 TestError: []const u8,
287 TestSafety: []const u8,
288 Exe: ExpectedOutcome,
289 Obj: ?[]const u8,
263290 };
264291};
265292
293const Link = struct {
294 url: []const u8,
295 name: []const u8,
296 token: Token,
297};
298
266299const Node = union(enum) {
267300 Content: []const u8,
268301 Nav,
269302 HeaderOpen: HeaderOpen,
270303 SeeAlso: []const SeeAlsoItem,
271304 Code: Code,
305 Link: Link,
272306};
273307
274308const Toc = struct {
......@@ -282,9 +316,9 @@ const Action = enum {
282316 Close,
283317};
284318
285fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
319fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
286320 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
289323 var header_stack_size: usize = 0;
290324 var last_action = Action.Open;
......@@ -365,7 +399,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
365399 }
366400 } else if (mem.eql(u8, tag_name, "see_also")) {
367401 var list = std.ArrayList(SeeAlsoItem).init(allocator);
368 %defer list.deinit();
402 errdefer list.deinit();
369403
370404 while (true) {
371405 const see_also_tok = tokenizer.next();
......@@ -385,6 +419,31 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
385419 else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),
386420 }
387421 }
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 });
388447 } else if (mem.eql(u8, tag_name, "code_begin")) {
389448 _ = try eatToken(tokenizer, Token.Id.Separator);
390449 const code_kind_tok = try eatToken(tokenizer, Token.Id.TagContent);
......@@ -401,28 +460,71 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
401460 }
402461 const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
403462 var code_kind_id: Code.Id = undefined;
463 var is_inline = false;
404464 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 };
406468 } else if (mem.eql(u8, code_kind_str, "test")) {
407469 code_kind_id = Code.Id.Test;
408 } else if (mem.eql(u8, code_kind_str, "error")) {
409 code_kind_id = Code.Id.Error;
470 } else if (mem.eql(u8, code_kind_str, "test_err")) {
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;
410484 } else {
411485 return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);
412486 }
413 const source_token = try eatToken(tokenizer, Token.Id.Content);
414 _ = try eatToken(tokenizer, Token.Id.BracketOpen);
415 const end_code_tag = try eatToken(tokenizer, Token.Id.TagContent);
416 const end_tag_name = tokenizer.buffer[end_code_tag.start..end_code_tag.end];
417 if (!mem.eql(u8, end_tag_name, "code_end")) {
418 return parseError(tokenizer, end_code_tag, "expected code_end token");
419 }
420 _ = try eatToken(tokenizer, Token.Id.BracketClose);
421 try nodes.append(Node {.Code = Code{
487
488 var mode = builtin.Mode.Debug;
489 var link_objects = std.ArrayList([]const u8).init(allocator);
490 defer link_objects.deinit();
491 var target_windows = false;
492 var link_libc = false;
493
494 const source_token = while (true) {
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 {
422518 .id = code_kind_id,
423519 .name = name,
424520 .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,
425526 }});
527 tokenizer.code_node_count += 1;
426528 } else {
427529 return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);
428530 }
......@@ -438,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) -> %Toc {
438540 };
439541}
440542
441fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
543fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
442544 var buf = try std.Buffer.initSize(allocator, 0);
443545 defer buf.deinit();
444546
......@@ -458,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
458560 return buf.toOwnedSlice();
459561}
460562
461fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
563fn escapeHtml(allocator: &mem.Allocator, input: []const u8) %[]u8 {
462564 var buf = try std.Buffer.initSize(allocator, 0);
463565 defer buf.deinit();
464566
......@@ -476,14 +578,127 @@ fn escapeHtml(allocator: &mem.Allocator, input: []const u8) -> %[]u8 {
476578 return buf.toOwnedSlice();
477579}
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
479687error 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;
482691 for (toc.nodes) |node| {
483692 switch (node) {
484693 Node.Content => |data| {
485694 try out.write(data);
486695 },
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 },
487702 Node.Nav => {
488703 try out.write(toc.toc);
489704 },
......@@ -502,65 +717,281 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
502717 try out.write("</ul>\n");
503718 },
504719 Node.Code => |code| {
720 code_progress_index += 1;
721 warn("docgen example code {}/{}...", code_progress_index, tokenizer.code_node_count);
722
505723 const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
506724 const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
507725 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 }
508729 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);
511730 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);
513731 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);
515732 try io.writeFile(tmp_source_file_name, trimmed_raw_source, null);
516733
517734 switch (code.id) {
518 Code.Id.Exe => {
519 {
520 const args = [][]const u8 {zig_exe, "build-exe", tmp_source_file_name, "--output", tmp_bin_file_name};
521 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
735 Code.Id.Exe => |expected_outcome| {
736 const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
737 const tmp_bin_file_name = try os.path.join(allocator, tmp_dir_name, name_plus_bin_ext);
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);
522775 switch (result.term) {
523776 os.ChildProcess.Term.Exited => |exit_code| {
524 if (exit_code != 0) {
525 warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
526 for (args) |arg| warn("{} ", arg) else warn("\n");
527 return parseError(tokenizer, code.source_token, "example failed to compile");
777 if (exit_code == 0) {
778 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
779 for (run_args) |arg| warn("{} ", arg) else warn("\n");
780 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
528781 }
529782 },
530 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 },
783 else => {},
535784 }
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 },
536846 }
537 const args = [][]const u8 {tmp_bin_file_name};
538 const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
847 const result = try os.ChildProcess.exec(allocator, test_args.toSliceConst(), null, null, max_doc_file_size);
539848 switch (result.term) {
540849 os.ChildProcess.Term.Exited => |exit_code| {
541 if (exit_code != 0) {
542 warn("The following command exited with code {}:\n", exit_code);
543 for (args) |arg| warn("{} ", arg) else warn("\n");
544 return parseError(tokenizer, code.source_token, "example exited with code {}", exit_code);
850 if (exit_code == 0) {
851 warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
852 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
853 return parseError(tokenizer, code.source_token, "example incorrectly compiled");
545854 }
546855 },
547856 else => {
548 warn("The following command crashed:\n");
549 for (args) |arg| warn("{} ", arg) else warn("\n");
550 return parseError(tokenizer, code.source_token, "example crashed");
857 warn("{}\nThe following command crashed:\n", result.stderr);
858 for (test_args.toSliceConst()) |arg| warn("{} ", arg) else warn("\n");
859 return parseError(tokenizer, code.source_token, "example compile crashed");
551860 },
552861 }
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);
554869 },
555 Code.Id.Test => {
556 @panic("TODO");
870
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);
557904 },
558 Code.Id.Error => {
559 @panic("TODO");
905 Code.Id.Obj => |maybe_error_match| {
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 }
560968 },
561969 }
970 warn("OK\n");
562971 },
563972 }
564973 }
565974
566975}
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 @@
44 <meta charset="utf-8">
55 <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
66 <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>
810 <style type="text/css">
911 table, th, td {
1012 border-collapse: collapse;
......@@ -13,6 +15,27 @@
1315 th, td {
1416 padding: 0.1em;
1517 }
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 }
1639 @media screen and (min-width: 28.75em) {
1740 #nav {
1841 width: 20em;
......@@ -53,13 +76,17 @@
5376 If you search for something specific in this documentation and do not find it,
5477 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>.
5578 </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>
5683 {#header_close#}
5784 {#header_open|Hello World#}
5885
5986 {#code_begin|exe|hello#}
6087const std = @import("std");
6188
62pub fn main() -> %void {
89pub fn main() %void {
6390 // If this program is run without stdout attached, exit with an error.
6491 var stdout_file = try std.io.getStdOut();
6592 // If this program encounters pipe failure when printing to stdout, exit
......@@ -75,10 +102,14 @@ pub fn main() -> %void {
75102 {#code_begin|exe|hello#}
76103const warn = @import("std").debug.warn;
77104
78pub fn main() -> %void {
105pub fn main() void {
79106 warn("Hello, world!\n");
80107}
81108 {#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>
82113 {#see_also|Values|@import|Errors|Root Source File#}
83114 {#header_close#}
84115 {#header_open|Source Encoding#}
......@@ -101,7 +132,7 @@ const assert = std.debug.assert;
101132// error declaration, makes `error.ArgNotFound` available
102133error ArgNotFound;
103134
104pub fn main() -> %void {
135pub fn main() %void {
105136 // integers
106137 const one_plus_one: i32 = 1 + 1;
107138 warn("1 + 1 = {}\n", one_plus_one);
......@@ -354,7 +385,7 @@ pub fn main() -> %void {
354385 <tr>
355386 <td><code>noreturn</code></td>
356387 <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>
358389 </tr>
359390 <tr>
360391 <td><code>type</code></td>
......@@ -399,7 +430,8 @@ pub fn main() -> %void {
399430 {#see_also|Nullables|this#}
400431 {#header_close#}
401432 {#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;
403435const mem = @import("std").mem;
404436
405437test "string literals" {
......@@ -413,11 +445,10 @@ test "string literals" {
413445
414446 // A C string literal is a null terminated pointer.
415447 const null_terminated_bytes = c"hello";
416 assert(@typeOf(null_terminated_bytes) == &amp;const u8);
448 assert(@typeOf(null_terminated_bytes) == &const u8);
417449 assert(null_terminated_bytes[5] == 0);
418}</code></pre>
419 <pre><code class="sh">$ zig test string_literals.zig
420Test 1/1 string literals...OK</code></pre>
450}
451 {#code_end#}
421452 {#see_also|Arrays|Zig Test#}
422453 {#header_open|Escape Sequences#}
423454 <table>
......@@ -477,25 +508,29 @@ Test 1/1 string literals...OK</code></pre>
477508 However, if the next line begins with <code>\\</code> then a newline is appended and
478509 the string literal continues.
479510 </p>
480 <pre><code class="zig">const hello_world_in_c =
481 \\#include &lt;stdio.h&gt;
511 {#code_begin|syntax#}
512const hello_world_in_c =
513 \\#include <stdio.h>
482514 \\
483515 \\int main(int argc, char **argv) {
484516 \\ printf("hello world\n");
485517 \\ return 0;
486518 \\}
487;</code></pre>
519;
520 {#code_end#}
488521 <p>
489522 For a multiline C string literal, prepend <code>c</code> to each <code>\\</code>:
490523 </p>
491 <pre><code class="zig">const c_string_literal =
492 c\\#include &lt;stdio.h&gt;
524 {#code_begin|syntax#}
525const c_string_literal =
526 c\\#include <stdio.h>
493527 c\\
494528 c\\int main(int argc, char **argv) {
495529 c\\ printf("hello world\n");
496530 c\\ return 0;
497531 c\\}
498;</code></pre>
532;
533 {#code_end#}
499534 <p>
500535 In this example the variable <code>c_string_literal</code> has type <code>&amp;const char</code> and
501536 has a terminating null byte.
......@@ -505,9 +540,10 @@ Test 1/1 string literals...OK</code></pre>
505540 {#header_close#}
506541 {#header_open|Assignment#}
507542 <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 {
511547 // It works at global scope as well as inside functions.
512548 const y = 5678;
513549
......@@ -517,13 +553,11 @@ fn foo() {
517553
518554test "assignment" {
519555 foo();
520}</code></pre>
521 <pre><code class="sh">$ zig test test.zig
522test.zig:8:7: error: cannot assign to constant
523 y += 1;
524 ^</code></pre>
556}
557 {#code_end#}
525558 <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
528562test "var" {
529563 var y: i32 = 5678;
......@@ -531,38 +565,37 @@ test "var" {
531565 y += 1;
532566
533567 assert(y == 5679);
534}</code></pre>
535 <pre><code class="sh">$ zig test test.zig
536Test 1/1 assignment...OK</code></pre>
568}
569 {#code_end#}
537570 <p>Variables must be initialized:</p>
538 <pre><code class="zig">test "initialization" {
571 {#code_begin|test_err#}
572test "initialization" {
539573 var x: i32;
540574
541575 x = 1;
542}</code></pre>
543 <pre><code class="sh">$ zig test test.zig
544test.zig:3:5: error: variables must be initialized
545 var x: i32;
546 ^</code></pre>
576}
577 {#code_end#}
547578 <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
550582test "init with undefined" {
551583 var x: i32 = undefined;
552584 x = 1;
553585 assert(x == 1);
554}</code></pre>
555 <pre><code class="sh">$ zig test test.zig
556Test 1/1 init with undefined...OK</code></pre>
586}
587 {#code_end#}
557588 {#header_close#}
558589 {#header_close#}
559590 {#header_open|Integers#}
560591 {#header_open|Integer Literals#}
561 <pre><code class="zig">const decimal_int = 98222;
592 {#code_begin|syntax#}
593const decimal_int = 98222;
562594const hex_int = 0xff;
563595const another_hex_int = 0xFF;
564596const octal_int = 0o755;
565const binary_int = 0b11110000;</code></pre>
597const binary_int = 0b11110000;
598 {#code_end#}
566599 {#header_close#}
567600 {#header_open|Runtime Integer Values#}
568601 <p>
......@@ -573,9 +606,11 @@ const binary_int = 0b11110000;</code></pre>
573606 However, once an integer value is no longer known at compile-time, it must have a
574607 known size, and is vulnerable to undefined behavior.
575608 </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 {
577611 return a / b;
578}</code></pre>
612}
613 {#code_end#}
579614 <p>
580615 In this function, values <code>a</code> and <code>b</code> are known only at runtime,
581616 and thus this division operation is vulnerable to both integer overflow and
......@@ -590,52 +625,53 @@ const binary_int = 0b11110000;</code></pre>
590625 {#header_close#}
591626 {#header_close#}
592627 {#header_open|Floats#}
593 {#header_close#}
594628 {#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;
596631const another_float = 123.0;
597632const yet_another = 123.0e+77;
598633
599634const hex_floating_point = 0x103.70p-5;
600635const 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#}
602638 {#header_close#}
603639 {#header_open|Floating Point Operations#}
604640 <p>By default floating point operations use <code>Optimized</code> mode,
605641 but you can switch to <code>Strict</code> mode on a per-block basis:</p>
606 <p>foo.zig</p>
607 <pre><code class="zig">const builtin = @import("builtin");
608const big = f64(1 &lt;&lt; 40);
642 {#code_begin|obj|foo#}
643 {#code_release_fast#}
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 {
611648 @setFloatMode(this, builtin.FloatMode.Strict);
612649 return x + big - big;
613650}
614651
615export fn foo_optimized(x: f64) -&gt; f64 {
652export fn foo_optimized(x: f64) f64 {
616653 return x + big - big;
617}</code></pre>
618 <p>test.zig</p>
619 <pre><code class="zig">const warn = @import("std").debug.warn;
654}
655 {#code_end#}
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;
622extern fn foo_optimized(x: f64) -&gt; f64;
663extern fn foo_strict(x: f64) f64;
664extern fn foo_optimized(x: f64) f64;
623665
624pub fn main() -&gt; %void {
666pub fn main() %void {
625667 const x = 0.001;
626668 warn("optimized = {}\n", foo_optimized(x));
627669 warn("strict = {}\n", foo_strict(x));
628}</code></pre>
629 <p>For this test we have to separate code into two object files -
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>
670}
671 {#code_end#}
637672 {#see_also|@setFloatMode|Division by Zero#}
638673 {#header_close#}
674 {#header_close#}
639675 {#header_open|Operators#}
640676 {#header_open|Table of Operators#}
641677 <table>
......@@ -658,13 +694,13 @@ strict = 9.765625e-3</code></pre>
658694a += b</code></pre></td>
659695 <td>
660696 <ul>
661 <li><a href="#integers">Integers</a></li>
662 <li><a href="#floats">Floats</a></li>
697 <li>{#link|Integers#}</li>
698 <li>{#link|Floats#}</li>
663699 </ul>
664700 </td>
665701 <td>Addition.
666702 <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>
668704 </ul>
669705 </td>
670706 <td>
......@@ -676,7 +712,7 @@ a += b</code></pre></td>
676712a +%= b</code></pre></td>
677713 <td>
678714 <ul>
679 <li><a href="#integers">Integers</a></li>
715 <li>{#link|Integers#}</li>
680716 </ul>
681717 </td>
682718 <td>Wrapping Addition.
......@@ -693,13 +729,13 @@ a +%= b</code></pre></td>
693729a -= b</code></pre></td>
694730 <td>
695731 <ul>
696 <li><a href="#integers">Integers</a></li>
697 <li><a href="#floats">Floats</a></li>
732 <li>{#link|Integers#}</li>
733 <li>{#link|Floats#}</li>
698734 </ul>
699735 </td>
700736 <td>Subtraction.
701737 <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>
703739 </ul>
704740 </td>
705741 <td>
......@@ -711,7 +747,7 @@ a -= b</code></pre></td>
711747a -%= b</code></pre></td>
712748 <td>
713749 <ul>
714 <li><a href="#integers">Integers</a></li>
750 <li>{#link|Integers#}</li>
715751 </ul>
716752 </td>
717753 <td>Wrapping Subtraction.
......@@ -727,14 +763,14 @@ a -%= b</code></pre></td>
727763 <td><pre><code class="zig">-a<code></pre></td>
728764 <td>
729765 <ul>
730 <li><a href="#integers">Integers</a></li>
731 <li><a href="#floats">Floats</a></li>
766 <li>{#link|Integers#}</li>
767 <li>{#link|Floats#}</li>
732768 </ul>
733769 </td>
734770 <td>
735771 Negation.
736772 <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>
738774 </ul>
739775 </td>
740776 <td>
......@@ -745,7 +781,7 @@ a -%= b</code></pre></td>
745781 <td><pre><code class="zig">-%a<code></pre></td>
746782 <td>
747783 <ul>
748 <li><a href="#integers">Integers</a></li>
784 <li>{#link|Integers#}</li>
749785 </ul>
750786 </td>
751787 <td>
......@@ -763,13 +799,13 @@ a -%= b</code></pre></td>
763799a *= b</code></pre></td>
764800 <td>
765801 <ul>
766 <li><a href="#integers">Integers</a></li>
767 <li><a href="#floats">Floats</a></li>
802 <li>{#link|Integers#}</li>
803 <li>{#link|Floats#}</li>
768804 </ul>
769805 </td>
770806 <td>Multiplication.
771807 <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>
773809 </ul>
774810 </td>
775811 <td>
......@@ -781,7 +817,7 @@ a *= b</code></pre></td>
781817a *%= b</code></pre></td>
782818 <td>
783819 <ul>
784 <li><a href="#integers">Integers</a></li>
820 <li>{#link|Integers#}</li>
785821 </ul>
786822 </td>
787823 <td>Wrapping Multiplication.
......@@ -798,19 +834,19 @@ a *%= b</code></pre></td>
798834a /= b</code></pre></td>
799835 <td>
800836 <ul>
801 <li><a href="#integers">Integers</a></li>
802 <li><a href="#floats">Floats</a></li>
837 <li>{#link|Integers#}</li>
838 <li>{#link|Floats#}</li>
803839 </ul>
804840 </td>
805841 <td>Divison.
806842 <ul>
807 <li>Can cause <a href="#undef-integer-overflow">overflow</a> for integers.</li>
808 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> 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>
843 <li>Can cause {#link|overflow|Default Operations#} for integers.</li>
844 <li>Can cause {#link|Division by Zero#} for integers.</li>
845 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li>
810846 <li>For non-compile-time-known signed integers, must use
811 <a href="#builtin-divTrunc">@divTrunc</a>,
812 <a href="#builtin-divFloor">@divFloor</a>, or
813 <a href="#builtin-divExact">@divExact</a> instead of <code>/</code>.
847 {#link|@divTrunc#},
848 {#link|@divFloor#}, or
849 {#link|@divExact#} instead of <code>/</code>.
814850 </li>
815851 </ul>
816852 </td>
......@@ -823,17 +859,17 @@ a /= b</code></pre></td>
823859a %= b</code></pre></td>
824860 <td>
825861 <ul>
826 <li><a href="#integers">Integers</a></li>
827 <li><a href="#floats">Floats</a></li>
862 <li>{#link|Integers#}</li>
863 <li>{#link|Floats#}</li>
828864 </ul>
829865 </td>
830866 <td>Remainder Division.
831867 <ul>
832 <li>Can cause <a href="#undef-division-by-zero">division by zero</a> 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>
868 <li>Can cause {#link|Division by Zero#} for integers.</li>
869 <li>Can cause {#link|Division by Zero#} for floats in {#link|FloatMode.Optimized Mode|Floating Point Operations#}.</li>
834870 <li>For non-compile-time-known signed integers, must use
835 <a href="#builtin-rem">@rem</a> or
836 <a href="#builtin-mod">@mod</a> instead of <code>%</code>.
871 {#link|@rem#} or
872 {#link|@mod#} instead of <code>%</code>.
837873 </li>
838874 </ul>
839875 </td>
......@@ -846,13 +882,13 @@ a %= b</code></pre></td>
846882a &lt;&lt;= b</code></pre></td>
847883 <td>
848884 <ul>
849 <li><a href="#integers">Integers</a></li>
885 <li>{#link|Integers#}</li>
850886 </ul>
851887 </td>
852888 <td>Bit Shift Left.
853889 <ul>
854 <li>See also <a href="#builtin-shlExact">@shlExact</a>.</li>
855 <li>See also <a href="#builtin-shlWithOverflow">@shlWithOverflow</a>.</li>
890 <li>See also {#link|@shlExact#}.</li>
891 <li>See also {#link|@shlWithOverflow#}.</li>
856892 </ul>
857893 </td>
858894 <td>
......@@ -864,12 +900,12 @@ a &lt;&lt;= b</code></pre></td>
864900a &gt;&gt;= b</code></pre></td>
865901 <td>
866902 <ul>
867 <li><a href="#integers">Integers</a></li>
903 <li>{#link|Integers#}</li>
868904 </ul>
869905 </td>
870906 <td>Bit Shift Right.
871907 <ul>
872 <li>See also <a href="#builtin-shrExact">@shrExact</a>.</li>
908 <li>See also {#link|@shrExact#}.</li>
873909 </ul>
874910 </td>
875911 <td>
......@@ -881,7 +917,7 @@ a &gt;&gt;= b</code></pre></td>
881917a &amp;= b</code></pre></td>
882918 <td>
883919 <ul>
884 <li><a href="#integers">Integers</a></li>
920 <li>{#link|Integers#}</li>
885921 </ul>
886922 </td>
887923 <td>Bitwise AND.
......@@ -895,7 +931,7 @@ a &amp;= b</code></pre></td>
895931a |= b</code></pre></td>
896932 <td>
897933 <ul>
898 <li><a href="#integers">Integers</a></li>
934 <li>{#link|Integers#}</li>
899935 </ul>
900936 </td>
901937 <td>Bitwise OR.
......@@ -909,7 +945,7 @@ a |= b</code></pre></td>
909945a ^= b</code></pre></td>
910946 <td>
911947 <ul>
912 <li><a href="#integers">Integers</a></li>
948 <li>{#link|Integers#}</li>
913949 </ul>
914950 </td>
915951 <td>Bitwise XOR.
......@@ -922,7 +958,7 @@ a ^= b</code></pre></td>
922958 <td><pre><code class="zig">~a<code></pre></td>
923959 <td>
924960 <ul>
925 <li><a href="#integers">Integers</a></li>
961 <li>{#link|Integers#}</li>
926962 </ul>
927963 </td>
928964 <td>
......@@ -936,13 +972,13 @@ a ^= b</code></pre></td>
936972 <td><pre><code class="zig">a ?? b</code></pre></td>
937973 <td>
938974 <ul>
939 <li><a href="#nullables">Nullables</a></li>
975 <li>{#link|Nullables#}</li>
940976 </ul>
941977 </td>
942978 <td>If <code>a</code> is <code>null</code>,
943979 returns <code>b</code> ("default value"),
944980 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#}.
946982 </td>
947983 <td>
948984 <pre><code class="zig">const value: ?u32 = null;
......@@ -954,7 +990,7 @@ unwrapped == 1234</code></pre>
954990 <td><pre><code class="zig">??a</code></pre></td>
955991 <td>
956992 <ul>
957 <li><a href="#nullables">Nullables</a></li>
993 <li>{#link|Nullables#}</li>
958994 </ul>
959995 </td>
960996 <td>
......@@ -971,13 +1007,13 @@ unwrapped == 1234</code></pre>
9711007a catch |err| b</code></pre></td>
9721008 <td>
9731009 <ul>
974 <li><a href="#errors">Error Unions</a></li>
1010 <li>{#link|Error Unions|Errors#}</li>
9751011 </ul>
9761012 </td>
9771013 <td>If <code>a</code> is an <code>error</code>,
9781014 returns <code>b</code> ("default value"),
9791015 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#}.
9811017 <code>err</code> is the <code>error</code> and is in scope of the expression <code>b</code>.
9821018 </td>
9831019 <td>
......@@ -986,26 +1022,11 @@ const unwrapped = value catch 1234;
9861022unwrapped == 1234</code></pre>
9871023 </td>
9881024 </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>
10041025 <tr>
10051026 <td><pre><code class="zig">a and b<code></pre></td>
10061027 <td>
10071028 <ul>
1008 <li><a href="#primitive-types">bool</a></li>
1029 <li>{#link|bool|Primitive Types#}</li>
10091030 </ul>
10101031 </td>
10111032 <td>
......@@ -1020,7 +1041,7 @@ unwrapped == 1234</code></pre>
10201041 <td><pre><code class="zig">a or b<code></pre></td>
10211042 <td>
10221043 <ul>
1023 <li><a href="#primitive-types">bool</a></li>
1044 <li>{#link|bool|Primitive Types#}</li>
10241045 </ul>
10251046 </td>
10261047 <td>
......@@ -1035,7 +1056,7 @@ unwrapped == 1234</code></pre>
10351056 <td><pre><code class="zig">!a<code></pre></td>
10361057 <td>
10371058 <ul>
1038 <li><a href="#primitive-types">bool</a></li>
1059 <li>{#link|bool|Primitive Types#}</li>
10391060 </ul>
10401061 </td>
10411062 <td>
......@@ -1049,10 +1070,10 @@ unwrapped == 1234</code></pre>
10491070 <td><pre><code class="zig">a == b<code></pre></td>
10501071 <td>
10511072 <ul>
1052 <li><a href="#integers">Integers</a></li>
1053 <li><a href="#floats">Floats</a></li>
1054 <li><a href="#primitive-types">bool</a></li>
1055 <li><a href="#primitive-types">type</a></li>
1073 <li>{#link|Integers#}</li>
1074 <li>{#link|Floats#}</li>
1075 <li>{#link|bool|Primitive Types#}</li>
1076 <li>{#link|type|Primitive Types#}</li>
10561077 </ul>
10571078 </td>
10581079 <td>
......@@ -1066,7 +1087,7 @@ unwrapped == 1234</code></pre>
10661087 <td><pre><code class="zig">a == null<code></pre></td>
10671088 <td>
10681089 <ul>
1069 <li><a href="#nullables">Nullables</a></li>
1090 <li>{#link|Nullables#}</li>
10701091 </ul>
10711092 </td>
10721093 <td>
......@@ -1081,10 +1102,10 @@ value == null</code></pre>
10811102 <td><pre><code class="zig">a != b<code></pre></td>
10821103 <td>
10831104 <ul>
1084 <li><a href="#integers">Integers</a></li>
1085 <li><a href="#floats">Floats</a></li>
1086 <li><a href="#primitive-types">bool</a></li>
1087 <li><a href="#primitive-types">type</a></li>
1105 <li>{#link|Integers#}</li>
1106 <li>{#link|Floats#}</li>
1107 <li>{#link|bool|Primitive Types#}</li>
1108 <li>{#link|type|Primitive Types#}</li>
10881109 </ul>
10891110 </td>
10901111 <td>
......@@ -1098,8 +1119,8 @@ value == null</code></pre>
10981119 <td><pre><code class="zig">a &gt; b<code></pre></td>
10991120 <td>
11001121 <ul>
1101 <li><a href="#integers">Integers</a></li>
1102 <li><a href="#floats">Floats</a></li>
1122 <li>{#link|Integers#}</li>
1123 <li>{#link|Floats#}</li>
11031124 </ul>
11041125 </td>
11051126 <td>
......@@ -1113,8 +1134,8 @@ value == null</code></pre>
11131134 <td><pre><code class="zig">a &gt;= b<code></pre></td>
11141135 <td>
11151136 <ul>
1116 <li><a href="#integers">Integers</a></li>
1117 <li><a href="#floats">Floats</a></li>
1137 <li>{#link|Integers#}</li>
1138 <li>{#link|Floats#}</li>
11181139 </ul>
11191140 </td>
11201141 <td>
......@@ -1128,8 +1149,8 @@ value == null</code></pre>
11281149 <td><pre><code class="zig">a &lt; b<code></pre></td>
11291150 <td>
11301151 <ul>
1131 <li><a href="#integers">Integers</a></li>
1132 <li><a href="#floats">Floats</a></li>
1152 <li>{#link|Integers#}</li>
1153 <li>{#link|Floats#}</li>
11331154 </ul>
11341155 </td>
11351156 <td>
......@@ -1143,8 +1164,8 @@ value == null</code></pre>
11431164 <td><pre><code class="zig">a &lt;= b<code></pre></td>
11441165 <td>
11451166 <ul>
1146 <li><a href="#integers">Integers</a></li>
1147 <li><a href="#floats">Floats</a></li>
1167 <li>{#link|Integers#}</li>
1168 <li>{#link|Floats#}</li>
11481169 </ul>
11491170 </td>
11501171 <td>
......@@ -1158,13 +1179,13 @@ value == null</code></pre>
11581179 <td><pre><code class="zig">a ++ b<code></pre></td>
11591180 <td>
11601181 <ul>
1161 <li><a href="#arrays">Arrays</a></li>
1182 <li>{#link|Arrays#}</li>
11621183 </ul>
11631184 </td>
11641185 <td>
11651186 Array concatenation.
11661187 <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#}.
11681189 </ul>
11691190 </td>
11701191 <td>
......@@ -1179,13 +1200,13 @@ mem.eql(u32, together, []u32{1,2,3,4})</code></pre>
11791200 <td><pre><code class="zig">a ** b<code></pre></td>
11801201 <td>
11811202 <ul>
1182 <li><a href="#arrays">Arrays</a></li>
1203 <li>{#link|Arrays#}</li>
11831204 </ul>
11841205 </td>
11851206 <td>
11861207 Array multiplication.
11871208 <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#}.
11891210 </ul>
11901211 </td>
11911212 <td>
......@@ -1198,7 +1219,7 @@ mem.eql(u8, pattern, "ababab")</code></pre>
11981219 <td><pre><code class="zig">*a<code></pre></td>
11991220 <td>
12001221 <ul>
1201 <li><a href="#pointers">Pointers</a></li>
1222 <li>{#link|Pointers#}</li>
12021223 </ul>
12031224 </td>
12041225 <td>
......@@ -1228,7 +1249,7 @@ const ptr = &amp;x;
12281249 {#header_close#}
12291250 {#header_open|Precedence#}
12301251 <pre><code>x() x[] x.y
1231!x -x -%x ~x *x &amp;x ?x %x %%x ??x
1252!x -x -%x ~x *x &amp;x ?x %x ??x
12321253x{}
12331254* / % ** *%
12341255+ - ++ +% -%
......@@ -1244,7 +1265,8 @@ or
12441265 {#header_close#}
12451266 {#header_close#}
12461267 {#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;
12481270const mem = @import("std").mem;
12491271
12501272// array literal
......@@ -1314,7 +1336,7 @@ comptime {
13141336}
13151337
13161338// use compile-time code to initialize an array
1317var fancy_array = {
1339var fancy_array = init: {
13181340 var initial_value: [10]Point = undefined;
13191341 for (initial_value) |*pt, i| {
13201342 *pt = Point {
......@@ -1322,7 +1344,7 @@ var fancy_array = {
13221344 .y = i32(i) * 2,
13231345 };
13241346 }
1325 initial_value
1347 break :init initial_value;
13261348};
13271349const Point = struct {
13281350 x: i32,
......@@ -1336,26 +1358,23 @@ test "compile-time array initalization" {
13361358
13371359// call a function to initialize an array
13381360var more_points = []Point{makePoint(3)} ** 10;
1339fn makePoint(x: i32) -&gt; Point {
1340 Point {
1361fn makePoint(x: i32) Point {
1362 return Point {
13411363 .x = x,
13421364 .y = x * 2,
1343 }
1365 };
13441366}
13451367test "array initialization with function calls" {
13461368 assert(more_points[4].x == 3);
13471369 assert(more_points[4].y == 6);
13481370 assert(more_points.len == 10);
1349}</code></pre>
1350 <pre><code class="sh">$ zig test arrays.zig
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>
1371}
1372 {#code_end#}
13551373 {#see_also|for|Slices#}
13561374 {#header_close#}
13571375 {#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
13601379test "address of syntax" {
13611380 // Get the address of a variable:
......@@ -1366,12 +1385,12 @@ test "address of syntax" {
13661385 assert(*x_ptr == 1234);
13671386
13681387 // 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
13711390 // If you want to mutate the value, you'd need an address of a mutable variable:
13721391 var y: i32 = 5678;
13731392 const y_ptr = &y;
1374 assert(@typeOf(y_ptr) == &amp;i32);
1393 assert(@typeOf(y_ptr) == &i32);
13751394 *y_ptr += 1;
13761395 assert(*y_ptr == 5679);
13771396}
......@@ -1381,7 +1400,7 @@ test "pointer array access" {
13811400 // need such a thing, use array index syntax:
13821401
13831402 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
13861405 assert(array[2] == 3);
13871406 ptr[1] += 1;
......@@ -1392,10 +1411,10 @@ test "pointer slicing" {
13921411 // In Zig, we prefer using slices over null-terminated pointers.
13931412 // You can turn a pointer into a slice using slice syntax:
13941413 var array = []u8{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
1395 const ptr = &amp;array[1];
1414 const ptr = &array[1];
13961415 const slice = ptr[1..3];
13971416
1398 assert(slice.ptr == &amp;ptr[1]);
1417 assert(slice.ptr == &ptr[1]);
13991418 assert(slice.len == 2);
14001419
14011420 // Slices have bounds checking and are therefore protected
......@@ -1410,7 +1429,7 @@ comptime {
14101429 // Pointers work at compile-time too, as long as you don't use
14111430 // @ptrCast.
14121431 var x: i32 = 1;
1413 const ptr = &amp;x;
1432 const ptr = &x;
14141433 *ptr += 1;
14151434 x += 1;
14161435 assert(*ptr == 3);
......@@ -1418,7 +1437,7 @@ comptime {
14181437
14191438test "@ptrToInt and @intToPtr" {
14201439 // To convert an integer address into a pointer, use @intToPtr:
1421 const ptr = @intToPtr(&amp;i32, 0xdeadbeef);
1440 const ptr = @intToPtr(&i32, 0xdeadbeef);
14221441
14231442 // To convert a pointer to an integer, use @ptrToInt:
14241443 const addr = @ptrToInt(ptr);
......@@ -1430,7 +1449,7 @@ test "@ptrToInt and @intToPtr" {
14301449comptime {
14311450 // Zig is able to do this at compile-time, as long as
14321451 // ptr is never dereferenced.
1433 const ptr = @intToPtr(&amp;i32, 0xdeadbeef);
1452 const ptr = @intToPtr(&i32, 0xdeadbeef);
14341453 const addr = @ptrToInt(ptr);
14351454 assert(@typeOf(addr) == usize);
14361455 assert(addr == 0xdeadbeef);
......@@ -1440,34 +1459,34 @@ test "volatile" {
14401459 // In Zig, loads and stores are assumed to not have side effects.
14411460 // If a given load or store should have side effects, such as
14421461 // 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
14451464 // Now loads and stores with mmio_ptr are guaranteed to all happen
14461465 // and in the same order as in source code.
1447 assert(@typeOf(mmio_ptr) == &amp;volatile u8);
1466 assert(@typeOf(mmio_ptr) == &volatile u8);
14481467}
14491468
14501469test "nullable pointers" {
14511470 // Pointers cannot be null. If you want a null pointer, use the nullable
14521471 // prefix `?` to make the pointer type nullable.
1453 var ptr: ?&amp;i32 = null;
1472 var ptr: ?&i32 = null;
14541473
14551474 var x: i32 = 1;
1456 ptr = &amp;x;
1475 ptr = &x;
14571476
14581477 assert(*??ptr == 1);
14591478
14601479 // Nullable pointers are the same size as normal pointers, because pointer
14611480 // value 0 is used as the null value.
1462 assert(@sizeOf(?&amp;i32) == @sizeOf(&amp;i32));
1481 assert(@sizeOf(?&i32) == @sizeOf(&i32));
14631482}
14641483
14651484test "pointer casting" {
14661485 // To convert one pointer type to another, use @ptrCast. This is an unsafe
14671486 // operation that Zig cannot protect you against. Use @ptrCast only when other
14681487 // conversions are not possible.
1469 const bytes = []u8{0x12, 0x12, 0x12, 0x12};
1470 const u32_ptr = @ptrCast(&amp;const u32, &amp;bytes[0]);
1488 const bytes align(@alignOf(u32)) = []u8{0x12, 0x12, 0x12, 0x12};
1489 const u32_ptr = @ptrCast(&const u32, &bytes[0]);
14711490 assert(*u32_ptr == 0x12121212);
14721491
14731492 // Even this example is contrived - there are better ways to do the above than
......@@ -1481,23 +1500,15 @@ test "pointer casting" {
14811500
14821501test "pointer child type" {
14831502 // pointer types have a `child` field which tells you the type they point to.
1484 assert((&amp;u32).child == u32);
1485}</code></pre>
1486 <pre><code class="sh">$ zig test test.zig
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>
1503 assert((&u32).Child == u32);
1504}
1505 {#code_end#}
14951506 {#header_open|Alignment#}
14961507 <p>
14971508 Each type has an <strong>alignment</strong> - a number of bytes such that,
14981509 when a value of the type is loaded from or stored to memory,
14991510 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.
15011512 </p>
15021513 <p>
15031514 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>
15071518 In Zig, a pointer type has an alignment value. If the value is equal to the
15081519 alignment of the underlying type, it can be omitted from the type:
15091520 </p>
1510 <pre><code class="zig">const assert = @import("std").debug.assert;
1521 {#code_begin|test#}
1522const assert = @import("std").debug.assert;
15111523const builtin = @import("builtin");
15121524
15131525test "variable alignment" {
15141526 var x: i32 = 1234;
15151527 const align_of_i32 = @alignOf(@typeOf(x));
1516 assert(@typeOf(&amp;x) == &amp;i32);
1517 assert(&amp;i32 == &amp;align(align_of_i32) i32);
1528 assert(@typeOf(&x) == &i32);
1529 assert(&i32 == &align(align_of_i32) i32);
15181530 if (builtin.arch == builtin.Arch.x86_64) {
1519 assert((&amp;i32).alignment == 4);
1531 assert((&i32).alignment == 4);
15201532 }
1521}</code></pre>
1533}
1534 {#code_end#}
15221535 <p>In the same way that a <code>&amp;i32</code> can be implicitly cast to a
15231536 <code>&amp;const i32</code>, a pointer with a larger alignment can be implicitly
15241537 cast to a pointer with a smaller alignment, but not vice versa.
......@@ -1527,72 +1540,50 @@ test "variable alignment" {
15271540 You can specify alignment on variables and functions. If you do this, then
15281541 pointers to them get the specified alignment:
15291542 </p>
1530 <pre><code class="zig">const assert = @import("std").debug.assert;
1543 {#code_begin|test#}
1544const assert = @import("std").debug.assert;
15311545
15321546var foo: u8 align(4) = 100;
15331547
15341548test "global variable alignment" {
1535 assert(@typeOf(&amp;foo).alignment == 4);
1536 assert(@typeOf(&amp;foo) == &amp;align(4) u8);
1537 const slice = (&amp;foo)[0..1];
1549 assert(@typeOf(&foo).alignment == 4);
1550 assert(@typeOf(&foo) == &align(4) u8);
1551 const slice = (&foo)[0..1];
15381552 assert(@typeOf(slice) == []align(4) u8);
15391553}
15401554
1541fn derp() align(@sizeOf(usize) * 2) -&gt; i32 { 1234 }
1542fn noop1() align(1) {}
1543fn noop4() align(4) {}
1555fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
1556fn noop1() align(1) void {}
1557fn noop4() align(4) void {}
15441558
15451559test "function alignment" {
15461560 assert(derp() == 1234);
1547 assert(@typeOf(noop1) == fn() align(1));
1548 assert(@typeOf(noop4) == fn() align(4));
1561 assert(@typeOf(noop1) == fn() align(1) void);
1562 assert(@typeOf(noop4) == fn() align(4) void);
15491563 noop1();
15501564 noop4();
1551}</code></pre>
1565}
1566 {#code_end#}
15521567 <p>
15531568 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 the
1569 has a bigger alignment, use {#link|@alignCast#} to change the
15551570 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#}:
15571572 </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
15601576test "pointer alignment safety" {
15611577 var array align(4) = []u32{0x11111111, 0x11111111};
15621578 const bytes = ([]u8)(array[0..]);
15631579 assert(foo(bytes) == 0x11111111);
15641580}
1565fn foo(bytes: []u8) -&gt; u32 {
1581fn foo(bytes: []u8) u32 {
15661582 const slice4 = bytes[1..5];
15671583 const int_slice = ([]u32)(@alignCast(4, slice4));
15681584 return int_slice[0];
1569}</code></pre>
1570 <pre><code class="sh">$ zig test test.zig
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>
1585}
1586 {#code_end#}
15961587 {#header_close#}
15971588 {#header_open|Type Based Alias Analysis#}
15981589 <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:
16021593 </p>
16031594 <p>As an example, this code produces undefined behavior:</p>
16041595 <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#}:
16061597 <pre><code class="zig">@bitCast(u32, f32(12.34))</code></pre>
16071598 <p>As an added benefit, the <code>@bitcast</code> version works at compile-time.</p>
16081599 {#see_also|Slices|Memory#}
16091600 {#header_close#}
16101601 {#header_close#}
16111602 {#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
16141606test "basic slices" {
16151607 var array = []i32{1, 2, 3, 4};
......@@ -1618,38 +1610,17 @@ test "basic slices" {
16181610 // compile-time, whereas the slice's length is known at runtime.
16191611 // Both can be accessed with the `len` field.
16201612 const slice = array[0..array.len];
1621 assert(slice.ptr == &amp;array[0]);
1613 assert(slice.ptr == &array[0]);
16221614 assert(slice.len == array.len);
16231615
16241616 // Slices have array bounds checking. If you try to access something out
16251617 // of bounds, you'll get a safety check failure:
16261618 slice[10] += 1;
1627}</code></pre>
1628 <pre><code class="sh">$ zig test test.zig
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>
1619}
1620 {#code_end#}
16511621 <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;
16531624const mem = @import("std").mem;
16541625const fmt = @import("std").fmt;
16551626
......@@ -1663,8 +1634,8 @@ test "using slices for strings" {
16631634 var all_together: [100]u8 = undefined;
16641635 // You can use slice syntax on an array to convert an array into a slice.
16651636 const all_together_slice = all_together[0..];
1666 // String concatenation example:
1667 const hello_world = fmt.bufPrint(all_together_slice, "{} {}", hello, world);
1637 // String concatenation example.
1638 const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", hello, world);
16681639
16691640 // Generally, you can use UTF-8 and not worry about whether something is a
16701641 // string. If you don't need to deal with individual characters, no need
......@@ -1674,7 +1645,7 @@ test "using slices for strings" {
16741645
16751646test "slice pointer" {
16761647 var array: [10]u8 = undefined;
1677 const ptr = &amp;array[0];
1648 const ptr = &array[0];
16781649
16791650 // You can use slicing syntax to convert a pointer into a slice:
16801651 const slice = ptr[0..5];
......@@ -1692,20 +1663,18 @@ test "slice pointer" {
16921663test "slice widening" {
16931664 // Zig supports slice widening and slice narrowing. Cast a slice of u8
16941665 // 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};
16961667 const slice = ([]const u32)(array[0..]);
16971668 assert(slice.len == 2);
16981669 assert(slice[0] == 0x12121212);
16991670 assert(slice[1] == 0x13131313);
1700}</code></pre>
1701 <pre><code class="sh">$ zig test test.zig
1702Test 1/3 using slices for strings...OK
1703Test 2/3 slice pointer...OK
1704Test 3/3 slice widening...OK</code></pre>
1671}
1672 {#code_end#}
17051673 {#see_also|Pointers|for|Arrays#}
17061674 {#header_close#}
17071675 {#header_open|struct#}
1708 <pre><code class="zig">// Declare a struct.
1676 {#code_begin|test|structs#}
1677// Declare a struct.
17091678// Zig gives no guarantees about the order of fields and whether or
17101679// not there will be padding.
17111680const Point = struct {
......@@ -1741,7 +1710,7 @@ const Vec3 = struct {
17411710 y: f32,
17421711 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 {
17451714 return Vec3 {
17461715 .x = x,
17471716 .y = y,
......@@ -1749,7 +1718,7 @@ const Vec3 = struct {
17491718 };
17501719 }
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 {
17531722 return self.x * other.x + self.y * other.y + self.z * other.z;
17541723 }
17551724};
......@@ -1781,7 +1750,7 @@ test "struct namespaced variable" {
17811750
17821751// struct field order is determined by the compiler for optimal performance.
17831752// 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 {
17851754 const point = @fieldParentPtr(Point, "x", x);
17861755 point.y = y;
17871756}
......@@ -1790,22 +1759,22 @@ test "field parent pointer" {
17901759 .x = 0.1234,
17911760 .y = 0.5678,
17921761 };
1793 setYBasedOnX(&amp;point.x, 0.9);
1762 setYBasedOnX(&point.x, 0.9);
17941763 assert(point.y == 0.9);
17951764}
17961765
17971766// You can return a struct from a function. This is how we do generics
17981767// in Zig:
1799fn LinkedList(comptime T: type) -&gt; type {
1768fn LinkedList(comptime T: type) type {
18001769 return struct {
18011770 pub const Node = struct {
1802 prev: ?&amp;Node,
1803 next: ?&amp;Node,
1771 prev: ?&Node,
1772 next: ?&Node,
18041773 data: T,
18051774 };
18061775
1807 first: ?&amp;Node,
1808 last: ?&amp;Node,
1776 first: ?&Node,
1777 last: ?&Node,
18091778 len: usize,
18101779 };
18111780}
......@@ -1833,21 +1802,18 @@ test "linked list" {
18331802 .data = 1234,
18341803 };
18351804 var list2 = LinkedList(i32) {
1836 .first = &amp;node,
1837 .last = &amp;node,
1805 .first = &node,
1806 .last = &node,
18381807 .len = 1,
18391808 };
18401809 assert((??list2.first).data == 1234);
1841}</code></pre>
1842 <pre><code class="sh">$ zig test structs.zig
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>
1810}
1811 {#code_end#}
18471812 {#see_also|comptime|@fieldParentPtr#}
18481813 {#header_close#}
18491814 {#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;
18511817const mem = @import("std").mem;
18521818
18531819// Declare an enum.
......@@ -1896,7 +1862,7 @@ const Suit = enum {
18961862 Diamonds,
18971863 Hearts,
18981864
1899 pub fn isClubs(self: Suit) -&gt; bool {
1865 pub fn isClubs(self: Suit) bool {
19001866 return self == Suit.Clubs;
19011867 }
19021868};
......@@ -1914,9 +1880,9 @@ const Foo = enum {
19141880test "enum variant switch" {
19151881 const p = Foo.Number;
19161882 const what_is_it = switch (p) {
1917 Foo.String =&gt; "this is a string",
1918 Foo.Number =&gt; "this is a number",
1919 Foo.None =&gt; "this is a none",
1883 Foo.String => "this is a string",
1884 Foo.Number => "this is a number",
1885 Foo.None => "this is a none",
19201886 };
19211887 assert(mem.eql(u8, what_is_it, "this is a number"));
19221888}
......@@ -1945,22 +1911,30 @@ test "@memberName" {
19451911// @tagName gives a []const u8 representation of an enum value:
19461912test "@tagName" {
19471913 assert(mem.eql(u8, @tagName(Small.Three), "Three"));
1948}</code></pre>
1949 <p>TODO extern enum</p>
1914}
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#}
19501932 <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>
19601933 {#see_also|@memberName|@memberCount|@tagName#}
19611934 {#header_close#}
19621935 {#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;
19641938const mem = @import("std").mem;
19651939
19661940// A union has only 1 active field at a time.
......@@ -2008,19 +1982,19 @@ test "union variant switch" {
20081982 const p = Foo { .Number = 54 };
20091983 const what_is_it = switch (p) {
20101984 // Capture by reference
2011 Foo.String =&gt; |*x| {
2012 "this is a string"
1985 Foo.String => |*x| blk: {
1986 break :blk "this is a string";
20131987 },
20141988
20151989 // Capture by value
2016 Foo.Number =&gt; |x| {
1990 Foo.Number => |x| blk: {
20171991 assert(x == 54);
2018 "this is a number"
1992 break :blk "this is a number";
20191993 },
20201994
2021 Foo.None =&gt; {
2022 "this is a none"
2023 }
1995 Foo.None => blk: {
1996 break :blk "this is a none";
1997 },
20241998 };
20251999 assert(mem.eql(u8, what_is_it, "this is a number"));
20262000}
......@@ -2053,22 +2027,16 @@ const Small2 = union(enum) {
20532027};
20542028test "@tagName" {
20552029 assert(mem.eql(u8, @tagName(Small2.C), "C"));
2056}</code></pre>
2057 <pre><code class="sh">$ zig test union.zig
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>
2030}
2031 {#code_end#}
20652032 <p>
20662033 Unions with an enum tag are generated as a struct with a tag field and union field. Zig
20672034 sorts the order of the tag and union field by the largest alignment.
20682035 </p>
20692036 {#header_close#}
20702037 {#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;
20722040const builtin = @import("builtin");
20732041
20742042test "switch simple" {
......@@ -2082,59 +2050,59 @@ test "switch simple" {
20822050 // the cases and use an if.
20832051 const b = switch (a) {
20842052 // Multiple cases can be combined via a ','
2085 1, 2, 3 =&gt; 0,
2053 1, 2, 3 => 0,
20862054
20872055 // Ranges can be specified using the ... syntax. These are inclusive
20882056 // both ends.
2089 5 ... 100 =&gt; 1,
2057 5 ... 100 => 1,
20902058
20912059 // Branches can be arbitrarily complex.
2092 101 =&gt; {
2060 101 => blk: {
20932061 const c: u64 = 5;
2094 c * 2 + 1
2062 break :blk c * 2 + 1;
20952063 },
20962064
20972065 // Switching on arbitrary expressions is allowed as long as the
20982066 // expression is known at compile-time.
2099 zz =&gt; zz,
2100 comptime {
2067 zz => zz,
2068 comptime blk: {
21012069 const d: u32 = 5;
21022070 const e: u32 = 100;
2103 d + e
2104 } =&gt; 107,
2071 break :blk d + e;
2072 } => 107,
21052073
21062074 // The else branch catches everything not already captured.
21072075 // Else branches are mandatory unless the entire range of values
21082076 // is handled.
2109 else =&gt; 9,
2077 else => 9,
21102078 };
21112079
21122080 assert(b == 1);
21132081}
21142082
21152083test "switch enum" {
2116 const Item = enum {
2084 const Item = union(enum) {
21172085 A: u32,
21182086 C: struct { x: u8, y: u8 },
21192087 D,
21202088 };
21212089
2122 var a = Item.A { 3 };
2090 var a = Item { .A = 3 };
21232091
21242092 // Switching on more complex enums is allowed.
21252093 const b = switch (a) {
21262094 // A capture group is allowed on a match, and will return the enum
21272095 // value matched.
2128 Item.A =&gt; |item| item,
2096 Item.A => |item| item,
21292097
21302098 // A reference to the matched value can be obtained using `*` syntax.
2131 Item.C =&gt; |*item| {
2099 Item.C => |*item| blk: {
21322100 (*item).x += 1;
2133 6
2101 break :blk 6;
21342102 },
21352103
21362104 // No else is required if the types cases was exhaustively handled
2137 Item.D =&gt; 8,
2105 Item.D => 8,
21382106 };
21392107
21402108 assert(b == 3);
......@@ -2142,37 +2110,35 @@ test "switch enum" {
21422110
21432111// Switch expressions can be used outside a function:
21442112const os_msg = switch (builtin.os) {
2145 builtin.Os.linux =&gt; "we found a linux user",
2146 else =&gt; "not a linux user",
2113 builtin.Os.linux => "we found a linux user",
2114 else => "not a linux user",
21472115};
21482116
21492117// Inside a function, switch statements implicitly are compile-time
21502118// evaluated if the target expression is compile-time known.
21512119test "switch inside function" {
21522120 switch (builtin.os) {
2153 builtin.Os.windows =&gt; {
2154 // On an OS other than windows, block is not even analyzed,
2121 builtin.Os.fuchsia => {
2122 // On an OS other than fuchsia, block is not even analyzed,
21552123 // 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.
21572125 @compileError("windows not supported");
21582126 },
2159 else =&gt; {},
2160 };
2161}</code></pre>
2162 <pre><code class="sh">$ zig test switch.zig
2163Test 1/2 switch simple...OK
2164Test 2/2 switch enum...OK
2165Test 3/3 switch inside function...OK</code></pre>
2127 else => {},
2128 }
2129}
2130 {#code_end#}
21662131 {#see_also|comptime|enum|@compileError|Compile Variables#}
21672132 {#header_close#}
21682133 {#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
21712137test "while basic" {
21722138 // A while loop is used to repeatedly execute an expression until
21732139 // some condition is no longer true.
21742140 var i: usize = 0;
2175 while (i &lt; 10) {
2141 while (i < 10) {
21762142 i += 1;
21772143 }
21782144 assert(i == 10);
......@@ -2194,7 +2160,7 @@ test "while continue" {
21942160 var i: usize = 0;
21952161 while (true) {
21962162 i += 1;
2197 if (i &lt; 10)
2163 if (i < 10)
21982164 continue;
21992165 break;
22002166 }
......@@ -2205,7 +2171,7 @@ test "while loop continuation expression" {
22052171 // You can give an expression to the while loop to execute when
22062172 // the loop is continued. This is respected by the continue control flow.
22072173 var i: usize = 0;
2208 while (i &lt; 10) : (i += 1) {}
2174 while (i < 10) : (i += 1) {}
22092175 assert(i == 10);
22102176}
22112177
......@@ -2214,9 +2180,9 @@ test "while loop continuation expression, more complicated" {
22142180 // expression.
22152181 var i1: usize = 1;
22162182 var j1: usize = 1;
2217 while (i1 * j1 &lt; 2000) : ({ i1 *= 2; j1 *= 3; }) {
2183 while (i1 * j1 < 2000) : ({ i1 *= 2; j1 *= 3; }) {
22182184 const my_ij1 = i1 * j1;
2219 assert(my_ij1 &lt; 2000);
2185 assert(my_ij1 < 2000);
22202186 }
22212187}
22222188
......@@ -2225,12 +2191,12 @@ test "while else" {
22252191 assert(!rangeHasNumber(0, 10, 15));
22262192}
22272193
2228fn rangeHasNumber(begin: usize, end: usize, number: usize) -&gt; bool {
2194fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
22292195 var i = begin;
22302196 // While loops are expressions. The result of the expression is the
22312197 // result of the else clause of a while loop, which is executed when
22322198 // 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) {
22342200 if (i == number) {
22352201 // break expressions, like return expressions, accept a value
22362202 // parameter. This is the result of the while expression.
......@@ -2238,9 +2204,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) -&gt; bool {
22382204 // evaluated.
22392205 break true;
22402206 }
2241 } else {
2242 false
2243 }
2207 } else false;
22442208}
22452209
22462210test "while null capture" {
......@@ -2278,22 +2242,18 @@ test "while null capture" {
22782242}
22792243
22802244var numbers_left: u32 = undefined;
2281fn eventuallyNullSequence() -&gt; ?u32 {
2282 return if (numbers_left == 0) {
2283 null
2284 } else {
2245fn eventuallyNullSequence() ?u32 {
2246 return if (numbers_left == 0) null else blk: {
22852247 numbers_left -= 1;
2286 numbers_left
2287 }
2248 break :blk numbers_left;
2249 };
22882250}
22892251error ReachedZero;
2290fn eventuallyErrorSequence() -&gt; %u32 {
2291 return if (numbers_left == 0) {
2292 error.ReachedZero
2293 } else {
2252fn eventuallyErrorSequence() %u32 {
2253 return if (numbers_left == 0) error.ReachedZero else blk: {
22942254 numbers_left -= 1;
2295 numbers_left
2296 }
2255 break :blk numbers_left;
2256 };
22972257}
22982258
22992259test "inline while loop" {
......@@ -2302,34 +2262,27 @@ test "inline while loop" {
23022262 // such as use types as first class values.
23032263 comptime var i = 0;
23042264 var sum: usize = 0;
2305 inline while (i &lt; 3) : (i += 1) {
2265 inline while (i < 3) : (i += 1) {
23062266 const T = switch (i) {
2307 0 =&gt; f32,
2308 1 =&gt; i8,
2309 2 =&gt; bool,
2310 else =&gt; unreachable,
2267 0 => f32,
2268 1 => i8,
2269 2 => bool,
2270 else => unreachable,
23112271 };
23122272 sum += typeNameLength(T);
23132273 }
23142274 assert(sum == 9);
23152275}
23162276
2317fn typeNameLength(comptime T: type) -&gt; usize {
2277fn typeNameLength(comptime T: type) usize {
23182278 return @typeName(T).len;
2319}</code></pre>
2320 <pre><code class="sh">$ zig while.zig
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>
2279}
2280 {#code_end#}
23292281 {#see_also|if|Nullables|Errors|comptime|unreachable#}
23302282 {#header_close#}
23312283 {#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
23342287test "for basics" {
23352288 const items = []i32 { 4, 5, 3, 4, 0 };
......@@ -2387,9 +2340,9 @@ test "for else" {
23872340 } else {
23882341 sum += ??value;
23892342 }
2390 } else {
2343 } else blk: {
23912344 assert(sum == 7);
2392 sum
2345 break :blk sum;
23932346 };
23942347}
23952348
......@@ -2404,28 +2357,25 @@ test "inline for loop" {
24042357 var sum: usize = 0;
24052358 inline for (nums) |i| {
24062359 const T = switch (i) {
2407 2 =&gt; f32,
2408 4 =&gt; i8,
2409 6 =&gt; bool,
2410 else =&gt; unreachable,
2360 2 => f32,
2361 4 => i8,
2362 6 => bool,
2363 else => unreachable,
24112364 };
24122365 sum += typeNameLength(T);
24132366 }
24142367 assert(sum == 9);
24152368}
24162369
2417fn typeNameLength(comptime T: type) -&gt; usize {
2370fn typeNameLength(comptime T: type) usize {
24182371 return @typeName(T).len;
2419}</code></pre>
2420 <pre><code class="sh">$ zig test for.zig
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>
2372}
2373 {#code_end#}
24252374 {#see_also|while|comptime|Arrays|Slices#}
24262375 {#header_close#}
24272376 {#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:
24292379// * bool
24302380// * ?T
24312381// * %T
......@@ -2439,9 +2389,9 @@ test "if boolean" {
24392389 if (a != b) {
24402390 assert(true);
24412391 } else if (a == 9) {
2442 unreachable
2392 unreachable;
24432393 } else {
2444 unreachable
2394 unreachable;
24452395 }
24462396
24472397 // If expressions are used instead of a ternary expression.
......@@ -2499,12 +2449,12 @@ test "if error union" {
24992449 if (a) |value| {
25002450 assert(value == 0);
25012451 } else |err| {
2502 unreachable
2452 unreachable;
25032453 }
25042454
25052455 const b: %u32 = error.BadValue;
25062456 if (b) |value| {
2507 unreachable
2457 unreachable;
25082458 } else |err| {
25092459 assert(err == error.BadValue);
25102460 }
......@@ -2524,27 +2474,26 @@ test "if error union" {
25242474 if (c) |*value| {
25252475 *value = 9;
25262476 } else |err| {
2527 unreachable
2477 unreachable;
25282478 }
25292479
25302480 if (c) |value| {
25312481 assert(value == 9);
25322482 } else |err| {
2533 unreachable
2483 unreachable;
25342484 }
2535}</code></pre>
2536 <pre><code class="sh">$ zig test if.zig
2537Test 1/3 if boolean...OK
2538Test 2/3 if nullable...OK
2539Test 3/3 if error union...OK</code></pre>
2485}
2486 {#code_end#}
25402487 {#see_also|Nullables|Errors#}
25412488 {#header_close#}
25422489 {#header_open|defer#}
2543 <pre><code class="zig">const assert = @import("std").debug.assert;
2544const printf = @import("std").io.stdout.printf;
2490 {#code_begin|test|defer#}
2491const std = @import("std");
2492const assert = std.debug.assert;
2493const warn = std.debug.warn;
25452494
25462495// defer will execute an expression at the end of the current scope.
2547fn deferExample() -&gt; usize {
2496fn deferExample() usize {
25482497 var a: usize = 1;
25492498
25502499 {
......@@ -2554,7 +2503,7 @@ fn deferExample() -&gt; usize {
25542503 assert(a == 2);
25552504
25562505 a = 5;
2557 a
2506 return a;
25582507}
25592508
25602509test "defer basics" {
......@@ -2563,43 +2512,43 @@ test "defer basics" {
25632512
25642513// If multiple defer statements are specified, they will be executed in
25652514// the reverse order they were run.
2566fn deferUnwindExample() {
2567 %%printf("\n");
2515fn deferUnwindExample() void {
2516 warn("\n");
25682517
25692518 defer {
2570 %%printf("1 ");
2519 warn("1 ");
25712520 }
25722521 defer {
2573 %%printf("2 ");
2522 warn("2 ");
25742523 }
25752524 if (false) {
25762525 // defers are not run if they are never executed.
25772526 defer {
2578 %%printf("3 ");
2527 warn("3 ");
25792528 }
25802529 }
25812530}
25822531
25832532test "defer unwinding" {
2584 deferUnwindExample()
2533 deferUnwindExample();
25852534}
25862535
2587// The %defer keyword is similar to defer, but will only execute if the
2536// The errdefer keyword is similar to defer, but will only execute if the
25882537// scope returns with an error.
25892538//
25902539// This is especially useful in allowing a function to clean up properly
25912540// on error, and replaces goto error handling tactics as seen in c.
25922541error DeferError;
2593fn deferErrorExample(is_error: bool) -&gt; %void {
2594 %%printf("\nstart of function\n");
2542fn deferErrorExample(is_error: bool) %void {
2543 warn("\nstart of function\n");
25952544
25962545 // This will always be executed on exit
25972546 defer {
2598 %%printf("end of function\n");
2547 warn("end of function\n");
25992548 }
26002549
2601 %defer {
2602 %%printf("encountered an error!\n");
2550 errdefer {
2551 warn("encountered an error!\n");
26032552 }
26042553
26052554 if (is_error) {
......@@ -2607,24 +2556,11 @@ fn deferErrorExample(is_error: bool) -&gt; %void {
26072556 }
26082557}
26092558
2610test "%defer unwinding" {
2559test "errdefer unwinding" {
26112560 _ = deferErrorExample(false);
26122561 _ = deferErrorExample(true);
26132562}
2614</code></pre>
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>
2563 {#code_end#}
26282564 {#see_also|Errors#}
26292565 {#header_close#}
26302566 {#header_open|unreachable#}
......@@ -2638,7 +2574,8 @@ OK
26382574 still emits <code>unreachable</code> as calls to <code>panic</code>.
26392575 </p>
26402576 {#header_open|Basics#}
2641 <pre><code class="zig">// unreachable is used to assert that control flow will never happen upon a
2577 {#code_begin|test#}
2578// unreachable is used to assert that control flow will never happen upon a
26422579// particular location:
26432580test "basic math" {
26442581 const x = 1;
......@@ -2647,56 +2584,34 @@ test "basic math" {
26472584 unreachable;
26482585 }
26492586}
2650
2651// in fact, this is how assert is implemented:
2652fn assert(ok: bool) {
2587 {#code_end#}
2588 <p>In fact, this is how assert is implemented:</p>
2589 {#code_begin|test_err#}
2590fn assert(ok: bool) void {
26532591 if (!ok) unreachable; // assertion failure
26542592}
26552593
26562594// This test will fail because we hit unreachable.
26572595test "this will fail" {
26582596 assert(false);
2659}</code></pre>
2660 <pre><code class="sh">$ zig test test.zig
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>
2597}
2598 {#code_end#}
26842599 {#header_close#}
26852600 {#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 {
2689 // The type of unreachable is noreturn.
2604test "type of unreachable" {
2605 comptime {
2606 // The type of unreachable is noreturn.
26902607
2691 // However this assertion will still fail because
2692 // evaluating unreachable at compile-time is a compile error.
2608 // However this assertion will still fail because
2609 // evaluating unreachable at compile-time is a compile error.
26932610
2694 assert(@typeOf(unreachable) == noreturn);
2695}</code></pre>
2696 <pre><code class="sh">$ zig build-obj test.zig
2697test.zig:9:12: error: unreachable code
2698 assert(@typeOf(unreachable) == noreturn);
2699 ^</code></pre>
2611 assert(@typeOf(unreachable) == noreturn);
2612 }
2613}
2614 {#code_end#}
27002615 {#see_also|Zig Test|Build Mode|comptime#}
27012616 {#header_close#}
27022617 {#header_close#}
......@@ -2707,7 +2622,6 @@ test.zig:9:12: error: unreachable code
27072622 <ul>
27082623 <li><code>break</code></li>
27092624 <li><code>continue</code></li>
2710 <li><code>goto</code></li>
27112625 <li><code>return</code></li>
27122626 <li><code>unreachable</code></li>
27132627 <li><code>while (true) {}</code></li>
......@@ -2715,31 +2629,38 @@ test.zig:9:12: error: unreachable code
27152629 <p>When resolving types together, such as <code>if</code> clauses or <code>switch</code> prongs,
27162630 the <code>noreturn</code> type is compatible with every other type. Consider:
27172631 </p>
2718 <pre><code class="zig">fn foo(condition: bool, b: u32) {
2632 {#code_begin|test#}
2633fn foo(condition: bool, b: u32) void {
27192634 const a = if (condition) b else return;
2720 bar(a);
2635 @panic("do something with a");
27212636}
2722
2723extern fn bar(value: u32);</code></pre>
2637test "noreturn" {
2638 foo(false, 1);
2639}
2640 {#code_end#}
27242641 <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" {
27282647 const value = bar() catch ExitProcess(1);
27292648 assert(value == 1234);
27302649}
27312650
2732fn bar() -&gt; %u32 {
2651fn bar() %u32 {
27332652 return 1234;
27342653}
27352654
2736const assert = @import("std").debug.assert;</code></pre>
2655const assert = @import("std").debug.assert;
2656 {#code_end#}
27372657 {#header_close#}
27382658 {#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
27412662// Functions are declared like this
2742fn add(a: i8, b: i8) -&gt; i8 {
2663fn add(a: i8, b: i8) i8 {
27432664 if (a == 0) {
27442665 // You can still return manually if needed.
27452666 return b;
......@@ -2750,84 +2671,84 @@ fn add(a: i8, b: i8) -&gt; i8 {
27502671
27512672// The export specifier makes a function externally visible in the generated
27522673// 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
27552676// The extern specifier is used to declare a function that will be resolved
27562677// at link time, when linking statically, or at runtime, when linking
27572678// dynamically.
27582679// The stdcallcc specifier changes the calling convention of the function.
2759extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) -&gt; noreturn;
2760extern "c" fn atan2(a: f64, b: f64) -&gt; f64;
2680extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) noreturn;
2681extern "c" fn atan2(a: f64, b: f64) f64;
27612682
2762// coldcc makes a function use the cold calling convention.
2763coldcc fn abort() -&gt; noreturn {
2683// The @setCold builtin tells the optimizer that a function is rarely called.
2684fn abort() noreturn {
2685 @setCold(true);
27642686 while (true) {}
27652687}
27662688
27672689// nakedcc makes a function not have any function prologue or epilogue.
27682690// This can be useful when integrating with assembly.
2769nakedcc fn _start() -&gt; noreturn {
2691nakedcc fn _start() noreturn {
27702692 abort();
27712693}
27722694
27732695// The pub specifier allows the function to be visible when importing.
27742696// 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
27772699// Functions can be used as values and are equivalent to pointers.
2778const call2_op = fn (a: i8, b: i8) -&gt; i8;
2779fn do_op(fn_call: call2_op, op1: i8, op2: i8) -&gt; i8 {
2780 fn_call(op1, op2)
2700const call2_op = fn (a: i8, b: i8) i8;
2701fn do_op(fn_call: call2_op, op1: i8, op2: i8) i8 {
2702 return fn_call(op1, op2);
27812703}
27822704
27832705test "function" {
27842706 assert(do_op(add, 5, 6) == 11);
27852707 assert(do_op(sub2, 5, 6) == -1);
2786}</code></pre>
2787 <pre><code class="sh">$ zig test function.zig
2788Test 1/1 function...OK
2789</code></pre>
2708}
2709 {#code_end#}
27902710 <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
27932714comptime {
2794 assert(@typeOf(foo) == fn());
2795 assert(@sizeOf(fn()) == @sizeOf(?fn()));
2715 assert(@typeOf(foo) == fn()void);
2716 assert(@sizeOf(fn()void) == @sizeOf(?fn()void));
27962717}
27972718
2798fn foo() { }</code></pre>
2799 <pre><code class="sh">$ zig build-obj test.zig</code></pre>
2719fn foo() void { }
2720 {#code_end#}
28002721 {#header_open|Pass-by-value Parameters#}
28012722 <p>
28022723 In Zig, structs, unions, and enums with payloads cannot be passed by value
28032724 to a function.
28042725 </p>
2805 <pre><code class="zig">const Foo = struct {
2726 {#code_begin|test_err|not copyable; cannot pass by value#}
2727const Foo = struct {
28062728 x: i32,
28072729};
28082730
2809fn bar(foo: Foo) {}
2731fn bar(foo: Foo) void {}
28102732
2811export fn entry() {
2733test "pass aggregate type by value to function" {
28122734 bar(Foo {.x = 12,});
2813}</code></pre>
2814 <pre><code class="sh">$ ./zig build-obj test.zig
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>
2735}
2736 {#code_end#}
28182737 <p>
28192738 Instead, one must use <code>&amp;const</code>. Zig allows implicitly casting something
28202739 to a const pointer to it:
28212740 </p>
2822 <pre><code class="zig">const Foo = struct {
2741 {#code_begin|test#}
2742const Foo = struct {
28232743 x: i32,
28242744};
28252745
2826fn bar(foo: &amp;const Foo) {}
2746fn bar(foo: &const Foo) void {}
28272747
2828export fn entry() {
2748test "implicitly cast to const pointer" {
28292749 bar(Foo {.x = 12,});
2830}</code></pre>
2750}
2751 {#code_end#}
28312752 <p>
28322753 However,
28332754 the C ABI does allow passing structs and unions by value. So functions which
......@@ -2842,9 +2763,11 @@ export fn entry() {
28422763 <p>
28432764 Among the top level declarations available is the error value declaration:
28442765 </p>
2845 <pre><code class="zig">error FileNotFound;
2766 {#code_begin|syntax#}
2767error FileNotFound;
28462768error OutOfMemory;
2847error UnexpectedToken;</code></pre>
2769error UnexpectedToken;
2770 {#code_end#}
28482771 <p>
28492772 These error values are assigned an unsigned integer value greater than 0 at
28502773 compile time. You are allowed to declare the same error value more than once,
......@@ -2862,7 +2785,7 @@ error UnexpectedToken;</code></pre>
28622785 The pure error type is one of the error values, and in the same way that pointers
28632786 cannot be null, a pure error is always an error.
28642787 </p>
2865 <pre><code class="zig">const pure_error = error.FileNotFound;</code></pre>
2788 {#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#}
28662789 <p>
28672790 Most of the time you will not find yourself using a pure error type. Instead,
28682791 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>
28712794 <p>
28722795 Here is a function to parse a string into a 64-bit integer:
28732796 </p>
2874 <pre><code class="zig">error InvalidChar;
2797 {#code_begin|test#}
2798error InvalidChar;
28752799error Overflow;
28762800
2877pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
2801pub fn parseU64(buf: []const u8, radix: u8) %u64 {
28782802 var x: u64 = 0;
28792803
28802804 for (buf) |c| {
28812805 const digit = charToDigit(c);
28822806
2883 if (digit &gt;= radix) {
2807 if (digit >= radix) {
28842808 return error.InvalidChar;
28852809 }
28862810
28872811 // x *= radix
2888 if (@mulWithOverflow(u64, x, radix, &amp;x)) {
2812 if (@mulWithOverflow(u64, x, radix, &x)) {
28892813 return error.Overflow;
28902814 }
28912815
28922816 // x += digit
2893 if (@addWithOverflow(u64, x, digit, &amp;x)) {
2817 if (@addWithOverflow(u64, x, digit, &x)) {
28942818 return error.Overflow;
28952819 }
28962820 }
28972821
28982822 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#}
29002839 <p>
29012840 Notice the return type is <code>%u64</code>. This means that the function
29022841 either returns an unsigned 64 bit integer, or an error.
......@@ -2916,29 +2855,35 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
29162855 <li>You know with complete certainty it will not return an error, so want to unconditionally unwrap it.</li>
29172856 <li>You want to take a different action for each possible error.</li>
29182857 </ul>
2919 <p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p>
2920 <pre><code class="zig">fn doAThing(str: []u8) {
2858 <p>If you want to provide a default value, you can use the <code>catch</code> binary operator:</p>
2859 {#code_begin|syntax#}
2860fn doAThing(str: []u8) void {
29212861 const number = parseU64(str, 10) catch 13;
29222862 // ...
2923}</code></pre>
2863}
2864 {#code_end#}
29242865 <p>
29252866 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 must
2867 a default value of 13. The type of the right hand side of the binary <code>catch</code> operator must
29272868 match the unwrapped error union type, or be of type <code>noreturn</code>.
29282869 </p>
29292870 <p>Let's say you wanted to return the error if you got one, otherwise continue with the
29302871 function logic:</p>
2931 <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {
2872 {#code_begin|syntax#}
2873fn doAThing(str: []u8) %void {
29322874 const number = parseU64(str, 10) catch |err| return err;
29332875 // ...
2934}</code></pre>
2876}
2877 {#code_end#}
29352878 <p>
29362879 There is a shortcut for this. The <code>try</code> expression:
29372880 </p>
2938 <pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {
2881 {#code_begin|syntax#}
2882fn doAThing(str: []u8) %void {
29392883 const number = try parseU64(str, 10);
29402884 // ...
2941}</code></pre>
2885}
2886 {#code_end#}
29422887 <p>
29432888 <code>try</code> evaluates an error union expression. If it is an error, it returns
29442889 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 {
29482893 Maybe you know with complete certainty that an expression will never be an error.
29492894 In this case you can do this:
29502895 </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#}
29522897 <p>
29532898 Here we know for sure that "1234" will parse successfully. So we put the
29542899 <code>unreachable</code> value on the right hand side. <code>unreachable</code> generates
29552900 a panic in Debug and ReleaseSafe modes and undefined behavior in ReleaseFast mode. So, while we're debugging the
29562901 application, if there <em>was</em> a surprise error here, the application would crash
29572902 appropriately.
2958 </p>
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.
2903 TODO: mention error return traces
29642904 </p>
29652905 <p>
29662906 Finally, you may want to take a different action for every situation. For that, we combine
29672907 the <code>if</code> and <code>switch</code> expression:
29682908 </p>
2969 <pre><code class="zig">fn doAThing(str: []u8) {
2909 {#code_begin|syntax#}
2910fn doAThing(str: []u8) void {
29702911 if (parseU64(str, 10)) |number| {
29712912 doSomethingWithNumber(number);
29722913 } else |err| switch (err) {
2973 error.Overflow =&gt; {
2914 error.Overflow => {
29742915 // handle overflow...
29752916 },
29762917 // we promise that InvalidChar won't happen (or crash in debug mode if it does)
2977 error.InvalidChar =&gt; unreachable,
2918 error.InvalidChar => unreachable,
29782919 }
2979}</code></pre>
2920}
2921 {#code_end#}
29802922 <p>
29812923 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>,
29832925 which evaluates the deferred expression on block exit path if and only if
29842926 the function returned with an error from the block.
29852927 </p>
29862928 <p>
29872929 Example:
29882930 </p>
2989 <pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo {
2931 {#code_begin|syntax#}
2932fn createFoo(param: i32) %Foo {
29902933 const foo = try tryToAllocateFoo();
29912934 // now we have allocated foo. we need to free it if the function fails.
29922935 // but we want to return it if the function succeeds.
2993 %defer deallocateFoo(foo);
2936 errdefer deallocateFoo(foo);
29942937
29952938 const tmp_buf = allocateTmpBuffer() ?? return error.OutOfMemory;
29962939 // tmp_buf is truly a temporary resource, and we for sure want to clean it up
29972940 // before this block leaves scope
29982941 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.
30032946 // but the defer will run!
30042947 return foo;
3005}</code></pre>
2948}
2949 {#code_end#}
30062950 <p>
30072951 The neat thing about this is that you get robust error handling without
30082952 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 {
30142958 <ul>
30152959 <li>These primitives give enough expressiveness that it's completely practical
30162960 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 and
2961 to ignore the error, you can add <code>catch unreachable</code> and
30182962 get the added benefit of crashing in Debug and ReleaseSafe modes if your assumption was wrong.
30192963 </li>
30202964 <li>
......@@ -3034,11 +2978,13 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
30342978 The question mark symbolizes the nullable type. You can convert a type to a nullable
30352979 type by putting a question mark in front of it, like this:
30362980 </p>
3037 <pre><code class="zig">// normal integer
2981 {#code_begin|syntax#}
2982// normal integer
30382983const normal_int: i32 = 1234;
30392984
30402985// nullable integer
3041const nullable_int: ?i32 = 5678;</code></pre>
2986const nullable_int: ?i32 = 5678;
2987 {#code_end#}
30422988 <p>
30432989 Now the variable <code>nullable_int</code> could be an <code>i32</code>, or <code>null</code>.
30442990 </p>
......@@ -3061,7 +3007,7 @@ const nullable_int: ?i32 = 5678;</code></pre>
30613007 Task: call malloc, if the result is null, return null.
30623008 </p>
30633009 <p>C code</p>
3064 <pre><code class="c">// malloc prototype included for reference
3010 <pre><code class="cpp">// malloc prototype included for reference
30653011void *malloc(size_t size);
30663012
30673013struct Foo *do_a_thing(void) {
......@@ -3070,23 +3016,25 @@ struct Foo *do_a_thing(void) {
30703016 // ...
30713017}</code></pre>
30723018 <p>Zig code</p>
3073 <pre><code class="zig">// malloc prototype included for reference
3074extern fn malloc(size: size_t) -&gt; ?&amp;u8;
3019 {#code_begin|syntax#}
3020// malloc prototype included for reference
3021extern fn malloc(size: size_t) ?&u8;
30753022
3076fn doAThing() -&gt; ?&amp;Foo {
3023fn doAThing() ?&Foo {
30773024 const ptr = malloc(1234) ?? return null;
30783025 // ...
3079}</code></pre>
3026}
3027 {#code_end#}
30803028 <p>
30813029 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> operator
3030 is <code>&u8</code> <em>not</em> <code>?&u8</code>. The <code>??</code> operator
30833031 unwrapped the nullable type and therefore <code>ptr</code> is guaranteed to be non-null everywhere
30843032 it is used in the function.
30853033 </p>
30863034 <p>
30873035 The other form of checking against NULL you might see looks like this:
30883036 </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) {
30903038 // do some stuff
30913039
30923040 if (foo) {
......@@ -3098,7 +3046,8 @@ fn doAThing() -&gt; ?&amp;Foo {
30983046 <p>
30993047 In Zig you can accomplish the same thing:
31003048 </p>
3101 <pre><code class="zig">fn doAThing(nullable_foo: ?&amp;Foo) {
3049 {#code_begin|syntax#}
3050fn doAThing(nullable_foo: ?&Foo) void {
31023051 // do some stuff
31033052
31043053 if (nullable_foo) |foo| {
......@@ -3106,7 +3055,8 @@ fn doAThing() -&gt; ?&amp;Foo {
31063055 }
31073056
31083057 // do some stuff
3109}</code></pre>
3058}
3059 {#code_end#}
31103060 <p>
31113061 Once again, the notable thing here is that inside the if block,
31123062 <code>foo</code> is no longer a nullable pointer, it is a pointer, which
......@@ -3140,7 +3090,7 @@ fn doAThing() -&gt; ?&amp;Foo {
31403090 {#header_open|this#}
31413091 <p>TODO: example of this referring to Self struct</p>
31423092 <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>
31443094 {#header_close#}
31453095 {#header_open|comptime#}
31463096 <p>
......@@ -3153,15 +3103,17 @@ fn doAThing() -&gt; ?&amp;Foo {
31533103 <p>
31543104 Compile-time parameters is how Zig implements generics. It is compile-time duck typing.
31553105 </p>
3156 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {
3157 if (a &gt; b) a else b
3106 {#code_begin|syntax#}
3107fn max(comptime T: type, a: T, b: T) T {
3108 return if (a > b) a else b;
31583109}
3159fn gimmeTheBiggerFloat(a: f32, b: f32) -&gt; f32 {
3160 max(f32, a, b)
3110fn gimmeTheBiggerFloat(a: f32, b: f32) f32 {
3111 return max(f32, a, b);
31613112}
3162fn gimmeTheBiggerInteger(a: u64, b: u64) -&gt; u64 {
3163 max(u64, a, b)
3164}</code></pre>
3113fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
3114 return max(u64, a, b);
3115}
3116 {#code_end#}
31653117 <p>
31663118 In Zig, types are first-class citizens. They can be assigned to variables, passed as parameters to functions,
31673119 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 {
31793131 <p>
31803132 For example, if we were to introduce another function to the above snippet:
31813133 </p>
3182 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {
3183 if (a &gt; b) a else b
3134 {#code_begin|test_err|unable to evaluate constant expression#}
3135fn 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);
31843140}
3185fn letsTryToPassARuntimeType(condition: bool) {
3141fn foo(condition: bool) void {
31863142 const result = max(
31873143 if (condition) f32 else u64,
31883144 1234,
31893145 5678);
3190}</code></pre>
3191 <p>
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>
3146}
3147 {#code_end#}
31973148 <p>
31983149 This is an error because the programmer attempted to pass a value only known at run-time
31993150 to a function which expects a value known at compile-time.
......@@ -3205,38 +3156,33 @@ fn letsTryToPassARuntimeType(condition: bool) {
32053156 <p>
32063157 For example:
32073158 </p>
3208 <pre><code class="zig">fn max(comptime T: type, a: T, b: T) -&gt; T {
3209 if (a &gt; b) a else b
3159 {#code_begin|test_err|operator not allowed for type 'bool'#}
3160fn max(comptime T: type, a: T, b: T) T {
3161 return if (a > b) a else b;
32103162}
3211fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {
3212 max(bool, a, b)
3213}</code></pre>
3214 <p>
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>
3163test "try to compare bools" {
3164 _ = max(bool, true, false);
3165}
3166 {#code_end#}
32233167 <p>
32243168 On the flip side, inside the function definition with the <code>comptime</code> parameter, the
32253169 value is known at compile-time. This means that we actually could make this work for the bool type
32263170 if we wanted to:
32273171 </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 {
32293174 if (T == bool) {
32303175 return a or b;
3231 } else if (a &gt; b) {
3176 } else if (a > b) {
32323177 return a;
32333178 } else {
32343179 return b;
32353180 }
32363181}
3237fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {
3238 max(bool, a, b)
3239}</code></pre>
3182test "try to compare bools" {
3183 @import("std").debug.assert(max(bool, false, true) == true);
3184}
3185 {#code_end#}
32403186 <p>
32413187 This works because Zig implicitly inlines <code>if</code> expressions when the condition
32423188 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 {
32463192 This means that the actual function generated for <code>max</code> in this situation looks like
32473193 this:
32483194 </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 {
32503197 return a or b;
3251}</code></pre>
3198}
3199 {#code_end#}
32523200 <p>
32533201 All the code that dealt with compile-time known values is eliminated and we are left with only
32543202 the necessary run-time code to accomplish the task.
......@@ -3271,11 +3219,12 @@ fn letsTryToCompareBools(a: bool, b: bool) -&gt; bool {
32713219 <p>
32723220 For example:
32733221 </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
32763225const CmdFn = struct {
32773226 name: []const u8,
3278 func: fn(i32) -&gt; i32,
3227 func: fn(i32) i32,
32793228};
32803229
32813230const cmd_fns = []CmdFn{
......@@ -3283,14 +3232,14 @@ const cmd_fns = []CmdFn{
32833232 CmdFn {.name = "two", .func = two},
32843233 CmdFn {.name = "three", .func = three},
32853234};
3286fn one(value: i32) -&gt; i32 { value + 1 }
3287fn two(value: i32) -&gt; i32 { value + 2 }
3288fn three(value: i32) -&gt; i32 { value + 3 }
3235fn one(value: i32) i32 { return value + 1; }
3236fn two(value: i32) i32 { return value + 2; }
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 {
32913240 var result: i32 = start_value;
32923241 comptime var i = 0;
3293 inline while (i &lt; cmd_fns.len) : (i += 1) {
3242 inline while (i < cmd_fns.len) : (i += 1) {
32943243 if (cmd_fns[i].name[0] == prefix_char) {
32953244 result = cmd_fns[i].func(result);
32963245 }
......@@ -3302,36 +3251,41 @@ test "perform fn" {
33023251 assert(performFn('t', 1) == 6);
33033252 assert(performFn('o', 0) == 1);
33043253 assert(performFn('w', 99) == 99);
3305}</code></pre>
3254}
3255 {#code_end#}
33063256 <p>
33073257 This example is a bit contrived, because the compile-time evaluation component is unnecessary;
33083258 this code would work fine if it was all done at run-time. But it does end up generating
33093259 different code. In this example, the function <code>performFn</code> is generated three different times,
33103260 for the different values of <code>prefix_char</code> provided:
33113261 </p>
3312 <pre><code class="zig">// From the line:
3262 {#code_begin|syntax#}
3263// From the line:
33133264// assert(performFn('t', 1) == 6);
3314fn performFn(start_value: i32) -&gt; i32 {
3265fn performFn(start_value: i32) i32 {
33153266 var result: i32 = start_value;
33163267 result = two(result);
33173268 result = three(result);
33183269 return result;
33193270}
3320
3271 {#code_end#}
3272 {#code_begin|syntax#}
33213273// From the line:
33223274// assert(performFn('o', 0) == 1);
3323fn performFn(start_value: i32) -&gt; i32 {
3275fn performFn(start_value: i32) i32 {
33243276 var result: i32 = start_value;
33253277 result = one(result);
33263278 return result;
33273279}
3328
3280 {#code_end#}
3281 {#code_begin|syntax#}
33293282// From the line:
33303283// assert(performFn('w', 99) == 99);
3331fn performFn(start_value: i32) -&gt; i32 {
3284fn performFn(start_value: i32) i32 {
33323285 var result: i32 = start_value;
33333286 return result;
3334}</code></pre>
3287}
3288 {#code_end#}
33353289 <p>
33363290 Note that this happens even in a debug build; in a release build these generated functions still
33373291 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 {
33473301 use a <code>comptime</code> expression to guarantee that the expression will be evaluated at compile-time.
33483302 If this cannot be accomplished, the compiler will emit an error. For example:
33493303 </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" {
33533308 comptime {
33543309 exit();
33553310 }
3356}</code></pre>
3357 <pre><code>./test.zig:5:9: error: unable to evaluate constant expression
3358 exit();
3359 ^</code></pre>
3311}
3312 {#code_end#}
33603313 <p>
33613314 It doesn't make sense that a program could call <code>exit()</code> (or any other external function)
33623315 at compile-time, so this is a compile error. However, a <code>comptime</code> expression does much
......@@ -3367,7 +3320,7 @@ fn foo() {
33673320 </p>
33683321 <ul>
33693322 <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>
33713324 expressions are evaluated at compile-time, or emit a compile error if this is not possible.</li>
33723325 <li>All function calls cause the compiler to interpret the function at compile-time, emitting a
33733326 compile error if the function tries to do something that has global run-time side effects.</li>
......@@ -3379,10 +3332,11 @@ fn foo() {
33793332 <p>
33803333 Let's look at an example:
33813334 </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 {
3385 if (index &lt; 2) return index;
3338fn fibonacci(index: u32) u32 {
3339 if (index < 2) return index;
33863340 return fibonacci(index - 1) + fibonacci(index - 2);
33873341}
33883342
......@@ -3394,16 +3348,16 @@ test "fibonacci" {
33943348 comptime {
33953349 assert(fibonacci(7) == 13);
33963350 }
3397}</code></pre>
3398 <pre><code>$ zig test test.zig
3399Test 1/1 testFibonacci...OK</code></pre>
3351}
3352 {#code_end#}
34003353 <p>
34013354 Imagine if we had forgotten the base case of the recursive function and tried to run the tests:
34023355 </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 {
3406 //if (index &lt; 2) return index;
3359fn fibonacci(index: u32) u32 {
3360 //if (index < 2) return index;
34073361 return fibonacci(index - 1) + fibonacci(index - 2);
34083362}
34093363
......@@ -3411,35 +3365,8 @@ test "fibonacci" {
34113365 comptime {
34123366 assert(fibonacci(7) == 13);
34133367 }
3414}</code></pre>
3415 <pre><code>$ zig test test.zig
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>
3368}
3369 {#code_end#}
34433370 <p>
34443371 The compiler produces an error which is a stack trace from trying to evaluate the
34453372 function at compile-time.
......@@ -3449,10 +3376,11 @@ test "fibonacci" {
34493376 undefined behavior, which is always a compile error if the compiler knows it happened.
34503377 But what would have happened if we used a signed integer?
34513378 </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 {
3455 //if (index &lt; 2) return index;
3382fn fibonacci(index: i32) i32 {
3383 //if (index < 2) return index;
34563384 return fibonacci(index - 1) + fibonacci(index - 2);
34573385}
34583386
......@@ -3460,61 +3388,31 @@ test "fibonacci" {
34603388 comptime {
34613389 assert(fibonacci(7) == 13);
34623390 }
3463}</code></pre>
3464 <pre><code>./test.zig:3:21: error: evaluation exceeded 1000 backwards branches
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>
3391}
3392 {#code_end#}
35003393 <p>
35013394 The compiler noticed that evaluating this function at compile-time took a long time,
35023395 and thus emitted a compile error and gave up. If the programmer wants to increase
35033396 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.
35053398 </p>
35063399 <p>
35073400 What if we fix the base case, but put the wrong value in the <code>assert</code> line?
35083401 </p>
3509 <pre><code class="zig">comptime {
3510 assert(fibonacci(7) == 99999);
3511}</code></pre>
3512 <pre><code>./test.zig:15:14: error: unable to evaluate constant expression
3513 if (!ok) unreachable;
3514 ^
3515./test.zig:10:15: note: called from here
3402 {#code_begin|test_err|encountered @panic at compile-time#}
3403const assert = @import("std").debug.assert;
3404
3405fn fibonacci(index: i32) i32 {
3406 if (index < 2) return index;
3407 return fibonacci(index - 1) + fibonacci(index - 2);
3408}
3409
3410test "fibonacci" {
3411 comptime {
35163412 assert(fibonacci(7) == 99999);
3517 ^</code></pre>
3413 }
3414}
3415 {#code_end#}
35183416 <p>
35193417 What happened is Zig started interpreting the <code>assert</code> function with the
35203418 parameter <code>ok</code> set to <code>false</code>. When the interpreter hit
......@@ -3528,17 +3426,18 @@ test "fibonacci" {
35283426 <code>comptime</code> expressions. This means that we can use functions to
35293427 initialize complex static data. For example:
35303428 </p>
3531 <pre><code class="zig">const first_25_primes = firstNPrimes(25);
3429 {#code_begin|test#}
3430const first_25_primes = firstNPrimes(25);
35323431const 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 {
35353434 var prime_list: [n]i32 = undefined;
35363435 var next_index: usize = 0;
35373436 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) {
35393438 var test_prime_index: usize = 0;
35403439 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) {
35423441 if (test_number % prime_list[test_prime_index] == 0) {
35433442 is_prime = false;
35443443 break;
......@@ -3552,19 +3451,24 @@ fn firstNPrimes(comptime n: usize) -&gt; [n]i32 {
35523451 return prime_list;
35533452}
35543453
3555fn sum(numbers: []i32) -&gt; i32 {
3454fn sum(numbers: []const i32) i32 {
35563455 var result: i32 = 0;
35573456 for (numbers) |x| {
35583457 result += x;
35593458 }
35603459 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#}
35623466 <p>
35633467 When we compile this program, Zig generates the constants
35643468 with the answer pre-computed. Here are the lines from the generated LLVM IR:
35653469 </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]
3567 @1 = internal unnamed_addr constant i32 1060</code></pre>
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]
3471@1 = internal unnamed_addr constant i32 1060</code></pre>
35683472 <p>
35693473 Note that we did not have to do anything special with the syntax of these functions. For example,
35703474 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 {
35823486 Here is an example of a generic <code>List</code> data structure, that we will instantiate with
35833487 the type <code>i32</code>. In Zig we refer to the type as <code>List(i32)</code>.
35843488 </p>
3585 <pre><code class="zig">fn List(comptime T: type) -&gt; type {
3586 struct {
3489 {#code_begin|syntax#}
3490fn List(comptime T: type) type {
3491 return struct {
35873492 items: []T,
35883493 len: usize,
3589 }
3590}</code></pre>
3494 };
3495}
3496 {#code_end#}
35913497 <p>
35923498 That's it. It's a function that returns an anonymous <code>struct</code>. For the purposes of error messages
35933499 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 {
35973503 To keep the language small and uniform, all aggregate types in Zig are anonymous. To give a type
35983504 a name, we assign it to a constant:
35993505 </p>
3600 <pre><code class="zig">const Node = struct {
3601 next: &amp;Node,
3506 {#code_begin|syntax#}
3507const Node = struct {
3508 next: &Node,
36023509 name: []u8,
3603};</code></pre>
3510};
3511 {#code_end#}
36043512 <p>
36053513 This works because all top level declarations are order-independent, and as long as there isn't
36063514 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;
36183526const a_number: i32 = 1234;
36193527const a_string = "foobar";
36203528
3621pub fn main() {
3529pub fn main() void {
36223530 warn("here is a string: '{}' here is a number: {}\n", a_string, a_number);
36233531}
36243532 {#code_end#}
......@@ -3627,8 +3535,9 @@ pub fn main() {
36273535 Let's crack open the implementation of this and see how it works:
36283536 </p>
36293537
3630 <pre><code class="zig">/// Calls print and then flushes the buffer.
3631pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt; %void {
3538 {#code_begin|syntax#}
3539/// Calls print and then flushes the buffer.
3540pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void {
36323541 const State = enum {
36333542 Start,
36343543 OpenBrace,
......@@ -3641,36 +3550,36 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
36413550
36423551 inline for (format) |c, i| {
36433552 switch (state) {
3644 State.Start =&gt; switch (c) {
3645 '{' =&gt; {
3646 if (start_index &lt; i) try self.write(format[start_index...i]);
3553 State.Start => switch (c) {
3554 '{' => {
3555 if (start_index < i) try self.write(format[start_index..i]);
36473556 state = State.OpenBrace;
36483557 },
3649 '}' =&gt; {
3650 if (start_index &lt; i) try self.write(format[start_index...i]);
3558 '}' => {
3559 if (start_index < i) try self.write(format[start_index..i]);
36513560 state = State.CloseBrace;
36523561 },
3653 else =&gt; {},
3562 else => {},
36543563 },
3655 State.OpenBrace =&gt; switch (c) {
3656 '{' =&gt; {
3564 State.OpenBrace => switch (c) {
3565 '{' => {
36573566 state = State.Start;
36583567 start_index = i;
36593568 },
3660 '}' =&gt; {
3569 '}' => {
36613570 try self.printValue(args[next_arg]);
36623571 next_arg += 1;
36633572 state = State.Start;
36643573 start_index = i + 1;
36653574 },
3666 else =&gt; @compileError("Unknown format character: " ++ c),
3575 else => @compileError("Unknown format character: " ++ c),
36673576 },
3668 State.CloseBrace =&gt; switch (c) {
3669 '}' =&gt; {
3577 State.CloseBrace => switch (c) {
3578 '}' => {
36703579 state = State.Start;
36713580 start_index = i;
36723581 },
3673 else =&gt; @compileError("Single '}' encountered in format string"),
3582 else => @compileError("Single '}' encountered in format string"),
36743583 },
36753584 }
36763585 }
......@@ -3682,11 +3591,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
36823591 @compileError("Incomplete format string: " ++ format);
36833592 }
36843593 }
3685 if (start_index &lt; format.len) {
3686 try self.write(format[start_index...format.len]);
3594 if (start_index < format.len) {
3595 try self.write(format[start_index..format.len]);
36873596 }
36883597 try self.flush();
3689}</code></pre>
3598}
3599 {#code_end#}
36903600 <p>
36913601 This is a proof of concept implementation; the actual function in the standard library has more
36923602 formatting capabilities.
......@@ -3698,19 +3608,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
36983608 When this function is analyzed from our example code above, Zig partially evaluates the function
36993609 and emits a function that actually looks like this:
37003610 </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 {
37023613 try self.write("here is a string: '");
37033614 try self.printValue(arg0);
37043615 try self.write("' here is a number: ");
37053616 try self.printValue(arg1);
37063617 try self.write("\n");
37073618 try self.flush();
3708}</code></pre>
3619}
3620 {#code_end#}
37093621 <p>
37103622 <code>printValue</code> is a function that takes a parameter of any type, and does different things depending
37113623 on the type:
37123624 </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 {
37143627 const T = @typeOf(value);
37153628 if (@isInteger(T)) {
37163629 return self.printInt(T, value);
......@@ -3722,18 +3635,22 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
37223635 } else {
37233636 @compileError("Unable to print type '" ++ @typeName(T) ++ "'");
37243637 }
3725}</code></pre>
3638}
3639 {#code_end#}
37263640 <p>
37273641 And now, what happens if we give too many arguments to <code>printf</code>?
37283642 </p>
3729 <pre><code class="zig">warn("here is a string: '{}' here is a number: {}\n",
3730 a_string, a_number, a_number);</code></pre>
3731 <pre><code>.../std/io.zig:147:17: error: Unused arguments
3732 @compileError("Unused arguments");
3733 ^
3734./test.zig:7:23: note: called from here
3735 warn("here is a number: {} and here is a string: {}\n",
3736 ^</code></pre>
3643 {#code_begin|test_err|Unused arguments#}
3644const warn = @import("std").debug.warn;
3645
3646const a_number: i32 = 1234;
3647const a_string = "foobar";
3648
3649test "printf too many arguments" {
3650 warn("here is a string: '{}' here is a number: {}\n",
3651 a_string, a_number, a_number);
3652}
3653 {#code_end#}
37373654 <p>
37383655 Zig gives programmers the tools needed to protect themselves against their own mistakes.
37393656 </p>
......@@ -3748,7 +3665,7 @@ const a_number: i32 = 1234;
37483665const a_string = "foobar";
37493666const fmt = "here is a string: '{}' here is a number: {}\n";
37503667
3751pub fn main() {
3668pub fn main() void {
37523669 warn(fmt, a_string, a_number);
37533670}
37543671 {#code_end#}
......@@ -3786,7 +3703,7 @@ pub fn main() {
37863703 at compile time.
37873704 </p>
37883705 {#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>
37903707 <p>
37913708 Performs <code>*result = a + b</code>. If overflow or underflow occurs,
37923709 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
......@@ -3836,7 +3753,7 @@ pub fn main() {
38363753 <code>?fn()</code>, or <code>[]T</code>. It returns the same type as <code>ptr</code>
38373754 except with the alignment adjusted to the new value.
38383755 </p>
3839 <p>A <a href="#undef-incorrect-pointer-alignment">pointer alignment safety check</a> is added
3756 <p>A {#link|pointer alignment safety check|Incorrect Pointer Alignment#} is added
38403757 to the generated code to make sure the pointer is aligned as promised.</p>
38413758
38423759 {#header_close#}
......@@ -3849,11 +3766,11 @@ pub fn main() {
38493766 </p>
38503767 <pre><code class="zig">const assert = @import("std").debug.assert;
38513768comptime {
3852 assert(&amp;u32 == &amp;align(@alignOf(u32)) u32);
3769 assert(&u32 == &align(@alignOf(u32)) u32);
38533770}</code></pre>
38543771 <p>
38553772 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#}.
38573774 </p>
38583775 {#see_also|Alignment#}
38593776 {#header_close#}
......@@ -3933,7 +3850,7 @@ comptime {
39333850
39343851 {#header_close#}
39353852 {#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>
39373854 <p>
39383855 This function performs an atomic compare exchange operation.
39393856 </p>
......@@ -3970,42 +3887,46 @@ comptime {
39703887 This function can be used to do "printf debugging" on
39713888 compile-time executing code.
39723889 </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: {
39763894 var val1: i32 = 99;
39773895 @compileLog("comptime val1 = ", val1);
39783896 val1 = val1 + 1;
3979 val1
3897 break :blk val1;
39803898};
39813899
3982pub fn main() -&gt; %void {
3900test "main" {
39833901 @compileLog("comptime in main");
39843902
39853903 warn("Runtime in main, num1 = {}.\n", num1);
3986}</code></pre>
3987
3904}
3905 {#code_end#}
39883906 </p>
39893907 <p>
39903908 will ouput:
39913909 </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>
40023910 <p>
40033911 If all <code>@compileLog</code> calls are removed or
40043912 not encountered by analysis, the
40053913 program compiles successfully and the generated executable prints:
40063914 </p>
4007<pre><code class="sh">Runtime in main, num1 = 100.</code></pre>
4008{{@ctheader_open:z}}
3915 {#code_begin|test#}
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#}
40093930 <pre><code class="zig">@ctz(x: T) -&gt; U</code></pre>
40103931 <p>
40113932 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
41104031 </p>
41114032 {#header_close#}
41124033 {#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>
41144035 <p>
41154036 If the binary is built with error return tracing, and this function is invoked in a
41164037 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
41294050 {#header_close#}
41304051 {#header_open|@fieldParentPtr#}
41314052 <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>
41334054 <p>
41344055 Given a pointer to a field, returns the base pointer of a struct.
41354056 </p>
......@@ -4173,12 +4094,15 @@ test.zig:6:2: error: found compile log statement
41734094 <p>
41744095 This calls a function, in the same way that invoking an expression with parentheses does:
41754096 </p>
4176 <pre><code class="zig">const assert = @import("std").debug.assert;
4097 {#code_begin|test#}
4098const assert = @import("std").debug.assert;
4099
41774100test "inline function call" {
41784101 assert(@inlineCall(add, 3, 9) == 12);
41794102}
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#}
41824106 <p>
41834107 Unlike a normal function call, however, <code>@inlineCall</code> guarantees that the call
41844108 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>
41884112 {#header_open|@intToPtr#}
41894113 <pre><code class="zig">@intToPtr(comptime DestType: type, int: usize) -&gt; DestType</code></pre>
41904114 <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#}.
41924116 </p>
41934117 {#header_close#}
41944118 {#header_open|@IntType#}
......@@ -4222,7 +4146,7 @@ fn add(a: i32, b: i32) -&gt; i32 { a + b }</code></pre>
42224146 <p>TODO</p>
42234147 {#header_close#}
42244148 {#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>
42264150 <p>
42274151 This function copies bytes from one region of memory to another. <code>dest</code> and
42284152 <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>
42404164mem.copy(u8, dest[0...byte_count], source[0...byte_count]);</code></pre>
42414165 {#header_close#}
42424166 {#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>
42444168 <p>
42454169 This function sets a region of memory to <code>c</code>. <code>dest</code> is a pointer.
42464170 </p>
......@@ -4279,7 +4203,7 @@ mem.set(u8, dest, c);</code></pre>
42794203 {#see_also|@rem#}
42804204 {#header_close#}
42814205 {#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>
42834207 <p>
42844208 Performs <code>*result = a * b</code>. If overflow or underflow occurs,
42854209 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>
43184242 This is typically used for type safety when interacting with C code that does not expose struct details.
43194243 Example:
43204244 </p>
4321 <pre><code class="zig">const Derp = @OpaqueType();
4245 {#code_begin|test_err|expected type '&Derp', found '&Wat'#}
4246const Derp = @OpaqueType();
43224247const Wat = @OpaqueType();
43234248
4324extern fn bar(d: &amp;Derp);
4325export fn foo(w: &amp;Wat) {
4249extern fn bar(d: &Derp) void;
4250export fn foo(w: &Wat) void {
43264251 bar(w);
4327}</code></pre>
4328 <pre><code class="sh">$ ./zig build-obj test.zig
4329test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
4330 bar(w);
4331 ^</code></pre>
4252}
4253
4254test "call foo" {
4255 foo(undefined);
4256}
4257 {#code_end#}
43324258 {#header_close#}
43334259 {#header_open|@panic#}
43344260 <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'
43634289 <li><code>fn()</code></li>
43644290 <li><code>?fn()</code></li>
43654291 </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
43684294 {#header_close#}
43694295 {#header_open|@rem#}
......@@ -4393,10 +4319,16 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
43934319 This function is only valid within function scope.
43944320 </p>
43954321 {#header_close#}
4396 {#header_open|@setDebugSafety#}
4397 <pre><code class="zig">@setDebugSafety(scope, safety_on: bool)</code></pre>
4322 {#header_open|@setCold#}
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>
43984330 <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.
44004332 </p>
44014333
44024334 {#header_close#}
......@@ -4413,22 +4345,24 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
44134345 <p>
44144346 Example:
44154347 </p>
4416 <pre><code class="zig">comptime {
4417 var i = 0;
4418 while (i &lt; 1001) : (i += 1) {}
4419}</code></pre>
4420 <pre><code class="sh">$ ./zig build-obj test.zig
4421/home/andy/dev/zig/build/test.zig:3:5: error: evaluation exceeded 1000 backwards branches
4422 while (i &lt; 1001) : (i += 1) {}
4423 ^</code></pre>
4424 <p>Now we use <code>@setEvalBranchQuota</code>:</p>
4425 <pre><code class="zig">comptime {
4426 @setEvalBranchQuota(1001);
4427 var i = 0;
4428 while (i &lt; 1001) : (i += 1) {}
4429}</code></pre>
4430 <pre><code class="sh">$ ./zig build-obj test.zig</code></pre>
4431 <p>(no output because it worked fine)</p>
4348 {#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
4349test "foo" {
4350 comptime {
4351 var i = 0;
4352 while (i < 1001) : (i += 1) {}
4353 }
4354}
4355 {#code_end#}
4356 <p>Now we use <code class="zig">@setEvalBranchQuota</code>:</p>
4357 {#code_begin|test#}
4358test "foo" {
4359 comptime {
4360 @setEvalBranchQuota(1001);
4361 var i = 0;
4362 while (i < 1001) : (i += 1) {}
4363 }
4364}
4365 {#code_end#}
44324366
44334367 {#see_also|comptime#}
44344368 {#header_close#}
......@@ -4437,10 +4371,12 @@ test.zig:5:9: error: expected type '&amp;Derp', found '&amp;Wat'
44374371 <p>
44384372 Sets the floating point mode for a given scope. Possible values are:
44394373 </p>
4440 <pre><code class="zig">pub const FloatMode = enum {
4374 {#code_begin|syntax#}
4375pub const FloatMode = enum {
44414376 Optimized,
44424377 Strict,
4443};</code></pre>
4378};
4379 {#code_end#}
44444380 <ul>
44454381 <li>
44464382 <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'
44864422 {#see_also|@shrExact|@shlWithOverflow#}
44874423 {#header_close#}
44884424 {#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>
44904426 <p>
44914427 Performs <code>*result = a &lt;&lt; b</code>. If overflow or underflow occurs,
44924428 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'
45204456 </p>
45214457 {#header_close#}
45224458 {#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>
45244460 <p>
45254461 Performs <code>*result = a - b</code>. If overflow or underflow occurs,
45264462 stores the overflowed bits in <code>result</code> and returns <code>true</code>.
......@@ -4556,7 +4492,8 @@ const b: u8 = @truncate(u8, a);
45564492 <p>
45574493 Returns which kind of type something is. Possible values:
45584494 </p>
4559 <pre><code class="zig">pub const TypeId = enum {
4495 {#code_begin|syntax#}
4496pub const TypeId = enum {
45604497 Type,
45614498 Void,
45624499 Bool,
......@@ -4574,7 +4511,6 @@ const b: u8 = @truncate(u8, a);
45744511 ErrorUnion,
45754512 Error,
45764513 Enum,
4577 EnumTag,
45784514 Union,
45794515 Fn,
45804516 Namespace,
......@@ -4582,8 +4518,8 @@ const b: u8 = @truncate(u8, a);
45824518 BoundFn,
45834519 ArgTuple,
45844520 Opaque,
4585};</code></pre>
4586
4521};
4522 {#code_end#}
45874523 {#header_close#}
45884524 {#header_open|@typeName#}
45894525 <pre><code class="zig">@typeName(T: type) -&gt; []u8</code></pre>
......@@ -4606,27 +4542,29 @@ const b: u8 = @truncate(u8, a);
46064542 Zig has three build modes:
46074543 </p>
46084544 <ul>
4609 <li><a href="#build-mode-debug">Debug</a> (default)</li>
4610 <li><a href="#build-mode-release-fast">ReleaseFast</a></li>
4611 <li><a href="#build-mode-release-safe">ReleaseSafe</a></li>
4545 <li>{#link|Debug#} (default)</li>
4546 <li>{#link|ReleaseFast#}</li>
4547 <li>{#link|ReleaseSafe#}</li>
46124548 </ul>
46134549 <p>
46144550 To add standard build options to a <code>build.zig</code> file:
46154551 </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 {
46194556 const exe = b.addExecutable("example", "example.zig");
46204557 exe.setBuildMode(b.standardReleaseOptions());
4621 b.default_step.dependOn(&amp;exe.step);
4622}</code></pre>
4558 b.default_step.dependOn(&exe.step);
4559}
4560 {#code_end#}
46234561 <p>
46244562 This causes these options to be available:
46254563 </p>
4626 <pre><code class="sh"> -Drelease-safe=(bool) optimizations on and safety on
4564 <pre><code class="shell"> -Drelease-safe=(bool) optimizations on and safety on
46274565 -Drelease-fast=(bool) optimizations on and safety off</code></pre>
46284566 {#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>
46304568 <ul>
46314569 <li>Fast compilation speed</li>
46324570 <li>Safety checks enabled</li>
......@@ -4634,7 +4572,7 @@ pub fn build(b: &amp;Builder) {
46344572 </ul>
46354573 {#header_close#}
46364574 {#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>
46384576 <ul>
46394577 <li>Fast runtime performance</li>
46404578 <li>Safety checks disabled</li>
......@@ -4642,7 +4580,7 @@ pub fn build(b: &amp;Builder) {
46424580 </ul>
46434581 {#header_close#}
46444582 {#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>
46464584 <ul>
46474585 <li>Medium runtime performance</li>
46484586 <li>Safety checks enabled</li>
......@@ -4657,79 +4595,47 @@ pub fn build(b: &amp;Builder) {
46574595 detected at compile-time, Zig emits an error. Most undefined behavior that
46584596 cannot be detected at compile-time can be detected at runtime. In these cases,
46594597 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#}
46614599 build mode disables all safety checks in order to facilitate optimizations.
46624600 </p>
46634601 <p>
46644602 When a safety check fails, Zig crashes with a stack trace, like this:
46654603 </p>
4666 <pre><code class="zig">test "safety check" {
4604 {#code_begin|test_err|reached unreachable code#}
4605test "safety check" {
46674606 unreachable;
4668}</code></pre>
4669 <pre><code class="sh">$ zig test test.zig
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>
4607}
4608 {#code_end#}
46924609 {#header_open|Reaching Unreachable Code#}
46934610 <p>At compile-time:</p>
4694 <pre><code class="zig">comptime {
4611 {#code_begin|test_err|unable to evaluate constant expression#}
4612comptime {
46954613 assert(false);
46964614}
4697fn assert(ok: bool) {
4615fn assert(ok: bool) void {
46984616 if (!ok) unreachable; // assertion failure
4699}</code></pre>
4700 <pre><code class="sh">$ zig build-obj test.zig
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>
4617}
4618 {#code_end#}
47104619 <p>At runtime crashes with the message <code>reached unreachable code</code> and a stack trace.</p>
47114620 {#header_close#}
47124621 {#header_open|Index out of Bounds#}
47134622 <p>At compile-time:</p>
4714 <pre><code class="zig">comptime {
4623 {#code_begin|test_err|index 5 outside array of size 5#}
4624comptime {
47154625 const array = "hello";
47164626 const garbage = array[5];
4717}</code></pre>
4718 <pre><code class="sh">$ zig build-obj test.zig
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>
4627}
4628 {#code_end#}
47224629 <p>At runtime crashes with the message <code>index out of bounds</code> and a stack trace.</p>
47234630 {#header_close#}
47244631 {#header_open|Cast Negative Number to Unsigned Integer#}
47254632 <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 {
47274635 const value: i32 = -1;
47284636 const unsigned = u32(value);
4729}</code></pre>
4730 <pre><code class="sh">$ zig build-obj test.zig test.zig:3:25: error: attempt to cast negative value to unsigned integer
4731 const unsigned = u32(value);
4732 ^</code></pre>
4637}
4638 {#code_end#}
47334639 <p>At runtime crashes with the message <code>attempt to cast negative value to unsigned integer</code> and a stack trace.</p>
47344640 <p>
47354641 If you are trying to obtain the maximum value of an unsigned integer, use <code>@maxValue(T)</code>,
......@@ -4738,14 +4644,12 @@ comptime {
47384644 {#header_close#}
47394645 {#header_open|Cast Truncates Data#}
47404646 <p>At compile-time:</p>
4741 <pre><code class="zig">comptime {
4647 {#code_begin|test_err|cast from 'u16' to 'u8' truncates bits#}
4648comptime {
47424649 const spartan_count: u16 = 300;
47434650 const byte = u8(spartan_count);
4744}</code></pre>
4745 <pre><code class="sh">$ zig build-obj test.zig
4746test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits
4747 const byte = u8(spartan_count);
4748 ^</code></pre>
4651}
4652 {#code_end#}
47494653 <p>At runtime crashes with the message <code>integer cast truncated bits</code> and a stack trace.</p>
47504654 <p>
47514655 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
47674671 <li><code>@divExact</code> (division)</li>
47684672 </ul>
47694673 <p>Example with addition at compile-time:</p>
4770 <pre><code class="zig">comptime {
4674 {#code_begin|test_err|operation caused overflow#}
4675comptime {
47714676 var byte: u8 = 255;
47724677 byte += 1;
4773}</code></pre>
4774 <pre><code class="sh">$ zig build-obj test.zig
4775/home/andy/dev/zig/build/test.zig:3:10: error: operation caused overflow
4776 byte += 1;
4777 ^</code></pre>
4678}
4679 {#code_end#}
47784680 <p>At runtime crashes with the message <code>integer overflow</code> and a stack trace.</p>
47794681 {#header_close#}
47804682 {#header_open|Standard Library Math Functions#}
......@@ -4789,23 +4691,20 @@ test.zig:3:20: error: cast from 'u16' to 'u8' truncates bits
47894691 <li><code>@import("std").math.shl</code></li>
47904692 </ul>
47914693 <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;
47934696const warn = @import("std").debug.warn;
4794pub fn main() -&gt; %void {
4697pub fn main() %void {
47954698 var byte: u8 = 255;
47964699
4797 byte = if (math.add(u8, byte, 1)) |result| {
4798 result
4799 } else |err| {
4700 byte = if (math.add(u8, byte, 1)) |result| result else |err| {
48004701 warn("unable to add one: {}\n", @errorName(err));
48014702 return err;
48024703 };
48034704
48044705 warn("result: {}\n", byte);
4805}</code></pre>
4806 <pre><code class="sh">$ zig build-exe test.zig
4807$ ./test
4808unable to add one: Overflow</code></pre>
4706}
4707 {#code_end#}
48094708 {#header_close#}
48104709 {#header_open|Builtin Overflow Functions#}
48114710 <p>
......@@ -4821,20 +4720,19 @@ unable to add one: Overflow</code></pre>
48214720 <p>
48224721 Example of <code>@addWithOverflow</code>:
48234722 </p>
4824 <pre><code class="zig">const warn = @import("std").debug.warn;
4825pub fn main() -&gt; %void {
4723 {#code_begin|exe#}
4724const warn = @import("std").debug.warn;
4725pub fn main() %void {
48264726 var byte: u8 = 255;
48274727
48284728 var result: u8 = undefined;
4829 if (@addWithOverflow(u8, byte, 10, &amp;result)) {
4729 if (@addWithOverflow(u8, byte, 10, &result)) {
48304730 warn("overflowed result: {}\n", result);
48314731 } else {
48324732 warn("result: {}\n", result);
48334733 }
4834}</code></pre>
4835 <pre><code class="sh">$ zig build-exe test.zig
4836$ ./test
4837overflowed result: 9</code></pre>
4734}
4735 {#code_end#}
48384736 {#header_close#}
48394737 {#header_open|Wrapping Operations#}
48404738 <p>
......@@ -4846,7 +4744,8 @@ overflowed result: 9</code></pre>
48464744 <li><code>-%</code> (wraparound negation)</li>
48474745 <li><code>*%</code> (wraparound multiplication)</li>
48484746 </ul>
4849 <pre><code class="zig">const assert = @import("std").debug.assert;
4747 {#code_begin|test#}
4748const assert = @import("std").debug.assert;
48504749
48514750test "wraparound addition and subtraction" {
48524751 const x: i32 = @maxValue(i32);
......@@ -4854,56 +4753,49 @@ test "wraparound addition and subtraction" {
48544753 assert(min_val == @minValue(i32));
48554754 const max_val = min_val -% 1;
48564755 assert(max_val == @maxValue(i32));
4857}</code></pre>
4756}
4757 {#code_end#}
48584758 {#header_close#}
48594759 {#header_close#}
48604760 {#header_open|Exact Left Shift Overflow#}
48614761 <p>At compile-time:</p>
4862 <pre><code class="zig">comptime {
4863 const x = @shlExact(u8(0b01010101), 2);
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
4762 {#code_begin|test_err|operation caused overflow#}
4763comptime {
48674764 const x = @shlExact(u8(0b01010101), 2);
4868 ^</code></pre>
4765}
4766 {#code_end#}
48694767 <p>At runtime crashes with the message <code>left shift overflowed bits</code> and a stack trace.</p>
48704768 {#header_close#}
48714769 {#header_open|Exact Right Shift Overflow#}
48724770 <p>At compile-time:</p>
4873 <pre><code class="zig">comptime {
4874 const x = @shrExact(u8(0b10101010), 2);
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
4771 {#code_begin|test_err|exact shift shifted out 1 bits#}
4772comptime {
48784773 const x = @shrExact(u8(0b10101010), 2);
4879 ^</code></pre>
4774}
4775 {#code_end#}
48804776 <p>At runtime crashes with the message <code>right shift overflowed bits</code> and a stack trace.</p>
48814777 {#header_close#}
48824778 {#header_open|Division by Zero#}
48834779 <p>At compile-time:</p>
4884 <pre><code class="zig">comptime {
4780 {#code_begin|test_err|division by zero#}
4781comptime {
48854782 const a: i32 = 1;
48864783 const b: i32 = 0;
48874784 const c = a / b;
4888}</code></pre>
4889 <pre><code class="sh">$ zig build-obj test.zig
4890/home/andy/dev/zig/build/test.zig:4:17: error: division by zero is undefined
4891 const c = a / b;
4892 ^</code></pre>
4785}
4786 {#code_end#}
48934787 <p>At runtime crashes with the message <code>division by zero</code> and a stack trace.</p>
48944788
48954789 {#header_close#}
48964790 {#header_open|Remainder Division by Zero#}
48974791 <p>At compile-time:</p>
4898 <pre><code class="zig">comptime {
4792 {#code_begin|test_err|division by zero#}
4793comptime {
48994794 const a: i32 = 10;
49004795 const b: i32 = 0;
49014796 const c = a % b;
4902}</code></pre>
4903 <pre><code class="sh">$ zig build-obj test.zig
4904/home/andy/dev/zig/build/test.zig:4:17: error: division by zero is undefined
4905 const c = a % b;
4906 ^</code></pre>
4797}
4798 {#code_end#}
49074799 <p>At runtime crashes with the message <code>remainder division by zero</code> and a stack trace.</p>
49084800
49094801 {#header_close#}
......@@ -4915,20 +4807,18 @@ test "wraparound addition and subtraction" {
49154807 {#header_close#}
49164808 {#header_open|Attempt to Unwrap Null#}
49174809 <p>At compile-time:</p>
4918 <pre><code class="zig">comptime {
4810 {#code_begin|test_err|unable to unwrap null#}
4811comptime {
49194812 const nullable_number: ?i32 = null;
49204813 const number = ??nullable_number;
4921}</code></pre>
4922 <pre><code class="sh">$ zig build-obj test.zig
4923/home/andy/dev/zig/build/test.zig:3:20: error: unable to unwrap null
4924 const number = ??nullable_number;
4925 ^</code></pre>
4814}
4815 {#code_end#}
49264816 <p>At runtime crashes with the message <code>attempt to unwrap null</code> and a stack trace.</p>
49274817 <p>One way to avoid this crash is to test for null instead of assuming non-null, with
49284818 the <code>if</code> expression:</p>
49294819 {#code_begin|exe|test#}
49304820const warn = @import("std").debug.warn;
4931pub fn main() {
4821pub fn main() void {
49324822 const nullable_number: ?i32 = null;
49334823
49344824 if (nullable_number) |number| {
......@@ -4941,26 +4831,24 @@ pub fn main() {
49414831 {#header_close#}
49424832 {#header_open|Attempt to Unwrap Error#}
49434833 <p>At compile-time:</p>
4944 <pre><code class="zig">comptime {
4945 const number = %%getNumberOrFail();
4834 {#code_begin|test_err|unable to unwrap error 'UnableToReturnNumber'#}
4835comptime {
4836 const number = getNumberOrFail() catch unreachable;
49464837}
49474838
49484839error UnableToReturnNumber;
49494840
4950fn getNumberOrFail() -&gt; %i32 {
4841fn getNumberOrFail() %i32 {
49514842 return error.UnableToReturnNumber;
4952}</code></pre>
4953 <pre><code class="sh">$ zig build-obj test.zig
4954/home/andy/dev/zig/build/test.zig:2:20: error: unable to unwrap error 'UnableToReturnNumber'
4955 const number = %%getNumberOrFail();
4956 ^</code></pre>
4843}
4844 {#code_end#}
49574845 <p>At runtime crashes with the message <code>attempt to unwrap error: ErrorCode</code> and a stack trace.</p>
49584846 <p>One way to avoid this crash is to test for an error instead of assuming a successful result, with
49594847 the <code>if</code> expression:</p>
4960 {#code_begin|exe|test#}
4848 {#code_begin|exe#}
49614849const warn = @import("std").debug.warn;
49624850
4963pub fn main() {
4851pub fn main() void {
49644852 const result = getNumberOrFail();
49654853
49664854 if (result) |number| {
......@@ -4972,23 +4860,21 @@ pub fn main() {
49724860
49734861error UnableToReturnNumber;
49744862
4975fn getNumberOrFail() -> %i32 {
4863fn getNumberOrFail() %i32 {
49764864 return error.UnableToReturnNumber;
49774865}
49784866 {#code_end#}
49794867 {#header_close#}
49804868 {#header_open|Invalid Error Code#}
49814869 <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;
49834872comptime {
49844873 const err = error.AnError;
49854874 const number = u32(err) + 10;
49864875 const invalid_err = error(number);
4987}</code></pre>
4988 <pre><code class="sh">$ zig build-obj test.zig
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>
4876}
4877 {#code_end#}
49924878 <p>At runtime crashes with the message <code>invalid error code</code> and a stack trace.</p>
49934879 {#header_close#}
49944880 {#header_open|Invalid Enum Cast#}
......@@ -5020,17 +4906,26 @@ comptime {
50204906 which the compiler makes available to every Zig source file. It contains
50214907 compile-time constants such as the current target, endianness, and release mode.
50224908 </p>
5023 <pre><code class="zig">const builtin = @import("builtin");
5024const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';</code></pre>
4909 {#code_begin|syntax#}
4910const builtin = @import("builtin");
4911const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';
4912 {#code_end#}
50254913 <p>
50264914 Example of what is imported with <code>@import("builtin")</code>:
50274915 </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 {
50294923 freestanding,
4924 ananas,
50304925 cloudabi,
5031 darwin,
50324926 dragonfly,
50334927 freebsd,
4928 fuchsia,
50344929 ios,
50354930 kfreebsd,
50364931 linux,
......@@ -5055,12 +4950,15 @@ const separator = if (builtin.os == builtin.Os.windows) '\\' else '/';</code></p
50554950 tvos,
50564951 watchos,
50574952 mesa3d,
4953 contiki,
4954 zen,
50584955};
50594956
50604957pub const Arch = enum {
50614958 armv8_2a,
50624959 armv8_1a,
50634960 armv8,
4961 armv8r,
50644962 armv8m_baseline,
50654963 armv8m_mainline,
50664964 armv7,
......@@ -5068,6 +4966,7 @@ pub const Arch = enum {
50684966 armv7m,
50694967 armv7s,
50704968 armv7k,
4969 armv7ve,
50714970 armv6,
50724971 armv6m,
50734972 armv6k,
......@@ -5087,16 +4986,20 @@ pub const Arch = enum {
50874986 mips64,
50884987 mips64el,
50894988 msp430,
4989 nios2,
50904990 powerpc,
50914991 powerpc64,
50924992 powerpc64le,
50934993 r600,
50944994 amdgcn,
4995 riscv32,
4996 riscv64,
50954997 sparc,
50964998 sparcv9,
50974999 sparcel,
50985000 s390x,
50995001 tce,
5002 tcele,
51005003 thumb,
51015004 thumbeb,
51025005 i386,
......@@ -5122,7 +5025,9 @@ pub const Arch = enum {
51225025 renderscript32,
51235026 renderscript64,
51245027};
5028
51255029pub const Environ = enum {
5030 unknown,
51265031 gnu,
51275032 gnuabi64,
51285033 gnueabi,
......@@ -5140,6 +5045,7 @@ pub const Environ = enum {
51405045 cygnus,
51415046 amdopencl,
51425047 coreclr,
5048 opencl,
51435049};
51445050
51455051pub const ObjectFormat = enum {
......@@ -5147,6 +5053,7 @@ pub const ObjectFormat = enum {
51475053 coff,
51485054 elf,
51495055 macho,
5056 wasm,
51505057};
51515058
51525059pub const GlobalLinkage = enum {
......@@ -5171,15 +5078,53 @@ pub const Mode = enum {
51715078 ReleaseFast,
51725079};
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;
51755119pub const is_test = false;
51765120pub const os = Os.linux;
51775121pub const arch = Arch.x86_64;
51785122pub const environ = Environ.gnu;
51795123pub const object_format = ObjectFormat.elf;
5180pub const mode = Mode.ReleaseFast;
5181pub const link_libs = [][]const u8 {
5182};</code></pre>
5124pub const mode = Mode.Debug;
5125pub const link_libc = false;
5126pub const have_error_return_tracing = true;
5127 {#code_end#}
51835128 {#see_also|Build Mode#}
51845129 {#header_close#}
51855130 {#header_open|Root Source File#}
......@@ -5230,16 +5175,19 @@ pub const link_libs = [][]const u8 {
52305175 {#see_also|Primitive Types#}
52315176 {#header_close#}
52325177 {#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 {
52365183 puts(c"this has a null terminator");
52375184 puts(
52385185 c\\and so
52395186 c\\does this
52405187 c\\multiline C string literal
52415188 );
5242}</code></pre>
5189}
5190 {#code_end#}
52435191 {#see_also|String Literals#}
52445192 {#header_close#}
52455193 {#header_open|Import from C Header File#}
......@@ -5247,40 +5195,49 @@ pub fn main() -&gt; %void {
52475195 The <code>@cImport</code> builtin function can be used
52485196 to directly import symbols from .h files:
52495197 </p>
5250 <pre><code class="zig">const c = @cImport(@cInclude("stdio.h"));
5251pub fn main() -&gt; %void {
5252 c.printf("hello\n");
5253}</code></pre>
5198 {#code_begin|exe#}
5199 {#link_libc#}
5200const c = @cImport({
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#}
52545209 <p>
52555210 The <code>@cImport</code> function takes an expression as a parameter.
52565211 This expression is evaluated at compile-time and is used to control
52575212 preprocessor directives and include multiple .h files:
52585213 </p>
5259 <pre><code class="zig">const builtin = @import("builtin");
5214 {#code_begin|syntax#}
5215const builtin = @import("builtin");
52605216
52615217const c = @cImport({
52625218 @cDefine("NDEBUG", builtin.mode == builtin.Mode.ReleaseFast);
52635219 if (something) {
52645220 @cDefine("_GNU_SOURCE", {});
52655221 }
5266 @cInclude("stdlib.h")
5222 @cInclude("stdlib.h");
52675223 if (something) {
52685224 @cUndef("_GNU_SOURCE");
52695225 }
52705226 @cInclude("soundio.h");
5271});</code></pre>
5227});
5228 {#code_end#}
52725229 {#see_also|@cImport|@cInclude|@cDefine|@cUndef|@import#}
52735230 {#header_close#}
52745231 {#header_open|Mixing Object Files#}
52755232 <p>
52765233 You can mix Zig object files with any other object files that respect the C ABI. Example:
52775234 </p>
5278 {#header_close#}
5279 {#header_open|base64.zig#}
5280 <pre><code class="zig">const base64 = @import("std").base64;
5235 <p class="file">base64.zig</p>
5236 {#code_begin|syntax#}
5237const base64 = @import("std").base64;
52815238
5282export fn decode_base_64(dest_ptr: &amp;u8, dest_len: usize,
5283 source_ptr: &amp;const u8, source_len: usize) -&gt; usize
5239export fn decode_base_64(dest_ptr: &u8, dest_len: usize,
5240 source_ptr: &const u8, source_len: usize) usize
52845241{
52855242 const src = source_ptr[0..source_len];
52865243 const dest = dest_ptr[0..dest_len];
......@@ -5289,9 +5246,9 @@ export fn decode_base_64(dest_ptr: &amp;u8, dest_len: usize,
52895246 base64_decoder.decode(dest[0..decoded_size], src);
52905247 return decoded_size;
52915248}
5292</code></pre>
5293{{teheader_open:st.c}}
5294 <pre><code class="c">// This header is generated by zig from base64.zig
5249 {#code_end#}
5250 <p class="file">test.c</p>
5251 <pre><code class="cpp">// This header is generated by zig from base64.zig
52955252#include "base64.h"
52965253
52975254#include &lt;string.h&gt;
......@@ -5307,11 +5264,11 @@ int main(int argc, char **argv) {
53075264
53085265 return 0;
53095266}</code></pre>
5310 {#header_close#}
5311 {#header_open|build.zig#}
5312 <pre><code class="zig">const Builder = @import("std").build.Builder;
5267 <p class="file">build.zig</p>
5268 {#code_begin|syntax#}
5269const Builder = @import("std").build.Builder;
53135270
5314pub fn build(b: &amp;Builder) {
5271pub fn build(b: &Builder) %void {
53155272 const obj = b.addObject("base64", "base64.zig");
53165273
53175274 const exe = b.addCExecutable("test");
......@@ -5322,11 +5279,12 @@ pub fn build(b: &amp;Builder) {
53225279 exe.addObject(obj);
53235280 exe.setOutputPath(".");
53245281
5325 b.default_step.dependOn(&amp;exe.step);
5326}</code></pre>
5282 b.default_step.dependOn(&exe.step);
5283}
5284 {#code_end#}
53275285 {#header_close#}
53285286 {#header_open|Terminal#}
5329 <pre><code class="sh">$ zig build
5287 <pre><code class="shell">$ zig build
53305288$ ./test
53315289all your base are belong to us</code></pre>
53325290 {#see_also|Targets|Zig Build System#}
......@@ -5338,11 +5296,12 @@ all your base are belong to us</code></pre>
53385296 what it looks like to execute <code>zig targets</code> on a Linux x86_64
53395297 computer:
53405298 </p>
5341 <pre><code class="sh">$ zig targets
5299 <pre><code class="shell">$ zig targets
53425300Architectures:
53435301 armv8_2a
53445302 armv8_1a
53455303 armv8
5304 armv8r
53465305 armv8m_baseline
53475306 armv8m_mainline
53485307 armv7
......@@ -5350,6 +5309,7 @@ Architectures:
53505309 armv7m
53515310 armv7s
53525311 armv7k
5312 armv7ve
53535313 armv6
53545314 armv6m
53555315 armv6k
......@@ -5369,16 +5329,20 @@ Architectures:
53695329 mips64
53705330 mips64el
53715331 msp430
5332 nios2
53725333 powerpc
53735334 powerpc64
53745335 powerpc64le
53755336 r600
53765337 amdgcn
5338 riscv32
5339 riscv64
53775340 sparc
53785341 sparcv9
53795342 sparcel
53805343 s390x
53815344 tce
5345 tcele
53825346 thumb
53835347 thumbeb
53845348 i386
......@@ -5392,6 +5356,7 @@ Architectures:
53925356 amdil64
53935357 hsail
53945358 hsail64
5359 spir
53955360 spir64
53965361 kalimbav3
53975362 kalimbav4
......@@ -5405,10 +5370,11 @@ Architectures:
54055370
54065371Operating Systems:
54075372 freestanding
5373 ananas
54085374 cloudabi
5409 darwin
54105375 dragonfly
54115376 freebsd
5377 fuchsia
54125378 ios
54135379 kfreebsd
54145380 linux (native)
......@@ -5433,8 +5399,11 @@ Operating Systems:
54335399 tvos
54345400 watchos
54355401 mesa3d
5402 contiki
5403 zen
54365404
54375405Environments:
5406 unknown
54385407 gnu (native)
54395408 gnuabi64
54405409 gnueabi
......@@ -5451,7 +5420,8 @@ Environments:
54515420 itanium
54525421 cygnus
54535422 amdopencl
5454 coreclr</code></pre>
5423 coreclr
5424 opencl</code></pre>
54555425 <p>
54565426 The Zig Standard Library (<code>@import("std")</code>) has architecture, environment, and operating sytsem
54575427 abstractions, and thus takes additional work to support more platforms. It currently supports
......@@ -5518,7 +5488,8 @@ coding style.
55185488 </p>
55195489 {#header_close#}
55205490 {#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");
55225493var global_var: i32 = undefined;
55235494const const_name = 42;
55245495const primitive_type_alias = f32;
......@@ -5527,7 +5498,7 @@ const string_alias = []u8;
55275498const StructName = struct {};
55285499const StructAlias = StructName;
55295500
5530fn functionName(param_name: TypeName) {
5501fn functionName(param_name: TypeName) void {
55315502 var functionPointer = functionName;
55325503 functionPointer();
55335504 functionPointer = otherFunction;
......@@ -5535,34 +5506,35 @@ fn functionName(param_name: TypeName) {
55355506}
55365507const functionAlias = functionName;
55375508
5538fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) -&gt; type {
5509fn ListTemplateFunction(comptime ChildType: type, comptime fixed_size: usize) type {
55395510 return List(ChildType, fixed_size);
55405511}
55415512
5542fn ShortList(comptime T: type, comptime n: usize) -&gt; type {
5543 struct {
5513fn ShortList(comptime T: type, comptime n: usize) type {
5514 return struct {
55445515 field_name: [n]T,
5545 fn methodName() {}
5546 }
5516 fn methodName() void {}
5517 };
55475518}
55485519
55495520// The word XML loses its casing when used in Zig identifiers.
55505521const xml_document =
5551 \\&lt;?xml version="1.0" encoding="UTF-8"?&gt;
5552 \\&lt;document&gt;
5553 \\&lt;/document&gt;
5522 \\<?xml version="1.0" encoding="UTF-8"?>
5523 \\<document>
5524 \\</document>
55545525;
55555526const XmlParser = struct {};
55565527
55575528// 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#}
55595531 <p>
55605532 See the Zig Standard Library for more examples.
55615533 </p>
55625534 {#header_close#}
55635535 {#header_close#}
55645536 {#header_open|Grammar#}
5565 <pre><code>Root = many(TopLevelItem) EOF
5537 <pre><code class="nohighlight">Root = many(TopLevelItem) EOF
55665538
55675539TopLevelItem = ErrorValueDecl | CompTimeExpression(Block) | TopLevelDecl | TestDecl
55685540
......@@ -5586,7 +5558,7 @@ UseDecl = "use" Expression ";"
55865558
55875559ExternDecl = "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
55915563FnDef = option("inline" | "export") FnProto Block
55925564
......@@ -5646,7 +5618,7 @@ TryExpression = "try" Expression
56465618
56475619BreakExpression = "break" option(":" Symbol) option(Expression)
56485620
5649Defer(body) = option("%") "defer" body
5621Defer(body) = ("defer" | "deferror") body
56505622
56515623IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
56525624
......@@ -5733,8 +5705,142 @@ ContainerDecl = option("extern" | "packed")
57335705 <p>TODO: document changes from a31b23c46ba2a8c28df01adc1aa0b4d878b9a5cf (compile time reflection additions)</p>
57345706 {#header_close#}
57355707 </div>
5736 <script src="highlight/highlight.pack.js"></script>
5737 <script>hljs.initHighlightingOnLoad();</script>
5708 <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>
57385844 </body>
57395845</html>
57405846
example/cat/main.zig+4-4
......@@ -5,7 +5,7 @@ const os = std.os;
55const warn = std.debug.warn;
66const allocator = std.debug.global_allocator;
77
8pub fn main() -> %void {
8pub fn main() %void {
99 var args_it = os.args();
1010 const exe = try unwrapArg(??args_it.next(allocator));
1111 var catted_anything = false;
......@@ -36,12 +36,12 @@ pub fn main() -> %void {
3636 }
3737}
3838
39fn usage(exe: []const u8) -> %void {
39fn usage(exe: []const u8) %void {
4040 warn("Usage: {} [FILE]...\n", exe);
4141 return error.Invalid;
4242}
4343
44fn cat_file(stdout: &io.File, file: &io.File) -> %void {
44fn cat_file(stdout: &io.File, file: &io.File) %void {
4545 var buf: [1024 * 4]u8 = undefined;
4646
4747 while (true) {
......@@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
6161 }
6262}
6363
64fn unwrapArg(arg: %[]u8) -> %[]u8 {
64fn unwrapArg(arg: %[]u8) %[]u8 {
6565 return arg catch |err| {
6666 warn("Unable to parse command line: {}\n", err);
6767 return err;
example/guess_number/main.zig+1-1
......@@ -5,7 +5,7 @@ const fmt = std.fmt;
55const Rand = std.rand.Rand;
66const os = std.os;
77
8pub fn main() -> %void {
8pub fn main() %void {
99 var stdout_file = try io.getStdOut();
1010 var stdout_file_stream = io.FileOutStream.init(&stdout_file);
1111 const stdout = &stdout_file_stream.stream;
example/hello_world/hello.zig+1-1
......@@ -1,6 +1,6 @@
11const std = @import("std");
22
3pub fn main() -> %void {
3pub fn main() %void {
44 // If this program is run without stdout attached, exit with an error.
55 var stdout_file = try std.io.getStdOut();
66 // 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({
77
88const 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 {
1111 if (c.printf(msg) != c_int(c.strlen(msg)))
1212 return -1;
1313
example/hello_world/hello_windows.zig+1-1
......@@ -1,6 +1,6 @@
11use @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 {
44 _ = MessageBoxA(null, c"hello", c"title", 0);
55 return 0;
66}
example/mix_o_files/base64.zig+1-1
......@@ -1,6 +1,6 @@
11const 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 {
44 const src = source_ptr[0..source_len];
55 const dest = dest_ptr[0..dest_len];
66 const base64_decoder = base64.standard_decoder_unsafe;
example/mix_o_files/build.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 const obj = b.addObject("base64", "base64.zig");
55
66 const exe = b.addCExecutable("test");
example/shared_library/build.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
55
66 const exe = b.addCExecutable("test");
example/shared_library/mathtest.zig+1-1
......@@ -1,3 +1,3 @@
1export fn add(a: i32, b: i32) -> i32 {
1export fn add(a: i32, b: i32) i32 {
22 return a + b;
33}
src-self-hosted/ast.zig+15-17
......@@ -20,7 +20,7 @@ pub const Node = struct {
2020 FloatLiteral,
2121 };
2222
23 pub fn iterate(base: &Node, index: usize) -> ?&Node {
23 pub fn iterate(base: &Node, index: usize) ?&Node {
2424 return switch (base.id) {
2525 Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
2626 Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
......@@ -35,7 +35,7 @@ pub const Node = struct {
3535 };
3636 }
3737
38 pub fn destroy(base: &Node, allocator: &mem.Allocator) {
38 pub fn destroy(base: &Node, allocator: &mem.Allocator) void {
3939 return switch (base.id) {
4040 Id.Root => allocator.destroy(@fieldParentPtr(NodeRoot, "base", base)),
4141 Id.VarDecl => allocator.destroy(@fieldParentPtr(NodeVarDecl, "base", base)),
......@@ -55,7 +55,7 @@ pub const NodeRoot = struct {
5555 base: Node,
5656 decls: ArrayList(&Node),
5757
58 pub fn iterate(self: &NodeRoot, index: usize) -> ?&Node {
58 pub fn iterate(self: &NodeRoot, index: usize) ?&Node {
5959 if (index < self.decls.len) {
6060 return self.decls.items[self.decls.len - index - 1];
6161 }
......@@ -76,7 +76,7 @@ pub const NodeVarDecl = struct {
7676 align_node: ?&Node,
7777 init_node: ?&Node,
7878
79 pub fn iterate(self: &NodeVarDecl, index: usize) -> ?&Node {
79 pub fn iterate(self: &NodeVarDecl, index: usize) ?&Node {
8080 var i = index;
8181
8282 if (self.type_node) |type_node| {
......@@ -102,7 +102,7 @@ pub const NodeIdentifier = struct {
102102 base: Node,
103103 name_token: Token,
104104
105 pub fn iterate(self: &NodeIdentifier, index: usize) -> ?&Node {
105 pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
106106 return null;
107107 }
108108};
......@@ -113,7 +113,7 @@ pub const NodeFnProto = struct {
113113 fn_token: Token,
114114 name_token: ?Token,
115115 params: ArrayList(&Node),
116 return_type: ?&Node,
116 return_type: &Node,
117117 var_args_token: ?Token,
118118 extern_token: ?Token,
119119 inline_token: ?Token,
......@@ -122,7 +122,7 @@ pub const NodeFnProto = struct {
122122 lib_name: ?&Node, // populated if this is an extern declaration
123123 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 {
126126 var i = index;
127127
128128 if (self.body_node) |body_node| {
......@@ -130,10 +130,8 @@ pub const NodeFnProto = struct {
130130 i -= 1;
131131 }
132132
133 if (self.return_type) |return_type| {
134 if (i < 1) return return_type;
135 i -= 1;
136 }
133 if (i < 1) return self.return_type;
134 i -= 1;
137135
138136 if (self.align_expr) |align_expr| {
139137 if (i < 1) return align_expr;
......@@ -160,7 +158,7 @@ pub const NodeParamDecl = struct {
160158 type_node: &Node,
161159 var_args_token: ?Token,
162160
163 pub fn iterate(self: &NodeParamDecl, index: usize) -> ?&Node {
161 pub fn iterate(self: &NodeParamDecl, index: usize) ?&Node {
164162 var i = index;
165163
166164 if (i < 1) return self.type_node;
......@@ -176,7 +174,7 @@ pub const NodeBlock = struct {
176174 end_token: Token,
177175 statements: ArrayList(&Node),
178176
179 pub fn iterate(self: &NodeBlock, index: usize) -> ?&Node {
177 pub fn iterate(self: &NodeBlock, index: usize) ?&Node {
180178 var i = index;
181179
182180 if (i < self.statements.len) return self.statements.items[i];
......@@ -198,7 +196,7 @@ pub const NodeInfixOp = struct {
198196 BangEqual,
199197 };
200198
201 pub fn iterate(self: &NodeInfixOp, index: usize) -> ?&Node {
199 pub fn iterate(self: &NodeInfixOp, index: usize) ?&Node {
202200 var i = index;
203201
204202 if (i < 1) return self.lhs;
......@@ -234,7 +232,7 @@ pub const NodePrefixOp = struct {
234232 volatile_token: ?Token,
235233 };
236234
237 pub fn iterate(self: &NodePrefixOp, index: usize) -> ?&Node {
235 pub fn iterate(self: &NodePrefixOp, index: usize) ?&Node {
238236 var i = index;
239237
240238 switch (self.op) {
......@@ -258,7 +256,7 @@ pub const NodeIntegerLiteral = struct {
258256 base: Node,
259257 token: Token,
260258
261 pub fn iterate(self: &NodeIntegerLiteral, index: usize) -> ?&Node {
259 pub fn iterate(self: &NodeIntegerLiteral, index: usize) ?&Node {
262260 return null;
263261 }
264262};
......@@ -267,7 +265,7 @@ pub const NodeFloatLiteral = struct {
267265 base: Node,
268266 token: Token,
269267
270 pub fn iterate(self: &NodeFloatLiteral, index: usize) -> ?&Node {
268 pub fn iterate(self: &NodeFloatLiteral, index: usize) ?&Node {
271269 return null;
272270 }
273271};
src-self-hosted/ir.zig+1-1
......@@ -33,7 +33,7 @@ pub const Instruction = struct {
3333 TypeOf,
3434 ToPtrType,
3535 PtrTypeChild,
36 SetDebugSafety,
36 SetRuntimeSafety,
3737 SetFloatMode,
3838 ArrayType,
3939 SliceType,
src-self-hosted/llvm.zig+1-1
......@@ -7,7 +7,7 @@ pub const ModuleRef = removeNullability(c.LLVMModuleRef);
77pub const ContextRef = removeNullability(c.LLVMContextRef);
88pub const BuilderRef = removeNullability(c.LLVMBuilderRef);
99
10fn removeNullability(comptime T: type) -> type {
10fn removeNullability(comptime T: type) type {
1111 comptime assert(@typeId(T) == builtin.TypeId.Nullable);
1212 return T.Child;
1313}
src-self-hosted/main.zig+10-10
......@@ -20,7 +20,7 @@ error ZigInstallationNotFound;
2020
2121const default_zig_cache_name = "zig-cache";
2222
23pub fn main() -> %void {
23pub fn main() %void {
2424 main2() catch |err| {
2525 if (err != error.InvalidCommandLineArguments) {
2626 warn("{}\n", @errorName(err));
......@@ -39,7 +39,7 @@ const Cmd = enum {
3939 Targets,
4040};
4141
42fn badArgs(comptime format: []const u8, args: ...) -> error {
42fn badArgs(comptime format: []const u8, args: ...) error {
4343 var stderr = try io.getStdErr();
4444 var stderr_stream_adapter = io.FileOutStream.init(&stderr);
4545 const stderr_stream = &stderr_stream_adapter.stream;
......@@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) -> error {
4848 return error.InvalidCommandLineArguments;
4949}
5050
51pub fn main2() -> %void {
51pub fn main2() %void {
5252 const allocator = std.heap.c_allocator;
5353
5454 const args = try os.argsAlloc(allocator);
......@@ -371,7 +371,7 @@ pub fn main2() -> %void {
371371 defer allocator.free(full_cache_dir);
372372
373373 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
376376 const module = try Module.create(allocator, root_name, zig_root_source_file,
377377 Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir);
......@@ -472,7 +472,7 @@ pub fn main2() -> %void {
472472 }
473473}
474474
475fn printUsage(stream: &io.OutStream) -> %void {
475fn printUsage(stream: &io.OutStream) %void {
476476 try stream.write(
477477 \\Usage: zig [command] [options]
478478 \\
......@@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) -> %void {
548548 );
549549}
550550
551fn printZen() -> %void {
551fn printZen() %void {
552552 var stdout_file = try io.getStdErr();
553553 try stdout_file.write(
554554 \\
......@@ -569,7 +569,7 @@ fn printZen() -> %void {
569569}
570570
571571/// 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 {
573573 if (zig_install_prefix_arg) |zig_install_prefix| {
574574 return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
575575 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
585585}
586586
587587/// Caller must free result
588fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 {
588fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8 {
589589 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
592592 const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig");
593593 defer allocator.free(test_index_file);
......@@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]
599599}
600600
601601/// Caller must free result
602fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 {
602fn findZigLibDir(allocator: &mem.Allocator) %[]u8 {
603603 const self_exe_path = try os.selfExeDirPath(allocator);
604604 defer allocator.free(self_exe_path);
605605
src-self-hosted/module.zig+18-18
......@@ -110,22 +110,22 @@ pub const Module = struct {
110110 };
111111
112112 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) -> %&Module
113 kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) %&Module
114114 {
115115 var name_buffer = try Buffer.init(allocator, name);
116 %defer name_buffer.deinit();
116 errdefer name_buffer.deinit();
117117
118118 const context = c.LLVMContextCreate() ?? return error.OutOfMemory;
119 %defer c.LLVMContextDispose(context);
119 errdefer c.LLVMContextDispose(context);
120120
121121 const module = c.LLVMModuleCreateWithNameInContext(name_buffer.ptr(), context) ?? return error.OutOfMemory;
122 %defer c.LLVMDisposeModule(module);
122 errdefer c.LLVMDisposeModule(module);
123123
124124 const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory;
125 %defer c.LLVMDisposeBuilder(builder);
125 errdefer c.LLVMDisposeBuilder(builder);
126126
127127 const module_ptr = try allocator.create(Module);
128 %defer allocator.destroy(module_ptr);
128 errdefer allocator.destroy(module_ptr);
129129
130130 *module_ptr = Module {
131131 .allocator = allocator,
......@@ -185,11 +185,11 @@ pub const Module = struct {
185185 return module_ptr;
186186 }
187187
188 fn dump(self: &Module) {
188 fn dump(self: &Module) void {
189189 c.LLVMDumpModule(self.module);
190190 }
191191
192 pub fn destroy(self: &Module) {
192 pub fn destroy(self: &Module) void {
193193 c.LLVMDisposeBuilder(self.builder);
194194 c.LLVMDisposeModule(self.module);
195195 c.LLVMContextDispose(self.context);
......@@ -198,7 +198,7 @@ pub const Module = struct {
198198 self.allocator.destroy(self);
199199 }
200200
201 pub fn build(self: &Module) -> %void {
201 pub fn build(self: &Module) %void {
202202 if (self.llvm_argv.len != 0) {
203203 var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
204204 [][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
......@@ -211,13 +211,13 @@ pub const Module = struct {
211211 try printError("unable to get real path '{}': {}", root_src_path, err);
212212 return err;
213213 };
214 %defer self.allocator.free(root_src_real_path);
214 errdefer self.allocator.free(root_src_real_path);
215215
216216 const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| {
217217 try printError("unable to open '{}': {}", root_src_real_path, err);
218218 return err;
219219 };
220 %defer self.allocator.free(source_code);
220 errdefer self.allocator.free(source_code);
221221 source_code[source_code.len - 3] = '\n';
222222 source_code[source_code.len - 2] = '\n';
223223 source_code[source_code.len - 1] = '\n';
......@@ -244,16 +244,16 @@ pub const Module = struct {
244244 var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);
245245 defer parser.deinit();
246246
247 const root_node = try parser.parse();
248 defer parser.freeAst(root_node);
247 const tree = try parser.parse();
248 defer tree.deinit();
249249
250250 var stderr_file = try std.io.getStdErr();
251251 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
252252 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
255255 warn("====fmt:====\n");
256 try parser.renderSource(out_stream, root_node);
256 try parser.renderSource(out_stream, tree.root_node);
257257
258258 warn("====ir:====\n");
259259 warn("TODO\n\n");
......@@ -263,11 +263,11 @@ pub const Module = struct {
263263
264264 }
265265
266 pub fn link(self: &Module, out_file: ?[]const u8) -> %void {
266 pub fn link(self: &Module, out_file: ?[]const u8) %void {
267267 warn("TODO link");
268268 }
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 {
271271 const is_libc = mem.eql(u8, name, "c");
272272
273273 if (is_libc) {
......@@ -297,7 +297,7 @@ pub const Module = struct {
297297 }
298298};
299299
300fn printError(comptime format: []const u8, args: ...) -> %void {
300fn printError(comptime format: []const u8, args: ...) %void {
301301 var stderr_file = try std.io.getStdErr();
302302 var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
303303 const out_stream = &stderr_file_out_stream.stream;
src-self-hosted/parser.zig+89-132
......@@ -20,14 +20,25 @@ pub const Parser = struct {
2020 put_back_tokens: [2]Token,
2121 put_back_count: usize,
2222 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
2532 // 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.
2735 const utility_bytes_align = @alignOf( union { a: RenderAstFrame, b: State, c: RenderState } );
2836 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 {
3142 return Parser {
3243 .allocator = allocator,
3344 .tokenizer = tokenizer,
......@@ -35,12 +46,10 @@ pub const Parser = struct {
3546 .put_back_count = 0,
3647 .source_file_name = source_file_name,
3748 .utility_bytes = []align(utility_bytes_align) u8{},
38 .cleanup_root_node = null,
3949 };
4050 }
4151
42 pub fn deinit(self: &Parser) {
43 assert(self.cleanup_root_node == null);
52 pub fn deinit(self: &Parser) void {
4453 self.allocator.free(self.utility_bytes);
4554 }
4655
......@@ -54,7 +63,7 @@ pub const Parser = struct {
5463 NullableField: &?&ast.Node,
5564 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 {
5867 switch (*self) {
5968 DestPtr.Field => |ptr| *ptr = value,
6069 DestPtr.NullableField => |ptr| *ptr = value,
......@@ -88,52 +97,16 @@ pub const Parser = struct {
8897 Statement: &ast.NodeBlock,
8998 };
9099
91 pub fn freeAst(self: &Parser, root_node: &ast.NodeRoot) {
92 // utility_bytes is big enough to do this iteration since we were able to do
93 // the parsing in the first place
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 {
100 /// Returns an AST tree, allocated with the parser's allocator.
101 /// Result should be freed with `freeAst` when done.
102 pub fn parse(self: &Parser) %Tree {
125103 var stack = self.initUtilityArrayList(State);
126104 defer self.deinitUtilityArrayList(stack);
127105
128 const root_node = x: {
129 const root_node = try self.createRoot();
130 %defer self.allocator.destroy(root_node);
131 // This stack append has to succeed for freeAst to work
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;
106 const root_node = try self.createRoot();
107 // TODO errdefer arena free root node
108
109 try stack.append(State.TopLevel);
137110
138111 while (true) {
139112 //{
......@@ -159,7 +132,7 @@ pub const Parser = struct {
159132 stack.append(State { .TopLevelExtern = token }) catch unreachable;
160133 continue;
161134 },
162 Token.Id.Eof => return root_node,
135 Token.Id.Eof => return Tree {.root_node = root_node},
163136 else => {
164137 self.putBackToken(token);
165138 // TODO shouldn't need this cast
......@@ -211,7 +184,7 @@ pub const Parser = struct {
211184 Token.Id.StringLiteral => {
212185 @panic("TODO extern with string literal");
213186 },
214 Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
187 Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
215188 stack.append(State.TopLevel) catch unreachable;
216189 const fn_token = try self.eatToken(Token.Id.Keyword_fn);
217190 // TODO shouldn't need this cast
......@@ -439,15 +412,11 @@ pub const Parser = struct {
439412 if (token.id == Token.Id.Keyword_align) {
440413 @panic("TODO fn proto align");
441414 }
442 if (token.id == Token.Id.Arrow) {
443 stack.append(State {
444 .TypeExpr = DestPtr {.NullableField = &fn_proto.return_type},
445 }) catch unreachable;
446 continue;
447 } else {
448 self.putBackToken(token);
449 continue;
450 }
415 self.putBackToken(token);
416 stack.append(State {
417 .TypeExpr = DestPtr {.Field = &fn_proto.return_type},
418 }) catch unreachable;
419 continue;
451420 },
452421
453422 State.ParamDecl => |fn_proto| {
......@@ -575,9 +544,8 @@ pub const Parser = struct {
575544 }
576545 }
577546
578 fn createRoot(self: &Parser) -> %&ast.NodeRoot {
547 fn createRoot(self: &Parser) %&ast.NodeRoot {
579548 const node = try self.allocator.create(ast.NodeRoot);
580 %defer self.allocator.destroy(node);
581549
582550 *node = ast.NodeRoot {
583551 .base = ast.Node {.id = ast.Node.Id.Root},
......@@ -587,10 +555,9 @@ pub const Parser = struct {
587555 }
588556
589557 fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
590 extern_token: &const ?Token) -> %&ast.NodeVarDecl
558 extern_token: &const ?Token) %&ast.NodeVarDecl
591559 {
592560 const node = try self.allocator.create(ast.NodeVarDecl);
593 %defer self.allocator.destroy(node);
594561
595562 *node = ast.NodeVarDecl {
596563 .base = ast.Node {.id = ast.Node.Id.VarDecl},
......@@ -610,10 +577,9 @@ pub const Parser = struct {
610577 }
611578
612579 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.NodeFnProto
580 cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) %&ast.NodeFnProto
614581 {
615582 const node = try self.allocator.create(ast.NodeFnProto);
616 %defer self.allocator.destroy(node);
617583
618584 *node = ast.NodeFnProto {
619585 .base = ast.Node {.id = ast.Node.Id.FnProto},
......@@ -621,7 +587,7 @@ pub const Parser = struct {
621587 .name_token = null,
622588 .fn_token = *fn_token,
623589 .params = ArrayList(&ast.Node).init(self.allocator),
624 .return_type = null,
590 .return_type = undefined,
625591 .var_args_token = null,
626592 .extern_token = *extern_token,
627593 .inline_token = *inline_token,
......@@ -633,9 +599,8 @@ pub const Parser = struct {
633599 return node;
634600 }
635601
636 fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl {
602 fn createParamDecl(self: &Parser) %&ast.NodeParamDecl {
637603 const node = try self.allocator.create(ast.NodeParamDecl);
638 %defer self.allocator.destroy(node);
639604
640605 *node = ast.NodeParamDecl {
641606 .base = ast.Node {.id = ast.Node.Id.ParamDecl},
......@@ -648,9 +613,8 @@ pub const Parser = struct {
648613 return node;
649614 }
650615
651 fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock {
616 fn createBlock(self: &Parser, begin_token: &const Token) %&ast.NodeBlock {
652617 const node = try self.allocator.create(ast.NodeBlock);
653 %defer self.allocator.destroy(node);
654618
655619 *node = ast.NodeBlock {
656620 .base = ast.Node {.id = ast.Node.Id.Block},
......@@ -661,9 +625,8 @@ pub const Parser = struct {
661625 return node;
662626 }
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 {
665629 const node = try self.allocator.create(ast.NodeInfixOp);
666 %defer self.allocator.destroy(node);
667630
668631 *node = ast.NodeInfixOp {
669632 .base = ast.Node {.id = ast.Node.Id.InfixOp},
......@@ -675,9 +638,8 @@ pub const Parser = struct {
675638 return node;
676639 }
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 {
679642 const node = try self.allocator.create(ast.NodePrefixOp);
680 %defer self.allocator.destroy(node);
681643
682644 *node = ast.NodePrefixOp {
683645 .base = ast.Node {.id = ast.Node.Id.PrefixOp},
......@@ -688,9 +650,8 @@ pub const Parser = struct {
688650 return node;
689651 }
690652
691 fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier {
653 fn createIdentifier(self: &Parser, name_token: &const Token) %&ast.NodeIdentifier {
692654 const node = try self.allocator.create(ast.NodeIdentifier);
693 %defer self.allocator.destroy(node);
694655
695656 *node = ast.NodeIdentifier {
696657 .base = ast.Node {.id = ast.Node.Id.Identifier},
......@@ -699,9 +660,8 @@ pub const Parser = struct {
699660 return node;
700661 }
701662
702 fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral {
663 fn createIntegerLiteral(self: &Parser, token: &const Token) %&ast.NodeIntegerLiteral {
703664 const node = try self.allocator.create(ast.NodeIntegerLiteral);
704 %defer self.allocator.destroy(node);
705665
706666 *node = ast.NodeIntegerLiteral {
707667 .base = ast.Node {.id = ast.Node.Id.IntegerLiteral},
......@@ -710,9 +670,8 @@ pub const Parser = struct {
710670 return node;
711671 }
712672
713 fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral {
673 fn createFloatLiteral(self: &Parser, token: &const Token) %&ast.NodeFloatLiteral {
714674 const node = try self.allocator.create(ast.NodeFloatLiteral);
715 %defer self.allocator.destroy(node);
716675
717676 *node = ast.NodeFloatLiteral {
718677 .base = ast.Node {.id = ast.Node.Id.FloatLiteral},
......@@ -721,40 +680,36 @@ pub const Parser = struct {
721680 return node;
722681 }
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 {
725684 const node = try self.createIdentifier(name_token);
726 %defer self.allocator.destroy(node);
727685 try dest_ptr.store(&node.base);
728686 return node;
729687 }
730688
731 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl {
689 fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) %&ast.NodeParamDecl {
732690 const node = try self.createParamDecl();
733 %defer self.allocator.destroy(node);
734691 try list.append(&node.base);
735692 return node;
736693 }
737694
738695 fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token,
739696 extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
740 inline_token: &const ?Token) -> %&ast.NodeFnProto
697 inline_token: &const ?Token) %&ast.NodeFnProto
741698 {
742699 const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
743 %defer self.allocator.destroy(node);
744700 try list.append(&node.base);
745701 return node;
746702 }
747703
748704 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.NodeVarDecl
705 mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) %&ast.NodeVarDecl
750706 {
751707 const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
752 %defer self.allocator.destroy(node);
753708 try list.append(&node.base);
754709 return node;
755710 }
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 {
758713 const loc = self.tokenizer.getTokenLocation(token);
759714 warn("{}:{}:{}: error: " ++ fmt ++ "\n", self.source_file_name, loc.line + 1, loc.column + 1, args);
760715 warn("{}\n", self.tokenizer.buffer[loc.line_start..loc.line_end]);
......@@ -775,24 +730,24 @@ pub const Parser = struct {
775730 return error.ParseError;
776731 }
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 {
779734 if (token.id != id) {
780735 return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
781736 }
782737 }
783738
784 fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token {
739 fn eatToken(self: &Parser, id: @TagType(Token.Id)) %Token {
785740 const token = self.getNextToken();
786741 try self.expectToken(token, id);
787742 return token;
788743 }
789744
790 fn putBackToken(self: &Parser, token: &const Token) {
745 fn putBackToken(self: &Parser, token: &const Token) void {
791746 self.put_back_tokens[self.put_back_count] = *token;
792747 self.put_back_count += 1;
793748 }
794749
795 fn getNextToken(self: &Parser) -> Token {
750 fn getNextToken(self: &Parser) Token {
796751 if (self.put_back_count != 0) {
797752 const put_back_index = self.put_back_count - 1;
798753 const put_back_token = self.put_back_tokens[put_back_index];
......@@ -808,7 +763,7 @@ pub const Parser = struct {
808763 indent: usize,
809764 };
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 {
812767 var stack = self.initUtilityArrayList(RenderAstFrame);
813768 defer self.deinitUtilityArrayList(stack);
814769
......@@ -847,7 +802,7 @@ pub const Parser = struct {
847802 Indent: usize,
848803 };
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 {
851806 var stack = self.initUtilityArrayList(RenderState);
852807 defer self.deinitUtilityArrayList(stack);
853808
......@@ -1039,14 +994,12 @@ pub const Parser = struct {
1039994 if (fn_proto.align_expr != null) {
1040995 @panic("TODO");
1041996 }
1042 if (fn_proto.return_type) |return_type| {
1043 try stream.print(" -> ");
1044 if (fn_proto.body_node) |body_node| {
1045 try stack.append(RenderState { .Expression = body_node});
1046 try stack.append(RenderState { .Text = " "});
1047 }
1048 try stack.append(RenderState { .Expression = return_type});
997 try stream.print(" ");
998 if (fn_proto.body_node) |body_node| {
999 try stack.append(RenderState { .Expression = body_node});
1000 try stack.append(RenderState { .Text = " "});
10491001 }
1002 try stack.append(RenderState { .Expression = fn_proto.return_type});
10501003 },
10511004 RenderState.Statement => |base| {
10521005 switch (base.id) {
......@@ -1066,7 +1019,7 @@ pub const Parser = struct {
10661019 }
10671020 }
10681021
1069 fn initUtilityArrayList(self: &Parser, comptime T: type) -> ArrayList(T) {
1022 fn initUtilityArrayList(self: &Parser, comptime T: type) ArrayList(T) {
10701023 const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);
10711024 self.utility_bytes = self.allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
10721025 const typed_slice = ([]T)(self.utility_bytes);
......@@ -1077,7 +1030,7 @@ pub const Parser = struct {
10771030 };
10781031 }
10791032
1080 fn deinitUtilityArrayList(self: &Parser, list: var) {
1033 fn deinitUtilityArrayList(self: &Parser, list: var) void {
10811034 self.utility_bytes = ([]align(utility_bytes_align) u8)(list.items);
10821035 }
10831036
......@@ -1085,7 +1038,7 @@ pub const Parser = struct {
10851038
10861039var 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 {
10891042 var padded_source: [0x100]u8 = undefined;
10901043 std.mem.copy(u8, padded_source[0..source.len], source);
10911044 padded_source[source.len + 0] = '\n';
......@@ -1096,30 +1049,34 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
10961049 var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
10971050 defer parser.deinit();
10981051
1099 const root_node = try parser.parse();
1100 defer parser.freeAst(root_node);
1052 const tree = try parser.parse();
1053 defer tree.deinit();
11011054
11021055 var buffer = try std.Buffer.initSize(allocator, 0);
11031056 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);
11051058 return buffer.toOwnedSlice();
11061059}
11071060
1061error TestFailed;
1062error NondeterministicMemoryUsage;
1063error MemoryLeakDetected;
1064
11081065// TODO test for memory leaks
11091066// TODO test for valid frees
1110fn testCanonical(source: []const u8) {
1067fn testCanonical(source: []const u8) %void {
11111068 const needed_alloc_count = x: {
11121069 // Try it once with unlimited memory, make sure it works
11131070 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
11141071 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);
11161073 if (!mem.eql(u8, result_source, source)) {
11171074 warn("\n====== expected this output: =========\n");
11181075 warn("{}", source);
11191076 warn("\n======== instead found this: =========\n");
11201077 warn("{}", result_source);
11211078 warn("\n======================================\n");
1122 @panic("test failed");
1079 return error.TestFailed;
11231080 }
11241081 failing_allocator.allocator.free(result_source);
11251082 break :x failing_allocator.index;
......@@ -1130,7 +1087,7 @@ fn testCanonical(source: []const u8) {
11301087 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
11311088 var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, fail_index);
11321089 if (testParse(source, &failing_allocator.allocator)) |_| {
1133 @panic("non-deterministic memory usage");
1090 return error.NondeterministicMemoryUsage;
11341091 } else |err| {
11351092 assert(err == error.OutOfMemory);
11361093 // TODO make this pass
......@@ -1139,19 +1096,19 @@ fn testCanonical(source: []const u8) {
11391096 // fail_index, needed_alloc_count,
11401097 // failing_allocator.allocated_bytes, failing_allocator.freed_bytes,
11411098 // failing_allocator.index, failing_allocator.deallocations);
1142 // @panic("memory leak detected");
1099 // return error.MemoryLeakDetected;
11431100 //}
11441101 }
11451102 }
11461103}
11471104
11481105test "zig fmt" {
1149 testCanonical(
1150 \\extern fn puts(s: &const u8) -> c_int;
1106 try testCanonical(
1107 \\extern fn puts(s: &const u8) c_int;
11511108 \\
11521109 );
11531110
1154 testCanonical(
1111 try testCanonical(
11551112 \\const a = b;
11561113 \\pub const a = b;
11571114 \\var a = b;
......@@ -1163,44 +1120,44 @@ test "zig fmt" {
11631120 \\
11641121 );
11651122
1166 testCanonical(
1123 try testCanonical(
11671124 \\extern var foo: c_int;
11681125 \\
11691126 );
11701127
1171 testCanonical(
1128 try testCanonical(
11721129 \\var foo: c_int align(1);
11731130 \\
11741131 );
11751132
1176 testCanonical(
1177 \\fn main(argc: c_int, argv: &&u8) -> c_int {
1133 try testCanonical(
1134 \\fn main(argc: c_int, argv: &&u8) c_int {
11781135 \\ const a = b;
11791136 \\}
11801137 \\
11811138 );
11821139
1183 testCanonical(
1184 \\fn foo(argc: c_int, argv: &&u8) -> c_int {
1140 try testCanonical(
1141 \\fn foo(argc: c_int, argv: &&u8) c_int {
11851142 \\ return 0;
11861143 \\}
11871144 \\
11881145 );
11891146
1190 testCanonical(
1191 \\extern fn f1(s: &align(&u8) u8) -> c_int;
1147 try testCanonical(
1148 \\extern fn f1(s: &align(&u8) u8) c_int;
11921149 \\
11931150 );
11941151
1195 testCanonical(
1196 \\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;
1198 \\extern fn f3(s: &align(1) const volatile u8) -> c_int;
1152 try testCanonical(
1153 \\extern fn f1(s: &&align(1) &const &volatile u8) c_int;
1154 \\extern fn f2(s: &align(1) const &align(1) volatile &const volatile u8) c_int;
1155 \\extern fn f3(s: &align(1) const volatile u8) c_int;
11991156 \\
12001157 );
12011158
1202 testCanonical(
1203 \\fn f1(a: bool, b: bool) -> bool {
1159 try testCanonical(
1160 \\fn f1(a: bool, b: bool) bool {
12041161 \\ a != b;
12051162 \\ return a == b;
12061163 \\}
src-self-hosted/target.zig+6-6
......@@ -11,7 +11,7 @@ pub const Target = union(enum) {
1111 Native,
1212 Cross: CrossTarget,
1313
14 pub fn oFileExt(self: &const Target) -> []const u8 {
14 pub fn oFileExt(self: &const Target) []const u8 {
1515 const environ = switch (*self) {
1616 Target.Native => builtin.environ,
1717 Target.Cross => |t| t.environ,
......@@ -22,28 +22,28 @@ pub const Target = union(enum) {
2222 };
2323 }
2424
25 pub fn exeFileExt(self: &const Target) -> []const u8 {
25 pub fn exeFileExt(self: &const Target) []const u8 {
2626 return switch (self.getOs()) {
2727 builtin.Os.windows => ".exe",
2828 else => "",
2929 };
3030 }
3131
32 pub fn getOs(self: &const Target) -> builtin.Os {
32 pub fn getOs(self: &const Target) builtin.Os {
3333 return switch (*self) {
3434 Target.Native => builtin.os,
3535 Target.Cross => |t| t.os,
3636 };
3737 }
3838
39 pub fn isDarwin(self: &const Target) -> bool {
39 pub fn isDarwin(self: &const Target) bool {
4040 return switch (self.getOs()) {
4141 builtin.Os.ios, builtin.Os.macosx => true,
4242 else => false,
4343 };
4444 }
4545
46 pub fn isWindows(self: &const Target) -> bool {
46 pub fn isWindows(self: &const Target) bool {
4747 return switch (self.getOs()) {
4848 builtin.Os.windows => true,
4949 else => false,
......@@ -51,7 +51,7 @@ pub const Target = union(enum) {
5151 }
5252};
5353
54pub fn initializeAll() {
54pub fn initializeAll() void {
5555 c.LLVMInitializeAllTargets();
5656 c.LLVMInitializeAllTargetInfos();
5757 c.LLVMInitializeAllTargetMCs();
src-self-hosted/tokenizer.zig+9-11
......@@ -16,7 +16,6 @@ pub const Token = struct {
1616 KeywordId{.bytes="and", .id = Id.Keyword_and},
1717 KeywordId{.bytes="asm", .id = Id.Keyword_asm},
1818 KeywordId{.bytes="break", .id = Id.Keyword_break},
19 KeywordId{.bytes="coldcc", .id = Id.Keyword_coldcc},
2019 KeywordId{.bytes="comptime", .id = Id.Keyword_comptime},
2120 KeywordId{.bytes="const", .id = Id.Keyword_const},
2221 KeywordId{.bytes="continue", .id = Id.Keyword_continue},
......@@ -54,7 +53,7 @@ pub const Token = struct {
5453 KeywordId{.bytes="while", .id = Id.Keyword_while},
5554 };
5655
57 fn getKeyword(bytes: []const u8) -> ?Id {
56 fn getKeyword(bytes: []const u8) ?Id {
5857 for (keywords) |kw| {
5958 if (mem.eql(u8, kw.bytes, bytes)) {
6059 return kw.id;
......@@ -97,7 +96,6 @@ pub const Token = struct {
9796 Keyword_and,
9897 Keyword_asm,
9998 Keyword_break,
100 Keyword_coldcc,
10199 Keyword_comptime,
102100 Keyword_const,
103101 Keyword_continue,
......@@ -148,7 +146,7 @@ pub const Tokenizer = struct {
148146 line_end: usize,
149147 };
150148
151 pub fn getTokenLocation(self: &Tokenizer, token: &const Token) -> Location {
149 pub fn getTokenLocation(self: &Tokenizer, token: &const Token) Location {
152150 var loc = Location {
153151 .line = 0,
154152 .column = 0,
......@@ -173,13 +171,13 @@ pub const Tokenizer = struct {
173171 }
174172
175173 /// For debugging purposes
176 pub fn dump(self: &Tokenizer, token: &const Token) {
174 pub fn dump(self: &Tokenizer, token: &const Token) void {
177175 std.debug.warn("{} \"{}\"\n", @tagName(token.id), self.buffer[token.start..token.end]);
178176 }
179177
180178 /// buffer must end with "\n\n\n". This is so that attempting to decode
181179 /// 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 {
183181 std.debug.assert(buffer[buffer.len - 1] == '\n');
184182 std.debug.assert(buffer[buffer.len - 2] == '\n');
185183 std.debug.assert(buffer[buffer.len - 3] == '\n');
......@@ -214,7 +212,7 @@ pub const Tokenizer = struct {
214212 Period2,
215213 };
216214
217 pub fn next(self: &Tokenizer) -> Token {
215 pub fn next(self: &Tokenizer) Token {
218216 if (self.pending_invalid_token) |token| {
219217 self.pending_invalid_token = null;
220218 return token;
......@@ -530,11 +528,11 @@ pub const Tokenizer = struct {
530528 return result;
531529 }
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 {
534532 return self.buffer[token.start..token.end];
535533 }
536534
537 fn checkLiteralCharacter(self: &Tokenizer) {
535 fn checkLiteralCharacter(self: &Tokenizer) void {
538536 if (self.pending_invalid_token != null) return;
539537 const invalid_length = self.getInvalidCharacterLength();
540538 if (invalid_length == 0) return;
......@@ -545,7 +543,7 @@ pub const Tokenizer = struct {
545543 };
546544 }
547545
548 fn getInvalidCharacterLength(self: &Tokenizer) -> u3 {
546 fn getInvalidCharacterLength(self: &Tokenizer) u3 {
549547 const c0 = self.buffer[self.index];
550548 if (c0 < 0x80) {
551549 if (c0 < 0x20 or c0 == 0x7f) {
......@@ -638,7 +636,7 @@ test "tokenizer - illegal unicode codepoints" {
638636 testTokenize("//\xe2\x80\xaa", []Token.Id{});
639637}
640638
641fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) {
639fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) void {
642640 // (test authors, just make this bigger if you need it)
643641 var padded_source: [0x100]u8 = undefined;
644642 std.mem.copy(u8, padded_source[0..source.len], source);
src/all_types.hpp+16-5
......@@ -1108,6 +1108,7 @@ struct TypeTableEntry {
11081108
11091109 bool zero_bits;
11101110 bool is_copyable;
1111 bool gen_h_loop_flag;
11111112
11121113 union {
11131114 TypeTableEntryPointer pointer;
......@@ -1204,6 +1205,9 @@ struct FnTableEntry {
12041205 AstNode *set_alignstack_node;
12051206 uint32_t alignstack_value;
12061207
1208 AstNode *set_cold_node;
1209 bool is_cold;
1210
12071211 ZigList<FnExport> export_list;
12081212 bool calls_errorable_function;
12091213};
......@@ -1250,7 +1254,8 @@ enum BuiltinFnId {
12501254 BuiltinFnIdMod,
12511255 BuiltinFnIdTruncate,
12521256 BuiltinFnIdIntType,
1253 BuiltinFnIdSetDebugSafety,
1257 BuiltinFnIdSetCold,
1258 BuiltinFnIdSetRuntimeSafety,
12541259 BuiltinFnIdSetFloatMode,
12551260 BuiltinFnIdTypeName,
12561261 BuiltinFnIdCanImplicitCast,
......@@ -1830,7 +1835,8 @@ enum IrInstructionId {
18301835 IrInstructionIdTypeOf,
18311836 IrInstructionIdToPtrType,
18321837 IrInstructionIdPtrTypeChild,
1833 IrInstructionIdSetDebugSafety,
1838 IrInstructionIdSetCold,
1839 IrInstructionIdSetRuntimeSafety,
18341840 IrInstructionIdSetFloatMode,
18351841 IrInstructionIdArrayType,
18361842 IrInstructionIdSliceType,
......@@ -2202,11 +2208,16 @@ struct IrInstructionPtrTypeChild {
22022208 IrInstruction *value;
22032209};
22042210
2205struct IrInstructionSetDebugSafety {
2211struct IrInstructionSetCold {
22062212 IrInstruction base;
22072213
2208 IrInstruction *scope_value;
2209 IrInstruction *debug_safety_on;
2214 IrInstruction *is_cold;
2215};
2216
2217struct IrInstructionSetRuntimeSafety {
2218 IrInstruction base;
2219
2220 IrInstruction *safety_on;
22102221};
22112222
22122223struct IrInstructionSetFloatMode {
src/analyze.cpp+126-50
......@@ -609,7 +609,10 @@ TypeTableEntry *get_array_type(CodeGen *g, TypeTableEntry *child_type, uint64_t
609609 buf_resize(&entry->name, 0);
610610 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 {
613616 entry->type_ref = child_type->type_ref ? LLVMArrayType(child_type->type_ref,
614617 (unsigned int)array_size) : nullptr;
615618
......@@ -915,9 +918,7 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
915918 if (fn_type_id->alignment != 0) {
916919 buf_appendf(&fn_type->name, " align(%" PRIu32 ")", fn_type_id->alignment);
917920 }
918 if (fn_type_id->return_type->id != TypeTableEntryIdVoid) {
919 buf_appendf(&fn_type->name, " -> %s", buf_ptr(&fn_type_id->return_type->name));
920 }
921 buf_appendf(&fn_type->name, " %s", buf_ptr(&fn_type_id->return_type->name));
921922 skip_debug_info = skip_debug_info || !fn_type_id->return_type->di_type;
922923
923924 // 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) {
10791080 const char *comma_str = (i == 0) ? "" : ",";
10801081 buf_appendf(&fn_type->name, "%svar", comma_str);
10811082 }
1082 buf_appendf(&fn_type->name, ")->var");
1083 buf_appendf(&fn_type->name, ")var");
10831084
10841085 fn_type->data.fn.fn_type_id = *fn_type_id;
10851086 fn_type->data.fn.is_generic = true;
......@@ -1155,6 +1156,104 @@ static bool analyze_const_string(CodeGen *g, Scope *scope, AstNode *node, Buf **
11551156 return true;
11561157}
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
11581257static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope) {
11591258 assert(proto_node->type == NodeTypeFnProto);
11601259 AstNodeFnProto *fn_proto = &proto_node->data.fn_proto;
......@@ -1205,6 +1304,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
12051304 }
12061305 }
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
12081315 switch (type_entry->id) {
12091316 case TypeTableEntryIdInvalid:
12101317 return g->builtin_types.entry_invalid;
......@@ -1269,6 +1376,14 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
12691376 fn_type_id.return_type = (fn_proto->return_type == nullptr) ?
12701377 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
12721387 switch (fn_type_id.return_type->id) {
12731388 case TypeTableEntryIdInvalid:
12741389 return g->builtin_types.entry_invalid;
......@@ -1421,46 +1536,6 @@ static void resolve_enum_type(CodeGen *g, TypeTableEntry *enum_type) {
14211536 enum_type->di_type = tag_di_type;
14221537}
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
14651540TypeTableEntry *get_struct_type(CodeGen *g, const char *type_name, const char *field_names[],
14661541 TypeTableEntry *field_types[], size_t field_count)
......@@ -1864,7 +1939,7 @@ static void resolve_union_type(CodeGen *g, TypeTableEntry *union_type) {
18641939 uint64_t padding_in_bits = biggest_size_in_bits - size_of_most_aligned_member_in_bits;
18651940
18661941 TypeTableEntry *tag_type = union_type->data.unionation.tag_type;
1867 if (tag_type == nullptr) {
1942 if (tag_type == nullptr || tag_type->zero_bits) {
18681943 assert(most_aligned_union_member != nullptr);
18691944
18701945 if (padding_in_bits > 0) {
......@@ -2506,8 +2581,10 @@ static void resolve_union_zero_bits(CodeGen *g, TypeTableEntry *union_type) {
25062581
25072582 if (create_enum_type) {
25082583 ImportTableEntry *import = get_scope_import(scope);
2509 uint64_t tag_debug_size_in_bits = 8*LLVMStoreSizeOfType(g->target_data_ref, tag_type->type_ref);
2510 uint64_t tag_debug_align_in_bits = 8*LLVMABIAlignmentOfType(g->target_data_ref, tag_type->type_ref);
2584 uint64_t tag_debug_size_in_bits = tag_type->zero_bits ? 0 :
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);
25112588 // TODO get a more accurate debug scope
25122589 ZigLLVMDIType *tag_di_type = ZigLLVMCreateDebugEnumerationType(g->dbuilder,
25132590 ZigLLVMFileToScope(import->di_file), buf_ptr(&tag_type->name),
......@@ -2586,7 +2663,7 @@ static bool scope_is_root_decls(Scope *scope) {
25862663
25872664static void wrong_panic_prototype(CodeGen *g, AstNode *proto_node, TypeTableEntry *fn_type) {
25882665 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'",
25902667 buf_ptr(&fn_type->name)));
25912668}
25922669
......@@ -3448,7 +3525,6 @@ TypeUnionField *find_union_type_field(TypeTableEntry *type_entry, Buf *name) {
34483525TypeUnionField *find_union_field_by_tag(TypeTableEntry *type_entry, const BigInt *tag) {
34493526 assert(type_entry->id == TypeTableEntryIdUnion);
34503527 assert(type_entry->data.unionation.zero_bits_known);
3451 assert(type_entry->data.unionation.gen_tag_index != SIZE_MAX);
34523528 for (uint32_t i = 0; i < type_entry->data.unionation.src_field_count; i += 1) {
34533529 TypeUnionField *field = &type_entry->data.unionation.fields[i];
34543530 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) {
9292static const char *defer_string(ReturnKind kind) {
9393 switch (kind) {
9494 case ReturnKindUnconditional: return "defer";
95 case ReturnKindError: return "%defer";
95 case ReturnKindError: return "errdefer";
9696 }
9797 zig_unreachable();
9898}
......@@ -450,10 +450,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
450450 }
451451
452452 AstNode *return_type_node = node->data.fn_proto.return_type;
453 if (return_type_node != nullptr) {
454 fprintf(ar->f, " -> ");
455 render_node_grouped(ar, return_type_node);
456 }
453 assert(return_type_node != nullptr);
454 fprintf(ar->f, " ");
455 render_node_grouped(ar, return_type_node);
457456 break;
458457 }
459458 case NodeTypeFnDef:
src/codegen.cpp+270-81
......@@ -485,11 +485,14 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) {
485485 addLLVMFnAttr(fn_table_entry->llvm_value, "naked");
486486 } else {
487487 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 }
491488 }
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
493496 LLVMSetLinkage(fn_table_entry->llvm_value, to_llvm_linkage(linkage));
494497
495498 if (linkage == GlobalLinkageIdInternal) {
......@@ -803,7 +806,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
803806 return true;
804807}
805808
806static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
809static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
807810 if (g->build_mode == BuildModeFastRelease)
808811 return false;
809812
......@@ -898,7 +901,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
898901 LLVMBuildUnreachable(g->builder);
899902}
900903
901static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {
904static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
902905 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
903906}
904907
......@@ -1137,7 +1140,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
11371140 return fn_val;
11381141}
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) {
11411144 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
11421145 LLVMValueRef err_ret_trace_val = g->cur_err_ret_trace_val;
11431146 if (err_ret_trace_val == nullptr) {
......@@ -1176,7 +1179,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
11761179 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
11771180
11781181 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);
1179 gen_debug_safety_crash(g, PanicMsgIdBoundsCheckFailure);
1182 gen_safety_crash(g, PanicMsgIdBoundsCheckFailure);
11801183
11811184 if (upper_value) {
11821185 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);
......@@ -1187,7 +1190,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
11871190 LLVMPositionBuilderAtEnd(g->builder, ok_block);
11881191}
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,
11911194 TypeTableEntry *wanted_type, LLVMValueRef expr_val)
11921195{
11931196 assert(actual_type->id == wanted_type->id);
......@@ -1206,7 +1209,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12061209
12071210 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&
12081211 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
1209 want_debug_safety)
1212 want_runtime_safety)
12101213 {
12111214 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
12121215 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
12161219 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12171220
12181221 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1219 gen_debug_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
1222 gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
12201223
12211224 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12221225 }
......@@ -1240,7 +1243,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12401243 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
12411244 } else if (actual_type->id == TypeTableEntryIdInt) {
12421245 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
1243 if (!want_debug_safety) {
1246 if (!want_runtime_safety) {
12441247 return trunc_val;
12451248 }
12461249 LLVMValueRef orig_val;
......@@ -1255,7 +1258,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12551258 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12561259
12571260 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1258 gen_debug_safety_crash(g, PanicMsgIdCastTruncatedData);
1261 gen_safety_crash(g, PanicMsgIdCastTruncatedData);
12591262
12601263 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12611264 return trunc_val;
......@@ -1283,7 +1286,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS
12831286 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
12841287
12851288 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1286 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
1289 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
12871290
12881291 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12891292 return result;
......@@ -1491,7 +1494,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
14911494 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
14921495
14931496 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1494 gen_debug_safety_crash(g, PanicMsgIdShlOverflowedBits);
1497 gen_safety_crash(g, PanicMsgIdShlOverflowedBits);
14951498
14961499 LLVMPositionBuilderAtEnd(g->builder, ok_block);
14971500 return result;
......@@ -1516,7 +1519,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry,
15161519 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
15171520
15181521 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1519 gen_debug_safety_crash(g, PanicMsgIdShrOverflowedBits);
1522 gen_safety_crash(g, PanicMsgIdShrOverflowedBits);
15201523
15211524 LLVMPositionBuilderAtEnd(g->builder, ok_block);
15221525 return result;
......@@ -1562,14 +1565,14 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
15621565 }
15631566}
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,
15661569 LLVMValueRef val1, LLVMValueRef val2,
15671570 TypeTableEntry *type_entry, DivKind div_kind)
15681571{
15691572 ZigLLVMSetFastMath(g->builder, want_fast_math);
15701573
15711574 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)) {
15731576 LLVMValueRef is_zero_bit;
15741577 if (type_entry->id == TypeTableEntryIdInt) {
15751578 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
15831586 LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block);
15841587
15851588 LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block);
1586 gen_debug_safety_crash(g, PanicMsgIdDivisionByZero);
1589 gen_safety_crash(g, PanicMsgIdDivisionByZero);
15871590
15881591 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
16001603 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);
16011604
16021605 LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block);
1603 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
1606 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
16041607
16051608 LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block);
16061609 }
......@@ -1612,7 +1615,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16121615 case DivKindFloat:
16131616 return result;
16141617 case DivKindExact:
1615 if (want_debug_safety) {
1618 if (want_runtime_safety) {
16161619 LLVMValueRef floored = gen_floor(g, result, type_entry);
16171620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
16181621 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
16211624 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16221625
16231626 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1624 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
1627 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16251628
16261629 LLVMPositionBuilderAtEnd(g->builder, ok_block);
16271630 }
......@@ -1669,7 +1672,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16691672 return LLVMBuildUDiv(g->builder, val1, val2, "");
16701673 }
16711674 case DivKindExact:
1672 if (want_debug_safety) {
1675 if (want_runtime_safety) {
16731676 LLVMValueRef remainder_val;
16741677 if (type_entry->data.integral.is_signed) {
16751678 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
16831686 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16841687
16851688 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1686 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
1689 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16871690
16881691 LLVMPositionBuilderAtEnd(g->builder, ok_block);
16891692 }
......@@ -1721,14 +1724,14 @@ enum RemKind {
17211724 RemKindMod,
17221725};
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,
17251728 LLVMValueRef val1, LLVMValueRef val2,
17261729 TypeTableEntry *type_entry, RemKind rem_kind)
17271730{
17281731 ZigLLVMSetFastMath(g->builder, want_fast_math);
17291732
17301733 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
1731 if (want_debug_safety) {
1734 if (want_runtime_safety) {
17321735 LLVMValueRef is_zero_bit;
17331736 if (type_entry->id == TypeTableEntryIdInt) {
17341737 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
17431746 LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block);
17441747
17451748 LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block);
1746 gen_debug_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
1749 gen_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
17471750
17481751 LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block);
17491752 }
......@@ -1789,8 +1792,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
17891792 op_id == IrBinOpBitShiftRightExact);
17901793 TypeTableEntry *type_entry = op1->value.type;
17911794
1792 bool want_debug_safety = bin_op_instruction->safety_check_on &&
1793 ir_want_debug_safety(g, &bin_op_instruction->base);
1795 bool want_runtime_safety = bin_op_instruction->safety_check_on &&
1796 ir_want_runtime_safety(g, &bin_op_instruction->base);
17941797
17951798 LLVMValueRef op1_value = ir_llvm_value(g, op1);
17961799 LLVMValueRef op2_value = ir_llvm_value(g, op2);
......@@ -1838,7 +1841,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18381841 bool is_wrapping = (op_id == IrBinOpAddWrap);
18391842 if (is_wrapping) {
18401843 return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
1841 } else if (want_debug_safety) {
1844 } else if (want_runtime_safety) {
18421845 return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);
18431846 } else if (type_entry->data.integral.is_signed) {
18441847 return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
......@@ -1863,7 +1866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18631866 bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);
18641867 if (is_sloppy) {
18651868 return LLVMBuildShl(g->builder, op1_value, op2_casted, "");
1866 } else if (want_debug_safety) {
1869 } else if (want_runtime_safety) {
18671870 return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);
18681871 } else if (type_entry->data.integral.is_signed) {
18691872 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");
......@@ -1884,7 +1887,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18841887 } else {
18851888 return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");
18861889 }
1887 } else if (want_debug_safety) {
1890 } else if (want_runtime_safety) {
18881891 return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);
18891892 } else if (type_entry->data.integral.is_signed) {
18901893 return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");
......@@ -1901,7 +1904,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19011904 bool is_wrapping = (op_id == IrBinOpSubWrap);
19021905 if (is_wrapping) {
19031906 return LLVMBuildSub(g->builder, op1_value, op2_value, "");
1904 } else if (want_debug_safety) {
1907 } else if (want_runtime_safety) {
19051908 return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);
19061909 } else if (type_entry->data.integral.is_signed) {
19071910 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
......@@ -1920,7 +1923,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19201923 bool is_wrapping = (op_id == IrBinOpMultWrap);
19211924 if (is_wrapping) {
19221925 return LLVMBuildMul(g->builder, op1_value, op2_value, "");
1923 } else if (want_debug_safety) {
1926 } else if (want_runtime_safety) {
19241927 return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);
19251928 } else if (type_entry->data.integral.is_signed) {
19261929 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
......@@ -1931,22 +1934,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19311934 zig_unreachable();
19321935 }
19331936 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),
19351938 op1_value, op2_value, type_entry, DivKindFloat);
19361939 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),
19381941 op1_value, op2_value, type_entry, DivKindExact);
19391942 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),
19411944 op1_value, op2_value, type_entry, DivKindTrunc);
19421945 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),
19441947 op1_value, op2_value, type_entry, DivKindFloor);
19451948 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),
19471950 op1_value, op2_value, type_entry, RemKindRem);
19481951 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),
19501953 op1_value, op2_value, type_entry, RemKindMod);
19511954 }
19521955 zig_unreachable();
......@@ -2004,7 +2007,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
20042007 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
20052008 } else if (src_size == 1) {
20062009 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)) {
20082011 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
20092012 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
20102013 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
......@@ -2013,7 +2016,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
20132016 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
20142017
20152018 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2016 gen_debug_safety_crash(g, PanicMsgIdSliceWidenRemainder);
2019 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
20172020
20182021 LLVMPositionBuilderAtEnd(g->builder, ok_block);
20192022 }
......@@ -2108,7 +2111,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
21082111 int_type = actual_type;
21092112 }
21102113 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,
21122115 instruction->base.value.type, target_val);
21132116}
21142117
......@@ -2130,7 +2133,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
21302133 TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;
21312134
21322135 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),
21342137 instruction->target->value.type, tag_int_type, target_val);
21352138}
21362139
......@@ -2144,7 +2147,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
21442147
21452148 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)) {
21482151 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
21492152 LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
21502153 LLVMValueRef ok_bit;
......@@ -2168,7 +2171,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
21682171 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
21692172
21702173 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2171 gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);
2174 gen_safety_crash(g, PanicMsgIdInvalidErrorCode);
21722175
21732176 LLVMPositionBuilderAtEnd(g->builder, ok_block);
21742177 }
......@@ -2185,11 +2188,11 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
21852188 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21862189
21872190 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),
21892192 g->err_tag_type, wanted_type, target_val);
21902193 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
21912194 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),
21932196 g->err_tag_type, wanted_type, target_val);
21942197 } else {
21952198 zig_panic("TODO");
......@@ -2202,8 +2205,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
22022205static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
22032206 IrInstructionUnreachable *unreachable_instruction)
22042207{
2205 if (ir_want_debug_safety(g, &unreachable_instruction->base)) {
2206 gen_debug_safety_crash(g, PanicMsgIdUnreachable);
2208 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
2209 gen_safety_crash(g, PanicMsgIdUnreachable);
22072210 } else {
22082211 LLVMBuildUnreachable(g->builder);
22092212 }
......@@ -2245,7 +2248,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
22452248 } else if (expr_type->id == TypeTableEntryIdInt) {
22462249 if (op_id == IrUnOpNegationWrap) {
22472250 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)) {
22492252 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
22502253 return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr);
22512254 } else if (expr_type->data.integral.is_signed) {
......@@ -2314,7 +2317,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
23142317 var->align_bytes, 0, 0);
23152318 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
23162319 } 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);
23182321 if (want_safe) {
23192322 TypeTableEntry *usize = g->builtin_types.entry_usize;
23202323 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
24062409 if (!type_has_bits(array_type))
24072410 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
24112414 if (array_type->id == TypeTableEntryIdArray) {
24122415 if (safety_check_on) {
......@@ -2590,7 +2593,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
25902593 return bitcasted_union_field_ptr;
25912594 }
25922595
2593 if (ir_want_debug_safety(g, &instruction->base)) {
2596 if (ir_want_runtime_safety(g, &instruction->base)) {
25942597 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
25952598 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
26032606 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
26042607
26052608 LLVMPositionBuilderAtEnd(g->builder, bad_block);
2606 gen_debug_safety_crash(g, PanicMsgIdBadUnionField);
2609 gen_safety_crash(g, PanicMsgIdBadUnionField);
26072610
26082611 LLVMPositionBuilderAtEnd(g->builder, ok_block);
26092612 }
......@@ -2773,14 +2776,14 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
27732776 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
27742777 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
27752778 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) {
27772780 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
27782781 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
27792782 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");
27802783 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
27812784
27822785 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2783 gen_debug_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
2786 gen_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
27842787
27852788 LLVMPositionBuilderAtEnd(g->builder, ok_block);
27862789 }
......@@ -2910,7 +2913,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
29102913 }
29112914
29122915 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)) {
29142917 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
29152918 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);
29162919 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
29322935
29332936 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
29342937 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)) {
29362939 size_t field_count = enum_type->data.enumeration.src_field_count;
29372940
29382941 // 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
29852988 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
29862989 assert(target_val);
29872990
2988 bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);
2989 if (!want_debug_safety) {
2991 bool want_runtime_safety = ir_want_runtime_safety(g, &instruction->base);
2992 if (!want_runtime_safety) {
29902993 return target_val;
29912994 }
29922995
......@@ -3035,7 +3038,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
30353038 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
30363039
30373040 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3038 gen_debug_safety_crash(g, PanicMsgIdIncorrectAlignment);
3041 gen_safety_crash(g, PanicMsgIdIncorrectAlignment);
30393042
30403043 LLVMPositionBuilderAtEnd(g->builder, ok_block);
30413044
......@@ -3173,7 +3176,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31733176
31743177 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
31783181 if (array_type->id == TypeTableEntryIdArray) {
31793182 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
......@@ -3184,7 +3187,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31843187 end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);
31853188 }
31863189
3187 if (want_debug_safety) {
3190 if (want_runtime_safety) {
31883191 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
31893192 if (instruction->end) {
31903193 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
31953198 if (!type_has_bits(array_type)) {
31963199 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 field
3201 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field
31993202 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
32003203 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
32013204 return tmp_struct_ptr;
......@@ -3219,7 +3222,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32193222 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
32203223 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
32213224
3222 if (want_debug_safety) {
3225 if (want_runtime_safety) {
32233226 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
32243227 }
32253228
......@@ -3243,7 +3246,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32433246 assert(len_index != SIZE_MAX);
32443247
32453248 LLVMValueRef prev_end = nullptr;
3246 if (!instruction->end || want_debug_safety) {
3249 if (!instruction->end || want_runtime_safety) {
32473250 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
32483251 prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
32493252 }
......@@ -3256,7 +3259,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32563259 end_val = prev_end;
32573260 }
32583261
3259 if (want_debug_safety) {
3262 if (want_runtime_safety) {
32603263 assert(prev_end);
32613264 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
32623265 if (instruction->end) {
......@@ -3429,7 +3432,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
34293432 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
34303433 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) {
34333436 LLVMValueRef err_val;
34343437 if (type_has_bits(child_type)) {
34353438 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
34443447 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
34453448
34463449 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
34493452 LLVMPositionBuilderAtEnd(g->builder, ok_block);
34503453 }
......@@ -3656,7 +3659,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
36563659 case IrInstructionIdToPtrType:
36573660 case IrInstructionIdPtrTypeChild:
36583661 case IrInstructionIdFieldPtr:
3659 case IrInstructionIdSetDebugSafety:
3662 case IrInstructionIdSetCold:
3663 case IrInstructionIdSetRuntimeSafety:
36603664 case IrInstructionIdSetFloatMode:
36613665 case IrInstructionIdArrayType:
36623666 case IrInstructionIdSliceType:
......@@ -5233,7 +5237,8 @@ static void define_builtin_fns(CodeGen *g) {
52335237 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
52345238 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
52355239 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);
52375242 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
52385243 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
52395244 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
......@@ -5788,7 +5793,76 @@ static const char *c_int_type_names[] = {
57885793 "unsigned long long",
57895794};
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) {
57925866 assert(type_entry);
57935867
57945868 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) {
58165890 return;
58175891 }
58185892
5893 prepend_c_type_to_decl_list(g, gen_h, type_entry);
5894
58195895 switch (type_entry->id) {
58205896 case TypeTableEntryIdVoid:
58215897 buf_init_from_str(out_buf, "void");
......@@ -5856,7 +5932,7 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
58565932 {
58575933 Buf child_buf = BUF_INIT;
58585934 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
58615937 const char *const_str = type_entry->data.pointer.is_const ? "const " : "";
58625938 buf_resize(out_buf, 0);
......@@ -5872,23 +5948,47 @@ static void get_c_type(CodeGen *g, TypeTableEntry *type_entry, Buf *out_buf) {
58725948 } else if (child_type->id == TypeTableEntryIdPointer ||
58735949 child_type->id == TypeTableEntryIdFn)
58745950 {
5875 return get_c_type(g, child_type, out_buf);
5951 return get_c_type(g, gen_h, child_type, out_buf);
58765952 } else {
58775953 zig_unreachable();
58785954 }
58795955 }
58805956 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 }
58815974 case TypeTableEntryIdOpaque:
58825975 {
5883 // TODO add to table of structs we need to declare
58845976 buf_init_from_buf(out_buf, &type_entry->name);
58855977 return;
58865978 }
58875979 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 }
58885990 case TypeTableEntryIdErrorUnion:
58895991 case TypeTableEntryIdPureError:
5890 case TypeTableEntryIdEnum:
5891 case TypeTableEntryIdUnion:
58925992 case TypeTableEntryIdFn:
58935993 zig_panic("TODO implement get_c_type for more types");
58945994 case TypeTableEntryIdInvalid:
......@@ -5942,6 +6042,9 @@ static void gen_h_file(CodeGen *g) {
59426042 if (!g->want_h_file)
59436043 return;
59446044
6045 GenH gen_h_data = {0};
6046 GenH *gen_h = &gen_h_data;
6047
59456048 codegen_add_time_event(g, "Generate .h");
59466049
59476050 assert(!g->is_test_build);
......@@ -5971,7 +6074,7 @@ static void gen_h_file(CodeGen *g) {
59716074 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
59726075
59736076 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
59766079 buf_appendf(&h_buf, "%s %s %s(",
59776080 buf_ptr(export_macro),
......@@ -5987,9 +6090,16 @@ static void gen_h_file(CodeGen *g) {
59876090
59886091 const char *comma_str = (param_i == 0) ? "" : ", ";
59896092 const char *restrict_str = param_info->is_noalias ? "restrict" : "";
5990 get_c_type(g, param_info->type, &param_type_c);
5991 buf_appendf(&h_buf, "%s%s%s %s", comma_str, buf_ptr(&param_type_c),
5992 restrict_str, buf_ptr(param_name));
6093 get_c_type(g, gen_h, param_info->type, &param_type_c);
6094
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 }
59936103 }
59946104 buf_appendf(&h_buf, ")");
59956105 } else {
......@@ -6027,6 +6137,85 @@ static void gen_h_file(CodeGen *g) {
60276137 fprintf(out_h, "#endif\n");
60286138 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
60306219 fprintf(out_h, "%s", buf_ptr(&h_buf));
60316220
60326221 fprintf(out_h, "\n#endif\n");
src/ir.cpp+132-69
......@@ -272,8 +272,12 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *)
272272 return IrInstructionIdPtrTypeChild;
273273}
274274
275static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {
276 return IrInstructionIdSetDebugSafety;
275static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
276 return IrInstructionIdSetCold;
277}
278
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) {
280 return IrInstructionIdSetRuntimeSafety;
277281}
278282
279283static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) {
......@@ -1262,15 +1266,22 @@ static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstN
12621266 return &instruction->base;
12631267}
12641268
1265static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
1266 IrInstruction *scope_value, IrInstruction *debug_safety_on)
1269static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) {
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)
12671280{
1268 IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, scope, source_node);
1269 instruction->scope_value = scope_value;
1270 instruction->debug_safety_on = debug_safety_on;
1281 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node);
1282 instruction->safety_on = safety_on;
12711283
1272 ir_ref_instruction(scope_value, irb->current_basic_block);
1273 ir_ref_instruction(debug_safety_on, irb->current_basic_block);
1284 ir_ref_instruction(safety_on, irb->current_basic_block);
12741285
12751286 return &instruction->base;
12761287}
......@@ -3065,19 +3076,23 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
30653076 return arg;
30663077 return ir_build_typeof(irb, scope, node, arg);
30673078 }
3068 case BuiltinFnIdSetDebugSafety:
3079 case BuiltinFnIdSetCold:
30693080 {
30703081 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
30713082 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
30723083 if (arg0_value == irb->codegen->invalid_instruction)
30733084 return arg0_value;
30743085
3075 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
3076 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
3077 if (arg1_value == irb->codegen->invalid_instruction)
3078 return arg1_value;
3086 return ir_build_set_cold(irb, scope, node, arg0_value);
3087 }
3088 case BuiltinFnIdSetRuntimeSafety:
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);
30813096 }
30823097 case BuiltinFnIdSetFloatMode:
30833098 {
......@@ -4769,7 +4784,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
47694784}
47704785
47714786static 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,
47734789 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values)
47744790{
47754791 assert(switch_node->type == NodeTypeSwitchExpr);
......@@ -4786,7 +4802,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
47864802 bool is_shadowable = false;
47874803 bool is_const = true;
47884804 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);
47904806 child_scope = var->child_scope;
47914807 IrInstruction *var_value;
47924808 if (prong_value) {
......@@ -4827,10 +4843,13 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
48274843 ZigList<IrInstructionSwitchBrCase> cases = {0};
48284844
48294845 IrInstruction *is_comptime;
4846 IrInstruction *var_is_comptime;
48304847 if (ir_should_inline(irb->exec, scope)) {
48314848 is_comptime = ir_build_const_bool(irb, scope, node, true);
4849 var_is_comptime = is_comptime;
48324850 } else {
48334851 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);
48344853 }
48354854
48364855 ZigList<IrInstruction *> incoming_values = {0};
......@@ -4856,7 +4875,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
48564875 IrBasicBlock *prev_block = irb->current_basic_block;
48574876 ir_set_cursor_at_end_and_append_block(irb, else_block);
48584877 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))
48604879 {
48614880 return irb->codegen->invalid_instruction;
48624881 }
......@@ -4923,7 +4942,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
49234942
49244943 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
49254944 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))
49274946 {
49284947 return irb->codegen->invalid_instruction;
49294948 }
......@@ -4967,7 +4986,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
49674986 IrBasicBlock *prev_block = irb->current_basic_block;
49684987 ir_set_cursor_at_end_and_append_block(irb, prong_block);
49694988 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))
49714990 {
49724991 return irb->codegen->invalid_instruction;
49734992 }
......@@ -4992,7 +5011,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
49925011
49935012 ir_set_cursor_at_end_and_append_block(irb, end_block);
49945013 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 }
49965019}
49975020
49985021static 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 *
88168839 if (op_id == IrBinOpBitShiftLeftLossy) {
88178840 op_id = IrBinOpBitShiftLeftExact;
88188841 }
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 }
88198849 } else {
88208850 TypeTableEntry *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen,
88218851 op1->value.type->data.integral.bit_count - 1);
......@@ -9002,7 +9032,7 @@ static TypeTableEntry *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp
90029032 int err;
90039033 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, out_val))) {
90049034 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"));
90069036 return ira->codegen->builtin_types.entry_invalid;
90079037 } else if (err == ErrorOverflow) {
90089038 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,
1154011570 return ira->codegen->builtin_types.entry_type;
1154111571}
1154211572
11543static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
11544 IrInstructionSetDebugSafety *set_debug_safety_instruction)
11545{
11546 IrInstruction *target_instruction = set_debug_safety_instruction->scope_value->other;
11547 TypeTableEntry *target_type = target_instruction->value.type;
11548 if (type_is_invalid(target_type))
11573static TypeTableEntry *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) {
11574 if (ira->new_irb.exec->is_inline) {
11575 // ignore setCold when running functions at compile time
11576 ir_build_const_from(ira, &instruction->base);
11577 return ira->codegen->builtin_types.entry_void;
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))
1154911583 return ira->codegen->builtin_types.entry_invalid;
11550 ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad);
11551 if (!target_val)
11584
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"));
1155211588 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{
1155411606 if (ira->new_irb.exec->is_inline) {
11555 // ignore setDebugSafety when running functions at compile time
11556 ir_build_const_from(ira, &set_debug_safety_instruction->base);
11607 // ignore setRuntimeSafety when running functions at compile time
11608 ir_build_const_from(ira, &set_runtime_safety_instruction->base);
1155711609 return ira->codegen->builtin_types.entry_void;
1155811610 }
1155911611
1156011612 bool *safety_off_ptr;
1156111613 AstNode **safety_set_node_ptr;
11562 if (target_type->id == TypeTableEntryIdBlock) {
11563 ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;
11564 safety_off_ptr = &block_scope->safety_off;
11565 safety_set_node_ptr = &block_scope->safety_set_node;
11566 } else if (target_type->id == TypeTableEntryIdFn) {
11567 FnTableEntry *target_fn = target_val->data.x_fn.fn_entry;
11568 assert(target_fn->def_scope);
11569 safety_off_ptr = &target_fn->def_scope->safety_off;
11570 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
11571 } else if (target_type->id == TypeTableEntryIdMetaType) {
11572 ScopeDecls *decls_scope;
11573 TypeTableEntry *type_arg = target_val->data.x_type;
11574 if (type_arg->id == TypeTableEntryIdStruct) {
11575 decls_scope = type_arg->data.structure.decls_scope;
11576 } else if (type_arg->id == TypeTableEntryIdEnum) {
11577 decls_scope = type_arg->data.enumeration.decls_scope;
11578 } else if (type_arg->id == TypeTableEntryIdUnion) {
11579 decls_scope = type_arg->data.unionation.decls_scope;
11614
11615 Scope *scope = set_runtime_safety_instruction->base.scope;
11616 while (scope != nullptr) {
11617 if (scope->id == ScopeIdBlock) {
11618 ScopeBlock *block_scope = (ScopeBlock *)scope;
11619 safety_off_ptr = &block_scope->safety_off;
11620 safety_set_node_ptr = &block_scope->safety_set_node;
11621 break;
11622 } else if (scope->id == ScopeIdFnDef) {
11623 ScopeFnDef *def_scope = (ScopeFnDef *)scope;
11624 FnTableEntry *target_fn = def_scope->fn_entry;
11625 assert(target_fn->def_scope != nullptr);
11626 safety_off_ptr = &target_fn->def_scope->safety_off;
11627 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
11628 break;
11629 } else if (scope->id == ScopeIdDecls) {
11630 ScopeDecls *decls_scope = (ScopeDecls *)scope;
11631 safety_off_ptr = &decls_scope->safety_off;
11632 safety_set_node_ptr = &decls_scope->safety_set_node;
11633 break;
1158011634 } else {
11581 ir_add_error_node(ira, target_instruction->source_node,
11582 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
11583 return ira->codegen->builtin_types.entry_invalid;
11635 scope = scope->parent;
11636 continue;
1158411637 }
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;
1159111638 }
11639 assert(scope != nullptr);
1159211640
11593 IrInstruction *debug_safety_on_value = set_debug_safety_instruction->debug_safety_on->other;
11594 bool want_debug_safety;
11595 if (!ir_resolve_bool(ira, debug_safety_on_value, &want_debug_safety))
11641 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->other;
11642 bool want_runtime_safety;
11643 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety))
1159611644 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;
1159911647 if (*safety_set_node_ptr) {
1160011648 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"));
1160211650 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));
1160311651 return ira->codegen->builtin_types.entry_invalid;
1160411652 }
1160511653 *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);
1160911657 return ira->codegen->builtin_types.entry_void;
1161011658}
1161111659
......@@ -12243,11 +12291,18 @@ static TypeTableEntry *ir_analyze_instruction_switch_target(IrAnalyze *ira,
1224312291 }
1224412292 TypeTableEntry *tag_type = target_type->data.unionation.tag_type;
1224512293 assert(tag_type != nullptr);
12294 assert(tag_type->id == TypeTableEntryIdEnum);
1224612295 if (pointee_val) {
1224712296 ConstExprValue *out_val = ir_build_const_from(ira, &switch_target_instruction->base);
1224812297 bigint_init_bigint(&out_val->data.x_enum_tag, &pointee_val->data.x_union.tag);
1224912298 return tag_type;
1225012299 }
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
1225212307 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope,
1225312308 switch_target_instruction->base.source_node, target_value_ptr);
......@@ -14499,6 +14554,11 @@ static TypeTableEntry *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructio
1449914554 if (type_is_invalid(msg->value.type))
1450014555 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
1450214562 TypeTableEntry *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, true);
1450314563 TypeTableEntry *str_type = get_slice_type(ira->codegen, u8_ptr_type);
1450414564 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type);
......@@ -15212,8 +15272,10 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1521215272 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction);
1521315273 case IrInstructionIdPtrTypeChild:
1521415274 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
15215 case IrInstructionIdSetDebugSafety:
15216 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
15275 case IrInstructionIdSetCold:
15276 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
15277 case IrInstructionIdSetRuntimeSafety:
15278 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
1521715279 case IrInstructionIdSetFloatMode:
1521815280 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
1521915281 case IrInstructionIdSliceType:
......@@ -15448,7 +15510,8 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1544815510 case IrInstructionIdCall:
1544915511 case IrInstructionIdReturn:
1545015512 case IrInstructionIdUnreachable:
15451 case IrInstructionIdSetDebugSafety:
15513 case IrInstructionIdSetCold:
15514 case IrInstructionIdSetRuntimeSafety:
1545215515 case IrInstructionIdSetFloatMode:
1545315516 case IrInstructionIdImport:
1545415517 case IrInstructionIdCompileErr:
src/ir_print.cpp+14-7
......@@ -368,11 +368,15 @@ static void ir_print_union_field_ptr(IrPrint *irp, IrInstructionUnionFieldPtr *i
368368 fprintf(irp->f, ")");
369369}
370370
371static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {
372 fprintf(irp->f, "@setDebugSafety(");
373 ir_print_other_instruction(irp, instruction->scope_value);
374 fprintf(irp->f, ", ");
375 ir_print_other_instruction(irp, instruction->debug_safety_on);
371static void ir_print_set_cold(IrPrint *irp, IrInstructionSetCold *instruction) {
372 fprintf(irp->f, "@setCold(");
373 ir_print_other_instruction(irp, instruction->is_cold);
374 fprintf(irp->f, ")");
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);
376380 fprintf(irp->f, ")");
377381}
378382
......@@ -1081,8 +1085,11 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10811085 case IrInstructionIdUnionFieldPtr:
10821086 ir_print_union_field_ptr(irp, (IrInstructionUnionFieldPtr *)instruction);
10831087 break;
1084 case IrInstructionIdSetDebugSafety:
1085 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);
1088 case IrInstructionIdSetCold:
1089 ir_print_set_cold(irp, (IrInstructionSetCold *)instruction);
1090 break;
1091 case IrInstructionIdSetRuntimeSafety:
1092 ir_print_set_runtime_safety(irp, (IrInstructionSetRuntimeSafety *)instruction);
10861093 break;
10871094 case IrInstructionIdSetFloatMode:
10881095 ir_print_set_float_mode(irp, (IrInstructionSetFloatMode *)instruction);
src/main.cpp+1-1
......@@ -462,7 +462,7 @@ int main(int argc, char **argv) {
462462 Termination term;
463463 os_spawn_process(buf_ptr(path_to_build_exe), args, &term);
464464 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");
466466 fprintf(stderr, "%s", buf_ptr(path_to_build_exe));
467467 for (size_t i = 0; i < args.length; i += 1) {
468468 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,
390390
391391#if defined(ZIG_OS_WINDOWS)
392392
393/*
394static void win32_panic(const char *str) {
395 DWORD err = GetLastError();
396 LPSTR messageBuffer = nullptr;
397 FormatMessageA(
398 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
399 NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
400 zig_panic(str, messageBuffer);
401 LocalFree(messageBuffer);
402}
403*/
393//static void win32_panic(const char *str) {
394// DWORD err = GetLastError();
395// LPSTR messageBuffer = nullptr;
396// FormatMessageA(
397// 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// zig_panic(str, messageBuffer);
400// LocalFree(messageBuffer);
401//}
404402
405403static int os_exec_process_windows(const char *exe, ZigList<const char *> &args,
406404 Termination *term, Buf *out_stderr, Buf *out_stdout)
......@@ -794,9 +792,18 @@ int os_delete_file(Buf *path) {
794792}
795793
796794int 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
797803 if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {
798804 return ErrorFileSystem;
799805 }
806#endif
800807 return 0;
801808}
802809
src/parser.cpp+8-27
......@@ -84,11 +84,6 @@ static AstNode *ast_create_node(ParseContext *pc, NodeType type, Token *first_to
8484 return node;
8585}
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
9388static void parse_asm_template(ParseContext *pc, AstNode *node) {
9489 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) {
14951490}
14961491
14971492/*
1498Defer(body) = option("%") "defer" body
1493Defer(body) = ("defer" | "errdefer") body
14991494*/
15001495static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
15011496 Token *token = &pc->tokens->at(*token_index);
......@@ -1503,15 +1498,10 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
15031498 NodeType node_type;
15041499 ReturnKind kind;
15051500
1506 if (token->id == TokenIdPercent) {
1507 Token *next_token = &pc->tokens->at(*token_index + 1);
1508 if (next_token->id == TokenIdKeywordDefer) {
1509 kind = ReturnKindError;
1510 node_type = NodeTypeDefer;
1511 *token_index += 2;
1512 } else {
1513 return nullptr;
1514 }
1501 if (token->id == TokenIdKeywordErrdefer) {
1502 kind = ReturnKindError;
1503 node_type = NodeTypeDefer;
1504 *token_index += 1;
15151505 } else if (token->id == TokenIdKeywordDefer) {
15161506 kind = ReturnKindUnconditional;
15171507 node_type = NodeTypeDefer;
......@@ -2250,7 +2240,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
22502240}
22512241
22522242/*
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
22542244*/
22552245static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
22562246 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
22582248
22592249 CallingConvention cc;
22602250 bool is_extern = false;
2261 if (first_token->id == TokenIdKeywordColdCC) {
2262 *token_index += 1;
2263 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
2264 cc = CallingConventionCold;
2265 } else if (first_token->id == TokenIdKeywordNakedCC) {
2251 if (first_token->id == TokenIdKeywordNakedCC) {
22662252 *token_index += 1;
22672253 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
22682254 cc = CallingConventionNaked;
......@@ -2329,12 +2315,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
23292315 ast_eat_token(pc, token_index, TokenIdRParen);
23302316 next_token = &pc->tokens->at(*token_index);
23312317 }
2332 if (next_token->id == TokenIdArrow) {
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 }
2318 node->data.fn_proto.return_type = ast_parse_type_expr(pc, token_index, true);
23382319
23392320 return node;
23402321}
src/tokenizer.cpp+2-2
......@@ -112,13 +112,13 @@ static const struct ZigKeyword zig_keywords[] = {
112112 {"asm", TokenIdKeywordAsm},
113113 {"break", TokenIdKeywordBreak},
114114 {"catch", TokenIdKeywordCatch},
115 {"coldcc", TokenIdKeywordColdCC},
116115 {"comptime", TokenIdKeywordCompTime},
117116 {"const", TokenIdKeywordConst},
118117 {"continue", TokenIdKeywordContinue},
119118 {"defer", TokenIdKeywordDefer},
120119 {"else", TokenIdKeywordElse},
121120 {"enum", TokenIdKeywordEnum},
121 {"errdefer", TokenIdKeywordErrdefer},
122122 {"error", TokenIdKeywordError},
123123 {"export", TokenIdKeywordExport},
124124 {"extern", TokenIdKeywordExtern},
......@@ -1509,13 +1509,13 @@ const char * token_name(TokenId id) {
15091509 case TokenIdKeywordAsm: return "asm";
15101510 case TokenIdKeywordBreak: return "break";
15111511 case TokenIdKeywordCatch: return "catch";
1512 case TokenIdKeywordColdCC: return "coldcc";
15131512 case TokenIdKeywordCompTime: return "comptime";
15141513 case TokenIdKeywordConst: return "const";
15151514 case TokenIdKeywordContinue: return "continue";
15161515 case TokenIdKeywordDefer: return "defer";
15171516 case TokenIdKeywordElse: return "else";
15181517 case TokenIdKeywordEnum: return "enum";
1518 case TokenIdKeywordErrdefer: return "errdefer";
15191519 case TokenIdKeywordError: return "error";
15201520 case TokenIdKeywordExport: return "export";
15211521 case TokenIdKeywordExtern: return "extern";
src/tokenizer.hpp+1-1
......@@ -51,13 +51,13 @@ enum TokenId {
5151 TokenIdKeywordAsm,
5252 TokenIdKeywordBreak,
5353 TokenIdKeywordCatch,
54 TokenIdKeywordColdCC,
5554 TokenIdKeywordCompTime,
5655 TokenIdKeywordConst,
5756 TokenIdKeywordContinue,
5857 TokenIdKeywordDefer,
5958 TokenIdKeywordElse,
6059 TokenIdKeywordEnum,
60 TokenIdKeywordErrdefer,
6161 TokenIdKeywordError,
6262 TokenIdKeywordExport,
6363 TokenIdKeywordExtern,
src/translate_c.cpp+1-1
......@@ -922,7 +922,7 @@ static AstNode *trans_type(Context *c, const Type *ty, const SourceLocation &sou
922922 // void foo(void) -> Foo;
923923 // we want to keep the return type AST node.
924924 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");
926926 }
927927 }
928928
std/array_list.zig+16-16
......@@ -4,11 +4,11 @@ const assert = debug.assert;
44const mem = std.mem;
55const Allocator = mem.Allocator;
66
7pub fn ArrayList(comptime T: type) -> type {
7pub fn ArrayList(comptime T: type) type {
88 return AlignedArrayList(T, @alignOf(T));
99}
1010
11pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
11pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
1212 return struct {
1313 const Self = this;
1414
......@@ -20,7 +20,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
2020 allocator: &Allocator,
2121
2222 /// Deinitialize with `deinit` or use `toOwnedSlice`.
23 pub fn init(allocator: &Allocator) -> Self {
23 pub fn init(allocator: &Allocator) Self {
2424 return Self {
2525 .items = []align(A) T{},
2626 .len = 0,
......@@ -28,22 +28,22 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
2828 };
2929 }
3030
31 pub fn deinit(l: &Self) {
31 pub fn deinit(l: &Self) void {
3232 l.allocator.free(l.items);
3333 }
3434
35 pub fn toSlice(l: &Self) -> []align(A) T {
35 pub fn toSlice(l: &Self) []align(A) T {
3636 return l.items[0..l.len];
3737 }
3838
39 pub fn toSliceConst(l: &const Self) -> []align(A) const T {
39 pub fn toSliceConst(l: &const Self) []align(A) const T {
4040 return l.items[0..l.len];
4141 }
4242
4343 /// ArrayList takes ownership of the passed in slice. The slice must have been
4444 /// allocated with `allocator`.
4545 /// 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 {
4747 return Self {
4848 .items = slice,
4949 .len = slice.len,
......@@ -52,35 +52,35 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
5252 }
5353
5454 /// 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 {
5656 const allocator = self.allocator;
5757 const result = allocator.alignedShrink(T, A, self.items, self.len);
5858 *self = init(allocator);
5959 return result;
6060 }
6161
62 pub fn append(l: &Self, item: &const T) -> %void {
62 pub fn append(l: &Self, item: &const T) %void {
6363 const new_item_ptr = try l.addOne();
6464 *new_item_ptr = *item;
6565 }
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 {
6868 try l.ensureCapacity(l.len + items.len);
6969 mem.copy(T, l.items[l.len..], items);
7070 l.len += items.len;
7171 }
7272
73 pub fn resize(l: &Self, new_len: usize) -> %void {
73 pub fn resize(l: &Self, new_len: usize) %void {
7474 try l.ensureCapacity(new_len);
7575 l.len = new_len;
7676 }
7777
78 pub fn shrink(l: &Self, new_len: usize) {
78 pub fn shrink(l: &Self, new_len: usize) void {
7979 assert(new_len <= l.len);
8080 l.len = new_len;
8181 }
8282
83 pub fn ensureCapacity(l: &Self, new_capacity: usize) -> %void {
83 pub fn ensureCapacity(l: &Self, new_capacity: usize) %void {
8484 var better_capacity = l.items.len;
8585 if (better_capacity >= new_capacity) return;
8686 while (true) {
......@@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
9090 l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
9191 }
9292
93 pub fn addOne(l: &Self) -> %&T {
93 pub fn addOne(l: &Self) %&T {
9494 const new_length = l.len + 1;
9595 try l.ensureCapacity(new_length);
9696 const result = &l.items[l.len];
......@@ -98,12 +98,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
9898 return result;
9999 }
100100
101 pub fn pop(self: &Self) -> T {
101 pub fn pop(self: &Self) T {
102102 self.len -= 1;
103103 return self.items[self.len];
104104 }
105105
106 pub fn popOrNull(self: &Self) -> ?T {
106 pub fn popOrNull(self: &Self) ?T {
107107 if (self.len == 0)
108108 return null;
109109 return self.pop();
std/base64.zig+18-18
......@@ -11,7 +11,7 @@ pub const Base64Encoder = struct {
1111 pad_char: u8,
1212
1313 /// 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 {
1515 assert(alphabet_chars.len == 64);
1616 var char_in_alphabet = []bool{false} ** 256;
1717 for (alphabet_chars) |c| {
......@@ -27,12 +27,12 @@ pub const Base64Encoder = struct {
2727 }
2828
2929 /// ceil(source_len * 4/3)
30 pub fn calcSize(source_len: usize) -> usize {
30 pub fn calcSize(source_len: usize) usize {
3131 return @divTrunc(source_len + 2, 3) * 4;
3232 }
3333
3434 /// 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 {
3636 assert(dest.len == Base64Encoder.calcSize(source.len));
3737
3838 var i: usize = 0;
......@@ -90,7 +90,7 @@ pub const Base64Decoder = struct {
9090 char_in_alphabet: [256]bool,
9191 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 {
9494 assert(alphabet_chars.len == 64);
9595
9696 var result = Base64Decoder{
......@@ -111,7 +111,7 @@ pub const Base64Decoder = struct {
111111 }
112112
113113 /// 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 {
115115 if (source.len % 4 != 0) return error.InvalidPadding;
116116 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
117117 }
......@@ -119,7 +119,7 @@ pub const Base64Decoder = struct {
119119 /// dest.len must be what you get from ::calcSize.
120120 /// invalid characters result in error.InvalidCharacter.
121121 /// 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 {
123123 assert(dest.len == (decoder.calcSize(source) catch unreachable));
124124 assert(source.len % 4 == 0);
125125
......@@ -168,7 +168,7 @@ error OutputTooSmall;
168168pub const Base64DecoderWithIgnore = struct {
169169 decoder: Base64Decoder,
170170 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 {
172172 var result = Base64DecoderWithIgnore {
173173 .decoder = Base64Decoder.init(alphabet_chars, pad_char),
174174 .char_is_ignored = []bool{false} ** 256,
......@@ -185,7 +185,7 @@ pub const Base64DecoderWithIgnore = struct {
185185 }
186186
187187 /// 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 {
189189 return @divTrunc(encoded_len, 4) * 3;
190190 }
191191
......@@ -193,7 +193,7 @@ pub const Base64DecoderWithIgnore = struct {
193193 /// Invalid padding results in error.InvalidPadding.
194194 /// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
195195 /// 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 {
197197 const decoder = &decoder_with_ignore.decoder;
198198
199199 var src_cursor: usize = 0;
......@@ -293,7 +293,7 @@ pub const Base64DecoderUnsafe = struct {
293293 char_to_index: [256]u8,
294294 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 {
297297 assert(alphabet_chars.len == 64);
298298 var result = Base64DecoderUnsafe {
299299 .char_to_index = undefined,
......@@ -307,13 +307,13 @@ pub const Base64DecoderUnsafe = struct {
307307 }
308308
309309 /// 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 {
311311 return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
312312 }
313313
314314 /// dest.len must be what you get from ::calcDecodedSizeExactUnsafe.
315315 /// 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 {
317317 assert(dest.len == decoder.calcSize(source));
318318
319319 var src_index: usize = 0;
......@@ -359,7 +359,7 @@ pub const Base64DecoderUnsafe = struct {
359359 }
360360};
361361
362fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) -> usize {
362fn calcDecodedSizeExactUnsafe(source: []const u8, pad_char: u8) usize {
363363 if (source.len == 0) return 0;
364364 var result = @divExact(source.len, 4) * 3;
365365 if (source[source.len - 1] == pad_char) {
......@@ -378,7 +378,7 @@ test "base64" {
378378 comptime (testBase64() catch unreachable);
379379}
380380
381fn testBase64() -> %void {
381fn testBase64() %void {
382382 try testAllApis("", "");
383383 try testAllApis("f", "Zg==");
384384 try testAllApis("fo", "Zm8=");
......@@ -412,7 +412,7 @@ fn testBase64() -> %void {
412412 try testOutputTooSmallError("AAAAAA==");
413413}
414414
415fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void {
415fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void {
416416 // Base64Encoder
417417 {
418418 var buffer: [0x100]u8 = undefined;
......@@ -449,7 +449,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v
449449 }
450450}
451451
452fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %void {
452fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %void {
453453 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
454454 standard_alphabet_chars, standard_pad_char, " ");
455455 var buffer: [0x100]u8 = undefined;
......@@ -459,7 +459,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %
459459}
460460
461461error ExpectedError;
462fn testError(encoded: []const u8, expected_err: error) -> %void {
462fn testError(encoded: []const u8, expected_err: error) %void {
463463 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
464464 standard_alphabet_chars, standard_pad_char, " ");
465465 var buffer: [0x100]u8 = undefined;
......@@ -475,7 +475,7 @@ fn testError(encoded: []const u8, expected_err: error) -> %void {
475475 } else |err| if (err != expected_err) return err;
476476}
477477
478fn testOutputTooSmallError(encoded: []const u8) -> %void {
478fn testOutputTooSmallError(encoded: []const u8) %void {
479479 const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
480480 standard_alphabet_chars, standard_pad_char, " ");
481481 var buffer: [0x100]u8 = undefined;
std/buf_map.zig+12-12
......@@ -9,14 +9,14 @@ pub const BufMap = struct {
99
1010 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 {
1313 var self = BufMap {
1414 .hash_map = BufMapHashMap.init(allocator),
1515 };
1616 return self;
1717 }
1818
19 pub fn deinit(self: &BufMap) {
19 pub fn deinit(self: &BufMap) void {
2020 var it = self.hash_map.iterator();
2121 while (true) {
2222 const entry = it.next() ?? break;
......@@ -27,47 +27,47 @@ pub const BufMap = struct {
2727 self.hash_map.deinit();
2828 }
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 {
3131 if (self.hash_map.get(key)) |entry| {
3232 const value_copy = try self.copy(value);
33 %defer self.free(value_copy);
33 errdefer self.free(value_copy);
3434 _ = try self.hash_map.put(key, value_copy);
3535 self.free(entry.value);
3636 } else {
3737 const key_copy = try self.copy(key);
38 %defer self.free(key_copy);
38 errdefer self.free(key_copy);
3939 const value_copy = try self.copy(value);
40 %defer self.free(value_copy);
40 errdefer self.free(value_copy);
4141 _ = try self.hash_map.put(key_copy, value_copy);
4242 }
4343 }
4444
45 pub fn get(self: &BufMap, key: []const u8) -> ?[]const u8 {
45 pub fn get(self: &BufMap, key: []const u8) ?[]const u8 {
4646 const entry = self.hash_map.get(key) ?? return null;
4747 return entry.value;
4848 }
4949
50 pub fn delete(self: &BufMap, key: []const u8) {
50 pub fn delete(self: &BufMap, key: []const u8) void {
5151 const entry = self.hash_map.remove(key) ?? return;
5252 self.free(entry.key);
5353 self.free(entry.value);
5454 }
5555
56 pub fn count(self: &const BufMap) -> usize {
56 pub fn count(self: &const BufMap) usize {
5757 return self.hash_map.size;
5858 }
5959
60 pub fn iterator(self: &const BufMap) -> BufMapHashMap.Iterator {
60 pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
6161 return self.hash_map.iterator();
6262 }
6363
64 fn free(self: &BufMap, value: []const u8) {
64 fn free(self: &BufMap, value: []const u8) void {
6565 // remove the const
6666 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
6767 self.hash_map.allocator.free(mut_value);
6868 }
6969
70 fn copy(self: &BufMap, value: []const u8) -> %[]const u8 {
70 fn copy(self: &BufMap, value: []const u8) %[]const u8 {
7171 const result = try self.hash_map.allocator.alloc(u8, value.len);
7272 mem.copy(u8, result, value);
7373 return result;
std/buf_set.zig+10-10
......@@ -7,14 +7,14 @@ pub const BufSet = struct {
77
88 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 {
1111 var self = BufSet {
1212 .hash_map = BufSetHashMap.init(a),
1313 };
1414 return self;
1515 }
1616
17 pub fn deinit(self: &BufSet) {
17 pub fn deinit(self: &BufSet) void {
1818 var it = self.hash_map.iterator();
1919 while (true) {
2020 const entry = it.next() ?? break;
......@@ -24,38 +24,38 @@ pub const BufSet = struct {
2424 self.hash_map.deinit();
2525 }
2626
27 pub fn put(self: &BufSet, key: []const u8) -> %void {
27 pub fn put(self: &BufSet, key: []const u8) %void {
2828 if (self.hash_map.get(key) == null) {
2929 const key_copy = try self.copy(key);
30 %defer self.free(key_copy);
30 errdefer self.free(key_copy);
3131 _ = try self.hash_map.put(key_copy, {});
3232 }
3333 }
3434
35 pub fn delete(self: &BufSet, key: []const u8) {
35 pub fn delete(self: &BufSet, key: []const u8) void {
3636 const entry = self.hash_map.remove(key) ?? return;
3737 self.free(entry.key);
3838 }
3939
40 pub fn count(self: &const BufSet) -> usize {
40 pub fn count(self: &const BufSet) usize {
4141 return self.hash_map.size;
4242 }
4343
44 pub fn iterator(self: &const BufSet) -> BufSetHashMap.Iterator {
44 pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
4545 return self.hash_map.iterator();
4646 }
4747
48 pub fn allocator(self: &const BufSet) -> &Allocator {
48 pub fn allocator(self: &const BufSet) &Allocator {
4949 return self.hash_map.allocator;
5050 }
5151
52 fn free(self: &BufSet, value: []const u8) {
52 fn free(self: &BufSet, value: []const u8) void {
5353 // remove the const
5454 const mut_value = @ptrCast(&u8, value.ptr)[0..value.len];
5555 self.hash_map.allocator.free(mut_value);
5656 }
5757
58 fn copy(self: &BufSet, value: []const u8) -> %[]const u8 {
58 fn copy(self: &BufSet, value: []const u8) %[]const u8 {
5959 const result = try self.hash_map.allocator.alloc(u8, value.len);
6060 mem.copy(u8, result, value);
6161 return result;
std/buffer.zig+22-22
......@@ -12,14 +12,14 @@ pub const Buffer = struct {
1212 list: ArrayList(u8),
1313
1414 /// Must deinitialize with deinit.
15 pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {
15 pub fn init(allocator: &Allocator, m: []const u8) %Buffer {
1616 var self = try initSize(allocator, m.len);
1717 mem.copy(u8, self.list.items, m);
1818 return self;
1919 }
2020
2121 /// Must deinitialize with deinit.
22 pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {
22 pub fn initSize(allocator: &Allocator, size: usize) %Buffer {
2323 var self = initNull(allocator);
2424 try self.resize(size);
2525 return self;
......@@ -30,21 +30,21 @@ pub const Buffer = struct {
3030 /// * ::replaceContents
3131 /// * ::replaceContentsBuffer
3232 /// * ::resize
33 pub fn initNull(allocator: &Allocator) -> Buffer {
33 pub fn initNull(allocator: &Allocator) Buffer {
3434 return Buffer {
3535 .list = ArrayList(u8).init(allocator),
3636 };
3737 }
3838
3939 /// Must deinitialize with deinit.
40 pub fn initFromBuffer(buffer: &const Buffer) -> %Buffer {
40 pub fn initFromBuffer(buffer: &const Buffer) %Buffer {
4141 return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
4242 }
4343
4444 /// Buffer takes ownership of the passed in slice. The slice must have been
4545 /// allocated with `allocator`.
4646 /// Must deinitialize with deinit.
47 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) -> Buffer {
47 pub fn fromOwnedSlice(allocator: &Allocator, slice: []u8) Buffer {
4848 var self = Buffer {
4949 .list = ArrayList(u8).fromOwnedSlice(allocator, slice),
5050 };
......@@ -54,7 +54,7 @@ pub const Buffer = struct {
5454
5555 /// The caller owns the returned memory. The Buffer becomes null and
5656 /// is safe to `deinit`.
57 pub fn toOwnedSlice(self: &Buffer) -> []u8 {
57 pub fn toOwnedSlice(self: &Buffer) []u8 {
5858 const allocator = self.list.allocator;
5959 const result = allocator.shrink(u8, self.list.items, self.len());
6060 *self = initNull(allocator);
......@@ -62,55 +62,55 @@ pub const Buffer = struct {
6262 }
6363
6464
65 pub fn deinit(self: &Buffer) {
65 pub fn deinit(self: &Buffer) void {
6666 self.list.deinit();
6767 }
6868
69 pub fn toSlice(self: &Buffer) -> []u8 {
69 pub fn toSlice(self: &Buffer) []u8 {
7070 return self.list.toSlice()[0..self.len()];
7171 }
7272
73 pub fn toSliceConst(self: &const Buffer) -> []const u8 {
73 pub fn toSliceConst(self: &const Buffer) []const u8 {
7474 return self.list.toSliceConst()[0..self.len()];
7575 }
7676
77 pub fn shrink(self: &Buffer, new_len: usize) {
77 pub fn shrink(self: &Buffer, new_len: usize) void {
7878 assert(new_len <= self.len());
7979 self.list.shrink(new_len + 1);
8080 self.list.items[self.len()] = 0;
8181 }
8282
83 pub fn resize(self: &Buffer, new_len: usize) -> %void {
83 pub fn resize(self: &Buffer, new_len: usize) %void {
8484 try self.list.resize(new_len + 1);
8585 self.list.items[self.len()] = 0;
8686 }
8787
88 pub fn isNull(self: &const Buffer) -> bool {
88 pub fn isNull(self: &const Buffer) bool {
8989 return self.list.len == 0;
9090 }
9191
92 pub fn len(self: &const Buffer) -> usize {
92 pub fn len(self: &const Buffer) usize {
9393 return self.list.len - 1;
9494 }
9595
96 pub fn append(self: &Buffer, m: []const u8) -> %void {
96 pub fn append(self: &Buffer, m: []const u8) %void {
9797 const old_len = self.len();
9898 try self.resize(old_len + m.len);
9999 mem.copy(u8, self.list.toSlice()[old_len..], m);
100100 }
101101
102102 // 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 {
104104 return fmt.format(self, append, format, args);
105105 }
106106
107107 // TODO: remove, use OutStream for this
108 pub fn appendByte(self: &Buffer, byte: u8) -> %void {
108 pub fn appendByte(self: &Buffer, byte: u8) %void {
109109 return self.appendByteNTimes(byte, 1);
110110 }
111111
112112 // 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 {
114114 var prev_size: usize = self.len();
115115 const new_size = prev_size + count;
116116 try self.resize(new_size);
......@@ -121,29 +121,29 @@ pub const Buffer = struct {
121121 }
122122 }
123123
124 pub fn eql(self: &const Buffer, m: []const u8) -> bool {
124 pub fn eql(self: &const Buffer, m: []const u8) bool {
125125 return mem.eql(u8, self.toSliceConst(), m);
126126 }
127127
128 pub fn startsWith(self: &const Buffer, m: []const u8) -> bool {
128 pub fn startsWith(self: &const Buffer, m: []const u8) bool {
129129 if (self.len() < m.len) return false;
130130 return mem.eql(u8, self.list.items[0..m.len], m);
131131 }
132132
133 pub fn endsWith(self: &const Buffer, m: []const u8) -> bool {
133 pub fn endsWith(self: &const Buffer, m: []const u8) bool {
134134 const l = self.len();
135135 if (l < m.len) return false;
136136 const start = l - m.len;
137137 return mem.eql(u8, self.list.items[start..l], m);
138138 }
139139
140 pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {
140 pub fn replaceContents(self: &const Buffer, m: []const u8) %void {
141141 try self.resize(m.len);
142142 mem.copy(u8, self.list.toSlice(), m);
143143 }
144144
145145 /// For passing to C functions.
146 pub fn ptr(self: &const Buffer) -> &u8 {
146 pub fn ptr(self: &const Buffer) &u8 {
147147 return self.list.items.ptr;
148148 }
149149};
std/build.zig+124-124
......@@ -90,7 +90,7 @@ pub const Builder = struct {
9090 };
9191
9292 pub fn init(allocator: &Allocator, zig_exe: []const u8, build_root: []const u8,
93 cache_root: []const u8) -> Builder
93 cache_root: []const u8) Builder
9494 {
9595 var self = Builder {
9696 .zig_exe = zig_exe,
......@@ -136,7 +136,7 @@ pub const Builder = struct {
136136 return self;
137137 }
138138
139 pub fn deinit(self: &Builder) {
139 pub fn deinit(self: &Builder) void {
140140 self.lib_paths.deinit();
141141 self.include_paths.deinit();
142142 self.rpaths.deinit();
......@@ -144,85 +144,85 @@ pub const Builder = struct {
144144 self.top_level_steps.deinit();
145145 }
146146
147 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) {
147 pub fn setInstallPrefix(self: &Builder, maybe_prefix: ?[]const u8) void {
148148 self.prefix = maybe_prefix ?? "/usr/local"; // TODO better default
149149 self.lib_dir = os.path.join(self.allocator, self.prefix, "lib") catch unreachable;
150150 self.exe_dir = os.path.join(self.allocator, self.prefix, "bin") catch unreachable;
151151 }
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 {
154154 return LibExeObjStep.createExecutable(self, name, root_src);
155155 }
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 {
158158 return LibExeObjStep.createObject(self, name, root_src);
159159 }
160160
161161 pub fn addSharedLibrary(self: &Builder, name: []const u8, root_src: ?[]const u8,
162 ver: &const Version) -> &LibExeObjStep
162 ver: &const Version) &LibExeObjStep
163163 {
164164 return LibExeObjStep.createSharedLibrary(self, name, root_src, ver);
165165 }
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 {
168168 return LibExeObjStep.createStaticLibrary(self, name, root_src);
169169 }
170170
171 pub fn addTest(self: &Builder, root_src: []const u8) -> &TestStep {
171 pub fn addTest(self: &Builder, root_src: []const u8) &TestStep {
172172 const test_step = self.allocator.create(TestStep) catch unreachable;
173173 *test_step = TestStep.init(self, root_src);
174174 return test_step;
175175 }
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 {
178178 const obj_step = LibExeObjStep.createObject(self, name, null);
179179 obj_step.addAssemblyFile(src);
180180 return obj_step;
181181 }
182182
183 pub fn addCStaticLibrary(self: &Builder, name: []const u8) -> &LibExeObjStep {
183 pub fn addCStaticLibrary(self: &Builder, name: []const u8) &LibExeObjStep {
184184 return LibExeObjStep.createCStaticLibrary(self, name);
185185 }
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 {
188188 return LibExeObjStep.createCSharedLibrary(self, name, ver);
189189 }
190190
191 pub fn addCExecutable(self: &Builder, name: []const u8) -> &LibExeObjStep {
191 pub fn addCExecutable(self: &Builder, name: []const u8) &LibExeObjStep {
192192 return LibExeObjStep.createCExecutable(self, name);
193193 }
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 {
196196 return LibExeObjStep.createCObject(self, name, src);
197197 }
198198
199199 /// ::argv is copied.
200200 pub fn addCommand(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
201 argv: []const []const u8) -> &CommandStep
201 argv: []const []const u8) &CommandStep
202202 {
203203 return CommandStep.create(self, cwd, env_map, argv);
204204 }
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 {
207207 const write_file_step = self.allocator.create(WriteFileStep) catch unreachable;
208208 *write_file_step = WriteFileStep.init(self, file_path, data);
209209 return write_file_step;
210210 }
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 {
213213 const data = self.fmt(format, args);
214214 const log_step = self.allocator.create(LogStep) catch unreachable;
215215 *log_step = LogStep.init(self, data);
216216 return log_step;
217217 }
218218
219 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) -> &RemoveDirStep {
219 pub fn addRemoveDirTree(self: &Builder, dir_path: []const u8) &RemoveDirStep {
220220 const remove_dir_step = self.allocator.create(RemoveDirStep) catch unreachable;
221221 *remove_dir_step = RemoveDirStep.init(self, dir_path);
222222 return remove_dir_step;
223223 }
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 {
226226 return Version {
227227 .major = major,
228228 .minor = minor,
......@@ -230,19 +230,19 @@ pub const Builder = struct {
230230 };
231231 }
232232
233 pub fn addCIncludePath(self: &Builder, path: []const u8) {
233 pub fn addCIncludePath(self: &Builder, path: []const u8) void {
234234 self.include_paths.append(path) catch unreachable;
235235 }
236236
237 pub fn addRPath(self: &Builder, path: []const u8) {
237 pub fn addRPath(self: &Builder, path: []const u8) void {
238238 self.rpaths.append(path) catch unreachable;
239239 }
240240
241 pub fn addLibPath(self: &Builder, path: []const u8) {
241 pub fn addLibPath(self: &Builder, path: []const u8) void {
242242 self.lib_paths.append(path) catch unreachable;
243243 }
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 {
246246 var wanted_steps = ArrayList(&Step).init(self.allocator);
247247 defer wanted_steps.deinit();
248248
......@@ -260,7 +260,7 @@ pub const Builder = struct {
260260 }
261261 }
262262
263 pub fn getInstallStep(self: &Builder) -> &Step {
263 pub fn getInstallStep(self: &Builder) &Step {
264264 if (self.have_install_step)
265265 return &self.install_tls.step;
266266
......@@ -269,7 +269,7 @@ pub const Builder = struct {
269269 return &self.install_tls.step;
270270 }
271271
272 pub fn getUninstallStep(self: &Builder) -> &Step {
272 pub fn getUninstallStep(self: &Builder) &Step {
273273 if (self.have_uninstall_step)
274274 return &self.uninstall_tls.step;
275275
......@@ -278,7 +278,7 @@ pub const Builder = struct {
278278 return &self.uninstall_tls.step;
279279 }
280280
281 fn makeUninstall(uninstall_step: &Step) -> %void {
281 fn makeUninstall(uninstall_step: &Step) %void {
282282 const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
283283 const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
284284
......@@ -292,7 +292,7 @@ pub const Builder = struct {
292292 // TODO remove empty directories
293293 }
294294
295 fn makeOneStep(self: &Builder, s: &Step) -> %void {
295 fn makeOneStep(self: &Builder, s: &Step) %void {
296296 if (s.loop_flag) {
297297 warn("Dependency loop detected:\n {}\n", s.name);
298298 return error.DependencyLoopDetected;
......@@ -313,7 +313,7 @@ pub const Builder = struct {
313313 try s.make();
314314 }
315315
316 fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step {
316 fn getTopLevelStepByName(self: &Builder, name: []const u8) %&Step {
317317 for (self.top_level_steps.toSliceConst()) |top_level_step| {
318318 if (mem.eql(u8, top_level_step.step.name, name)) {
319319 return &top_level_step.step;
......@@ -323,7 +323,7 @@ pub const Builder = struct {
323323 return error.InvalidStepName;
324324 }
325325
326 fn processNixOSEnvVars(self: &Builder) {
326 fn processNixOSEnvVars(self: &Builder) void {
327327 if (os.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
328328 var it = mem.split(nix_cflags_compile, " ");
329329 while (true) {
......@@ -365,7 +365,7 @@ pub const Builder = struct {
365365 }
366366 }
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 {
369369 const type_id = comptime typeToEnum(T);
370370 const available_option = AvailableOption {
371371 .name = name,
......@@ -418,7 +418,7 @@ pub const Builder = struct {
418418 }
419419 }
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 {
422422 const step_info = self.allocator.create(TopLevelStep) catch unreachable;
423423 *step_info = TopLevelStep {
424424 .step = Step.initNoOp(name, self.allocator),
......@@ -428,7 +428,7 @@ pub const Builder = struct {
428428 return &step_info.step;
429429 }
430430
431 pub fn standardReleaseOptions(self: &Builder) -> builtin.Mode {
431 pub fn standardReleaseOptions(self: &Builder) builtin.Mode {
432432 if (self.release_mode) |mode| return mode;
433433
434434 const release_safe = self.option(bool, "release-safe", "optimizations on and safety on") ?? false;
......@@ -449,7 +449,7 @@ pub const Builder = struct {
449449 return mode;
450450 }
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 {
453453 if (self.user_input_options.put(name, UserInputOption {
454454 .name = name,
455455 .value = UserValue { .Scalar = value },
......@@ -486,7 +486,7 @@ pub const Builder = struct {
486486 return false;
487487 }
488488
489 pub fn addUserInputFlag(self: &Builder, name: []const u8) -> bool {
489 pub fn addUserInputFlag(self: &Builder, name: []const u8) bool {
490490 if (self.user_input_options.put(name, UserInputOption {
491491 .name = name,
492492 .value = UserValue {.Flag = {} },
......@@ -507,7 +507,7 @@ pub const Builder = struct {
507507 return false;
508508 }
509509
510 fn typeToEnum(comptime T: type) -> TypeId {
510 fn typeToEnum(comptime T: type) TypeId {
511511 return switch (@typeId(T)) {
512512 builtin.TypeId.Int => TypeId.Int,
513513 builtin.TypeId.Float => TypeId.Float,
......@@ -520,11 +520,11 @@ pub const Builder = struct {
520520 };
521521 }
522522
523 fn markInvalidUserInput(self: &Builder) {
523 fn markInvalidUserInput(self: &Builder) void {
524524 self.invalid_user_input = true;
525525 }
526526
527 pub fn typeIdName(id: TypeId) -> []const u8 {
527 pub fn typeIdName(id: TypeId) []const u8 {
528528 return switch (id) {
529529 TypeId.Bool => "bool",
530530 TypeId.Int => "int",
......@@ -534,7 +534,7 @@ pub const Builder = struct {
534534 };
535535 }
536536
537 pub fn validateUserInputDidItFail(self: &Builder) -> bool {
537 pub fn validateUserInputDidItFail(self: &Builder) bool {
538538 // make sure all args are used
539539 var it = self.user_input_options.iterator();
540540 while (true) {
......@@ -548,11 +548,11 @@ pub const Builder = struct {
548548 return self.invalid_user_input;
549549 }
550550
551 fn spawnChild(self: &Builder, argv: []const []const u8) -> %void {
551 fn spawnChild(self: &Builder, argv: []const []const u8) %void {
552552 return self.spawnChildEnvMap(null, &self.env_map, argv);
553553 }
554554
555 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) {
555 fn printCmd(cwd: ?[]const u8, argv: []const []const u8) void {
556556 if (cwd) |yes_cwd| warn("cd {} && ", yes_cwd);
557557 for (argv) |arg| {
558558 warn("{} ", arg);
......@@ -561,7 +561,7 @@ pub const Builder = struct {
561561 }
562562
563563 fn spawnChildEnvMap(self: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
564 argv: []const []const u8) -> %void
564 argv: []const []const u8) %void
565565 {
566566 if (self.verbose) {
567567 printCmd(cwd, argv);
......@@ -595,28 +595,28 @@ pub const Builder = struct {
595595 }
596596 }
597597
598 pub fn makePath(self: &Builder, path: []const u8) -> %void {
598 pub fn makePath(self: &Builder, path: []const u8) %void {
599599 os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
600600 warn("Unable to create path {}: {}\n", path, @errorName(err));
601601 return err;
602602 };
603603 }
604604
605 pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) {
605 pub fn installArtifact(self: &Builder, artifact: &LibExeObjStep) void {
606606 self.getInstallStep().dependOn(&self.addInstallArtifact(artifact).step);
607607 }
608608
609 pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) -> &InstallArtifactStep {
609 pub fn addInstallArtifact(self: &Builder, artifact: &LibExeObjStep) &InstallArtifactStep {
610610 return InstallArtifactStep.create(self, artifact);
611611 }
612612
613613 ///::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 {
615615 self.getInstallStep().dependOn(&self.addInstallFile(src_path, dest_rel_path).step);
616616 }
617617
618618 ///::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 {
620620 const full_dest_path = os.path.resolve(self.allocator, self.prefix, dest_rel_path) catch unreachable;
621621 self.pushInstalledFile(full_dest_path);
622622
......@@ -625,16 +625,16 @@ pub const Builder = struct {
625625 return install_step;
626626 }
627627
628 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) {
628 pub fn pushInstalledFile(self: &Builder, full_path: []const u8) void {
629629 _ = self.getUninstallStep();
630630 self.installed_files.append(full_path) catch unreachable;
631631 }
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 {
634634 return self.copyFileMode(source_path, dest_path, 0o666);
635635 }
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 {
638638 if (self.verbose) {
639639 warn("cp {} {}\n", source_path, dest_path);
640640 }
......@@ -651,15 +651,15 @@ pub const Builder = struct {
651651 };
652652 }
653653
654 fn pathFromRoot(self: &Builder, rel_path: []const u8) -> []u8 {
654 fn pathFromRoot(self: &Builder, rel_path: []const u8) []u8 {
655655 return os.path.resolve(self.allocator, self.build_root, rel_path) catch unreachable;
656656 }
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 {
659659 return fmt_lib.allocPrint(self.allocator, format, args) catch unreachable;
660660 }
661661
662 fn getCCExe(self: &Builder) -> []const u8 {
662 fn getCCExe(self: &Builder) []const u8 {
663663 if (builtin.environ == builtin.Environ.msvc) {
664664 return "cl.exe";
665665 } else {
......@@ -672,7 +672,7 @@ pub const Builder = struct {
672672 }
673673 }
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 {
676676 // TODO report error for ambiguous situations
677677 const exe_extension = (Target { .Native = {}}).exeFileExt();
678678 for (self.search_prefixes.toSliceConst()) |search_prefix| {
......@@ -721,7 +721,7 @@ pub const Builder = struct {
721721 return error.FileNotFound;
722722 }
723723
724 pub fn exec(self: &Builder, argv: []const []const u8) -> %[]u8 {
724 pub fn exec(self: &Builder, argv: []const []const u8) %[]u8 {
725725 const max_output_size = 100 * 1024;
726726 const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);
727727 switch (result.term) {
......@@ -743,7 +743,7 @@ pub const Builder = struct {
743743 }
744744 }
745745
746 pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) {
746 pub fn addSearchPrefix(self: &Builder, search_prefix: []const u8) void {
747747 self.search_prefixes.append(search_prefix) catch unreachable;
748748 }
749749};
......@@ -764,7 +764,7 @@ pub const Target = union(enum) {
764764 Native: void,
765765 Cross: CrossTarget,
766766
767 pub fn oFileExt(self: &const Target) -> []const u8 {
767 pub fn oFileExt(self: &const Target) []const u8 {
768768 const environ = switch (*self) {
769769 Target.Native => builtin.environ,
770770 Target.Cross => |t| t.environ,
......@@ -775,42 +775,42 @@ pub const Target = union(enum) {
775775 };
776776 }
777777
778 pub fn exeFileExt(self: &const Target) -> []const u8 {
778 pub fn exeFileExt(self: &const Target) []const u8 {
779779 return switch (self.getOs()) {
780780 builtin.Os.windows => ".exe",
781781 else => "",
782782 };
783783 }
784784
785 pub fn libFileExt(self: &const Target) -> []const u8 {
785 pub fn libFileExt(self: &const Target) []const u8 {
786786 return switch (self.getOs()) {
787787 builtin.Os.windows => ".lib",
788788 else => ".a",
789789 };
790790 }
791791
792 pub fn getOs(self: &const Target) -> builtin.Os {
792 pub fn getOs(self: &const Target) builtin.Os {
793793 return switch (*self) {
794794 Target.Native => builtin.os,
795795 Target.Cross => |t| t.os,
796796 };
797797 }
798798
799 pub fn isDarwin(self: &const Target) -> bool {
799 pub fn isDarwin(self: &const Target) bool {
800800 return switch (self.getOs()) {
801801 builtin.Os.ios, builtin.Os.macosx => true,
802802 else => false,
803803 };
804804 }
805805
806 pub fn isWindows(self: &const Target) -> bool {
806 pub fn isWindows(self: &const Target) bool {
807807 return switch (self.getOs()) {
808808 builtin.Os.windows => true,
809809 else => false,
810810 };
811811 }
812812
813 pub fn wantSharedLibSymLinks(self: &const Target) -> bool {
813 pub fn wantSharedLibSymLinks(self: &const Target) bool {
814814 return !self.isWindows();
815815 }
816816};
......@@ -865,58 +865,58 @@ pub const LibExeObjStep = struct {
865865 };
866866
867867 pub fn createSharedLibrary(builder: &Builder, name: []const u8, root_src: ?[]const u8,
868 ver: &const Version) -> &LibExeObjStep
868 ver: &const Version) &LibExeObjStep
869869 {
870870 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
871871 *self = initExtraArgs(builder, name, root_src, Kind.Lib, false, ver);
872872 return self;
873873 }
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 {
876876 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
877877 *self = initC(builder, name, Kind.Lib, version, false);
878878 return self;
879879 }
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 {
882882 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
883883 *self = initExtraArgs(builder, name, root_src, Kind.Lib, true, builder.version(0, 0, 0));
884884 return self;
885885 }
886886
887 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) -> &LibExeObjStep {
887 pub fn createCStaticLibrary(builder: &Builder, name: []const u8) &LibExeObjStep {
888888 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
889889 *self = initC(builder, name, Kind.Lib, builder.version(0, 0, 0), true);
890890 return self;
891891 }
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 {
894894 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
895895 *self = initExtraArgs(builder, name, root_src, Kind.Obj, false, builder.version(0, 0, 0));
896896 return self;
897897 }
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 {
900900 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
901901 *self = initC(builder, name, Kind.Obj, builder.version(0, 0, 0), false);
902902 self.object_src = src;
903903 return self;
904904 }
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 {
907907 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
908908 *self = initExtraArgs(builder, name, root_src, Kind.Exe, false, builder.version(0, 0, 0));
909909 return self;
910910 }
911911
912 pub fn createCExecutable(builder: &Builder, name: []const u8) -> &LibExeObjStep {
912 pub fn createCExecutable(builder: &Builder, name: []const u8) &LibExeObjStep {
913913 const self = builder.allocator.create(LibExeObjStep) catch unreachable;
914914 *self = initC(builder, name, Kind.Exe, builder.version(0, 0, 0), false);
915915 return self;
916916 }
917917
918918 fn initExtraArgs(builder: &Builder, name: []const u8, root_src: ?[]const u8, kind: Kind,
919 static: bool, ver: &const Version) -> LibExeObjStep
919 static: bool, ver: &const Version) LibExeObjStep
920920 {
921921 var self = LibExeObjStep {
922922 .strip = false,
......@@ -956,7 +956,7 @@ pub const LibExeObjStep = struct {
956956 return self;
957957 }
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 {
960960 var self = LibExeObjStep {
961961 .builder = builder,
962962 .name = name,
......@@ -996,7 +996,7 @@ pub const LibExeObjStep = struct {
996996 return self;
997997 }
998998
999 fn computeOutFileNames(self: &LibExeObjStep) {
999 fn computeOutFileNames(self: &LibExeObjStep) void {
10001000 switch (self.kind) {
10011001 Kind.Obj => {
10021002 self.out_filename = self.builder.fmt("{}{}", self.name, self.target.oFileExt());
......@@ -1031,7 +1031,7 @@ pub const LibExeObjStep = struct {
10311031 }
10321032
10331033 pub fn setTarget(self: &LibExeObjStep, target_arch: builtin.Arch, target_os: builtin.Os,
1034 target_environ: builtin.Environ)
1034 target_environ: builtin.Environ) void
10351035 {
10361036 self.target = Target {
10371037 .Cross = CrossTarget {
......@@ -1044,16 +1044,16 @@ pub const LibExeObjStep = struct {
10441044 }
10451045
10461046 // 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 {
10481048 self.linker_script = path;
10491049 }
10501050
1051 pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) {
1051 pub fn linkFramework(self: &LibExeObjStep, framework_name: []const u8) void {
10521052 assert(self.target.isDarwin());
10531053 self.frameworks.put(framework_name) catch unreachable;
10541054 }
10551055
1056 pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) {
1056 pub fn linkLibrary(self: &LibExeObjStep, lib: &LibExeObjStep) void {
10571057 assert(self.kind != Kind.Obj);
10581058 assert(lib.kind == Kind.Lib);
10591059
......@@ -1074,26 +1074,26 @@ pub const LibExeObjStep = struct {
10741074 }
10751075 }
10761076
1077 pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) {
1077 pub fn linkSystemLibrary(self: &LibExeObjStep, name: []const u8) void {
10781078 assert(self.kind != Kind.Obj);
10791079 self.link_libs.put(name) catch unreachable;
10801080 }
10811081
1082 pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) {
1082 pub fn addSourceFile(self: &LibExeObjStep, file: []const u8) void {
10831083 assert(self.kind != Kind.Obj);
10841084 assert(!self.is_zig);
10851085 self.source_files.append(file) catch unreachable;
10861086 }
10871087
1088 pub fn setVerboseLink(self: &LibExeObjStep, value: bool) {
1088 pub fn setVerboseLink(self: &LibExeObjStep, value: bool) void {
10891089 self.verbose_link = value;
10901090 }
10911091
1092 pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) {
1092 pub fn setBuildMode(self: &LibExeObjStep, mode: builtin.Mode) void {
10931093 self.build_mode = mode;
10941094 }
10951095
1096 pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) {
1096 pub fn setOutputPath(self: &LibExeObjStep, file_path: []const u8) void {
10971097 self.output_path = file_path;
10981098
10991099 // catch a common mistake
......@@ -1102,14 +1102,14 @@ pub const LibExeObjStep = struct {
11021102 }
11031103 }
11041104
1105 pub fn getOutputPath(self: &LibExeObjStep) -> []const u8 {
1105 pub fn getOutputPath(self: &LibExeObjStep) []const u8 {
11061106 return if (self.output_path) |output_path|
11071107 output_path
11081108 else
11091109 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_filename) catch unreachable;
11101110 }
11111111
1112 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) {
1112 pub fn setOutputHPath(self: &LibExeObjStep, file_path: []const u8) void {
11131113 self.output_h_path = file_path;
11141114
11151115 // catch a common mistake
......@@ -1118,24 +1118,24 @@ pub const LibExeObjStep = struct {
11181118 }
11191119 }
11201120
1121 pub fn getOutputHPath(self: &LibExeObjStep) -> []const u8 {
1121 pub fn getOutputHPath(self: &LibExeObjStep) []const u8 {
11221122 return if (self.output_h_path) |output_h_path|
11231123 output_h_path
11241124 else
11251125 os.path.join(self.builder.allocator, self.builder.cache_root, self.out_h_filename) catch unreachable;
11261126 }
11271127
1128 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) {
1128 pub fn addAssemblyFile(self: &LibExeObjStep, path: []const u8) void {
11291129 self.assembly_files.append(path) catch unreachable;
11301130 }
11311131
1132 pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) {
1132 pub fn addObjectFile(self: &LibExeObjStep, path: []const u8) void {
11331133 assert(self.kind != Kind.Obj);
11341134
11351135 self.object_files.append(path) catch unreachable;
11361136 }
11371137
1138 pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) {
1138 pub fn addObject(self: &LibExeObjStep, obj: &LibExeObjStep) void {
11391139 assert(obj.kind == Kind.Obj);
11401140 assert(self.kind != Kind.Obj);
11411141
......@@ -1152,15 +1152,15 @@ pub const LibExeObjStep = struct {
11521152 self.include_dirs.append(self.builder.cache_root) catch unreachable;
11531153 }
11541154
1155 pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) {
1155 pub fn addIncludeDir(self: &LibExeObjStep, path: []const u8) void {
11561156 self.include_dirs.append(path) catch unreachable;
11571157 }
11581158
1159 pub fn addLibPath(self: &LibExeObjStep, path: []const u8) {
1159 pub fn addLibPath(self: &LibExeObjStep, path: []const u8) void {
11601160 self.lib_paths.append(path) catch unreachable;
11611161 }
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 {
11641164 assert(self.is_zig);
11651165
11661166 self.packages.append(Pkg {
......@@ -1169,23 +1169,23 @@ pub const LibExeObjStep = struct {
11691169 }) catch unreachable;
11701170 }
11711171
1172 pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) {
1172 pub fn addCompileFlags(self: &LibExeObjStep, flags: []const []const u8) void {
11731173 for (flags) |flag| {
11741174 self.cflags.append(flag) catch unreachable;
11751175 }
11761176 }
11771177
1178 pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) {
1178 pub fn setNoStdLib(self: &LibExeObjStep, disable: bool) void {
11791179 assert(!self.is_zig);
11801180 self.disable_libc = disable;
11811181 }
11821182
1183 fn make(step: &Step) -> %void {
1183 fn make(step: &Step) %void {
11841184 const self = @fieldParentPtr(LibExeObjStep, "step", step);
11851185 return if (self.is_zig) self.makeZig() else self.makeC();
11861186 }
11871187
1188 fn makeZig(self: &LibExeObjStep) -> %void {
1188 fn makeZig(self: &LibExeObjStep) %void {
11891189 const builder = self.builder;
11901190
11911191 assert(self.is_zig);
......@@ -1351,7 +1351,7 @@ pub const LibExeObjStep = struct {
13511351 }
13521352 }
13531353
1354 fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) {
1354 fn appendCompileFlags(self: &LibExeObjStep, args: &ArrayList([]const u8)) void {
13551355 if (!self.strip) {
13561356 args.append("-g") catch unreachable;
13571357 }
......@@ -1396,7 +1396,7 @@ pub const LibExeObjStep = struct {
13961396 }
13971397 }
13981398
1399 fn makeC(self: &LibExeObjStep) -> %void {
1399 fn makeC(self: &LibExeObjStep) %void {
14001400 const builder = self.builder;
14011401
14021402 const cc = builder.getCCExe();
......@@ -1635,7 +1635,7 @@ pub const TestStep = struct {
16351635 target: Target,
16361636 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 {
16391639 const step_name = builder.fmt("test {}", root_src);
16401640 return TestStep {
16411641 .step = Step.init(step_name, builder.allocator, make),
......@@ -1651,28 +1651,28 @@ pub const TestStep = struct {
16511651 };
16521652 }
16531653
1654 pub fn setVerbose(self: &TestStep, value: bool) {
1654 pub fn setVerbose(self: &TestStep, value: bool) void {
16551655 self.verbose = value;
16561656 }
16571657
1658 pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) {
1658 pub fn setBuildMode(self: &TestStep, mode: builtin.Mode) void {
16591659 self.build_mode = mode;
16601660 }
16611661
1662 pub fn linkSystemLibrary(self: &TestStep, name: []const u8) {
1662 pub fn linkSystemLibrary(self: &TestStep, name: []const u8) void {
16631663 self.link_libs.put(name) catch unreachable;
16641664 }
16651665
1666 pub fn setNamePrefix(self: &TestStep, text: []const u8) {
1666 pub fn setNamePrefix(self: &TestStep, text: []const u8) void {
16671667 self.name_prefix = text;
16681668 }
16691669
1670 pub fn setFilter(self: &TestStep, text: ?[]const u8) {
1670 pub fn setFilter(self: &TestStep, text: ?[]const u8) void {
16711671 self.filter = text;
16721672 }
16731673
16741674 pub fn setTarget(self: &TestStep, target_arch: builtin.Arch, target_os: builtin.Os,
1675 target_environ: builtin.Environ)
1675 target_environ: builtin.Environ) void
16761676 {
16771677 self.target = Target {
16781678 .Cross = CrossTarget {
......@@ -1683,11 +1683,11 @@ pub const TestStep = struct {
16831683 };
16841684 }
16851685
1686 pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) {
1686 pub fn setExecCmd(self: &TestStep, args: []const ?[]const u8) void {
16871687 self.exec_cmd_args = args;
16881688 }
16891689
1690 fn make(step: &Step) -> %void {
1690 fn make(step: &Step) %void {
16911691 const self = @fieldParentPtr(TestStep, "step", step);
16921692 const builder = self.builder;
16931693
......@@ -1781,7 +1781,7 @@ pub const CommandStep = struct {
17811781
17821782 /// ::argv is copied.
17831783 pub fn create(builder: &Builder, cwd: ?[]const u8, env_map: &const BufMap,
1784 argv: []const []const u8) -> &CommandStep
1784 argv: []const []const u8) &CommandStep
17851785 {
17861786 const self = builder.allocator.create(CommandStep) catch unreachable;
17871787 *self = CommandStep {
......@@ -1796,7 +1796,7 @@ pub const CommandStep = struct {
17961796 return self;
17971797 }
17981798
1799 fn make(step: &Step) -> %void {
1799 fn make(step: &Step) %void {
18001800 const self = @fieldParentPtr(CommandStep, "step", step);
18011801
18021802 const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
......@@ -1812,7 +1812,7 @@ const InstallArtifactStep = struct {
18121812
18131813 const Self = this;
18141814
1815 pub fn create(builder: &Builder, artifact: &LibExeObjStep) -> &Self {
1815 pub fn create(builder: &Builder, artifact: &LibExeObjStep) &Self {
18161816 const self = builder.allocator.create(Self) catch unreachable;
18171817 const dest_dir = switch (artifact.kind) {
18181818 LibExeObjStep.Kind.Obj => unreachable,
......@@ -1836,7 +1836,7 @@ const InstallArtifactStep = struct {
18361836 return self;
18371837 }
18381838
1839 fn make(step: &Step) -> %void {
1839 fn make(step: &Step) %void {
18401840 const self = @fieldParentPtr(Self, "step", step);
18411841 const builder = self.builder;
18421842
......@@ -1859,7 +1859,7 @@ pub const InstallFileStep = struct {
18591859 src_path: []const u8,
18601860 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 {
18631863 return InstallFileStep {
18641864 .builder = builder,
18651865 .step = Step.init(builder.fmt("install {}", src_path), builder.allocator, make),
......@@ -1868,7 +1868,7 @@ pub const InstallFileStep = struct {
18681868 };
18691869 }
18701870
1871 fn make(step: &Step) -> %void {
1871 fn make(step: &Step) %void {
18721872 const self = @fieldParentPtr(InstallFileStep, "step", step);
18731873 try self.builder.copyFile(self.src_path, self.dest_path);
18741874 }
......@@ -1880,7 +1880,7 @@ pub const WriteFileStep = struct {
18801880 file_path: []const u8,
18811881 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 {
18841884 return WriteFileStep {
18851885 .builder = builder,
18861886 .step = Step.init(builder.fmt("writefile {}", file_path), builder.allocator, make),
......@@ -1889,7 +1889,7 @@ pub const WriteFileStep = struct {
18891889 };
18901890 }
18911891
1892 fn make(step: &Step) -> %void {
1892 fn make(step: &Step) %void {
18931893 const self = @fieldParentPtr(WriteFileStep, "step", step);
18941894 const full_path = self.builder.pathFromRoot(self.file_path);
18951895 const full_path_dir = os.path.dirname(full_path);
......@@ -1909,7 +1909,7 @@ pub const LogStep = struct {
19091909 builder: &Builder,
19101910 data: []const u8,
19111911
1912 pub fn init(builder: &Builder, data: []const u8) -> LogStep {
1912 pub fn init(builder: &Builder, data: []const u8) LogStep {
19131913 return LogStep {
19141914 .builder = builder,
19151915 .step = Step.init(builder.fmt("log {}", data), builder.allocator, make),
......@@ -1917,7 +1917,7 @@ pub const LogStep = struct {
19171917 };
19181918 }
19191919
1920 fn make(step: &Step) -> %void {
1920 fn make(step: &Step) %void {
19211921 const self = @fieldParentPtr(LogStep, "step", step);
19221922 warn("{}", self.data);
19231923 }
......@@ -1928,7 +1928,7 @@ pub const RemoveDirStep = struct {
19281928 builder: &Builder,
19291929 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 {
19321932 return RemoveDirStep {
19331933 .builder = builder,
19341934 .step = Step.init(builder.fmt("RemoveDir {}", dir_path), builder.allocator, make),
......@@ -1936,7 +1936,7 @@ pub const RemoveDirStep = struct {
19361936 };
19371937 }
19381938
1939 fn make(step: &Step) -> %void {
1939 fn make(step: &Step) %void {
19401940 const self = @fieldParentPtr(RemoveDirStep, "step", step);
19411941
19421942 const full_path = self.builder.pathFromRoot(self.dir_path);
......@@ -1949,12 +1949,12 @@ pub const RemoveDirStep = struct {
19491949
19501950pub const Step = struct {
19511951 name: []const u8,
1952 makeFn: fn(self: &Step) -> %void,
1952 makeFn: fn(self: &Step) %void,
19531953 dependencies: ArrayList(&Step),
19541954 loop_flag: bool,
19551955 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 {
19581958 return Step {
19591959 .name = name,
19601960 .makeFn = makeFn,
......@@ -1963,11 +1963,11 @@ pub const Step = struct {
19631963 .done_flag = false,
19641964 };
19651965 }
1966 pub fn initNoOp(name: []const u8, allocator: &Allocator) -> Step {
1966 pub fn initNoOp(name: []const u8, allocator: &Allocator) Step {
19671967 return init(name, allocator, makeNoOp);
19681968 }
19691969
1970 pub fn make(self: &Step) -> %void {
1970 pub fn make(self: &Step) %void {
19711971 if (self.done_flag)
19721972 return;
19731973
......@@ -1975,15 +1975,15 @@ pub const Step = struct {
19751975 self.done_flag = true;
19761976 }
19771977
1978 pub fn dependOn(self: &Step, other: &Step) {
1978 pub fn dependOn(self: &Step, other: &Step) void {
19791979 self.dependencies.append(other) catch unreachable;
19801980 }
19811981
1982 fn makeNoOp(self: &Step) -> %void {}
1982 fn makeNoOp(self: &Step) %void {}
19831983};
19841984
19851985fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8,
1986 filename_name_only: []const u8) -> %void
1986 filename_name_only: []const u8) %void
19871987{
19881988 const out_dir = os.path.dirname(output_path);
19891989 const out_basename = os.path.basename(output_path);
std/c/darwin.zig+3-3
......@@ -1,5 +1,5 @@
1extern "c" fn __error() -> &c_int;
2pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) -> c_int;
1extern "c" fn __error() &c_int;
2pub extern "c" fn _NSGetExecutablePath(buf: &u8, bufsize: &u32) c_int;
33
44
55pub use @import("../os/darwin_errno.zig");
......@@ -41,7 +41,7 @@ pub const sigset_t = u32;
4141
4242/// Renamed from `sigaction` to `Sigaction` to avoid conflict with function name.
4343pub const Sigaction = extern struct {
44 handler: extern fn(c_int),
44 handler: extern fn(c_int)void,
4545 sa_mask: sigset_t,
4646 sa_flags: c_int,
4747};
std/c/index.zig+37-37
......@@ -9,43 +9,43 @@ pub use switch(builtin.os) {
99};
1010const empty_import = @import("../empty.zig");
1111
12pub extern "c" fn abort() -> noreturn;
13pub extern "c" fn exit(code: c_int) -> noreturn;
14pub extern "c" fn isatty(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;
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;
19pub extern "c" fn open(path: &const u8, oflag: 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;
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;
12pub extern "c" fn abort() noreturn;
13pub extern "c" fn exit(code: c_int) noreturn;
14pub extern "c" fn isatty(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;
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;
19pub extern "c" fn open(path: &const u8, oflag: 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;
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;
2424pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
25 fd: c_int, offset: isize) -> ?&c_void;
26pub extern "c" fn munmap(addr: &c_void, len: usize) -> c_int;
27pub extern "c" fn unlink(path: &const u8) -> c_int;
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;
30pub extern "c" fn fork() -> 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;
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;
35pub extern "c" fn chdir(path: &const u8) -> c_int;
25 fd: c_int, offset: isize) ?&c_void;
26pub extern "c" fn munmap(addr: &c_void, len: usize) c_int;
27pub extern "c" fn unlink(path: &const u8) c_int;
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;
30pub extern "c" fn fork() 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;
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;
35pub extern "c" fn chdir(path: &const u8) c_int;
3636pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
37 envp: &const ?&const u8) -> 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;
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;
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;
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;
46pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) -> c_int;
37 envp: &const ?&const u8) 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;
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;
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;
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;
46pub extern "c" fn setregid(rgid: c_uint, egid: c_uint) c_int;
4747
48pub extern "c" fn malloc(usize) -> ?&c_void;
49pub extern "c" fn realloc(&c_void, usize) -> ?&c_void;
50pub extern "c" fn free(&c_void);
51pub extern "c" fn posix_memalign(memptr: &&c_void, alignment: usize, size: usize) -> c_int;
48pub extern "c" fn malloc(usize) ?&c_void;
49pub extern "c" fn realloc(&c_void, usize) ?&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;
std/c/linux.zig+2-2
......@@ -1,5 +1,5 @@
11pub use @import("../os/linux_errno.zig");
22
3pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) -> c_int;
4extern "c" fn __errno_location() -> &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;
55pub const _errno = __errno_location;
std/c/windows.zig+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 {
99 a: usize, b: usize, c: usize, d: usize, x: usize, y: usize,
1010};
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 {
1313 return RoundParam { .a = a, .b = b, .c = c, .d = d, .x = x, .y = y, };
1414}
1515
......@@ -19,7 +19,7 @@ fn Rp(a: usize, b: usize, c: usize, d: usize, x: usize, y: usize) -> RoundParam
1919pub const Blake2s224 = Blake2s(224);
2020pub const Blake2s256 = Blake2s(256);
2121
22fn Blake2s(comptime out_len: usize) -> type { return struct {
22fn Blake2s(comptime out_len: usize) type { return struct {
2323 const Self = this;
2424 const block_size = 64;
2525 const digest_size = out_len / 8;
......@@ -48,7 +48,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
4848 buf: [64]u8,
4949 buf_len: u8,
5050
51 pub fn init() -> Self {
51 pub fn init() Self {
5252 debug.assert(8 <= out_len and out_len <= 512);
5353
5454 var s: Self = undefined;
......@@ -56,7 +56,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
5656 return s;
5757 }
5858
59 pub fn reset(d: &Self) {
59 pub fn reset(d: &Self) void {
6060 mem.copy(u32, d.h[0..], iv[0..]);
6161
6262 // No key plus default parameters
......@@ -65,13 +65,13 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
6565 d.buf_len = 0;
6666 }
6767
68 pub fn hash(b: []const u8, out: []u8) {
68 pub fn hash(b: []const u8, out: []u8) void {
6969 var d = Self.init();
7070 d.update(b);
7171 d.final(out);
7272 }
7373
74 pub fn update(d: &Self, b: []const u8) {
74 pub fn update(d: &Self, b: []const u8) void {
7575 var off: usize = 0;
7676
7777 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
9494 d.buf_len += u8(b[off..].len);
9595 }
9696
97 pub fn final(d: &Self, out: []u8) {
97 pub fn final(d: &Self, out: []u8) void {
9898 debug.assert(out.len >= out_len / 8);
9999
100100 mem.set(u8, d.buf[d.buf_len..], 0);
......@@ -108,7 +108,7 @@ fn Blake2s(comptime out_len: usize) -> type { return struct {
108108 }
109109 }
110110
111 fn round(d: &Self, b: []const u8, last: bool) {
111 fn round(d: &Self, b: []const u8, last: bool) void {
112112 debug.assert(b.len == 64);
113113
114114 var m: [16]u32 = undefined;
......@@ -236,7 +236,7 @@ test "blake2s256 streaming" {
236236pub const Blake2b384 = Blake2b(384);
237237pub const Blake2b512 = Blake2b(512);
238238
239fn Blake2b(comptime out_len: usize) -> type { return struct {
239fn Blake2b(comptime out_len: usize) type { return struct {
240240 const Self = this;
241241 const block_size = 128;
242242 const digest_size = out_len / 8;
......@@ -269,7 +269,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
269269 buf: [128]u8,
270270 buf_len: u8,
271271
272 pub fn init() -> Self {
272 pub fn init() Self {
273273 debug.assert(8 <= out_len and out_len <= 512);
274274
275275 var s: Self = undefined;
......@@ -277,7 +277,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
277277 return s;
278278 }
279279
280 pub fn reset(d: &Self) {
280 pub fn reset(d: &Self) void {
281281 mem.copy(u64, d.h[0..], iv[0..]);
282282
283283 // No key plus default parameters
......@@ -286,13 +286,13 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
286286 d.buf_len = 0;
287287 }
288288
289 pub fn hash(b: []const u8, out: []u8) {
289 pub fn hash(b: []const u8, out: []u8) void {
290290 var d = Self.init();
291291 d.update(b);
292292 d.final(out);
293293 }
294294
295 pub fn update(d: &Self, b: []const u8) {
295 pub fn update(d: &Self, b: []const u8) void {
296296 var off: usize = 0;
297297
298298 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -315,7 +315,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
315315 d.buf_len += u8(b[off..].len);
316316 }
317317
318 pub fn final(d: &Self, out: []u8) {
318 pub fn final(d: &Self, out: []u8) void {
319319 mem.set(u8, d.buf[d.buf_len..], 0);
320320 d.t += d.buf_len;
321321 d.round(d.buf[0..], true);
......@@ -327,7 +327,7 @@ fn Blake2b(comptime out_len: usize) -> type { return struct {
327327 }
328328 }
329329
330 fn round(d: &Self, b: []const u8, last: bool) {
330 fn round(d: &Self, b: []const u8, last: bool) void {
331331 debug.assert(b.len == 128);
332332
333333 var m: [16]u64 = undefined;
std/crypto/md5.zig+7-7
......@@ -10,7 +10,7 @@ const RoundParam = struct {
1010 k: usize, s: u32, t: u32
1111};
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 {
1414 return RoundParam { .a = a, .b = b, .c = c, .d = d, .k = k, .s = s, .t = t };
1515}
1616
......@@ -25,13 +25,13 @@ pub const Md5 = struct {
2525 buf_len: u8,
2626 total_len: u64,
2727
28 pub fn init() -> Self {
28 pub fn init() Self {
2929 var d: Self = undefined;
3030 d.reset();
3131 return d;
3232 }
3333
34 pub fn reset(d: &Self) {
34 pub fn reset(d: &Self) void {
3535 d.s[0] = 0x67452301;
3636 d.s[1] = 0xEFCDAB89;
3737 d.s[2] = 0x98BADCFE;
......@@ -40,13 +40,13 @@ pub const Md5 = struct {
4040 d.total_len = 0;
4141 }
4242
43 pub fn hash(b: []const u8, out: []u8) {
43 pub fn hash(b: []const u8, out: []u8) void {
4444 var d = Md5.init();
4545 d.update(b);
4646 d.final(out);
4747 }
4848
49 pub fn update(d: &Self, b: []const u8) {
49 pub fn update(d: &Self, b: []const u8) void {
5050 var off: usize = 0;
5151
5252 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -71,7 +71,7 @@ pub const Md5 = struct {
7171 d.total_len +%= b.len;
7272 }
7373
74 pub fn final(d: &Self, out: []u8) {
74 pub fn final(d: &Self, out: []u8) void {
7575 debug.assert(out.len >= 16);
7676
7777 // The buffer here will never be completely full.
......@@ -103,7 +103,7 @@ pub const Md5 = struct {
103103 }
104104 }
105105
106 fn round(d: &Self, b: []const u8) {
106 fn round(d: &Self, b: []const u8) void {
107107 debug.assert(b.len == 64);
108108
109109 var s: [16]u32 = undefined;
std/crypto/sha1.zig+7-7
......@@ -10,7 +10,7 @@ const RoundParam = struct {
1010 a: usize, b: usize, c: usize, d: usize, e: usize, i: u32,
1111};
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 {
1414 return RoundParam { .a = a, .b = b, .c = c, .d = d, .e = e, .i = i };
1515}
1616
......@@ -25,13 +25,13 @@ pub const Sha1 = struct {
2525 buf_len: u8,
2626 total_len: u64,
2727
28 pub fn init() -> Self {
28 pub fn init() Self {
2929 var d: Self = undefined;
3030 d.reset();
3131 return d;
3232 }
3333
34 pub fn reset(d: &Self) {
34 pub fn reset(d: &Self) void {
3535 d.s[0] = 0x67452301;
3636 d.s[1] = 0xEFCDAB89;
3737 d.s[2] = 0x98BADCFE;
......@@ -41,13 +41,13 @@ pub const Sha1 = struct {
4141 d.total_len = 0;
4242 }
4343
44 pub fn hash(b: []const u8, out: []u8) {
44 pub fn hash(b: []const u8, out: []u8) void {
4545 var d = Sha1.init();
4646 d.update(b);
4747 d.final(out);
4848 }
4949
50 pub fn update(d: &Self, b: []const u8) {
50 pub fn update(d: &Self, b: []const u8) void {
5151 var off: usize = 0;
5252
5353 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -71,7 +71,7 @@ pub const Sha1 = struct {
7171 d.total_len += b.len;
7272 }
7373
74 pub fn final(d: &Self, out: []u8) {
74 pub fn final(d: &Self, out: []u8) void {
7575 debug.assert(out.len >= 20);
7676
7777 // The buffer here will never be completely full.
......@@ -103,7 +103,7 @@ pub const Sha1 = struct {
103103 }
104104 }
105105
106 fn round(d: &Self, b: []const u8) {
106 fn round(d: &Self, b: []const u8) void {
107107 debug.assert(b.len == 64);
108108
109109 var s: [16]u32 = undefined;
std/crypto/sha2.zig+16-16
......@@ -13,7 +13,7 @@ const RoundParam256 = struct {
1313 i: usize, k: u32,
1414};
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 {
1717 return RoundParam256 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
1818}
1919
......@@ -56,7 +56,7 @@ const Sha256Params = Sha2Params32 {
5656pub const Sha224 = Sha2_32(Sha224Params);
5757pub const Sha256 = Sha2_32(Sha256Params);
5858
59fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
59fn Sha2_32(comptime params: Sha2Params32) type { return struct {
6060 const Self = this;
6161 const block_size = 64;
6262 const digest_size = params.out_len / 8;
......@@ -67,13 +67,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
6767 buf_len: u8,
6868 total_len: u64,
6969
70 pub fn init() -> Self {
70 pub fn init() Self {
7171 var d: Self = undefined;
7272 d.reset();
7373 return d;
7474 }
7575
76 pub fn reset(d: &Self) {
76 pub fn reset(d: &Self) void {
7777 d.s[0] = params.iv0;
7878 d.s[1] = params.iv1;
7979 d.s[2] = params.iv2;
......@@ -86,13 +86,13 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
8686 d.total_len = 0;
8787 }
8888
89 pub fn hash(b: []const u8, out: []u8) {
89 pub fn hash(b: []const u8, out: []u8) void {
9090 var d = Self.init();
9191 d.update(b);
9292 d.final(out);
9393 }
9494
95 pub fn update(d: &Self, b: []const u8) {
95 pub fn update(d: &Self, b: []const u8) void {
9696 var off: usize = 0;
9797
9898 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
116116 d.total_len += b.len;
117117 }
118118
119 pub fn final(d: &Self, out: []u8) {
119 pub fn final(d: &Self, out: []u8) void {
120120 debug.assert(out.len >= params.out_len / 8);
121121
122122 // The buffer here will never be completely full.
......@@ -151,7 +151,7 @@ fn Sha2_32(comptime params: Sha2Params32) -> type { return struct {
151151 }
152152 }
153153
154 fn round(d: &Self, b: []const u8) {
154 fn round(d: &Self, b: []const u8) void {
155155 debug.assert(b.len == 64);
156156
157157 var s: [64]u32 = undefined;
......@@ -329,7 +329,7 @@ const RoundParam512 = struct {
329329 i: usize, k: u64,
330330};
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 {
333333 return RoundParam512 { .a = a, .b = b, .c = c, .d = d, .e = e, .f = f, .g = g, .h = h, .i = i, .k = k };
334334}
335335
......@@ -372,7 +372,7 @@ const Sha512Params = Sha2Params64 {
372372pub const Sha384 = Sha2_64(Sha384Params);
373373pub const Sha512 = Sha2_64(Sha512Params);
374374
375fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
375fn Sha2_64(comptime params: Sha2Params64) type { return struct {
376376 const Self = this;
377377 const block_size = 128;
378378 const digest_size = params.out_len / 8;
......@@ -383,13 +383,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
383383 buf_len: u8,
384384 total_len: u128,
385385
386 pub fn init() -> Self {
386 pub fn init() Self {
387387 var d: Self = undefined;
388388 d.reset();
389389 return d;
390390 }
391391
392 pub fn reset(d: &Self) {
392 pub fn reset(d: &Self) void {
393393 d.s[0] = params.iv0;
394394 d.s[1] = params.iv1;
395395 d.s[2] = params.iv2;
......@@ -402,13 +402,13 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
402402 d.total_len = 0;
403403 }
404404
405 pub fn hash(b: []const u8, out: []u8) {
405 pub fn hash(b: []const u8, out: []u8) void {
406406 var d = Self.init();
407407 d.update(b);
408408 d.final(out);
409409 }
410410
411 pub fn update(d: &Self, b: []const u8) {
411 pub fn update(d: &Self, b: []const u8) void {
412412 var off: usize = 0;
413413
414414 // Partial buffer exists from previous update. Copy into buffer then hash.
......@@ -432,7 +432,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
432432 d.total_len += b.len;
433433 }
434434
435 pub fn final(d: &Self, out: []u8) {
435 pub fn final(d: &Self, out: []u8) void {
436436 debug.assert(out.len >= params.out_len / 8);
437437
438438 // The buffer here will never be completely full.
......@@ -467,7 +467,7 @@ fn Sha2_64(comptime params: Sha2Params64) -> type { return struct {
467467 }
468468 }
469469
470 fn round(d: &Self, b: []const u8) {
470 fn round(d: &Self, b: []const u8) void {
471471 debug.assert(b.len == 128);
472472
473473 var s: [80]u64 = undefined;
std/crypto/sha3.zig+7-7
......@@ -10,7 +10,7 @@ pub const Sha3_256 = Keccak(256, 0x06);
1010pub const Sha3_384 = Keccak(384, 0x06);
1111pub 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 {
1414 const Self = this;
1515 const block_size = 200;
1616 const digest_size = bits / 8;
......@@ -19,25 +19,25 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
1919 offset: usize,
2020 rate: usize,
2121
22 pub fn init() -> Self {
22 pub fn init() Self {
2323 var d: Self = undefined;
2424 d.reset();
2525 return d;
2626 }
2727
28 pub fn reset(d: &Self) {
28 pub fn reset(d: &Self) void {
2929 mem.set(u8, d.s[0..], 0);
3030 d.offset = 0;
3131 d.rate = 200 - (bits / 4);
3232 }
3333
34 pub fn hash(b: []const u8, out: []u8) {
34 pub fn hash(b: []const u8, out: []u8) void {
3535 var d = Self.init();
3636 d.update(b);
3737 d.final(out);
3838 }
3939
40 pub fn update(d: &Self, b: []const u8) {
40 pub fn update(d: &Self, b: []const u8) void {
4141 var ip: usize = 0;
4242 var len = b.len;
4343 var rate = d.rate - d.offset;
......@@ -62,7 +62,7 @@ fn Keccak(comptime bits: usize, comptime delim: u8) -> type { return struct {
6262 d.offset = offset + len;
6363 }
6464
65 pub fn final(d: &Self, out: []u8) {
65 pub fn final(d: &Self, out: []u8) void {
6666 // padding
6767 d.s[d.offset] ^= delim;
6868 d.s[d.rate - 1] ^= 0x80;
......@@ -109,7 +109,7 @@ const M5 = []const usize {
109109 0, 1, 2, 3, 4, 0, 1, 2, 3, 4
110110};
111111
112fn keccak_f(comptime F: usize, d: []u8) {
112fn keccak_f(comptime F: usize, d: []u8) void {
113113 debug.assert(d.len == F / 8);
114114
115115 const B = F / 25;
std/crypto/test.zig+2-2
......@@ -3,7 +3,7 @@ const mem = @import("../mem.zig");
33const fmt = @import("../fmt/index.zig");
44
55// 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 {
77 var h: [expected.len / 2]u8 = undefined;
88 Hasher.hash(input, h[0..]);
99
......@@ -11,7 +11,7 @@ pub fn assertEqualHash(comptime Hasher: var, comptime expected: []const u8, inpu
1111}
1212
1313// 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 {
1515 var expected_bytes: [expected.len / 2]u8 = undefined;
1616 for (expected_bytes) |*r, i| {
1717 *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({
1818
1919const Mb = 1024 * 1024;
2020
21pub fn main() -> %void {
21pub fn main() %void {
2222 var stdout_file = try std.io.getStdOut();
2323 var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
2424 const stdout = &stdout_out_stream.stream;
std/cstr.zig+9-9
......@@ -3,13 +3,13 @@ const debug = std.debug;
33const mem = std.mem;
44const assert = debug.assert;
55
6pub fn len(ptr: &const u8) -> usize {
6pub fn len(ptr: &const u8) usize {
77 var count: usize = 0;
88 while (ptr[count] != 0) : (count += 1) {}
99 return count;
1010}
1111
12pub fn cmp(a: &const u8, b: &const u8) -> i8 {
12pub fn cmp(a: &const u8, b: &const u8) i8 {
1313 var index: usize = 0;
1414 while (a[index] == b[index] and a[index] != 0) : (index += 1) {}
1515 if (a[index] > b[index]) {
......@@ -21,11 +21,11 @@ pub fn cmp(a: &const u8, b: &const u8) -> i8 {
2121 }
2222}
2323
24pub fn toSliceConst(str: &const u8) -> []const u8 {
24pub fn toSliceConst(str: &const u8) []const u8 {
2525 return str[0..len(str)];
2626}
2727
28pub fn toSlice(str: &u8) -> []u8 {
28pub fn toSlice(str: &u8) []u8 {
2929 return str[0..len(str)];
3030}
3131
......@@ -34,7 +34,7 @@ test "cstr fns" {
3434 testCStrFnsImpl();
3535}
3636
37fn testCStrFnsImpl() {
37fn testCStrFnsImpl() void {
3838 assert(cmp(c"aoeu", c"aoez") == -1);
3939 assert(len(c"123456789") == 9);
4040}
......@@ -42,7 +42,7 @@ fn testCStrFnsImpl() {
4242/// Returns a mutable slice with exactly the same size which is guaranteed to
4343/// have a null byte after it.
4444/// 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 {
4646 const result = try allocator.alloc(u8, slice.len + 1);
4747 mem.copy(u8, result, slice);
4848 result[slice.len] = 0;
......@@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {
5656
5757 /// Takes N lists of strings, concatenates the lists together, and adds a null terminator
5858 /// 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 {
6060 var new_len: usize = 1; // 1 for the list null
6161 var byte_count: usize = 0;
6262 for (slices) |slice| {
......@@ -71,7 +71,7 @@ pub const NullTerminated2DArray = struct {
7171 byte_count += index_size;
7272
7373 const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
74 %defer allocator.free(buf);
74 errdefer allocator.free(buf);
7575
7676 var write_index = index_size;
7777 const index_buf = ([]?&u8)(buf);
......@@ -96,7 +96,7 @@ pub const NullTerminated2DArray = struct {
9696 };
9797 }
9898
99 pub fn deinit(self: &NullTerminated2DArray) {
99 pub fn deinit(self: &NullTerminated2DArray) void {
100100 const buf = @ptrCast(&u8, self.ptr);
101101 self.allocator.free(buf[0..self.byte_count]);
102102 }
std/debug/failing_allocator.zig+4-4
......@@ -12,7 +12,7 @@ pub const FailingAllocator = struct {
1212 freed_bytes: usize,
1313 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 {
1616 return FailingAllocator {
1717 .internal_allocator = allocator,
1818 .fail_index = fail_index,
......@@ -28,7 +28,7 @@ pub const FailingAllocator = struct {
2828 };
2929 }
3030
31 fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) -> %[]u8 {
31 fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) %[]u8 {
3232 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
3333 if (self.index == self.fail_index) {
3434 return error.OutOfMemory;
......@@ -39,7 +39,7 @@ pub const FailingAllocator = struct {
3939 return result;
4040 }
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 {
4343 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
4444 if (new_size <= old_mem.len) {
4545 self.freed_bytes += old_mem.len - new_size;
......@@ -55,7 +55,7 @@ pub const FailingAllocator = struct {
5555 return result;
5656 }
5757
58 fn free(allocator: &mem.Allocator, bytes: []u8) {
58 fn free(allocator: &mem.Allocator, bytes: []u8) void {
5959 const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
6060 self.freed_bytes += bytes.len;
6161 self.deallocations += 1;
std/debug/index.zig+51-51
......@@ -25,11 +25,11 @@ error TodoSupportCOFFDebugInfo;
2525var stderr_file: io.File = undefined;
2626var stderr_file_out_stream: io.FileOutStream = undefined;
2727var stderr_stream: ?&io.OutStream = null;
28pub fn warn(comptime fmt: []const u8, args: ...) {
28pub fn warn(comptime fmt: []const u8, args: ...) void {
2929 const stderr = getStderrStream() catch return;
3030 stderr.print(fmt, args) catch return;
3131}
32fn getStderrStream() -> %&io.OutStream {
32fn getStderrStream() %&io.OutStream {
3333 if (stderr_stream) |st| {
3434 return st;
3535 } else {
......@@ -42,7 +42,7 @@ fn getStderrStream() -> %&io.OutStream {
4242}
4343
4444var self_debug_info: ?&ElfStackTrace = null;
45pub fn getSelfDebugInfo() -> %&ElfStackTrace {
45pub fn getSelfDebugInfo() %&ElfStackTrace {
4646 if (self_debug_info) |info| {
4747 return info;
4848 } else {
......@@ -53,7 +53,7 @@ pub fn getSelfDebugInfo() -> %&ElfStackTrace {
5353}
5454
5555/// Tries to print the current stack trace to stderr, unbuffered, and ignores any error returned.
56pub fn dumpCurrentStackTrace() {
56pub fn dumpCurrentStackTrace() void {
5757 const stderr = getStderrStream() catch return;
5858 const debug_info = getSelfDebugInfo() catch |err| {
5959 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
......@@ -67,7 +67,7 @@ pub fn dumpCurrentStackTrace() {
6767}
6868
6969/// 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 {
7171 const stderr = getStderrStream() catch return;
7272 const debug_info = getSelfDebugInfo() catch |err| {
7373 stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return;
......@@ -85,7 +85,7 @@ pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) {
8585/// generated, and the `unreachable` statement triggers a panic.
8686/// In ReleaseFast and ReleaseSmall modes, calls to this function can be
8787/// optimized away.
88pub fn assert(ok: bool) {
88pub fn assert(ok: bool) void {
8989 if (!ok) {
9090 // In ReleaseFast test mode, we still want assert(false) to crash, so
9191 // we insert an explicit call to @panic instead of unreachable.
......@@ -100,7 +100,7 @@ pub fn assert(ok: bool) {
100100
101101/// Call this function when you want to panic if the condition is not true.
102102/// If `ok` is `false`, this function will panic in every release mode.
103pub fn assertOrPanic(ok: bool) {
103pub fn assertOrPanic(ok: bool) void {
104104 if (!ok) {
105105 @panic("assertion failure");
106106 }
......@@ -108,7 +108,7 @@ pub fn assertOrPanic(ok: bool) {
108108
109109var panicking = false;
110110/// This is the default panic implementation.
111pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
111pub fn panic(comptime format: []const u8, args: ...) noreturn {
112112 // TODO an intrinsic that labels this as unlikely to be reached
113113
114114 // TODO
......@@ -130,7 +130,7 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
130130 os.abort();
131131}
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 {
134134 if (panicking) {
135135 os.abort();
136136 } else {
......@@ -153,7 +153,7 @@ error PathNotFound;
153153error InvalidDebugInfo;
154154
155155pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator,
156 debug_info: &ElfStackTrace, tty_color: bool) -> %void
156 debug_info: &ElfStackTrace, tty_color: bool) %void
157157{
158158 var frame_index: usize = undefined;
159159 var frames_left: usize = undefined;
......@@ -175,7 +175,7 @@ pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.O
175175}
176176
177177pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator,
178 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) -> %void
178 debug_info: &ElfStackTrace, tty_color: bool, ignore_frame_count: usize) %void
179179{
180180 var ignored_count: usize = 0;
181181
......@@ -191,7 +191,7 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat
191191 }
192192}
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 {
195195 if (builtin.os == builtin.Os.windows) {
196196 return error.UnsupportedDebugInfo;
197197 }
......@@ -232,7 +232,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a
232232 }
233233}
234234
235pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
235pub fn openSelfDebugInfo(allocator: &mem.Allocator) %&ElfStackTrace {
236236 switch (builtin.object_format) {
237237 builtin.ObjectFormat.elf => {
238238 const st = try allocator.create(ElfStackTrace);
......@@ -248,10 +248,10 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
248248 .compile_unit_list = ArrayList(CompileUnit).init(allocator),
249249 };
250250 st.self_exe_file = try os.openSelfExe();
251 %defer st.self_exe_file.close();
251 errdefer st.self_exe_file.close();
252252
253253 try st.elf.openFile(allocator, &st.self_exe_file);
254 %defer st.elf.close();
254 errdefer st.elf.close();
255255
256256 st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
257257 st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
......@@ -276,7 +276,7 @@ pub fn openSelfDebugInfo(allocator: &mem.Allocator) -> %&ElfStackTrace {
276276 }
277277}
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 {
280280 var f = try io.File.openRead(line_info.file_name, allocator);
281281 defer f.close();
282282 // TODO fstat and make sure that the file has the correct size
......@@ -320,17 +320,17 @@ pub const ElfStackTrace = struct {
320320 abbrev_table_list: ArrayList(AbbrevTableHeader),
321321 compile_unit_list: ArrayList(CompileUnit),
322322
323 pub fn allocator(self: &const ElfStackTrace) -> &mem.Allocator {
323 pub fn allocator(self: &const ElfStackTrace) &mem.Allocator {
324324 return self.abbrev_table_list.allocator;
325325 }
326326
327 pub fn readString(self: &ElfStackTrace) -> %[]u8 {
327 pub fn readString(self: &ElfStackTrace) %[]u8 {
328328 var in_file_stream = io.FileInStream.init(&self.self_exe_file);
329329 const in_stream = &in_file_stream.stream;
330330 return readStringRaw(self.allocator(), in_stream);
331331 }
332332
333 pub fn close(self: &ElfStackTrace) {
333 pub fn close(self: &ElfStackTrace) void {
334334 self.self_exe_file.close();
335335 self.elf.close();
336336 }
......@@ -387,7 +387,7 @@ const Constant = struct {
387387 payload: []u8,
388388 signed: bool,
389389
390 fn asUnsignedLe(self: &const Constant) -> %u64 {
390 fn asUnsignedLe(self: &const Constant) %u64 {
391391 if (self.payload.len > @sizeOf(u64))
392392 return error.InvalidDebugInfo;
393393 if (self.signed)
......@@ -406,7 +406,7 @@ const Die = struct {
406406 value: FormValue,
407407 };
408408
409 fn getAttr(self: &const Die, id: u64) -> ?&const FormValue {
409 fn getAttr(self: &const Die, id: u64) ?&const FormValue {
410410 for (self.attrs.toSliceConst()) |*attr| {
411411 if (attr.id == id)
412412 return &attr.value;
......@@ -414,7 +414,7 @@ const Die = struct {
414414 return null;
415415 }
416416
417 fn getAttrAddr(self: &const Die, id: u64) -> %u64 {
417 fn getAttrAddr(self: &const Die, id: u64) %u64 {
418418 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
419419 return switch (*form_value) {
420420 FormValue.Address => |value| value,
......@@ -422,7 +422,7 @@ const Die = struct {
422422 };
423423 }
424424
425 fn getAttrSecOffset(self: &const Die, id: u64) -> %u64 {
425 fn getAttrSecOffset(self: &const Die, id: u64) %u64 {
426426 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
427427 return switch (*form_value) {
428428 FormValue.Const => |value| value.asUnsignedLe(),
......@@ -431,7 +431,7 @@ const Die = struct {
431431 };
432432 }
433433
434 fn getAttrUnsignedLe(self: &const Die, id: u64) -> %u64 {
434 fn getAttrUnsignedLe(self: &const Die, id: u64) %u64 {
435435 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
436436 return switch (*form_value) {
437437 FormValue.Const => |value| value.asUnsignedLe(),
......@@ -439,7 +439,7 @@ const Die = struct {
439439 };
440440 }
441441
442 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) -> %[]u8 {
442 fn getAttrString(self: &const Die, st: &ElfStackTrace, id: u64) %[]u8 {
443443 const form_value = self.getAttr(id) ?? return error.MissingDebugInfo;
444444 return switch (*form_value) {
445445 FormValue.String => |value| value,
......@@ -462,7 +462,7 @@ const LineInfo = struct {
462462 file_name: []u8,
463463 allocator: &mem.Allocator,
464464
465 fn deinit(self: &const LineInfo) {
465 fn deinit(self: &const LineInfo) void {
466466 self.allocator.free(self.file_name);
467467 }
468468};
......@@ -489,7 +489,7 @@ const LineNumberProgram = struct {
489489 prev_end_sequence: bool,
490490
491491 pub fn init(is_stmt: bool, include_dirs: []const []const u8,
492 file_entries: &ArrayList(FileEntry), target_address: usize) -> LineNumberProgram
492 file_entries: &ArrayList(FileEntry), target_address: usize) LineNumberProgram
493493 {
494494 return LineNumberProgram {
495495 .address = 0,
......@@ -512,7 +512,7 @@ const LineNumberProgram = struct {
512512 };
513513 }
514514
515 pub fn checkLineMatch(self: &LineNumberProgram) -> %?LineInfo {
515 pub fn checkLineMatch(self: &LineNumberProgram) %?LineInfo {
516516 if (self.target_address >= self.prev_address and self.target_address < self.address) {
517517 const file_entry = if (self.prev_file == 0) {
518518 return error.MissingDebugInfo;
......@@ -524,7 +524,7 @@ const LineNumberProgram = struct {
524524 return error.InvalidDebugInfo;
525525 } else self.include_dirs[file_entry.dir_index];
526526 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);
528528 return LineInfo {
529529 .line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
530530 .column = self.prev_column,
......@@ -544,7 +544,7 @@ const LineNumberProgram = struct {
544544 }
545545};
546546
547fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
547fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) %[]u8 {
548548 var buf = ArrayList(u8).init(allocator);
549549 while (true) {
550550 const byte = try in_stream.readByte();
......@@ -555,58 +555,58 @@ fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
555555 return buf.toSlice();
556556}
557557
558fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 {
558fn getString(st: &ElfStackTrace, offset: u64) %[]u8 {
559559 const pos = st.debug_str.offset + offset;
560560 try st.self_exe_file.seekTo(pos);
561561 return st.readString();
562562}
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 {
565565 const buf = try global_allocator.alloc(u8, size);
566 %defer global_allocator.free(buf);
566 errdefer global_allocator.free(buf);
567567 if ((try in_stream.read(buf)) < size) return error.EndOfFile;
568568 return buf;
569569}
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 {
572572 const buf = try readAllocBytes(allocator, in_stream, size);
573573 return FormValue { .Block = buf };
574574}
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 {
577577 const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
578578 return parseFormValueBlockLen(allocator, in_stream, block_len);
579579}
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 {
582582 return FormValue { .Const = Constant {
583583 .signed = signed,
584584 .payload = try readAllocBytes(allocator, in_stream, size),
585585 }};
586586}
587587
588fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {
588fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) %u64 {
589589 return if (is_64) try in_stream.readIntLe(u64)
590590 else u64(try in_stream.readIntLe(u32)) ;
591591}
592592
593fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
593fn parseFormValueTargetAddrSize(in_stream: &io.InStream) %u64 {
594594 return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))
595595 else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
596596 else unreachable;
597597}
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 {
600600 const buf = try readAllocBytes(allocator, in_stream, size);
601601 return FormValue { .Ref = buf };
602602}
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 {
605605 const block_len = try in_stream.readIntLe(T);
606606 return parseFormValueRefLen(allocator, in_stream, block_len);
607607}
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 {
610610 return switch (form_id) {
611611 DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },
612612 DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
......@@ -656,7 +656,7 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
656656 };
657657}
658658
659fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
659fn parseAbbrevTable(st: &ElfStackTrace) %AbbrevTable {
660660 const in_file = &st.self_exe_file;
661661 var in_file_stream = io.FileInStream.init(in_file);
662662 const in_stream = &in_file_stream.stream;
......@@ -688,7 +688,7 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
688688
689689/// Gets an already existing AbbrevTable given the abbrev_offset, or if not found,
690690/// 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 {
692692 for (st.abbrev_table_list.toSlice()) |*header| {
693693 if (header.offset == abbrev_offset) {
694694 return &header.table;
......@@ -702,7 +702,7 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable
702702 return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;
703703}
704704
705fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&const AbbrevTableEntry {
705fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) ?&const AbbrevTableEntry {
706706 for (abbrev_table.toSliceConst()) |*table_entry| {
707707 if (table_entry.abbrev_code == abbrev_code)
708708 return table_entry;
......@@ -710,7 +710,7 @@ fn getAbbrevTableEntry(abbrev_table: &const AbbrevTable, abbrev_code: u64) -> ?&
710710 return null;
711711}
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 {
714714 const in_file = &st.self_exe_file;
715715 var in_file_stream = io.FileInStream.init(in_file);
716716 const in_stream = &in_file_stream.stream;
......@@ -732,7 +732,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -
732732 return result;
733733}
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 {
736736 const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);
737737
738738 const in_file = &st.self_exe_file;
......@@ -910,7 +910,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
910910 return error.MissingDebugInfo;
911911}
912912
913fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
913fn scanAllCompileUnits(st: &ElfStackTrace) %void {
914914 const debug_info_end = st.debug_info.offset + st.debug_info.size;
915915 var this_unit_offset = st.debug_info.offset;
916916 var cu_index: usize = 0;
......@@ -986,7 +986,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
986986 }
987987}
988988
989fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUnit {
989fn findCompileUnit(st: &ElfStackTrace, target_address: u64) %&const CompileUnit {
990990 var in_file_stream = io.FileInStream.init(&st.self_exe_file);
991991 const in_stream = &in_file_stream.stream;
992992 for (st.compile_unit_list.toSlice()) |*compile_unit| {
......@@ -1022,7 +1022,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
10221022 return error.MissingDebugInfo;
10231023}
10241024
1025fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
1025fn readInitialLength(in_stream: &io.InStream, is_64: &bool) %u64 {
10261026 const first_32_bits = try in_stream.readIntLe(u32);
10271027 *is_64 = (first_32_bits == 0xffffffff);
10281028 if (*is_64) {
......@@ -1033,7 +1033,7 @@ fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
10331033 }
10341034}
10351035
1036fn readULeb128(in_stream: &io.InStream) -> %u64 {
1036fn readULeb128(in_stream: &io.InStream) %u64 {
10371037 var result: u64 = 0;
10381038 var shift: usize = 0;
10391039
......@@ -1054,7 +1054,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 {
10541054 }
10551055}
10561056
1057fn readILeb128(in_stream: &io.InStream) -> %i64 {
1057fn readILeb128(in_stream: &io.InStream) %i64 {
10581058 var result: i64 = 0;
10591059 var shift: usize = 0;
10601060
std/elf.zig+6-6
......@@ -81,14 +81,14 @@ pub const Elf = struct {
8181 prealloc_file: io.File,
8282
8383 /// 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 {
8585 try elf.prealloc_file.open(path);
8686 try elf.openFile(allocator, &elf.prealloc_file);
8787 elf.auto_close_stream = true;
8888 }
8989
9090 /// 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 {
9292 elf.allocator = allocator;
9393 elf.in_file = file;
9494 elf.auto_close_stream = false;
......@@ -183,7 +183,7 @@ pub const Elf = struct {
183183 try elf.in_file.seekTo(elf.section_header_offset);
184184
185185 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
188188 if (elf.is_64) {
189189 if (sh_entry_size != 64) return error.InvalidFormat;
......@@ -232,14 +232,14 @@ pub const Elf = struct {
232232 }
233233 }
234234
235 pub fn close(elf: &Elf) {
235 pub fn close(elf: &Elf) void {
236236 elf.allocator.free(elf.section_headers);
237237
238238 if (elf.auto_close_stream)
239239 elf.in_file.close();
240240 }
241241
242 pub fn findSection(elf: &Elf, name: []const u8) -> %?&SectionHeader {
242 pub fn findSection(elf: &Elf, name: []const u8) %?&SectionHeader {
243243 var file_stream = io.FileInStream.init(elf.in_file);
244244 const in = &file_stream.stream;
245245
......@@ -263,7 +263,7 @@ pub const Elf = struct {
263263 return null;
264264 }
265265
266 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {
266 pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) %void {
267267 try elf.in_file.seekTo(elf_section.offset);
268268 }
269269};
std/endian.zig+4-4
......@@ -1,19 +1,19 @@
11const mem = @import("mem.zig");
22const builtin = @import("builtin");
33
4pub fn swapIfLe(comptime T: type, x: T) -> T {
4pub fn swapIfLe(comptime T: type, x: T) T {
55 return swapIf(builtin.Endian.Little, T, x);
66}
77
8pub fn swapIfBe(comptime T: type, x: T) -> T {
8pub fn swapIfBe(comptime T: type, x: T) T {
99 return swapIf(builtin.Endian.Big, T, x);
1010}
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 {
1313 return if (builtin.endian == endian) swap(T, x) else x;
1414}
1515
16pub fn swap(comptime T: type, x: T) -> T {
16pub fn swap(comptime T: type, x: T) T {
1717 var buf: [@sizeOf(T)]u8 = undefined;
1818 mem.writeInt(buf[0..], x, builtin.Endian.Little);
1919 return mem.readInt(buf, T, builtin.Endian.Big);
std/fmt/errol/enum3.zig+1-1
......@@ -438,7 +438,7 @@ const Slab = struct {
438438 exp: i32,
439439};
440440
441fn slab(str: []const u8, exp: i32) -> Slab {
441fn slab(str: []const u8, exp: i32) Slab {
442442 return Slab {
443443 .str = str,
444444 .exp = exp,
std/fmt/errol/index.zig+16-16
......@@ -13,7 +13,7 @@ pub const FloatDecimal = struct {
1313};
1414
1515/// Corrected Errol3 double to ASCII conversion.
16pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
16pub fn errol3(value: f64, buffer: []u8) FloatDecimal {
1717 const bits = @bitCast(u64, value);
1818 const i = tableLowerBound(bits);
1919 if (i < enum3.len and enum3[i] == bits) {
......@@ -30,7 +30,7 @@ pub fn errol3(value: f64, buffer: []u8) -> FloatDecimal {
3030}
3131
3232/// Uncorrected Errol3 double to ASCII conversion.
33fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
33fn errol3u(val: f64, buffer: []u8) FloatDecimal {
3434 // check if in integer or fixed range
3535
3636 if (val > 9.007199254740992e15 and val < 3.40282366920938e+38) {
......@@ -133,7 +133,7 @@ fn errol3u(val: f64, buffer: []u8) -> FloatDecimal {
133133 };
134134}
135135
136fn tableLowerBound(k: u64) -> usize {
136fn tableLowerBound(k: u64) usize {
137137 var i = enum3.len;
138138 var j: usize = 0;
139139
......@@ -153,7 +153,7 @@ fn tableLowerBound(k: u64) -> usize {
153153/// @in: The HP number.
154154/// @val: The double.
155155/// &returns: The HP number.
156fn hpProd(in: &const HP, val: f64) -> HP {
156fn hpProd(in: &const HP, val: f64) HP {
157157 var hi: f64 = undefined;
158158 var lo: f64 = undefined;
159159 split(in.val, &hi, &lo);
......@@ -175,12 +175,12 @@ fn hpProd(in: &const HP, val: f64) -> HP {
175175/// @val: The double.
176176/// @hi: The high bits.
177177/// @lo: The low bits.
178fn split(val: f64, hi: &f64, lo: &f64) {
178fn split(val: f64, hi: &f64, lo: &f64) void {
179179 *hi = gethi(val);
180180 *lo = val - *hi;
181181}
182182
183fn gethi(in: f64) -> f64 {
183fn gethi(in: f64) f64 {
184184 const bits = @bitCast(u64, in);
185185 const new_bits = bits & 0xFFFFFFFFF8000000;
186186 return @bitCast(f64, new_bits);
......@@ -188,7 +188,7 @@ fn gethi(in: f64) -> f64 {
188188
189189/// Normalize the number by factoring in the error.
190190/// @hp: The float pair.
191fn hpNormalize(hp: &HP) {
191fn hpNormalize(hp: &HP) void {
192192 const val = hp.val;
193193
194194 hp.val += hp.off;
......@@ -197,7 +197,7 @@ fn hpNormalize(hp: &HP) {
197197
198198/// Divide the high-precision number by ten.
199199/// @hp: The high-precision number
200fn hpDiv10(hp: &HP) {
200fn hpDiv10(hp: &HP) void {
201201 var val = hp.val;
202202
203203 hp.val /= 10.0;
......@@ -213,7 +213,7 @@ fn hpDiv10(hp: &HP) {
213213
214214/// Multiply the high-precision number by ten.
215215/// @hp: The high-precision number
216fn hpMul10(hp: &HP) {
216fn hpMul10(hp: &HP) void {
217217 const val = hp.val;
218218
219219 hp.val *= 10.0;
......@@ -233,7 +233,7 @@ fn hpMul10(hp: &HP) {
233233/// @val: The val.
234234/// @buf: The output buffer.
235235/// &return: The exponent.
236fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
236fn errolInt(val: f64, buffer: []u8) FloatDecimal {
237237 const pow19 = u128(1e19);
238238
239239 assert((val > 9.007199254740992e15) and val < (3.40282366920938e38));
......@@ -291,7 +291,7 @@ fn errolInt(val: f64, buffer: []u8) -> FloatDecimal {
291291/// @val: The val.
292292/// @buf: The output buffer.
293293/// &return: The exponent.
294fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
294fn errolFixed(val: f64, buffer: []u8) FloatDecimal {
295295 assert((val >= 16.0) and (val < 9.007199254740992e15));
296296
297297 const u = u64(val);
......@@ -347,11 +347,11 @@ fn errolFixed(val: f64, buffer: []u8) -> FloatDecimal {
347347 };
348348}
349349
350fn fpnext(val: f64) -> f64 {
350fn fpnext(val: f64) f64 {
351351 return @bitCast(f64, @bitCast(u64, val) +% 1);
352352}
353353
354fn fpprev(val: f64) -> f64 {
354fn fpprev(val: f64) f64 {
355355 return @bitCast(f64, @bitCast(u64, val) -% 1);
356356}
357357
......@@ -373,7 +373,7 @@ pub const c_digits_lut = []u8 {
373373 '9', '8', '9', '9',
374374};
375375
376fn u64toa(value_param: u64, buffer: []u8) -> usize {
376fn u64toa(value_param: u64, buffer: []u8) usize {
377377 var value = value_param;
378378 const kTen8: u64 = 100000000;
379379 const kTen9: u64 = kTen8 * 10;
......@@ -606,7 +606,7 @@ fn u64toa(value_param: u64, buffer: []u8) -> usize {
606606 return buf_index;
607607}
608608
609fn fpeint(from: f64) -> u128 {
609fn fpeint(from: f64) u128 {
610610 const bits = @bitCast(u64, from);
611611 assert((bits & ((1 << 52) - 1)) == 0);
612612
......@@ -621,7 +621,7 @@ fn fpeint(from: f64) -> u128 {
621621/// @a: Integer a.
622622/// @b: Integer b.
623623/// &returns: An index within [0, 19).
624fn mismatch10(a: u64, b: u64) -> i32 {
624fn mismatch10(a: u64, b: u64) i32 {
625625 const pow10 = 10000000000;
626626 const af = a / pow10;
627627 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
2424/// Renders fmt string with args, calling output with slices of bytes.
2525/// If `output` returns an error, the error is returned from `format` and
2626/// `output` is not called again.
27pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
28 comptime fmt: []const u8, args: ...) -> %void
27pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
28 comptime fmt: []const u8, args: ...) %void
2929{
3030 comptime var start_index = 0;
3131 comptime var state = State.Start;
......@@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
191191 }
192192}
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 {
195195 const T = @typeOf(value);
196196 switch (@typeId(T)) {
197197 builtin.TypeId.Int => {
......@@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
240240 }
241241}
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 {
244244 return output(context, (&c)[0..1]);
245245}
246246
247247pub fn formatBuf(buf: []const u8, width: usize,
248 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
248 context: var, output: fn(@typeOf(context), []const u8)%void) %void
249249{
250250 try output(context, buf);
251251
......@@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
256256 }
257257}
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 {
260260 var x = f64(value);
261261
262262 // Errol doesn't handle these special cases.
......@@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
294294 }
295295}
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 {
298298 var x = f64(value);
299299
300300 // Errol doesn't handle these special cases.
......@@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
336336
337337
338338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
339 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
339 context: var, output: fn(@typeOf(context), []const u8)%void) %void
340340{
341341 if (@typeOf(value).is_signed) {
342342 return formatIntSigned(value, base, uppercase, width, context, output);
......@@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
346346}
347347
348348fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
349 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
349 context: var, output: fn(@typeOf(context), []const u8)%void) %void
350350{
351351 const uint = @IntType(false, @typeOf(value).bit_count);
352352 if (value < 0) {
......@@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
367367}
368368
369369fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
370 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
370 context: var, output: fn(@typeOf(context), []const u8)%void) %void
371371{
372372 // max_int_digits accounts for the minus sign. when printing an unsigned
373373 // number we don't need to do that.
......@@ -405,7 +405,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
405405 }
406406}
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 {
409409 var context = FormatIntBuf {
410410 .out_buf = out_buf,
411411 .index = 0,
......@@ -417,12 +417,12 @@ const FormatIntBuf = struct {
417417 out_buf: []u8,
418418 index: usize,
419419};
420fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) -> %void {
420fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) %void {
421421 mem.copy(u8, context.out_buf[context.index..], bytes);
422422 context.index += bytes.len;
423423}
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 {
426426 if (!T.is_signed)
427427 return parseUnsigned(T, buf, radix);
428428 if (buf.len == 0)
......@@ -446,7 +446,7 @@ test "fmt.parseInt" {
446446 assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
447447}
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 {
450450 var x: T = 0;
451451
452452 for (buf) |c| {
......@@ -459,7 +459,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
459459}
460460
461461error InvalidChar;
462fn charToDigit(c: u8, radix: u8) -> %u8 {
462fn charToDigit(c: u8, radix: u8) %u8 {
463463 const value = switch (c) {
464464 '0' ... '9' => c - '0',
465465 'A' ... 'Z' => c - 'A' + 10,
......@@ -473,7 +473,7 @@ fn charToDigit(c: u8, radix: u8) -> %u8 {
473473 return value;
474474}
475475
476fn digitToChar(digit: u8, uppercase: bool) -> u8 {
476fn digitToChar(digit: u8, uppercase: bool) u8 {
477477 return switch (digit) {
478478 0 ... 9 => digit + '0',
479479 10 ... 35 => digit + ((if (uppercase) u8('A') else u8('a')) - 10),
......@@ -486,19 +486,19 @@ const BufPrintContext = struct {
486486};
487487
488488error BufferTooSmall;
489fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void {
489fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) %void {
490490 if (context.remaining.len < bytes.len) return error.BufferTooSmall;
491491 mem.copy(u8, context.remaining, bytes);
492492 context.remaining = context.remaining[bytes.len..];
493493}
494494
495pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 {
495pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) %[]u8 {
496496 var context = BufPrintContext { .remaining = buf, };
497497 try format(&context, bufPrintWrite, fmt, args);
498498 return buf[0..buf.len - context.remaining.len];
499499}
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 {
502502 var size: usize = 0;
503503 // Cannot fail because `countSize` cannot fail.
504504 format(&size, countSize, fmt, args) catch unreachable;
......@@ -506,7 +506,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...
506506 return bufPrint(buf, fmt, args);
507507}
508508
509fn countSize(size: &usize, bytes: []const u8) -> %void {
509fn countSize(size: &usize, bytes: []const u8) %void {
510510 *size += bytes.len;
511511}
512512
......@@ -528,7 +528,7 @@ test "buf print int" {
528528 assert(mem.eql(u8, bufPrintIntToSlice(buf, i32(-42), 10, false, 3), "-42"));
529529}
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 {
532532 return buf[0..formatIntBuf(buf, value, base, uppercase, width)];
533533}
534534
......@@ -644,7 +644,7 @@ test "fmt.format" {
644644 }
645645}
646646
647pub fn trim(buf: []const u8) -> []const u8 {
647pub fn trim(buf: []const u8) []const u8 {
648648 var start: usize = 0;
649649 while (start < buf.len and isWhiteSpace(buf[start])) : (start += 1) { }
650650
......@@ -671,7 +671,7 @@ test "fmt.trim" {
671671 assert(mem.eql(u8, "abc", trim("abc ")));
672672}
673673
674pub fn isWhiteSpace(byte: u8) -> bool {
674pub fn isWhiteSpace(byte: u8) bool {
675675 return switch (byte) {
676676 ' ', '\t', '\n', '\r' => true,
677677 else => false,
std/hash_map.zig+18-18
......@@ -10,8 +10,8 @@ const want_modification_safety = builtin.mode != builtin.Mode.ReleaseFast;
1010const debug_u32 = if (want_modification_safety) u32 else void;
1111
1212pub fn HashMap(comptime K: type, comptime V: type,
13 comptime hash: fn(key: K)->u32,
14 comptime eql: fn(a: K, b: K)->bool) -> type
13 comptime hash: fn(key: K)u32,
14 comptime eql: fn(a: K, b: K)bool) type
1515{
1616 return struct {
1717 entries: []Entry,
......@@ -39,7 +39,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
3939 // used to detect concurrent modification
4040 initial_modification_count: debug_u32,
4141
42 pub fn next(it: &Iterator) -> ?&Entry {
42 pub fn next(it: &Iterator) ?&Entry {
4343 if (want_modification_safety) {
4444 assert(it.initial_modification_count == it.hm.modification_count); // concurrent modification
4545 }
......@@ -56,7 +56,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
5656 }
5757 };
5858
59 pub fn init(allocator: &Allocator) -> Self {
59 pub fn init(allocator: &Allocator) Self {
6060 return Self {
6161 .entries = []Entry{},
6262 .allocator = allocator,
......@@ -66,11 +66,11 @@ pub fn HashMap(comptime K: type, comptime V: type,
6666 };
6767 }
6868
69 pub fn deinit(hm: &Self) {
69 pub fn deinit(hm: &Self) void {
7070 hm.allocator.free(hm.entries);
7171 }
7272
73 pub fn clear(hm: &Self) {
73 pub fn clear(hm: &Self) void {
7474 for (hm.entries) |*entry| {
7575 entry.used = false;
7676 }
......@@ -80,7 +80,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
8080 }
8181
8282 /// 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 {
8484 if (hm.entries.len == 0) {
8585 try hm.initCapacity(16);
8686 }
......@@ -102,18 +102,18 @@ pub fn HashMap(comptime K: type, comptime V: type,
102102 return hm.internalPut(key, value);
103103 }
104104
105 pub fn get(hm: &Self, key: K) -> ?&Entry {
105 pub fn get(hm: &Self, key: K) ?&Entry {
106106 if (hm.entries.len == 0) {
107107 return null;
108108 }
109109 return hm.internalGet(key);
110110 }
111111
112 pub fn contains(hm: &Self, key: K) -> bool {
112 pub fn contains(hm: &Self, key: K) bool {
113113 return hm.get(key) != null;
114114 }
115115
116 pub fn remove(hm: &Self, key: K) -> ?&Entry {
116 pub fn remove(hm: &Self, key: K) ?&Entry {
117117 hm.incrementModificationCount();
118118 const start_index = hm.keyToIndex(key);
119119 {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,
142142 return null;
143143 }
144144
145 pub fn iterator(hm: &const Self) -> Iterator {
145 pub fn iterator(hm: &const Self) Iterator {
146146 return Iterator {
147147 .hm = hm,
148148 .count = 0,
......@@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
151151 };
152152 }
153153
154 fn initCapacity(hm: &Self, capacity: usize) -> %void {
154 fn initCapacity(hm: &Self, capacity: usize) %void {
155155 hm.entries = try hm.allocator.alloc(Entry, capacity);
156156 hm.size = 0;
157157 hm.max_distance_from_start_index = 0;
......@@ -160,14 +160,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
160160 }
161161 }
162162
163 fn incrementModificationCount(hm: &Self) {
163 fn incrementModificationCount(hm: &Self) void {
164164 if (want_modification_safety) {
165165 hm.modification_count +%= 1;
166166 }
167167 }
168168
169169 /// 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 {
171171 var key = orig_key;
172172 var value = *orig_value;
173173 const start_index = hm.keyToIndex(key);
......@@ -217,7 +217,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
217217 unreachable; // put into a full map
218218 }
219219
220 fn internalGet(hm: &Self, key: K) -> ?&Entry {
220 fn internalGet(hm: &Self, key: K) ?&Entry {
221221 const start_index = hm.keyToIndex(key);
222222 {var roll_over: usize = 0; while (roll_over <= hm.max_distance_from_start_index) : (roll_over += 1) {
223223 const index = (start_index + roll_over) % hm.entries.len;
......@@ -229,7 +229,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
229229 return null;
230230 }
231231
232 fn keyToIndex(hm: &Self, key: K) -> usize {
232 fn keyToIndex(hm: &Self, key: K) usize {
233233 return usize(hash(key)) % hm.entries.len;
234234 }
235235 };
......@@ -254,10 +254,10 @@ test "basicHashMapTest" {
254254 assert(map.get(2) == null);
255255}
256256
257fn hash_i32(x: i32) -> u32 {
257fn hash_i32(x: i32) u32 {
258258 return @bitCast(u32, x);
259259}
260260
261fn eql_i32(a: i32, b: i32) -> bool {
261fn eql_i32(a: i32, b: i32) bool {
262262 return a == b;
263263}
std/heap.zig+10-10
......@@ -18,14 +18,14 @@ var c_allocator_state = Allocator {
1818 .freeFn = cFree,
1919};
2020
21fn cAlloc(self: &Allocator, n: usize, alignment: u29) -> %[]u8 {
21fn cAlloc(self: &Allocator, n: usize, alignment: u29) %[]u8 {
2222 return if (c.malloc(usize(n))) |buf|
2323 @ptrCast(&u8, buf)[0..n]
2424 else
2525 error.OutOfMemory;
2626}
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 {
2929 const old_ptr = @ptrCast(&c_void, old_mem.ptr);
3030 if (c.realloc(old_ptr, new_size)) |buf| {
3131 return @ptrCast(&u8, buf)[0..new_size];
......@@ -36,7 +36,7 @@ fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ->
3636 }
3737}
3838
39fn cFree(self: &Allocator, old_mem: []u8) {
39fn cFree(self: &Allocator, old_mem: []u8) void {
4040 const old_ptr = @ptrCast(&c_void, old_mem.ptr);
4141 c.free(old_ptr);
4242}
......@@ -47,7 +47,7 @@ pub const IncrementingAllocator = struct {
4747 end_index: usize,
4848 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 {
5151 switch (builtin.os) {
5252 Os.linux, Os.macosx, Os.ios => {
5353 const p = os.posix;
......@@ -85,7 +85,7 @@ pub const IncrementingAllocator = struct {
8585 }
8686 }
8787
88 fn deinit(self: &IncrementingAllocator) {
88 fn deinit(self: &IncrementingAllocator) void {
8989 switch (builtin.os) {
9090 Os.linux, Os.macosx, Os.ios => {
9191 _ = os.posix.munmap(self.bytes.ptr, self.bytes.len);
......@@ -97,15 +97,15 @@ pub const IncrementingAllocator = struct {
9797 }
9898 }
9999
100 fn reset(self: &IncrementingAllocator) {
100 fn reset(self: &IncrementingAllocator) void {
101101 self.end_index = 0;
102102 }
103103
104 fn bytesLeft(self: &const IncrementingAllocator) -> usize {
104 fn bytesLeft(self: &const IncrementingAllocator) usize {
105105 return self.bytes.len - self.end_index;
106106 }
107107
108 fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 {
108 fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
109109 const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
110110 const addr = @ptrToInt(&self.bytes[self.end_index]);
111111 const rem = @rem(addr, alignment);
......@@ -120,7 +120,7 @@ pub const IncrementingAllocator = struct {
120120 return result;
121121 }
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 {
124124 if (new_size <= old_mem.len) {
125125 return old_mem[0..new_size];
126126 } else {
......@@ -130,7 +130,7 @@ pub const IncrementingAllocator = struct {
130130 }
131131 }
132132
133 fn free(allocator: &Allocator, bytes: []u8) {
133 fn free(allocator: &Allocator, bytes: []u8) void {
134134 // Do nothing. That's the point of an incrementing allocator.
135135 }
136136};
std/io.zig+91-51
......@@ -48,8 +48,9 @@ error PathNotFound;
4848error OutOfMemory;
4949error Unseekable;
5050error EndOfFile;
51error FilePosLargerThanPointerRange;
5152
52pub fn getStdErr() -> %File {
53pub fn getStdErr() %File {
5354 const handle = if (is_windows)
5455 try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
5556 else if (is_posix)
......@@ -59,7 +60,7 @@ pub fn getStdErr() -> %File {
5960 return File.openHandle(handle);
6061}
6162
62pub fn getStdOut() -> %File {
63pub fn getStdOut() %File {
6364 const handle = if (is_windows)
6465 try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
6566 else if (is_posix)
......@@ -69,7 +70,7 @@ pub fn getStdOut() -> %File {
6970 return File.openHandle(handle);
7071}
7172
72pub fn getStdIn() -> %File {
73pub fn getStdIn() %File {
7374 const handle = if (is_windows)
7475 try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
7576 else if (is_posix)
......@@ -84,7 +85,7 @@ pub const FileInStream = struct {
8485 file: &File,
8586 stream: InStream,
8687
87 pub fn init(file: &File) -> FileInStream {
88 pub fn init(file: &File) FileInStream {
8889 return FileInStream {
8990 .file = file,
9091 .stream = InStream {
......@@ -93,7 +94,7 @@ pub const FileInStream = struct {
9394 };
9495 }
9596
96 fn readFn(in_stream: &InStream, buffer: []u8) -> %usize {
97 fn readFn(in_stream: &InStream, buffer: []u8) %usize {
9798 const self = @fieldParentPtr(FileInStream, "stream", in_stream);
9899 return self.file.read(buffer);
99100 }
......@@ -104,7 +105,7 @@ pub const FileOutStream = struct {
104105 file: &File,
105106 stream: OutStream,
106107
107 pub fn init(file: &File) -> FileOutStream {
108 pub fn init(file: &File) FileOutStream {
108109 return FileOutStream {
109110 .file = file,
110111 .stream = OutStream {
......@@ -113,7 +114,7 @@ pub const FileOutStream = struct {
113114 };
114115 }
115116
116 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
117 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
117118 const self = @fieldParentPtr(FileOutStream, "stream", out_stream);
118119 return self.file.write(bytes);
119120 }
......@@ -128,7 +129,7 @@ pub const File = struct {
128129 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
129130 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
130131 /// 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 {
132133 if (is_posix) {
133134 const flags = system.O_LARGEFILE|system.O_RDONLY;
134135 const fd = try os.posixOpen(path, flags, 0, allocator);
......@@ -143,7 +144,7 @@ pub const File = struct {
143144 }
144145
145146 /// 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 {
147148 return openWriteMode(path, 0o666, allocator);
148149
149150 }
......@@ -153,7 +154,7 @@ pub const File = struct {
153154 /// size buffer is too small, and the provided allocator is null, error.NameTooLong is returned.
154155 /// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
155156 /// 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 {
157158 if (is_posix) {
158159 const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;
159160 const fd = try os.posixOpen(path, flags, mode, allocator);
......@@ -169,7 +170,7 @@ pub const File = struct {
169170
170171 }
171172
172 pub fn openHandle(handle: os.FileHandle) -> File {
173 pub fn openHandle(handle: os.FileHandle) File {
173174 return File {
174175 .handle = handle,
175176 };
......@@ -178,17 +179,17 @@ pub const File = struct {
178179
179180 /// Upon success, the stream is in an uninitialized state. To continue using it,
180181 /// you must use the open() function.
181 pub fn close(self: &File) {
182 pub fn close(self: &File) void {
182183 os.close(self.handle);
183184 self.handle = undefined;
184185 }
185186
186187 /// Calls `os.isTty` on `self.handle`.
187 pub fn isTty(self: &File) -> bool {
188 pub fn isTty(self: &File) bool {
188189 return os.isTty(self.handle);
189190 }
190191
191 pub fn seekForward(self: &File, amount: isize) -> %void {
192 pub fn seekForward(self: &File, amount: isize) %void {
192193 switch (builtin.os) {
193194 Os.linux, Os.macosx, Os.ios => {
194195 const result = system.lseek(self.handle, amount, system.SEEK_CUR);
......@@ -204,14 +205,24 @@ pub const File = struct {
204205 };
205206 }
206207 },
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 },
207217 else => @compileError("unsupported OS"),
208218 }
209219 }
210220
211 pub fn seekTo(self: &File, pos: usize) -> %void {
221 pub fn seekTo(self: &File, pos: usize) %void {
212222 switch (builtin.os) {
213223 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);
215226 const err = system.getErrno(result);
216227 if (err > 0) {
217228 return switch (err) {
......@@ -224,11 +235,21 @@ pub const File = struct {
224235 };
225236 }
226237 },
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 },
227248 else => @compileError("unsupported OS: " ++ @tagName(builtin.os)),
228249 }
229250 }
230251
231 pub fn getPos(self: &File) -> %usize {
252 pub fn getPos(self: &File) %usize {
232253 switch (builtin.os) {
233254 Os.linux, Os.macosx, Os.ios => {
234255 const result = system.lseek(self.handle, 0, system.SEEK_CUR);
......@@ -245,11 +266,30 @@ pub const File = struct {
245266 }
246267 return result;
247268 },
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 },
248288 else => @compileError("unsupported OS"),
249289 }
250290 }
251291
252 pub fn getEndPos(self: &File) -> %usize {
292 pub fn getEndPos(self: &File) %usize {
253293 if (is_posix) {
254294 var stat: system.Stat = undefined;
255295 const err = system.getErrno(system.fstat(self.handle, &stat));
......@@ -278,7 +318,7 @@ pub const File = struct {
278318 }
279319 }
280320
281 pub fn read(self: &File, buffer: []u8) -> %usize {
321 pub fn read(self: &File, buffer: []u8) %usize {
282322 if (is_posix) {
283323 var index: usize = 0;
284324 while (index < buffer.len) {
......@@ -320,7 +360,7 @@ pub const File = struct {
320360 }
321361 }
322362
323 fn write(self: &File, bytes: []const u8) -> %void {
363 fn write(self: &File, bytes: []const u8) %void {
324364 if (is_posix) {
325365 try os.posixWrite(self.handle, bytes);
326366 } else if (is_windows) {
......@@ -338,12 +378,12 @@ pub const InStream = struct {
338378 /// Return the number of bytes read. If the number read is smaller than buf.len, it
339379 /// means the stream reached the end. Reaching the end of a stream is not an error
340380 /// condition.
341 readFn: fn(self: &InStream, buffer: []u8) -> %usize,
381 readFn: fn(self: &InStream, buffer: []u8) %usize,
342382
343383 /// Replaces `buffer` contents by reading from the stream until it is finished.
344384 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
345385 /// 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 {
347387 try buffer.resize(0);
348388
349389 var actual_buf_len: usize = 0;
......@@ -368,7 +408,7 @@ pub const InStream = struct {
368408 /// memory would be greater than `max_size`, returns `error.StreamTooLong`.
369409 /// Caller owns returned memory.
370410 /// 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 {
372412 var buf = Buffer.initNull(allocator);
373413 defer buf.deinit();
374414
......@@ -380,7 +420,7 @@ pub const InStream = struct {
380420 /// Does not include the delimiter in the result.
381421 /// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
382422 /// 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 {
384424 try buf.resize(0);
385425
386426 while (true) {
......@@ -403,7 +443,7 @@ pub const InStream = struct {
403443 /// Caller owns returned memory.
404444 /// If this function returns an error, the contents from the stream read so far are lost.
405445 pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,
406 delimiter: u8, max_size: usize) -> %[]u8
446 delimiter: u8, max_size: usize) %[]u8
407447 {
408448 var buf = Buffer.initNull(allocator);
409449 defer buf.deinit();
......@@ -415,43 +455,43 @@ pub const InStream = struct {
415455 /// Returns the number of bytes read. If the number read is smaller than buf.len, it
416456 /// means the stream reached the end. Reaching the end of a stream is not an error
417457 /// condition.
418 pub fn read(self: &InStream, buffer: []u8) -> %usize {
458 pub fn read(self: &InStream, buffer: []u8) %usize {
419459 return self.readFn(self, buffer);
420460 }
421461
422462 /// 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 {
424464 const amt_read = try self.read(buf);
425465 if (amt_read < buf.len) return error.EndOfStream;
426466 }
427467
428468 /// Reads 1 byte from the stream or returns `error.EndOfStream`.
429 pub fn readByte(self: &InStream) -> %u8 {
469 pub fn readByte(self: &InStream) %u8 {
430470 var result: [1]u8 = undefined;
431471 try self.readNoEof(result[0..]);
432472 return result[0];
433473 }
434474
435475 /// Same as `readByte` except the returned byte is signed.
436 pub fn readByteSigned(self: &InStream) -> %i8 {
476 pub fn readByteSigned(self: &InStream) %i8 {
437477 return @bitCast(i8, try self.readByte());
438478 }
439479
440 pub fn readIntLe(self: &InStream, comptime T: type) -> %T {
480 pub fn readIntLe(self: &InStream, comptime T: type) %T {
441481 return self.readInt(builtin.Endian.Little, T);
442482 }
443483
444 pub fn readIntBe(self: &InStream, comptime T: type) -> %T {
484 pub fn readIntBe(self: &InStream, comptime T: type) %T {
445485 return self.readInt(builtin.Endian.Big, T);
446486 }
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 {
449489 var bytes: [@sizeOf(T)]u8 = undefined;
450490 try self.readNoEof(bytes[0..]);
451491 return mem.readInt(bytes, T, endian);
452492 }
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 {
455495 assert(size <= @sizeOf(T));
456496 assert(size <= 8);
457497 var input_buf: [8]u8 = undefined;
......@@ -464,22 +504,22 @@ pub const InStream = struct {
464504};
465505
466506pub 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 {
470510 return std.fmt.format(self, self.writeFn, format, args);
471511 }
472512
473 pub fn write(self: &OutStream, bytes: []const u8) -> %void {
513 pub fn write(self: &OutStream, bytes: []const u8) %void {
474514 return self.writeFn(self, bytes);
475515 }
476516
477 pub fn writeByte(self: &OutStream, byte: u8) -> %void {
517 pub fn writeByte(self: &OutStream, byte: u8) %void {
478518 const slice = (&byte)[0..1];
479519 return self.writeFn(self, slice);
480520 }
481521
482 pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) -> %void {
522 pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) %void {
483523 const slice = (&byte)[0..1];
484524 var i: usize = 0;
485525 while (i < n) : (i += 1) {
......@@ -492,25 +532,25 @@ pub const OutStream = struct {
492532/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed
493533/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.
494534/// 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 {
496536 var file = try File.openWrite(path, allocator);
497537 defer file.close();
498538 try file.write(data);
499539}
500540
501541/// 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 {
503543 return readFileAllocExtra(path, allocator, 0);
504544}
505545/// On success, caller owns returned buffer.
506546/// 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 {
508548 var file = try File.openRead(path, allocator);
509549 defer file.close();
510550
511551 const size = try file.getEndPos();
512552 const buf = try allocator.alloc(u8, size + extra_len);
513 %defer allocator.free(buf);
553 errdefer allocator.free(buf);
514554
515555 var adapter = FileInStream.init(&file);
516556 try adapter.stream.readNoEof(buf[0..size]);
......@@ -519,7 +559,7 @@ pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len
519559
520560pub const BufferedInStream = BufferedInStreamCustom(os.page_size);
521561
522pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
562pub fn BufferedInStreamCustom(comptime buffer_size: usize) type {
523563 return struct {
524564 const Self = this;
525565
......@@ -531,7 +571,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
531571 start_index: usize,
532572 end_index: usize,
533573
534 pub fn init(unbuffered_in_stream: &InStream) -> Self {
574 pub fn init(unbuffered_in_stream: &InStream) Self {
535575 return Self {
536576 .unbuffered_in_stream = unbuffered_in_stream,
537577 .buffer = undefined,
......@@ -549,7 +589,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
549589 };
550590 }
551591
552 fn readFn(in_stream: &InStream, dest: []u8) -> %usize {
592 fn readFn(in_stream: &InStream, dest: []u8) %usize {
553593 const self = @fieldParentPtr(Self, "stream", in_stream);
554594
555595 var dest_index: usize = 0;
......@@ -590,7 +630,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
590630
591631pub const BufferedOutStream = BufferedOutStreamCustom(os.page_size);
592632
593pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
633pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
594634 return struct {
595635 const Self = this;
596636
......@@ -601,7 +641,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
601641 buffer: [buffer_size]u8,
602642 index: usize,
603643
604 pub fn init(unbuffered_out_stream: &OutStream) -> Self {
644 pub fn init(unbuffered_out_stream: &OutStream) Self {
605645 return Self {
606646 .unbuffered_out_stream = unbuffered_out_stream,
607647 .buffer = undefined,
......@@ -612,7 +652,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
612652 };
613653 }
614654
615 pub fn flush(self: &Self) -> %void {
655 pub fn flush(self: &Self) %void {
616656 if (self.index == 0)
617657 return;
618658
......@@ -620,7 +660,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
620660 self.index = 0;
621661 }
622662
623 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
663 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
624664 const self = @fieldParentPtr(Self, "stream", out_stream);
625665
626666 if (bytes.len >= self.buffer.len) {
......@@ -649,7 +689,7 @@ pub const BufferOutStream = struct {
649689 buffer: &Buffer,
650690 stream: OutStream,
651691
652 pub fn init(buffer: &Buffer) -> BufferOutStream {
692 pub fn init(buffer: &Buffer) BufferOutStream {
653693 return BufferOutStream {
654694 .buffer = buffer,
655695 .stream = OutStream {
......@@ -658,7 +698,7 @@ pub const BufferOutStream = struct {
658698 };
659699 }
660700
661 fn writeFn(out_stream: &OutStream, bytes: []const u8) -> %void {
701 fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
662702 const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);
663703 return self.buffer.append(bytes);
664704 }
std/linked_list.zig+18-18
......@@ -5,17 +5,17 @@ const mem = std.mem;
55const Allocator = mem.Allocator;
66
77/// Generic non-intrusive doubly linked list.
8pub fn LinkedList(comptime T: type) -> type {
8pub fn LinkedList(comptime T: type) type {
99 return BaseLinkedList(T, void, "");
1010}
1111
1212/// 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 {
1414 return BaseLinkedList(void, ParentType, field_name);
1515}
1616
1717/// 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 {
1919 return struct {
2020 const Self = this;
2121
......@@ -25,7 +25,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
2525 next: ?&Node,
2626 data: T,
2727
28 pub fn init(value: &const T) -> Node {
28 pub fn init(value: &const T) Node {
2929 return Node {
3030 .prev = null,
3131 .next = null,
......@@ -33,12 +33,12 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
3333 };
3434 }
3535
36 pub fn initIntrusive() -> Node {
36 pub fn initIntrusive() Node {
3737 // TODO: when #678 is solved this can become `init`.
3838 return Node.init({});
3939 }
4040
41 pub fn toData(node: &Node) -> &ParentType {
41 pub fn toData(node: &Node) &ParentType {
4242 comptime assert(isIntrusive());
4343 return @fieldParentPtr(ParentType, field_name, node);
4444 }
......@@ -52,7 +52,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
5252 ///
5353 /// Returns:
5454 /// An empty linked list.
55 pub fn init() -> Self {
55 pub fn init() Self {
5656 return Self {
5757 .first = null,
5858 .last = null,
......@@ -60,7 +60,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
6060 };
6161 }
6262
63 fn isIntrusive() -> bool {
63 fn isIntrusive() bool {
6464 return ParentType != void or field_name.len != 0;
6565 }
6666
......@@ -69,7 +69,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
6969 /// Arguments:
7070 /// node: Pointer to a node in the list.
7171 /// 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 {
7373 new_node.prev = node;
7474 if (node.next) |next_node| {
7575 // Intermediate node.
......@@ -90,7 +90,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
9090 /// Arguments:
9191 /// node: Pointer to a node in the list.
9292 /// 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 {
9494 new_node.next = node;
9595 if (node.prev) |prev_node| {
9696 // Intermediate node.
......@@ -110,7 +110,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
110110 ///
111111 /// Arguments:
112112 /// 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 {
114114 if (list.last) |last| {
115115 // Insert after last.
116116 list.insertAfter(last, new_node);
......@@ -124,7 +124,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
124124 ///
125125 /// Arguments:
126126 /// 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 {
128128 if (list.first) |first| {
129129 // Insert before first.
130130 list.insertBefore(first, new_node);
......@@ -143,7 +143,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
143143 ///
144144 /// Arguments:
145145 /// 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 {
147147 if (node.prev) |prev_node| {
148148 // Intermediate node.
149149 prev_node.next = node.next;
......@@ -167,7 +167,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
167167 ///
168168 /// Returns:
169169 /// A pointer to the last node in the list.
170 pub fn pop(list: &Self) -> ?&Node {
170 pub fn pop(list: &Self) ?&Node {
171171 const last = list.last ?? return null;
172172 list.remove(last);
173173 return last;
......@@ -177,7 +177,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
177177 ///
178178 /// Returns:
179179 /// A pointer to the first node in the list.
180 pub fn popFirst(list: &Self) -> ?&Node {
180 pub fn popFirst(list: &Self) ?&Node {
181181 const first = list.first ?? return null;
182182 list.remove(first);
183183 return first;
......@@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
190190 ///
191191 /// Returns:
192192 /// A pointer to the new node.
193 pub fn allocateNode(list: &Self, allocator: &Allocator) -> %&Node {
193 pub fn allocateNode(list: &Self, allocator: &Allocator) %&Node {
194194 comptime assert(!isIntrusive());
195195 return allocator.create(Node);
196196 }
......@@ -200,7 +200,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
200200 /// Arguments:
201201 /// node: Pointer to the node to deallocate.
202202 /// 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 {
204204 comptime assert(!isIntrusive());
205205 allocator.destroy(node);
206206 }
......@@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
213213 ///
214214 /// Returns:
215215 /// 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 {
217217 comptime assert(!isIntrusive());
218218 var node = try list.allocateNode(allocator);
219219 *node = Node.init(data);
std/math/acos.zig+5-5
......@@ -6,7 +6,7 @@ const std = @import("../index.zig");
66const math = std.math;
77const assert = std.debug.assert;
88
9pub fn acos(x: var) -> @typeOf(x) {
9pub fn acos(x: var) @typeOf(x) {
1010 const T = @typeOf(x);
1111 return switch (T) {
1212 f32 => acos32(x),
......@@ -15,7 +15,7 @@ pub fn acos(x: var) -> @typeOf(x) {
1515 };
1616}
1717
18fn r32(z: f32) -> f32 {
18fn r32(z: f32) f32 {
1919 const pS0 = 1.6666586697e-01;
2020 const pS1 = -4.2743422091e-02;
2121 const pS2 = -8.6563630030e-03;
......@@ -26,7 +26,7 @@ fn r32(z: f32) -> f32 {
2626 return p / q;
2727}
2828
29fn acos32(x: f32) -> f32 {
29fn acos32(x: f32) f32 {
3030 const pio2_hi = 1.5707962513e+00;
3131 const pio2_lo = 7.5497894159e-08;
3232
......@@ -73,7 +73,7 @@ fn acos32(x: f32) -> f32 {
7373 return 2 * (df + w);
7474}
7575
76fn r64(z: f64) -> f64 {
76fn r64(z: f64) f64 {
7777 const pS0: f64 = 1.66666666666666657415e-01;
7878 const pS1: f64 = -3.25565818622400915405e-01;
7979 const pS2: f64 = 2.01212532134862925881e-01;
......@@ -90,7 +90,7 @@ fn r64(z: f64) -> f64 {
9090 return p / q;
9191}
9292
93fn acos64(x: f64) -> f64 {
93fn acos64(x: f64) f64 {
9494 const pio2_hi: f64 = 1.57079632679489655800e+00;
9595 const pio2_lo: f64 = 6.12323399573676603587e-17;
9696
std/math/acosh.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn acosh(x: var) -> @typeOf(x) {
11pub fn acosh(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => acosh32(x),
......@@ -18,7 +18,7 @@ pub fn acosh(x: var) -> @typeOf(x) {
1818}
1919
2020// acosh(x) = log(x + sqrt(x * x - 1))
21fn acosh32(x: f32) -> f32 {
21fn acosh32(x: f32) f32 {
2222 const u = @bitCast(u32, x);
2323 const i = u & 0x7FFFFFFF;
2424
......@@ -36,7 +36,7 @@ fn acosh32(x: f32) -> f32 {
3636 }
3737}
3838
39fn acosh64(x: f64) -> f64 {
39fn acosh64(x: f64) f64 {
4040 const u = @bitCast(u64, x);
4141 const e = (u >> 52) & 0x7FF;
4242
std/math/asin.zig+5-5
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10pub fn asin(x: var) -> @typeOf(x) {
10pub fn asin(x: var) @typeOf(x) {
1111 const T = @typeOf(x);
1212 return switch (T) {
1313 f32 => asin32(x),
......@@ -16,7 +16,7 @@ pub fn asin(x: var) -> @typeOf(x) {
1616 };
1717}
1818
19fn r32(z: f32) -> f32 {
19fn r32(z: f32) f32 {
2020 const pS0 = 1.6666586697e-01;
2121 const pS1 = -4.2743422091e-02;
2222 const pS2 = -8.6563630030e-03;
......@@ -27,7 +27,7 @@ fn r32(z: f32) -> f32 {
2727 return p / q;
2828}
2929
30fn asin32(x: f32) -> f32 {
30fn asin32(x: f32) f32 {
3131 const pio2 = 1.570796326794896558e+00;
3232
3333 const hx: u32 = @bitCast(u32, x);
......@@ -65,7 +65,7 @@ fn asin32(x: f32) -> f32 {
6565 }
6666}
6767
68fn r64(z: f64) -> f64 {
68fn r64(z: f64) f64 {
6969 const pS0: f64 = 1.66666666666666657415e-01;
7070 const pS1: f64 = -3.25565818622400915405e-01;
7171 const pS2: f64 = 2.01212532134862925881e-01;
......@@ -82,7 +82,7 @@ fn r64(z: f64) -> f64 {
8282 return p / q;
8383}
8484
85fn asin64(x: f64) -> f64 {
85fn asin64(x: f64) f64 {
8686 const pio2_hi: f64 = 1.57079632679489655800e+00;
8787 const pio2_lo: f64 = 6.12323399573676603587e-17;
8888
std/math/asinh.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn asinh(x: var) -> @typeOf(x) {
11pub fn asinh(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => asinh32(x),
......@@ -18,7 +18,7 @@ pub fn asinh(x: var) -> @typeOf(x) {
1818}
1919
2020// 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 {
2222 const u = @bitCast(u32, x);
2323 const i = u & 0x7FFFFFFF;
2424 const s = i >> 31;
......@@ -50,7 +50,7 @@ fn asinh32(x: f32) -> f32 {
5050 return if (s != 0) -rx else rx;
5151}
5252
53fn asinh64(x: f64) -> f64 {
53fn asinh64(x: f64) f64 {
5454 const u = @bitCast(u64, x);
5555 const e = (u >> 52) & 0x7FF;
5656 const s = u >> 63;
std/math/atan.zig+3-3
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10pub fn atan(x: var) -> @typeOf(x) {
10pub fn atan(x: var) @typeOf(x) {
1111 const T = @typeOf(x);
1212 return switch (T) {
1313 f32 => atan32(x),
......@@ -16,7 +16,7 @@ pub fn atan(x: var) -> @typeOf(x) {
1616 };
1717}
1818
19fn atan32(x_: f32) -> f32 {
19fn atan32(x_: f32) f32 {
2020 const atanhi = []const f32 {
2121 4.6364760399e-01, // atan(0.5)hi
2222 7.8539812565e-01, // atan(1.0)hi
......@@ -108,7 +108,7 @@ fn atan32(x_: f32) -> f32 {
108108 }
109109}
110110
111fn atan64(x_: f64) -> f64 {
111fn atan64(x_: f64) f64 {
112112 const atanhi = []const f64 {
113113 4.63647609000806093515e-01, // atan(0.5)hi
114114 7.85398163397448278999e-01, // atan(1.0)hi
std/math/atan2.zig+3-3
......@@ -22,7 +22,7 @@ const std = @import("../index.zig");
2222const math = std.math;
2323const 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 {
2626 return switch (T) {
2727 f32 => atan2_32(x, y),
2828 f64 => atan2_64(x, y),
......@@ -30,7 +30,7 @@ fn atan2(comptime T: type, x: T, y: T) -> T {
3030 };
3131}
3232
33fn atan2_32(y: f32, x: f32) -> f32 {
33fn atan2_32(y: f32, x: f32) f32 {
3434 const pi: f32 = 3.1415927410e+00;
3535 const pi_lo: f32 = -8.7422776573e-08;
3636
......@@ -115,7 +115,7 @@ fn atan2_32(y: f32, x: f32) -> f32 {
115115 }
116116}
117117
118fn atan2_64(y: f64, x: f64) -> f64 {
118fn atan2_64(y: f64, x: f64) f64 {
119119 const pi: f64 = 3.1415926535897931160E+00;
120120 const pi_lo: f64 = 1.2246467991473531772E-16;
121121
std/math/atanh.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn atanh(x: var) -> @typeOf(x) {
11pub fn atanh(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => atanh_32(x),
......@@ -18,7 +18,7 @@ pub fn atanh(x: var) -> @typeOf(x) {
1818}
1919
2020// 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 {
2222 const u = @bitCast(u32, x);
2323 const i = u & 0x7FFFFFFF;
2424 const s = u >> 31;
......@@ -47,7 +47,7 @@ fn atanh_32(x: f32) -> f32 {
4747 return if (s != 0) -y else y;
4848}
4949
50fn atanh_64(x: f64) -> f64 {
50fn atanh_64(x: f64) f64 {
5151 const u = @bitCast(u64, x);
5252 const e = (u >> 52) & 0x7FF;
5353 const s = u >> 63;
std/math/cbrt.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn cbrt(x: var) -> @typeOf(x) {
11pub fn cbrt(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => cbrt32(x),
......@@ -17,7 +17,7 @@ pub fn cbrt(x: var) -> @typeOf(x) {
1717 };
1818}
1919
20fn cbrt32(x: f32) -> f32 {
20fn cbrt32(x: f32) f32 {
2121 const B1: u32 = 709958130; // (127 - 127.0 / 3 - 0.03306235651) * 2^23
2222 const B2: u32 = 642849266; // (127 - 127.0 / 3 - 24 / 3 - 0.03306235651) * 2^23
2323
......@@ -57,7 +57,7 @@ fn cbrt32(x: f32) -> f32 {
5757 return f32(t);
5858}
5959
60fn cbrt64(x: f64) -> f64 {
60fn cbrt64(x: f64) f64 {
6161 const B1: u32 = 715094163; // (1023 - 1023 / 3 - 0.03306235651 * 2^20
6262 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");
99const math = std.math;
1010const assert = std.debug.assert;
1111
12pub fn ceil(x: var) -> @typeOf(x) {
12pub fn ceil(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => ceil32(x),
......@@ -18,7 +18,7 @@ pub fn ceil(x: var) -> @typeOf(x) {
1818 };
1919}
2020
21fn ceil32(x: f32) -> f32 {
21fn ceil32(x: f32) f32 {
2222 var u = @bitCast(u32, x);
2323 var e = i32((u >> 23) & 0xFF) - 0x7F;
2424 var m: u32 = undefined;
......@@ -51,7 +51,7 @@ fn ceil32(x: f32) -> f32 {
5151 }
5252}
5353
54fn ceil64(x: f64) -> f64 {
54fn ceil64(x: f64) f64 {
5555 const u = @bitCast(u64, x);
5656 const e = (u >> 52) & 0x7FF;
5757 var y: f64 = undefined;
std/math/copysign.zig+3-3
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const 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 {
66 return switch (T) {
77 f32 => copysign32(x, y),
88 f64 => copysign64(x, y),
......@@ -10,7 +10,7 @@ pub fn copysign(comptime T: type, x: T, y: T) -> T {
1010 };
1111}
1212
13fn copysign32(x: f32, y: f32) -> f32 {
13fn copysign32(x: f32, y: f32) f32 {
1414 const ux = @bitCast(u32, x);
1515 const uy = @bitCast(u32, y);
1616
......@@ -19,7 +19,7 @@ fn copysign32(x: f32, y: f32) -> f32 {
1919 return @bitCast(f32, h1 | h2);
2020}
2121
22fn copysign64(x: f64, y: f64) -> f64 {
22fn copysign64(x: f64, y: f64) f64 {
2323 const ux = @bitCast(u64, x);
2424 const uy = @bitCast(u64, y);
2525
std/math/cos.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn cos(x: var) -> @typeOf(x) {
11pub fn cos(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => cos32(x),
......@@ -36,7 +36,7 @@ const C5 = 4.16666666666665929218E-2;
3636// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
3737//
3838// 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 {
4040 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4141
4242 const pi4a = 7.85398125648498535156e-1;
......@@ -89,7 +89,7 @@ fn cos32(x_: f32) -> f32 {
8989 }
9090}
9191
92fn cos64(x_: f64) -> f64 {
92fn cos64(x_: f64) f64 {
9393 const pi4a = 7.85398125648498535156e-1;
9494 const pi4b = 3.77489470793079817668E-8;
9595 const pi4c = 2.69515142907905952645E-15;
std/math/cosh.zig+3-3
......@@ -10,7 +10,7 @@ const math = std.math;
1010const expo2 = @import("expo2.zig").expo2;
1111const assert = std.debug.assert;
1212
13pub fn cosh(x: var) -> @typeOf(x) {
13pub fn cosh(x: var) @typeOf(x) {
1414 const T = @typeOf(x);
1515 return switch (T) {
1616 f32 => cosh32(x),
......@@ -22,7 +22,7 @@ pub fn cosh(x: var) -> @typeOf(x) {
2222// cosh(x) = (exp(x) + 1 / exp(x)) / 2
2323// = 1 + 0.5 * (exp(x) - 1) * (exp(x) - 1) / exp(x)
2424// = 1 + (x * x) / 2 + o(x^4)
25fn cosh32(x: f32) -> f32 {
25fn cosh32(x: f32) f32 {
2626 const u = @bitCast(u32, x);
2727 const ux = u & 0x7FFFFFFF;
2828 const ax = @bitCast(f32, ux);
......@@ -47,7 +47,7 @@ fn cosh32(x: f32) -> f32 {
4747 return expo2(ax);
4848}
4949
50fn cosh64(x: f64) -> f64 {
50fn cosh64(x: f64) f64 {
5151 const u = @bitCast(u64, x);
5252 const w = u32(u >> 32);
5353 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
std/math/exp.zig+3-3
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10pub fn exp(x: var) -> @typeOf(x) {
10pub fn exp(x: var) @typeOf(x) {
1111 const T = @typeOf(x);
1212 return switch (T) {
1313 f32 => exp32(x),
......@@ -16,7 +16,7 @@ pub fn exp(x: var) -> @typeOf(x) {
1616 };
1717}
1818
19fn exp32(x_: f32) -> f32 {
19fn exp32(x_: f32) f32 {
2020 const half = []f32 { 0.5, -0.5 };
2121 const ln2hi = 6.9314575195e-1;
2222 const ln2lo = 1.4286067653e-6;
......@@ -93,7 +93,7 @@ fn exp32(x_: f32) -> f32 {
9393 }
9494}
9595
96fn exp64(x_: f64) -> f64 {
96fn exp64(x_: f64) f64 {
9797 const half = []const f64 { 0.5, -0.5 };
9898 const ln2hi: f64 = 6.93147180369123816490e-01;
9999 const ln2lo: f64 = 1.90821492927058770002e-10;
std/math/exp2.zig+3-3
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10pub fn exp2(x: var) -> @typeOf(x) {
10pub fn exp2(x: var) @typeOf(x) {
1111 const T = @typeOf(x);
1212 return switch (T) {
1313 f32 => exp2_32(x),
......@@ -35,7 +35,7 @@ const exp2ft = []const f64 {
3535 0x1.5ab07dd485429p+0,
3636};
3737
38fn exp2_32(x: f32) -> f32 {
38fn exp2_32(x: f32) f32 {
3939 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4040
4141 const tblsiz = u32(exp2ft.len);
......@@ -352,7 +352,7 @@ const exp2dt = []f64 {
352352 0x1.690f4b19e9471p+0, -0x1.9780p-45,
353353};
354354
355fn exp2_64(x: f64) -> f64 {
355fn exp2_64(x: f64) f64 {
356356 @setFloatMode(this, @import("builtin").FloatMode.Strict);
357357
358358 const tblsiz = u32(exp2dt.len / 2);
std/math/expm1.zig+3-3
......@@ -9,7 +9,7 @@ const std = @import("../index.zig");
99const math = std.math;
1010const assert = std.debug.assert;
1111
12pub fn expm1(x: var) -> @typeOf(x) {
12pub fn expm1(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => expm1_32(x),
......@@ -18,7 +18,7 @@ pub fn expm1(x: var) -> @typeOf(x) {
1818 };
1919}
2020
21fn expm1_32(x_: f32) -> f32 {
21fn expm1_32(x_: f32) f32 {
2222 @setFloatMode(this, builtin.FloatMode.Strict);
2323 const o_threshold: f32 = 8.8721679688e+01;
2424 const ln2_hi: f32 = 6.9313812256e-01;
......@@ -145,7 +145,7 @@ fn expm1_32(x_: f32) -> f32 {
145145 }
146146}
147147
148fn expm1_64(x_: f64) -> f64 {
148fn expm1_64(x_: f64) f64 {
149149 @setFloatMode(this, builtin.FloatMode.Strict);
150150 const o_threshold: f64 = 7.09782712893383973096e+02;
151151 const ln2_hi: f64 = 6.93147180369123816490e-01;
std/math/expo2.zig+3-3
......@@ -1,6 +1,6 @@
11const math = @import("index.zig");
22
3pub fn expo2(x: var) -> @typeOf(x) {
3pub fn expo2(x: var) @typeOf(x) {
44 const T = @typeOf(x);
55 return switch (T) {
66 f32 => expo2f(x),
......@@ -9,7 +9,7 @@ pub fn expo2(x: var) -> @typeOf(x) {
99 };
1010}
1111
12fn expo2f(x: f32) -> f32 {
12fn expo2f(x: f32) f32 {
1313 const k: u32 = 235;
1414 const kln2 = 0x1.45C778p+7;
1515
......@@ -18,7 +18,7 @@ fn expo2f(x: f32) -> f32 {
1818 return math.exp(x - kln2) * scale * scale;
1919}
2020
21fn expo2d(x: f64) -> f64 {
21fn expo2d(x: f64) f64 {
2222 const k: u32 = 2043;
2323 const kln2 = 0x1.62066151ADD8BP+10;
2424
std/math/fabs.zig+3-3
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10pub fn fabs(x: var) -> @typeOf(x) {
10pub fn fabs(x: var) @typeOf(x) {
1111 const T = @typeOf(x);
1212 return switch (T) {
1313 f32 => fabs32(x),
......@@ -16,13 +16,13 @@ pub fn fabs(x: var) -> @typeOf(x) {
1616 };
1717}
1818
19fn fabs32(x: f32) -> f32 {
19fn fabs32(x: f32) f32 {
2020 var u = @bitCast(u32, x);
2121 u &= 0x7FFFFFFF;
2222 return @bitCast(f32, u);
2323}
2424
25fn fabs64(x: f64) -> f64 {
25fn fabs64(x: f64) f64 {
2626 var u = @bitCast(u64, x);
2727 u &= @maxValue(u64) >> 1;
2828 return @bitCast(f64, u);
std/math/floor.zig+3-3
......@@ -9,7 +9,7 @@ const assert = std.debug.assert;
99const std = @import("../index.zig");
1010const math = std.math;
1111
12pub fn floor(x: var) -> @typeOf(x) {
12pub fn floor(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => floor32(x),
......@@ -18,7 +18,7 @@ pub fn floor(x: var) -> @typeOf(x) {
1818 };
1919}
2020
21fn floor32(x: f32) -> f32 {
21fn floor32(x: f32) f32 {
2222 var u = @bitCast(u32, x);
2323 const e = i32((u >> 23) & 0xFF) - 0x7F;
2424 var m: u32 = undefined;
......@@ -52,7 +52,7 @@ fn floor32(x: f32) -> f32 {
5252 }
5353}
5454
55fn floor64(x: f64) -> f64 {
55fn floor64(x: f64) f64 {
5656 const u = @bitCast(u64, x);
5757 const e = (u >> 52) & 0x7FF;
5858 var y: f64 = undefined;
std/math/fma.zig+7-7
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const 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 {
66 return switch (T) {
77 f32 => fma32(x, y, z),
88 f64 => fma64(x, y ,z),
......@@ -10,7 +10,7 @@ pub fn fma(comptime T: type, x: T, y: T, z: T) -> T {
1010 };
1111}
1212
13fn fma32(x: f32, y: f32, z: f32) -> f32 {
13fn fma32(x: f32, y: f32, z: f32) f32 {
1414 const xy = f64(x) * y;
1515 const xy_z = xy + z;
1616 const u = @bitCast(u64, xy_z);
......@@ -24,7 +24,7 @@ fn fma32(x: f32, y: f32, z: f32) -> f32 {
2424 }
2525}
2626
27fn fma64(x: f64, y: f64, z: f64) -> f64 {
27fn fma64(x: f64, y: f64, z: f64) f64 {
2828 if (!math.isFinite(x) or !math.isFinite(y)) {
2929 return x * y + z;
3030 }
......@@ -73,7 +73,7 @@ fn fma64(x: f64, y: f64, z: f64) -> f64 {
7373
7474const dd = struct { hi: f64, lo: f64, };
7575
76fn dd_add(a: f64, b: f64) -> dd {
76fn dd_add(a: f64, b: f64) dd {
7777 var ret: dd = undefined;
7878 ret.hi = a + b;
7979 const s = ret.hi - a;
......@@ -81,7 +81,7 @@ fn dd_add(a: f64, b: f64) -> dd {
8181 return ret;
8282}
8383
84fn dd_mul(a: f64, b: f64) -> dd {
84fn dd_mul(a: f64, b: f64) dd {
8585 var ret: dd = undefined;
8686 const split: f64 = 0x1.0p27 + 1.0;
8787
......@@ -103,7 +103,7 @@ fn dd_mul(a: f64, b: f64) -> dd {
103103 return ret;
104104}
105105
106fn add_adjusted(a: f64, b: f64) -> f64 {
106fn add_adjusted(a: f64, b: f64) f64 {
107107 var sum = dd_add(a, b);
108108 if (sum.lo != 0) {
109109 var uhii = @bitCast(u64, sum.hi);
......@@ -117,7 +117,7 @@ fn add_adjusted(a: f64, b: f64) -> f64 {
117117 return sum.hi;
118118}
119119
120fn add_and_denorm(a: f64, b: f64, scale: i32) -> f64 {
120fn add_and_denorm(a: f64, b: f64, scale: i32) f64 {
121121 var sum = dd_add(a, b);
122122 if (sum.lo != 0) {
123123 var uhii = @bitCast(u64, sum.hi);
std/math/frexp.zig+4-4
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11fn frexp_result(comptime T: type) -> type {
11fn frexp_result(comptime T: type) type {
1212 return struct {
1313 significand: T,
1414 exponent: i32,
......@@ -17,7 +17,7 @@ fn frexp_result(comptime T: type) -> type {
1717pub const frexp32_result = frexp_result(f32);
1818pub 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)) {
2121 const T = @typeOf(x);
2222 return switch (T) {
2323 f32 => frexp32(x),
......@@ -26,7 +26,7 @@ pub fn frexp(x: var) -> frexp_result(@typeOf(x)) {
2626 };
2727}
2828
29fn frexp32(x: f32) -> frexp32_result {
29fn frexp32(x: f32) frexp32_result {
3030 var result: frexp32_result = undefined;
3131
3232 var y = @bitCast(u32, x);
......@@ -63,7 +63,7 @@ fn frexp32(x: f32) -> frexp32_result {
6363 return result;
6464}
6565
66fn frexp64(x: f64) -> frexp64_result {
66fn frexp64(x: f64) frexp64_result {
6767 var result: frexp64_result = undefined;
6868
6969 var y = @bitCast(u64, x);
std/math/hypot.zig+4-4
......@@ -9,7 +9,7 @@ const std = @import("../index.zig");
99const math = std.math;
1010const 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 {
1313 return switch (T) {
1414 f32 => hypot32(x, y),
1515 f64 => hypot64(x, y),
......@@ -17,7 +17,7 @@ pub fn hypot(comptime T: type, x: T, y: T) -> T {
1717 };
1818}
1919
20fn hypot32(x: f32, y: f32) -> f32 {
20fn hypot32(x: f32, y: f32) f32 {
2121 var ux = @bitCast(u32, x);
2222 var uy = @bitCast(u32, y);
2323
......@@ -52,7 +52,7 @@ fn hypot32(x: f32, y: f32) -> f32 {
5252 return z * math.sqrt(f32(f64(x) * x + f64(y) * y));
5353}
5454
55fn sq(hi: &f64, lo: &f64, x: f64) {
55fn sq(hi: &f64, lo: &f64, x: f64) void {
5656 const split: f64 = 0x1.0p27 + 1.0;
5757 const xc = x * split;
5858 const xh = x - xc + xc;
......@@ -61,7 +61,7 @@ fn sq(hi: &f64, lo: &f64, x: f64) {
6161 *lo = xh * xh - *hi + 2 * xh * xl + xl * xl;
6262}
6363
64fn hypot64(x: f64, y: f64) -> f64 {
64fn hypot64(x: f64, y: f64) f64 {
6565 var ux = @bitCast(u64, x);
6666 var uy = @bitCast(u64, y);
6767
std/math/ilogb.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn ilogb(x: var) -> i32 {
11pub fn ilogb(x: var) i32 {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => ilogb32(x),
......@@ -21,7 +21,7 @@ pub fn ilogb(x: var) -> i32 {
2121const fp_ilogbnan = -1 - i32(@maxValue(u32) >> 1);
2222const fp_ilogb0 = fp_ilogbnan;
2323
24fn ilogb32(x: f32) -> i32 {
24fn ilogb32(x: f32) i32 {
2525 var u = @bitCast(u32, x);
2626 var e = i32((u >> 23) & 0xFF);
2727
......@@ -57,7 +57,7 @@ fn ilogb32(x: f32) -> i32 {
5757 return e - 0x7F;
5858}
5959
60fn ilogb64(x: f64) -> i32 {
60fn ilogb64(x: f64) i32 {
6161 var u = @bitCast(u64, x);
6262 var e = i32((u >> 52) & 0x7FF);
6363
std/math/index.zig+43-43
......@@ -35,13 +35,13 @@ pub const nan = @import("nan.zig").nan;
3535pub const snan = @import("nan.zig").snan;
3636pub 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 {
3939 assert(@typeId(T) == TypeId.Float);
4040 return fabs(x - y) < epsilon;
4141}
4242
4343// TODO: Hide the following in an internal module.
44pub fn forceEval(value: var) {
44pub fn forceEval(value: var) void {
4545 const T = @typeOf(value);
4646 switch (T) {
4747 f32 => {
......@@ -60,23 +60,23 @@ pub fn forceEval(value: var) {
6060 }
6161}
6262
63pub fn raiseInvalid() {
63pub fn raiseInvalid() void {
6464 // Raise INVALID fpu exception
6565}
6666
67pub fn raiseUnderflow() {
67pub fn raiseUnderflow() void {
6868 // Raise UNDERFLOW fpu exception
6969}
7070
71pub fn raiseOverflow() {
71pub fn raiseOverflow() void {
7272 // Raise OVERFLOW fpu exception
7373}
7474
75pub fn raiseInexact() {
75pub fn raiseInexact() void {
7676 // Raise INEXACT fpu exception
7777}
7878
79pub fn raiseDivByZero() {
79pub fn raiseDivByZero() void {
8080 // Raise INEXACT fpu exception
8181}
8282
......@@ -175,7 +175,7 @@ test "math" {
175175}
176176
177177
178pub fn min(x: var, y: var) -> @typeOf(x + y) {
178pub fn min(x: var, y: var) @typeOf(x + y) {
179179 return if (x < y) x else y;
180180}
181181
......@@ -183,7 +183,7 @@ test "math.min" {
183183 assert(min(i32(-1), i32(2)) == -1);
184184}
185185
186pub fn max(x: var, y: var) -> @typeOf(x + y) {
186pub fn max(x: var, y: var) @typeOf(x + y) {
187187 return if (x > y) x else y;
188188}
189189
......@@ -192,36 +192,36 @@ test "math.max" {
192192}
193193
194194error Overflow;
195pub fn mul(comptime T: type, a: T, b: T) -> %T {
195pub fn mul(comptime T: type, a: T, b: T) %T {
196196 var answer: T = undefined;
197197 return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
198198}
199199
200200error Overflow;
201pub fn add(comptime T: type, a: T, b: T) -> %T {
201pub fn add(comptime T: type, a: T, b: T) %T {
202202 var answer: T = undefined;
203203 return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
204204}
205205
206206error Overflow;
207pub fn sub(comptime T: type, a: T, b: T) -> %T {
207pub fn sub(comptime T: type, a: T, b: T) %T {
208208 var answer: T = undefined;
209209 return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
210210}
211211
212pub fn negate(x: var) -> %@typeOf(x) {
212pub fn negate(x: var) %@typeOf(x) {
213213 return sub(@typeOf(x), 0, x);
214214}
215215
216216error 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 {
218218 var answer: T = undefined;
219219 return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
220220}
221221
222222/// Shifts left. Overflowed bits are truncated.
223223/// 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 {
225225 const abs_shift_amt = absCast(shift_amt);
226226 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" {
245245
246246/// Shifts right. Overflowed bits are truncated.
247247/// 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 {
249249 const abs_shift_amt = absCast(shift_amt);
250250 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" {
269269
270270/// Rotates right. Only unsigned values can be rotated.
271271/// 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 {
273273 if (T.is_signed) {
274274 @compileError("cannot rotate signed integer");
275275 } else {
......@@ -288,7 +288,7 @@ test "math.rotr" {
288288
289289/// Rotates left. Only unsigned values can be rotated.
290290/// 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 {
292292 if (T.is_signed) {
293293 @compileError("cannot rotate signed integer");
294294 } else {
......@@ -306,7 +306,7 @@ test "math.rotl" {
306306}
307307
308308
309pub fn Log2Int(comptime T: type) -> type {
309pub fn Log2Int(comptime T: type) type {
310310 return @IntType(false, log2(T.bit_count));
311311}
312312
......@@ -315,7 +315,7 @@ test "math overflow functions" {
315315 comptime testOverflow();
316316}
317317
318fn testOverflow() {
318fn testOverflow() void {
319319 assert((mul(i32, 3, 4) catch unreachable) == 12);
320320 assert((add(i32, 3, 4) catch unreachable) == 7);
321321 assert((sub(i32, 3, 4) catch unreachable) == -1);
......@@ -324,14 +324,14 @@ fn testOverflow() {
324324
325325
326326error Overflow;
327pub fn absInt(x: var) -> %@typeOf(x) {
327pub fn absInt(x: var) %@typeOf(x) {
328328 const T = @typeOf(x);
329329 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
330330 comptime assert(T.is_signed); // must pass a signed integer to absInt
331331 if (x == @minValue(@typeOf(x)))
332332 return error.Overflow;
333333 {
334 @setDebugSafety(this, false);
334 @setRuntimeSafety(false);
335335 return if (x < 0) -x else x;
336336 }
337337}
......@@ -340,7 +340,7 @@ test "math.absInt" {
340340 testAbsInt();
341341 comptime testAbsInt();
342342}
343fn testAbsInt() {
343fn testAbsInt() void {
344344 assert((absInt(i32(-10)) catch unreachable) == 10);
345345 assert((absInt(i32(10)) catch unreachable) == 10);
346346}
......@@ -349,8 +349,8 @@ pub const absFloat = @import("fabs.zig").fabs;
349349
350350error DivisionByZero;
351351error Overflow;
352pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
353 @setDebugSafety(this, false);
352pub fn divTrunc(comptime T: type, numerator: T, denominator: T) %T {
353 @setRuntimeSafety(false);
354354 if (denominator == 0)
355355 return error.DivisionByZero;
356356 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -362,7 +362,7 @@ test "math.divTrunc" {
362362 testDivTrunc();
363363 comptime testDivTrunc();
364364}
365fn testDivTrunc() {
365fn testDivTrunc() void {
366366 assert((divTrunc(i32, 5, 3) catch unreachable) == 1);
367367 assert((divTrunc(i32, -5, 3) catch unreachable) == -1);
368368 if (divTrunc(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
......@@ -374,8 +374,8 @@ fn testDivTrunc() {
374374
375375error DivisionByZero;
376376error Overflow;
377pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
378 @setDebugSafety(this, false);
377pub fn divFloor(comptime T: type, numerator: T, denominator: T) %T {
378 @setRuntimeSafety(false);
379379 if (denominator == 0)
380380 return error.DivisionByZero;
381381 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -387,7 +387,7 @@ test "math.divFloor" {
387387 testDivFloor();
388388 comptime testDivFloor();
389389}
390fn testDivFloor() {
390fn testDivFloor() void {
391391 assert((divFloor(i32, 5, 3) catch unreachable) == 1);
392392 assert((divFloor(i32, -5, 3) catch unreachable) == -2);
393393 if (divFloor(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
......@@ -400,8 +400,8 @@ fn testDivFloor() {
400400error DivisionByZero;
401401error Overflow;
402402error UnexpectedRemainder;
403pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
404 @setDebugSafety(this, false);
403pub fn divExact(comptime T: type, numerator: T, denominator: T) %T {
404 @setRuntimeSafety(false);
405405 if (denominator == 0)
406406 return error.DivisionByZero;
407407 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -416,7 +416,7 @@ test "math.divExact" {
416416 testDivExact();
417417 comptime testDivExact();
418418}
419fn testDivExact() {
419fn testDivExact() void {
420420 assert((divExact(i32, 10, 5) catch unreachable) == 2);
421421 assert((divExact(i32, -10, 5) catch unreachable) == -2);
422422 if (divExact(i8, -5, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
......@@ -430,8 +430,8 @@ fn testDivExact() {
430430
431431error DivisionByZero;
432432error NegativeDenominator;
433pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {
434 @setDebugSafety(this, false);
433pub fn mod(comptime T: type, numerator: T, denominator: T) %T {
434 @setRuntimeSafety(false);
435435 if (denominator == 0)
436436 return error.DivisionByZero;
437437 if (denominator < 0)
......@@ -443,7 +443,7 @@ test "math.mod" {
443443 testMod();
444444 comptime testMod();
445445}
446fn testMod() {
446fn testMod() void {
447447 assert((mod(i32, -5, 3) catch unreachable) == 1);
448448 assert((mod(i32, 5, 3) catch unreachable) == 2);
449449 if (mod(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
......@@ -457,8 +457,8 @@ fn testMod() {
457457
458458error DivisionByZero;
459459error NegativeDenominator;
460pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {
461 @setDebugSafety(this, false);
460pub fn rem(comptime T: type, numerator: T, denominator: T) %T {
461 @setRuntimeSafety(false);
462462 if (denominator == 0)
463463 return error.DivisionByZero;
464464 if (denominator < 0)
......@@ -470,7 +470,7 @@ test "math.rem" {
470470 testRem();
471471 comptime testRem();
472472}
473fn testRem() {
473fn testRem() void {
474474 assert((rem(i32, -5, 3) catch unreachable) == -2);
475475 assert((rem(i32, 5, 3) catch unreachable) == 2);
476476 if (rem(i32, 10, -1)) |_| unreachable else |err| assert(err == error.NegativeDenominator);
......@@ -484,7 +484,7 @@ fn testRem() {
484484
485485/// Returns the absolute value of the integer parameter.
486486/// 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) {
488488 const uint = @IntType(false, @typeOf(x).bit_count);
489489 if (x >= 0)
490490 return uint(x);
......@@ -506,7 +506,7 @@ test "math.absCast" {
506506/// Returns the negation of the integer parameter.
507507/// Result is a signed integer.
508508error Overflow;
509pub fn negateCast(x: var) -> %@IntType(true, @typeOf(x).bit_count) {
509pub fn negateCast(x: var) %@IntType(true, @typeOf(x).bit_count) {
510510 if (@typeOf(x).is_signed)
511511 return negate(x);
512512
......@@ -533,7 +533,7 @@ test "math.negateCast" {
533533/// Cast an integer to a different integer type. If the value doesn't fit,
534534/// return an error.
535535error Overflow;
536pub fn cast(comptime T: type, x: var) -> %T {
536pub fn cast(comptime T: type, x: var) %T {
537537 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
538538 if (x > @maxValue(T)) {
539539 return error.Overflow;
......@@ -542,7 +542,7 @@ pub fn cast(comptime T: type, x: var) -> %T {
542542 }
543543}
544544
545pub fn floorPowerOfTwo(comptime T: type, value: T) -> T {
545pub fn floorPowerOfTwo(comptime T: type, value: T) T {
546546 var x = value;
547547
548548 comptime var i = 1;
......@@ -558,7 +558,7 @@ test "math.floorPowerOfTwo" {
558558 comptime testFloorPowerOfTwo();
559559}
560560
561fn testFloorPowerOfTwo() {
561fn testFloorPowerOfTwo() void {
562562 assert(floorPowerOfTwo(u32, 63) == 32);
563563 assert(floorPowerOfTwo(u32, 64) == 64);
564564 assert(floorPowerOfTwo(u32, 65) == 64);
std/math/inf.zig+1-1
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn inf(comptime T: type) -> T {
5pub fn inf(comptime T: type) T {
66 return switch (T) {
77 f32 => @bitCast(f32, math.inf_u32),
88 f64 => @bitCast(f64, math.inf_u64),
std/math/isfinite.zig+1-1
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn isFinite(x: var) -> bool {
5pub fn isFinite(x: var) bool {
66 const T = @typeOf(x);
77 switch (T) {
88 f32 => {
std/math/isinf.zig+3-3
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn isInf(x: var) -> bool {
5pub fn isInf(x: var) bool {
66 const T = @typeOf(x);
77 switch (T) {
88 f32 => {
......@@ -19,7 +19,7 @@ pub fn isInf(x: var) -> bool {
1919 }
2020}
2121
22pub fn isPositiveInf(x: var) -> bool {
22pub fn isPositiveInf(x: var) bool {
2323 const T = @typeOf(x);
2424 switch (T) {
2525 f32 => {
......@@ -34,7 +34,7 @@ pub fn isPositiveInf(x: var) -> bool {
3434 }
3535}
3636
37pub fn isNegativeInf(x: var) -> bool {
37pub fn isNegativeInf(x: var) bool {
3838 const T = @typeOf(x);
3939 switch (T) {
4040 f32 => {
std/math/isnan.zig+2-2
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn isNan(x: var) -> bool {
5pub fn isNan(x: var) bool {
66 const T = @typeOf(x);
77 switch (T) {
88 f32 => {
......@@ -21,7 +21,7 @@ pub fn isNan(x: var) -> bool {
2121
2222// Note: A signalling nan is identical to a standard right now by may have a different bit
2323// representation in the future when required.
24pub fn isSignalNan(x: var) -> bool {
24pub fn isSignalNan(x: var) bool {
2525 return isNan(x);
2626}
2727
std/math/isnormal.zig+1-1
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn isNormal(x: var) -> bool {
5pub fn isNormal(x: var) bool {
66 const T = @typeOf(x);
77 switch (T) {
88 f32 => {
std/math/ln.zig+3-3
......@@ -11,7 +11,7 @@ const assert = std.debug.assert;
1111const builtin = @import("builtin");
1212const TypeId = builtin.TypeId;
1313
14pub fn ln(x: var) -> @typeOf(x) {
14pub fn ln(x: var) @typeOf(x) {
1515 const T = @typeOf(x);
1616 switch (@typeId(T)) {
1717 TypeId.FloatLiteral => {
......@@ -34,7 +34,7 @@ pub fn ln(x: var) -> @typeOf(x) {
3434 }
3535}
3636
37pub fn ln_32(x_: f32) -> f32 {
37pub fn ln_32(x_: f32) f32 {
3838 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3939
4040 const ln2_hi: f32 = 6.9313812256e-01;
......@@ -88,7 +88,7 @@ pub fn ln_32(x_: f32) -> f32 {
8888 return s * (hfsq + R) + dk * ln2_lo - hfsq + f + dk * ln2_hi;
8989}
9090
91pub fn ln_64(x_: f64) -> f64 {
91pub fn ln_64(x_: f64) f64 {
9292 const ln2_hi: f64 = 6.93147180369123816490e-01;
9393 const ln2_lo: f64 = 1.90821492927058770002e-10;
9494 const Lg1: f64 = 6.666666666666735130e-01;
std/math/log.zig+1-1
......@@ -4,7 +4,7 @@ const builtin = @import("builtin");
44const TypeId = builtin.TypeId;
55const 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 {
88 if (base == 2) {
99 return math.log2(x);
1010 } else if (base == 10) {
std/math/log10.zig+3-3
......@@ -11,7 +11,7 @@ const assert = std.debug.assert;
1111const builtin = @import("builtin");
1212const TypeId = builtin.TypeId;
1313
14pub fn log10(x: var) -> @typeOf(x) {
14pub fn log10(x: var) @typeOf(x) {
1515 const T = @typeOf(x);
1616 switch (@typeId(T)) {
1717 TypeId.FloatLiteral => {
......@@ -34,7 +34,7 @@ pub fn log10(x: var) -> @typeOf(x) {
3434 }
3535}
3636
37pub fn log10_32(x_: f32) -> f32 {
37pub fn log10_32(x_: f32) f32 {
3838 const ivln10hi: f32 = 4.3432617188e-01;
3939 const ivln10lo: f32 = -3.1689971365e-05;
4040 const log10_2hi: f32 = 3.0102920532e-01;
......@@ -94,7 +94,7 @@ pub fn log10_32(x_: f32) -> f32 {
9494 return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;
9595}
9696
97pub fn log10_64(x_: f64) -> f64 {
97pub fn log10_64(x_: f64) f64 {
9898 const ivln10hi: f64 = 4.34294481878168880939e-01;
9999 const ivln10lo: f64 = 2.50829467116452752298e-11;
100100 const log10_2hi: f64 = 3.01029995663611771306e-01;
std/math/log1p.zig+3-3
......@@ -10,7 +10,7 @@ const std = @import("../index.zig");
1010const math = std.math;
1111const assert = std.debug.assert;
1212
13pub fn log1p(x: var) -> @typeOf(x) {
13pub fn log1p(x: var) @typeOf(x) {
1414 const T = @typeOf(x);
1515 return switch (T) {
1616 f32 => log1p_32(x),
......@@ -19,7 +19,7 @@ pub fn log1p(x: var) -> @typeOf(x) {
1919 };
2020}
2121
22fn log1p_32(x: f32) -> f32 {
22fn log1p_32(x: f32) f32 {
2323 const ln2_hi = 6.9313812256e-01;
2424 const ln2_lo = 9.0580006145e-06;
2525 const Lg1: f32 = 0xaaaaaa.0p-24;
......@@ -95,7 +95,7 @@ fn log1p_32(x: f32) -> f32 {
9595 return s * (hfsq + R) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;
9696}
9797
98fn log1p_64(x: f64) -> f64 {
98fn log1p_64(x: f64) f64 {
9999 const ln2_hi: f64 = 6.93147180369123816490e-01;
100100 const ln2_lo: f64 = 1.90821492927058770002e-10;
101101 const Lg1: f64 = 6.666666666666735130e-01;
std/math/log2.zig+4-4
......@@ -11,7 +11,7 @@ const assert = std.debug.assert;
1111const builtin = @import("builtin");
1212const TypeId = builtin.TypeId;
1313
14pub fn log2(x: var) -> @typeOf(x) {
14pub fn log2(x: var) @typeOf(x) {
1515 const T = @typeOf(x);
1616 switch (@typeId(T)) {
1717 TypeId.FloatLiteral => {
......@@ -37,12 +37,12 @@ pub fn log2(x: var) -> @typeOf(x) {
3737 }
3838}
3939
40pub fn log2_int(comptime T: type, x: T) -> T {
40pub fn log2_int(comptime T: type, x: T) T {
4141 assert(x != 0);
4242 return T.bit_count - 1 - T(@clz(x));
4343}
4444
45pub fn log2_32(x_: f32) -> f32 {
45pub fn log2_32(x_: f32) f32 {
4646 const ivln2hi: f32 = 1.4428710938e+00;
4747 const ivln2lo: f32 = -1.7605285393e-04;
4848 const Lg1: f32 = 0xaaaaaa.0p-24;
......@@ -98,7 +98,7 @@ pub fn log2_32(x_: f32) -> f32 {
9898 return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + f32(k);
9999}
100100
101pub fn log2_64(x_: f64) -> f64 {
101pub fn log2_64(x_: f64) f64 {
102102 const ivln2hi: f64 = 1.44269504072144627571e+00;
103103 const ivln2lo: f64 = 1.67517131648865118353e-10;
104104 const Lg1: f64 = 6.666666666666735130e-01;
std/math/modf.zig+4-4
......@@ -7,7 +7,7 @@ const std = @import("../index.zig");
77const math = std.math;
88const assert = std.debug.assert;
99
10fn modf_result(comptime T: type) -> type {
10fn modf_result(comptime T: type) type {
1111 return struct {
1212 fpart: T,
1313 ipart: T,
......@@ -16,7 +16,7 @@ fn modf_result(comptime T: type) -> type {
1616pub const modf32_result = modf_result(f32);
1717pub 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)) {
2020 const T = @typeOf(x);
2121 return switch (T) {
2222 f32 => modf32(x),
......@@ -25,7 +25,7 @@ pub fn modf(x: var) -> modf_result(@typeOf(x)) {
2525 };
2626}
2727
28fn modf32(x: f32) -> modf32_result {
28fn modf32(x: f32) modf32_result {
2929 var result: modf32_result = undefined;
3030
3131 const u = @bitCast(u32, x);
......@@ -70,7 +70,7 @@ fn modf32(x: f32) -> modf32_result {
7070 return result;
7171}
7272
73fn modf64(x: f64) -> modf64_result {
73fn modf64(x: f64) modf64_result {
7474 var result: modf64_result = undefined;
7575
7676 const u = @bitCast(u64, x);
std/math/nan.zig+2-2
......@@ -1,6 +1,6 @@
11const math = @import("index.zig");
22
3pub fn nan(comptime T: type) -> T {
3pub fn nan(comptime T: type) T {
44 return switch (T) {
55 f32 => @bitCast(f32, math.nan_u32),
66 f64 => @bitCast(f64, math.nan_u64),
......@@ -10,7 +10,7 @@ pub fn nan(comptime T: type) -> T {
1010
1111// Note: A signalling nan is identical to a standard right now by may have a different bit
1212// representation in the future when required.
13pub fn snan(comptime T: type) -> T {
13pub fn snan(comptime T: type) T {
1414 return switch (T) {
1515 f32 => @bitCast(f32, math.nan_u32),
1616 f64 => @bitCast(f64, math.nan_u64),
std/math/pow.zig+2-2
......@@ -27,7 +27,7 @@ const math = std.math;
2727const assert = std.debug.assert;
2828
2929// 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
3232 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3333
......@@ -170,7 +170,7 @@ pub fn pow(comptime T: type, x: T, y: T) -> T {
170170 return math.scalbn(a1, ae);
171171}
172172
173fn isOddInteger(x: f64) -> bool {
173fn isOddInteger(x: f64) bool {
174174 const r = math.modf(x);
175175 return r.fpart == 0.0 and i64(r.ipart) & 1 == 1;
176176}
std/math/round.zig+3-3
......@@ -9,7 +9,7 @@ const assert = std.debug.assert;
99const std = @import("../index.zig");
1010const math = std.math;
1111
12pub fn round(x: var) -> @typeOf(x) {
12pub fn round(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => round32(x),
......@@ -18,7 +18,7 @@ pub fn round(x: var) -> @typeOf(x) {
1818 };
1919}
2020
21fn round32(x_: f32) -> f32 {
21fn round32(x_: f32) f32 {
2222 var x = x_;
2323 const u = @bitCast(u32, x);
2424 const e = (u >> 23) & 0xFF;
......@@ -55,7 +55,7 @@ fn round32(x_: f32) -> f32 {
5555 }
5656}
5757
58fn round64(x_: f64) -> f64 {
58fn round64(x_: f64) f64 {
5959 var x = x_;
6060 const u = @bitCast(u64, x);
6161 const e = (u >> 52) & 0x7FF;
std/math/scalbn.zig+3-3
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn scalbn(x: var, n: i32) -> @typeOf(x) {
5pub fn scalbn(x: var, n: i32) @typeOf(x) {
66 const T = @typeOf(x);
77 return switch (T) {
88 f32 => scalbn32(x, n),
......@@ -11,7 +11,7 @@ pub fn scalbn(x: var, n: i32) -> @typeOf(x) {
1111 };
1212}
1313
14fn scalbn32(x: f32, n_: i32) -> f32 {
14fn scalbn32(x: f32, n_: i32) f32 {
1515 var y = x;
1616 var n = n_;
1717
......@@ -41,7 +41,7 @@ fn scalbn32(x: f32, n_: i32) -> f32 {
4141 return y * @bitCast(f32, u);
4242}
4343
44fn scalbn64(x: f64, n_: i32) -> f64 {
44fn scalbn64(x: f64, n_: i32) f64 {
4545 var y = x;
4646 var n = n_;
4747
std/math/signbit.zig+3-3
......@@ -2,7 +2,7 @@ const std = @import("../index.zig");
22const math = std.math;
33const assert = std.debug.assert;
44
5pub fn signbit(x: var) -> bool {
5pub fn signbit(x: var) bool {
66 const T = @typeOf(x);
77 return switch (T) {
88 f32 => signbit32(x),
......@@ -11,12 +11,12 @@ pub fn signbit(x: var) -> bool {
1111 };
1212}
1313
14fn signbit32(x: f32) -> bool {
14fn signbit32(x: f32) bool {
1515 const bits = @bitCast(u32, x);
1616 return bits >> 31 != 0;
1717}
1818
19fn signbit64(x: f64) -> bool {
19fn signbit64(x: f64) bool {
2020 const bits = @bitCast(u64, x);
2121 return bits >> 63 != 0;
2222}
std/math/sin.zig+3-3
......@@ -9,7 +9,7 @@ const std = @import("../index.zig");
99const math = std.math;
1010const assert = std.debug.assert;
1111
12pub fn sin(x: var) -> @typeOf(x) {
12pub fn sin(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => sin32(x),
......@@ -37,7 +37,7 @@ const C5 = 4.16666666666665929218E-2;
3737// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
3838//
3939// 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 {
4141 @setFloatMode(this, @import("builtin").FloatMode.Strict);
4242
4343 const pi4a = 7.85398125648498535156e-1;
......@@ -91,7 +91,7 @@ fn sin32(x_: f32) -> f32 {
9191 }
9292}
9393
94fn sin64(x_: f64) -> f64 {
94fn sin64(x_: f64) f64 {
9595 const pi4a = 7.85398125648498535156e-1;
9696 const pi4b = 3.77489470793079817668E-8;
9797 const pi4c = 2.69515142907905952645E-15;
std/math/sinh.zig+3-3
......@@ -10,7 +10,7 @@ const math = std.math;
1010const assert = std.debug.assert;
1111const expo2 = @import("expo2.zig").expo2;
1212
13pub fn sinh(x: var) -> @typeOf(x) {
13pub fn sinh(x: var) @typeOf(x) {
1414 const T = @typeOf(x);
1515 return switch (T) {
1616 f32 => sinh32(x),
......@@ -22,7 +22,7 @@ pub fn sinh(x: var) -> @typeOf(x) {
2222// sinh(x) = (exp(x) - 1 / exp(x)) / 2
2323// = (exp(x) - 1 + (exp(x) - 1) / exp(x)) / 2
2424// = x + x^3 / 6 + o(x^5)
25fn sinh32(x: f32) -> f32 {
25fn sinh32(x: f32) f32 {
2626 const u = @bitCast(u32, x);
2727 const ux = u & 0x7FFFFFFF;
2828 const ax = @bitCast(f32, ux);
......@@ -53,7 +53,7 @@ fn sinh32(x: f32) -> f32 {
5353 return 2 * h * expo2(ax);
5454}
5555
56fn sinh64(x: f64) -> f64 {
56fn sinh64(x: f64) f64 {
5757 @setFloatMode(this, @import("builtin").FloatMode.Strict);
5858
5959 const u = @bitCast(u64, x);
std/math/sqrt.zig+4-4
......@@ -11,7 +11,7 @@ const assert = std.debug.assert;
1111const builtin = @import("builtin");
1212const 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)) {
1515 const T = @typeOf(x);
1616 switch (@typeId(T)) {
1717 TypeId.FloatLiteral => {
......@@ -50,7 +50,7 @@ pub fn sqrt(x: var) -> (if (@typeId(@typeOf(x)) == TypeId.Int) @IntType(false, @
5050 }
5151}
5252
53fn sqrt32(x: f32) -> f32 {
53fn sqrt32(x: f32) f32 {
5454 const tiny: f32 = 1.0e-30;
5555 const sign: i32 = @bitCast(i32, u32(0x80000000));
5656 var ix: i32 = @bitCast(i32, x);
......@@ -129,7 +129,7 @@ fn sqrt32(x: f32) -> f32 {
129129// NOTE: The original code is full of implicit signed -> unsigned assumptions and u32 wraparound
130130// behaviour. Most intermediate i32 values are changed to u32 where appropriate but there are
131131// potentially some edge cases remaining that are not handled in the same way.
132fn sqrt64(x: f64) -> f64 {
132fn sqrt64(x: f64) f64 {
133133 const tiny: f64 = 1.0e-300;
134134 const sign: u32 = 0x80000000;
135135 const u = @bitCast(u64, x);
......@@ -308,7 +308,7 @@ test "math.sqrt64.special" {
308308 assert(math.isNan(sqrt64(math.nan(f64))));
309309}
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) {
312312 var op = value;
313313 var res: T = 0;
314314 var one: T = 1 << (T.bit_count - 2);
std/math/tan.zig+3-3
......@@ -9,7 +9,7 @@ const std = @import("../index.zig");
99const math = std.math;
1010const assert = std.debug.assert;
1111
12pub fn tan(x: var) -> @typeOf(x) {
12pub fn tan(x: var) @typeOf(x) {
1313 const T = @typeOf(x);
1414 return switch (T) {
1515 f32 => tan32(x),
......@@ -30,7 +30,7 @@ const Tq4 = -5.38695755929454629881E7;
3030// NOTE: This is taken from the go stdlib. The musl implementation is much more complex.
3131//
3232// 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 {
3434 @setFloatMode(this, @import("builtin").FloatMode.Strict);
3535
3636 const pi4a = 7.85398125648498535156e-1;
......@@ -81,7 +81,7 @@ fn tan32(x_: f32) -> f32 {
8181 return r;
8282}
8383
84fn tan64(x_: f64) -> f64 {
84fn tan64(x_: f64) f64 {
8585 const pi4a = 7.85398125648498535156e-1;
8686 const pi4b = 3.77489470793079817668E-8;
8787 const pi4c = 2.69515142907905952645E-15;
std/math/tanh.zig+3-3
......@@ -10,7 +10,7 @@ const math = std.math;
1010const assert = std.debug.assert;
1111const expo2 = @import("expo2.zig").expo2;
1212
13pub fn tanh(x: var) -> @typeOf(x) {
13pub fn tanh(x: var) @typeOf(x) {
1414 const T = @typeOf(x);
1515 return switch (T) {
1616 f32 => tanh32(x),
......@@ -22,7 +22,7 @@ pub fn tanh(x: var) -> @typeOf(x) {
2222// tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
2323// = (exp(2x) - 1) / (exp(2x) - 1 + 2)
2424// = (1 - exp(-2x)) / (exp(-2x) - 1 + 2)
25fn tanh32(x: f32) -> f32 {
25fn tanh32(x: f32) f32 {
2626 const u = @bitCast(u32, x);
2727 const ux = u & 0x7FFFFFFF;
2828 const ax = @bitCast(f32, ux);
......@@ -66,7 +66,7 @@ fn tanh32(x: f32) -> f32 {
6666 }
6767}
6868
69fn tanh64(x: f64) -> f64 {
69fn tanh64(x: f64) f64 {
7070 const u = @bitCast(u64, x);
7171 const w = u32(u >> 32);
7272 const ax = @bitCast(f64, u & (@maxValue(u64) >> 1));
std/math/trunc.zig+3-3
......@@ -8,7 +8,7 @@ const std = @import("../index.zig");
88const math = std.math;
99const assert = std.debug.assert;
1010
11pub fn trunc(x: var) -> @typeOf(x) {
11pub fn trunc(x: var) @typeOf(x) {
1212 const T = @typeOf(x);
1313 return switch (T) {
1414 f32 => trunc32(x),
......@@ -17,7 +17,7 @@ pub fn trunc(x: var) -> @typeOf(x) {
1717 };
1818}
1919
20fn trunc32(x: f32) -> f32 {
20fn trunc32(x: f32) f32 {
2121 const u = @bitCast(u32, x);
2222 var e = i32(((u >> 23) & 0xFF)) - 0x7F + 9;
2323 var m: u32 = undefined;
......@@ -38,7 +38,7 @@ fn trunc32(x: f32) -> f32 {
3838 }
3939}
4040
41fn trunc64(x: f64) -> f64 {
41fn trunc64(x: f64) f64 {
4242 const u = @bitCast(u64, x);
4343 var e = i32(((u >> 52) & 0x7FF)) - 0x3FF + 12;
4444 var m: u64 = undefined;
std/math/x86_64/sqrt.zig+2-2
......@@ -1,4 +1,4 @@
1pub fn sqrt32(x: f32) -> f32 {
1pub fn sqrt32(x: f32) f32 {
22 return asm (
33 \\sqrtss %%xmm0, %%xmm0
44 : [ret] "={xmm0}" (-> f32)
......@@ -6,7 +6,7 @@ pub fn sqrt32(x: f32) -> f32 {
66 );
77}
88
9pub fn sqrt64(x: f64) -> f64 {
9pub fn sqrt64(x: f64) f64 {
1010 return asm (
1111 \\sqrtsd %%xmm0, %%xmm0
1212 : [ret] "={xmm0}" (-> f64)
std/mem.zig+50-50
......@@ -10,7 +10,7 @@ pub const Allocator = struct {
1010 /// Allocate byte_count bytes and return them in a slice, with the
1111 /// slice's pointer aligned at least to alignment bytes.
1212 /// 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
1515 /// If `new_byte_count > old_mem.len`:
1616 /// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
......@@ -21,26 +21,26 @@ pub const Allocator = struct {
2121 /// * alignment <= alignment of old_mem.ptr
2222 ///
2323 /// 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
2626 /// 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 {
3030 const slice = try self.alloc(T, 1);
3131 return &slice[0];
3232 }
3333
34 fn destroy(self: &Allocator, ptr: var) {
34 fn destroy(self: &Allocator, ptr: var) void {
3535 self.free(ptr[0..1]);
3636 }
3737
38 fn alloc(self: &Allocator, comptime T: type, n: usize) -> %[]T {
38 fn alloc(self: &Allocator, comptime T: type, n: usize) %[]T {
3939 return self.alignedAlloc(T, @alignOf(T), n);
4040 }
4141
4242 fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
43 n: usize) -> %[]align(alignment) T
43 n: usize) %[]align(alignment) T
4444 {
4545 const byte_count = try math.mul(usize, @sizeOf(T), n);
4646 const byte_slice = try self.allocFn(self, byte_count, alignment);
......@@ -51,12 +51,12 @@ pub const Allocator = struct {
5151 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
5252 }
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 {
5555 return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
5656 }
5757
5858 fn alignedRealloc(self: &Allocator, comptime T: type, comptime alignment: u29,
59 old_mem: []align(alignment) T, n: usize) -> %[]align(alignment) T
59 old_mem: []align(alignment) T, n: usize) %[]align(alignment) T
6060 {
6161 if (old_mem.len == 0) {
6262 return self.alloc(T, n);
......@@ -75,12 +75,12 @@ pub const Allocator = struct {
7575 /// Reallocate, but `n` must be less than or equal to `old_mem.len`.
7676 /// Unlike `realloc`, this function cannot fail.
7777 /// 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 {
7979 return self.alignedShrink(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
8080 }
8181
8282 fn alignedShrink(self: &Allocator, comptime T: type, comptime alignment: u29,
83 old_mem: []align(alignment) T, n: usize) -> []align(alignment) T
83 old_mem: []align(alignment) T, n: usize) []align(alignment) T
8484 {
8585 if (n == 0) {
8686 self.free(old_mem);
......@@ -97,7 +97,7 @@ pub const Allocator = struct {
9797 return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
9898 }
9999
100 fn free(self: &Allocator, memory: var) {
100 fn free(self: &Allocator, memory: var) void {
101101 const bytes = ([]const u8)(memory);
102102 if (bytes.len == 0)
103103 return;
......@@ -111,7 +111,7 @@ pub const FixedBufferAllocator = struct {
111111 end_index: usize,
112112 buffer: []u8,
113113
114 pub fn init(buffer: []u8) -> FixedBufferAllocator {
114 pub fn init(buffer: []u8) FixedBufferAllocator {
115115 return FixedBufferAllocator {
116116 .allocator = Allocator {
117117 .allocFn = alloc,
......@@ -123,7 +123,7 @@ pub const FixedBufferAllocator = struct {
123123 };
124124 }
125125
126 fn alloc(allocator: &Allocator, n: usize, alignment: u29) -> %[]u8 {
126 fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
127127 const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
128128 const addr = @ptrToInt(&self.buffer[self.end_index]);
129129 const rem = @rem(addr, alignment);
......@@ -138,7 +138,7 @@ pub const FixedBufferAllocator = struct {
138138 return result;
139139 }
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 {
142142 if (new_size <= old_mem.len) {
143143 return old_mem[0..new_size];
144144 } else {
......@@ -148,27 +148,27 @@ pub const FixedBufferAllocator = struct {
148148 }
149149 }
150150
151 fn free(allocator: &Allocator, bytes: []u8) { }
151 fn free(allocator: &Allocator, bytes: []u8) void { }
152152};
153153
154154
155155/// Copy all of source into dest at position 0.
156156/// 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 {
158158 // TODO instead of manually doing this check for the whole array
159 // and turning off debug safety, the compiler should detect loops like
159 // and turning off runtime safety, the compiler should detect loops like
160160 // this and automatically omit safety checks for loops
161 @setDebugSafety(this, false);
161 @setRuntimeSafety(false);
162162 assert(dest.len >= source.len);
163163 for (source) |s, i| dest[i] = s;
164164}
165165
166pub fn set(comptime T: type, dest: []T, value: T) {
166pub fn set(comptime T: type, dest: []T, value: T) void {
167167 for (dest) |*d| *d = value;
168168}
169169
170170/// 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 {
172172 const n = math.min(lhs.len, rhs.len);
173173 var i: usize = 0;
174174 while (i < n) : (i += 1) {
......@@ -188,7 +188,7 @@ test "mem.lessThan" {
188188}
189189
190190/// 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 {
192192 if (a.len != b.len) return false;
193193 for (a) |item, index| {
194194 if (b[index] != item) return false;
......@@ -197,14 +197,14 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool {
197197}
198198
199199/// 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 {
201201 const new_buf = try allocator.alloc(T, m.len);
202202 copy(T, new_buf, m);
203203 return new_buf;
204204}
205205
206206/// 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 {
208208 var begin: usize = 0;
209209 var end: usize = slice.len;
210210 while (begin < end and indexOfScalar(T, values_to_strip, slice[begin]) != null) : (begin += 1) {}
......@@ -218,11 +218,11 @@ test "mem.trim" {
218218}
219219
220220/// 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 {
222222 return indexOfScalarPos(T, slice, 0, value);
223223}
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 {
226226 var i: usize = start_index;
227227 while (i < slice.len) : (i += 1) {
228228 if (slice[i] == value)
......@@ -231,11 +231,11 @@ pub fn indexOfScalarPos(comptime T: type, slice: []const T, start_index: usize,
231231 return null;
232232}
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 {
235235 return indexOfAnyPos(T, slice, 0, values);
236236}
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 {
239239 var i: usize = start_index;
240240 while (i < slice.len) : (i += 1) {
241241 for (values) |value| {
......@@ -246,12 +246,12 @@ pub fn indexOfAnyPos(comptime T: type, slice: []const T, start_index: usize, val
246246 return null;
247247}
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 {
250250 return indexOfPos(T, haystack, 0, needle);
251251}
252252
253253// 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 {
255255 if (needle.len > haystack.len)
256256 return null;
257257
......@@ -275,7 +275,7 @@ test "mem.indexOf" {
275275/// T specifies the return type, which must be large enough to store
276276/// the result.
277277/// 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 {
279279 if (T.bit_count == 8) {
280280 return bytes[0];
281281 }
......@@ -298,7 +298,7 @@ pub fn readInt(bytes: []const u8, comptime T: type, endian: builtin.Endian) -> T
298298
299299/// Reads a big-endian int of type T from bytes.
300300/// 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 {
302302 if (T.is_signed) {
303303 return @bitCast(T, readIntBE(@IntType(false, T.bit_count), bytes));
304304 }
......@@ -312,7 +312,7 @@ pub fn readIntBE(comptime T: type, bytes: []const u8) -> T {
312312
313313/// Reads a little-endian int of type T from bytes.
314314/// 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 {
316316 if (T.is_signed) {
317317 return @bitCast(T, readIntLE(@IntType(false, T.bit_count), bytes));
318318 }
......@@ -327,7 +327,7 @@ pub fn readIntLE(comptime T: type, bytes: []const u8) -> T {
327327/// Writes an integer to memory with size equal to bytes.len. Pads with zeroes
328328/// to fill the entire buffer provided.
329329/// 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 {
331331 const uint = @IntType(false, @typeOf(value).bit_count);
332332 var bits = @truncate(uint, value);
333333 switch (endian) {
......@@ -351,7 +351,7 @@ pub fn writeInt(buf: []u8, value: var, endian: builtin.Endian) {
351351}
352352
353353
354pub fn hash_slice_u8(k: []const u8) -> u32 {
354pub fn hash_slice_u8(k: []const u8) u32 {
355355 // FNV 32-bit hash
356356 var h: u32 = 2166136261;
357357 for (k) |b| {
......@@ -360,7 +360,7 @@ pub fn hash_slice_u8(k: []const u8) -> u32 {
360360 return h;
361361}
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 {
364364 return eql(u8, a, b);
365365}
366366
......@@ -368,7 +368,7 @@ pub fn eql_slice_u8(a: []const u8, b: []const u8) -> bool {
368368/// any of the bytes in `split_bytes`.
369369/// split(" abc def ghi ", " ")
370370/// 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 {
372372 return SplitIterator {
373373 .index = 0,
374374 .buffer = buffer,
......@@ -384,7 +384,7 @@ test "mem.split" {
384384 assert(it.next() == null);
385385}
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 {
388388 return if (needle.len > haystack.len) false else eql(T, haystack[0 .. needle.len], needle);
389389}
390390
......@@ -393,7 +393,7 @@ const SplitIterator = struct {
393393 split_bytes: []const u8,
394394 index: usize,
395395
396 pub fn next(self: &SplitIterator) -> ?[]const u8 {
396 pub fn next(self: &SplitIterator) ?[]const u8 {
397397 // move to beginning of token
398398 while (self.index < self.buffer.len and self.isSplitByte(self.buffer[self.index])) : (self.index += 1) {}
399399 const start = self.index;
......@@ -409,14 +409,14 @@ const SplitIterator = struct {
409409 }
410410
411411 /// 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 {
413413 // move to beginning of token
414414 var index: usize = self.index;
415415 while (index < self.buffer.len and self.isSplitByte(self.buffer[index])) : (index += 1) {}
416416 return self.buffer[index..];
417417 }
418418
419 fn isSplitByte(self: &const SplitIterator, byte: u8) -> bool {
419 fn isSplitByte(self: &const SplitIterator, byte: u8) bool {
420420 for (self.split_bytes) |split_byte| {
421421 if (byte == split_byte) {
422422 return true;
......@@ -428,7 +428,7 @@ const SplitIterator = struct {
428428
429429/// Naively combines a series of strings with a separator.
430430/// 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 {
432432 comptime assert(strings.len >= 1);
433433 var total_strings_len: usize = strings.len; // 1 sep per string
434434 {
......@@ -440,7 +440,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
440440 }
441441
442442 const buf = try allocator.alloc(u8, total_strings_len);
443 %defer allocator.free(buf);
443 errdefer allocator.free(buf);
444444
445445 var buf_index: usize = 0;
446446 comptime var string_i = 0;
......@@ -474,7 +474,7 @@ test "testReadInt" {
474474 testReadIntImpl();
475475 comptime testReadIntImpl();
476476}
477fn testReadIntImpl() {
477fn testReadIntImpl() void {
478478 {
479479 const bytes = []u8{ 0x12, 0x34, 0x56, 0x78 };
480480 assert(readInt(bytes, u32, builtin.Endian.Big) == 0x12345678);
......@@ -507,7 +507,7 @@ test "testWriteInt" {
507507 testWriteIntImpl();
508508 comptime testWriteIntImpl();
509509}
510fn testWriteIntImpl() {
510fn testWriteIntImpl() void {
511511 var bytes: [4]u8 = undefined;
512512
513513 writeInt(bytes[0..], u32(0x12345678), builtin.Endian.Big);
......@@ -524,7 +524,7 @@ fn testWriteIntImpl() {
524524}
525525
526526
527pub fn min(comptime T: type, slice: []const T) -> T {
527pub fn min(comptime T: type, slice: []const T) T {
528528 var best = slice[0];
529529 for (slice[1..]) |item| {
530530 best = math.min(best, item);
......@@ -536,7 +536,7 @@ test "mem.min" {
536536 assert(min(u8, "abcdefg") == 'a');
537537}
538538
539pub fn max(comptime T: type, slice: []const T) -> T {
539pub fn max(comptime T: type, slice: []const T) T {
540540 var best = slice[0];
541541 for (slice[1..]) |item| {
542542 best = math.max(best, item);
......@@ -548,14 +548,14 @@ test "mem.max" {
548548 assert(max(u8, "abcdefg") == 'g');
549549}
550550
551pub fn swap(comptime T: type, a: &T, b: &T) {
551pub fn swap(comptime T: type, a: &T, b: &T) void {
552552 const tmp = *a;
553553 *a = *b;
554554 *b = tmp;
555555}
556556
557557/// In-place order reversal of a slice
558pub fn reverse(comptime T: type, items: []T) {
558pub fn reverse(comptime T: type, items: []T) void {
559559 var i: usize = 0;
560560 const end = items.len / 2;
561561 while (i < end) : (i += 1) {
......@@ -572,7 +572,7 @@ test "std.mem.reverse" {
572572
573573/// In-place rotation of the values in an array ([0 1 2 3] becomes [1 2 3 0] if we rotate by 1)
574574/// 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 {
576576 reverse(T, items[0..amount]);
577577 reverse(T, items[amount..]);
578578 reverse(T, items);
std/net.zig+10-10
......@@ -17,7 +17,7 @@ error BadFd;
1717const Connection = struct {
1818 socket_fd: i32,
1919
20 pub fn send(c: Connection, buf: []const u8) -> %usize {
20 pub fn send(c: Connection, buf: []const u8) %usize {
2121 const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
2222 const send_err = linux.getErrno(send_ret);
2323 switch (send_err) {
......@@ -31,7 +31,7 @@ const Connection = struct {
3131 }
3232 }
3333
34 pub fn recv(c: Connection, buf: []u8) -> %[]u8 {
34 pub fn recv(c: Connection, buf: []u8) %[]u8 {
3535 const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
3636 const recv_err = linux.getErrno(recv_ret);
3737 switch (recv_err) {
......@@ -48,7 +48,7 @@ const Connection = struct {
4848 }
4949 }
5050
51 pub fn close(c: Connection) -> %void {
51 pub fn close(c: Connection) %void {
5252 switch (linux.getErrno(linux.close(c.socket_fd))) {
5353 0 => return,
5454 linux.EBADF => unreachable,
......@@ -66,7 +66,7 @@ const Address = struct {
6666 sort_key: i32,
6767};
6868
69pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
69pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
7070 if (hostname.len == 0) {
7171
7272 unreachable; // TODO
......@@ -75,7 +75,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) -> %[]Address {
7575 unreachable; // TODO
7676}
7777
78pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
78pub fn connectAddr(addr: &Address, port: u16) %Connection {
7979 const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);
8080 const socket_err = linux.getErrno(socket_ret);
8181 if (socket_err > 0) {
......@@ -118,7 +118,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
118118 };
119119}
120120
121pub fn connect(hostname: []const u8, port: u16) -> %Connection {
121pub fn connect(hostname: []const u8, port: u16) %Connection {
122122 var addrs_buf: [1]Address = undefined;
123123 const addrs_slice = try lookup(hostname, addrs_buf[0..]);
124124 const main_addr = &addrs_slice[0];
......@@ -128,12 +128,12 @@ pub fn connect(hostname: []const u8, port: u16) -> %Connection {
128128
129129error InvalidIpLiteral;
130130
131pub fn parseIpLiteral(buf: []const u8) -> %Address {
131pub fn parseIpLiteral(buf: []const u8) %Address {
132132
133133 return error.InvalidIpLiteral;
134134}
135135
136fn hexDigit(c: u8) -> u8 {
136fn hexDigit(c: u8) u8 {
137137 // TODO use switch with range
138138 if ('0' <= c and c <= '9') {
139139 return c - '0';
......@@ -151,7 +151,7 @@ error Overflow;
151151error JunkAtEnd;
152152error Incomplete;
153153
154fn parseIp6(buf: []const u8) -> %Address {
154fn parseIp6(buf: []const u8) %Address {
155155 var result: Address = undefined;
156156 result.family = linux.AF_INET6;
157157 result.scope_id = 0;
......@@ -232,7 +232,7 @@ fn parseIp6(buf: []const u8) -> %Address {
232232 return error.Incomplete;
233233}
234234
235fn parseIp4(buf: []const u8) -> %u32 {
235fn parseIp4(buf: []const u8) %u32 {
236236 var result: u32 = undefined;
237237 const out_ptr = ([]u8)((&result)[0..1]);
238238
std/os/child_process.zig+49-49
......@@ -37,7 +37,7 @@ pub const ChildProcess = struct {
3737 pub argv: []const []const u8,
3838
3939 /// Possibly called from a signal handler. Must set this before calling `spawn`.
40 pub onTerm: ?fn(&ChildProcess),
40 pub onTerm: ?fn(&ChildProcess)void,
4141
4242 /// Leave as null to use the current env map using the supplied allocator.
4343 pub env_map: ?&const BufMap,
......@@ -74,9 +74,9 @@ pub const ChildProcess = struct {
7474
7575 /// First argument in argv is the executable.
7676 /// 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 {
7878 const child = try allocator.create(ChildProcess);
79 %defer allocator.destroy(child);
79 errdefer allocator.destroy(child);
8080
8181 *child = ChildProcess {
8282 .allocator = allocator,
......@@ -103,7 +103,7 @@ pub const ChildProcess = struct {
103103 return child;
104104 }
105105
106 pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void {
106 pub fn setUserName(self: &ChildProcess, name: []const u8) %void {
107107 const user_info = try os.getUserInfo(name);
108108 self.uid = user_info.uid;
109109 self.gid = user_info.gid;
......@@ -111,7 +111,7 @@ pub const ChildProcess = struct {
111111
112112 /// onTerm can be called before `spawn` returns.
113113 /// On success must call `kill` or `wait`.
114 pub fn spawn(self: &ChildProcess) -> %void {
114 pub fn spawn(self: &ChildProcess) %void {
115115 if (is_windows) {
116116 return self.spawnWindows();
117117 } else {
......@@ -119,13 +119,13 @@ pub const ChildProcess = struct {
119119 }
120120 }
121121
122 pub fn spawnAndWait(self: &ChildProcess) -> %Term {
122 pub fn spawnAndWait(self: &ChildProcess) %Term {
123123 try self.spawn();
124124 return self.wait();
125125 }
126126
127127 /// Forcibly terminates child process and then cleans up all resources.
128 pub fn kill(self: &ChildProcess) -> %Term {
128 pub fn kill(self: &ChildProcess) %Term {
129129 if (is_windows) {
130130 return self.killWindows(1);
131131 } else {
......@@ -133,7 +133,7 @@ pub const ChildProcess = struct {
133133 }
134134 }
135135
136 pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) -> %Term {
136 pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) %Term {
137137 if (self.term) |term| {
138138 self.cleanupStreams();
139139 return term;
......@@ -149,7 +149,7 @@ pub const ChildProcess = struct {
149149 return ??self.term;
150150 }
151151
152 pub fn killPosix(self: &ChildProcess) -> %Term {
152 pub fn killPosix(self: &ChildProcess) %Term {
153153 block_SIGCHLD();
154154 defer restore_SIGCHLD();
155155
......@@ -172,7 +172,7 @@ pub const ChildProcess = struct {
172172 }
173173
174174 /// 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 {
176176 if (is_windows) {
177177 return self.waitWindows();
178178 } else {
......@@ -189,7 +189,7 @@ pub const ChildProcess = struct {
189189 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
190190 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
191191 pub fn exec(allocator: &mem.Allocator, argv: []const []const u8, cwd: ?[]const u8,
192 env_map: ?&const BufMap, max_output_size: usize) -> %ExecResult
192 env_map: ?&const BufMap, max_output_size: usize) %ExecResult
193193 {
194194 const child = try ChildProcess.init(argv, allocator);
195195 defer child.deinit();
......@@ -220,7 +220,7 @@ pub const ChildProcess = struct {
220220 };
221221 }
222222
223 fn waitWindows(self: &ChildProcess) -> %Term {
223 fn waitWindows(self: &ChildProcess) %Term {
224224 if (self.term) |term| {
225225 self.cleanupStreams();
226226 return term;
......@@ -230,7 +230,7 @@ pub const ChildProcess = struct {
230230 return ??self.term;
231231 }
232232
233 fn waitPosix(self: &ChildProcess) -> %Term {
233 fn waitPosix(self: &ChildProcess) %Term {
234234 block_SIGCHLD();
235235 defer restore_SIGCHLD();
236236
......@@ -243,11 +243,11 @@ pub const ChildProcess = struct {
243243 return ??self.term;
244244 }
245245
246 pub fn deinit(self: &ChildProcess) {
246 pub fn deinit(self: &ChildProcess) void {
247247 self.allocator.destroy(self);
248248 }
249249
250 fn waitUnwrappedWindows(self: &ChildProcess) -> %void {
250 fn waitUnwrappedWindows(self: &ChildProcess) %void {
251251 const result = os.windowsWaitSingle(self.handle, windows.INFINITE);
252252
253253 self.term = (%Term)(x: {
......@@ -265,7 +265,7 @@ pub const ChildProcess = struct {
265265 return result;
266266 }
267267
268 fn waitUnwrapped(self: &ChildProcess) {
268 fn waitUnwrapped(self: &ChildProcess) void {
269269 var status: i32 = undefined;
270270 while (true) {
271271 const err = posix.getErrno(posix.waitpid(self.pid, &status, 0));
......@@ -281,7 +281,7 @@ pub const ChildProcess = struct {
281281 }
282282 }
283283
284 fn handleWaitResult(self: &ChildProcess, status: i32) {
284 fn handleWaitResult(self: &ChildProcess, status: i32) void {
285285 self.term = self.cleanupAfterWait(status);
286286
287287 if (self.onTerm) |onTerm| {
......@@ -289,13 +289,13 @@ pub const ChildProcess = struct {
289289 }
290290 }
291291
292 fn cleanupStreams(self: &ChildProcess) {
292 fn cleanupStreams(self: &ChildProcess) void {
293293 if (self.stdin) |*stdin| { stdin.close(); self.stdin = null; }
294294 if (self.stdout) |*stdout| { stdout.close(); self.stdout = null; }
295295 if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }
296296 }
297297
298 fn cleanupAfterWait(self: &ChildProcess, status: i32) -> %Term {
298 fn cleanupAfterWait(self: &ChildProcess, status: i32) %Term {
299299 children_nodes.remove(&self.llnode);
300300
301301 defer {
......@@ -319,7 +319,7 @@ pub const ChildProcess = struct {
319319 return statusToTerm(status);
320320 }
321321
322 fn statusToTerm(status: i32) -> Term {
322 fn statusToTerm(status: i32) Term {
323323 return if (posix.WIFEXITED(status))
324324 Term { .Exited = posix.WEXITSTATUS(status) }
325325 else if (posix.WIFSIGNALED(status))
......@@ -331,18 +331,18 @@ pub const ChildProcess = struct {
331331 ;
332332 }
333333
334 fn spawnPosix(self: &ChildProcess) -> %void {
334 fn spawnPosix(self: &ChildProcess) %void {
335335 // TODO atomically set a flag saying that we already did this
336336 install_SIGCHLD_handler();
337337
338338 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
341341 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
344344 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
347347 const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
348348 const dev_null_fd = if (any_ignore)
......@@ -367,7 +367,7 @@ pub const ChildProcess = struct {
367367 // This pipe is used to communicate errors between the time of fork
368368 // and execve from the child process to the parent process.
369369 const err_pipe = try makePipe();
370 %defer destroyPipe(err_pipe);
370 errdefer destroyPipe(err_pipe);
371371
372372 block_SIGCHLD();
373373 const pid_result = posix.fork();
......@@ -440,7 +440,7 @@ pub const ChildProcess = struct {
440440 if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }
441441 }
442442
443 fn spawnWindows(self: &ChildProcess) -> %void {
443 fn spawnWindows(self: &ChildProcess) %void {
444444 const saAttr = windows.SECURITY_ATTRIBUTES {
445445 .nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
446446 .bInheritHandle = windows.TRUE,
......@@ -479,7 +479,7 @@ pub const ChildProcess = struct {
479479 g_hChildStd_IN_Rd = null;
480480 },
481481 }
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
484484 var g_hChildStd_OUT_Rd: ?windows.HANDLE = null;
485485 var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
......@@ -497,7 +497,7 @@ pub const ChildProcess = struct {
497497 g_hChildStd_OUT_Wr = null;
498498 },
499499 }
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
502502 var g_hChildStd_ERR_Rd: ?windows.HANDLE = null;
503503 var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
......@@ -515,7 +515,7 @@ pub const ChildProcess = struct {
515515 g_hChildStd_ERR_Wr = null;
516516 },
517517 }
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
520520 const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
521521 defer self.allocator.free(cmd_line);
......@@ -623,7 +623,7 @@ pub const ChildProcess = struct {
623623 if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }
624624 }
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 {
627627 switch (stdio) {
628628 StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
629629 StdIo.Close => os.close(std_fileno),
......@@ -635,7 +635,7 @@ pub const ChildProcess = struct {
635635};
636636
637637fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?&u8,
638 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) -> %void
638 lpStartupInfo: &windows.STARTUPINFOA, lpProcessInformation: &windows.PROCESS_INFORMATION) %void
639639{
640640 if (windows.CreateProcessA(app_name, cmd_line, null, null, windows.TRUE, 0,
641641 @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: ?
655655
656656/// Caller must dealloc.
657657/// 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 {
659659 var buf = try Buffer.initSize(allocator, 0);
660660 defer buf.deinit();
661661
......@@ -690,7 +690,7 @@ fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8)
690690 return buf.toOwnedSlice();
691691}
692692
693fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {
693fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
694694 if (rd) |h| os.close(h);
695695 if (wr) |h| os.close(h);
696696}
......@@ -700,7 +700,7 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) {
700700// a namespace field lookup
701701const 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 {
704704 if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {
705705 const err = windows.GetLastError();
706706 return switch (err) {
......@@ -709,7 +709,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR
709709 }
710710}
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 {
713713 if (windows.SetHandleInformation(h, mask, flags) == 0) {
714714 const err = windows.GetLastError();
715715 return switch (err) {
......@@ -718,27 +718,27 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
718718 }
719719}
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 {
722722 var rd_h: windows.HANDLE = undefined;
723723 var wr_h: windows.HANDLE = undefined;
724724 try windowsMakePipe(&rd_h, &wr_h, sattr);
725 %defer windowsDestroyPipe(rd_h, wr_h);
725 errdefer windowsDestroyPipe(rd_h, wr_h);
726726 try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
727727 *rd = rd_h;
728728 *wr = wr_h;
729729}
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 {
732732 var rd_h: windows.HANDLE = undefined;
733733 var wr_h: windows.HANDLE = undefined;
734734 try windowsMakePipe(&rd_h, &wr_h, sattr);
735 %defer windowsDestroyPipe(rd_h, wr_h);
735 errdefer windowsDestroyPipe(rd_h, wr_h);
736736 try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
737737 *rd = rd_h;
738738 *wr = wr_h;
739739}
740740
741fn makePipe() -> %[2]i32 {
741fn makePipe() %[2]i32 {
742742 var fds: [2]i32 = undefined;
743743 const err = posix.getErrno(posix.pipe(&fds));
744744 if (err > 0) {
......@@ -750,33 +750,33 @@ fn makePipe() -> %[2]i32 {
750750 return fds;
751751}
752752
753fn destroyPipe(pipe: &const [2]i32) {
753fn destroyPipe(pipe: &const [2]i32) void {
754754 os.close((*pipe)[0]);
755755 os.close((*pipe)[1]);
756756}
757757
758758// Child of fork calls this to report an error to the fork parent.
759759// Then the child exits.
760fn forkChildErrReport(fd: i32, err: error) -> noreturn {
760fn forkChildErrReport(fd: i32, err: error) noreturn {
761761 _ = writeIntFd(fd, ErrInt(err));
762762 posix.exit(1);
763763}
764764
765765const ErrInt = @IntType(false, @sizeOf(error) * 8);
766766
767fn writeIntFd(fd: i32, value: ErrInt) -> %void {
767fn writeIntFd(fd: i32, value: ErrInt) %void {
768768 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
769769 mem.writeInt(bytes[0..], value, builtin.endian);
770770 os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;
771771}
772772
773fn readIntFd(fd: i32) -> %ErrInt {
773fn readIntFd(fd: i32) %ErrInt {
774774 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
775775 os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
776776 return mem.readInt(bytes[0..], ErrInt, builtin.endian);
777777}
778778
779extern fn sigchld_handler(_: i32) {
779extern fn sigchld_handler(_: i32) void {
780780 while (true) {
781781 var status: i32 = undefined;
782782 const pid_result = posix.waitpid(-1, &status, posix.WNOHANG);
......@@ -794,7 +794,7 @@ extern fn sigchld_handler(_: i32) {
794794 }
795795}
796796
797fn handleTerm(pid: i32, status: i32) {
797fn handleTerm(pid: i32, status: i32) void {
798798 var it = children_nodes.first;
799799 while (it) |node| : (it = node.next) {
800800 if (node.data.pid == pid) {
......@@ -810,12 +810,12 @@ const sigchld_set = x: {
810810 break :x signal_set;
811811};
812812
813fn block_SIGCHLD() {
813fn block_SIGCHLD() void {
814814 const err = posix.getErrno(posix.sigprocmask(posix.SIG_BLOCK, &sigchld_set, null));
815815 assert(err == 0);
816816}
817817
818fn restore_SIGCHLD() {
818fn restore_SIGCHLD() void {
819819 const err = posix.getErrno(posix.sigprocmask(posix.SIG_UNBLOCK, &sigchld_set, null));
820820 assert(err == 0);
821821}
......@@ -826,7 +826,7 @@ const sigchld_action = posix.Sigaction {
826826 .flags = posix.SA_RESTART | posix.SA_NOCLDSTOP,
827827};
828828
829fn install_SIGCHLD_handler() {
829fn install_SIGCHLD_handler() void {
830830 const err = posix.getErrno(posix.sigaction(posix.SIGCHLD, &sigchld_action, null));
831831 assert(err == 0);
832832}
std/os/darwin.zig+44-46
......@@ -98,67 +98,67 @@ pub const SIGINFO = 29; /// information request
9898pub const SIGUSR1 = 30; /// user defined signal 1
9999pub const SIGUSR2 = 31; /// user defined signal 2
100100
101fn wstatus(x: i32) -> i32 { return x & 0o177; }
101fn wstatus(x: i32) i32 { return x & 0o177; }
102102const wstopped = 0o177;
103pub fn WEXITSTATUS(x: i32) -> i32 { return x >> 8; }
104pub fn WTERMSIG(x: i32) -> i32 { return wstatus(x); }
105pub fn WSTOPSIG(x: i32) -> i32 { return x >> 8; }
106pub fn WIFEXITED(x: i32) -> bool { return wstatus(x) == 0; }
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; }
103pub fn WEXITSTATUS(x: i32) i32 { return x >> 8; }
104pub fn WTERMSIG(x: i32) i32 { return wstatus(x); }
105pub fn WSTOPSIG(x: i32) i32 { return x >> 8; }
106pub fn WIFEXITED(x: i32) bool { return wstatus(x) == 0; }
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; }
109109
110110/// 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 {
112112 const signed_r = @bitCast(isize, r);
113113 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
114114}
115115
116pub fn close(fd: i32) -> usize {
116pub fn close(fd: i32) usize {
117117 return errnoWrap(c.close(fd));
118118}
119119
120pub fn abort() -> noreturn {
120pub fn abort() noreturn {
121121 c.abort();
122122}
123123
124pub fn exit(code: i32) -> noreturn {
124pub fn exit(code: i32) noreturn {
125125 c.exit(code);
126126}
127127
128pub fn isatty(fd: i32) -> bool {
128pub fn isatty(fd: i32) bool {
129129 return c.isatty(fd) != 0;
130130}
131131
132pub fn fstat(fd: i32, buf: &c.Stat) -> usize {
132pub fn fstat(fd: i32, buf: &c.Stat) usize {
133133 return errnoWrap(c.@"fstat$INODE64"(fd, buf));
134134}
135135
136pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {
136pub fn lseek(fd: i32, offset: isize, whence: c_int) usize {
137137 return errnoWrap(c.lseek(fd, offset, whence));
138138}
139139
140pub fn open(path: &const u8, flags: u32, mode: usize) -> usize {
140pub fn open(path: &const u8, flags: u32, mode: usize) usize {
141141 return errnoWrap(c.open(path, @bitCast(c_int, flags), mode));
142142}
143143
144pub fn raise(sig: i32) -> usize {
144pub fn raise(sig: i32) usize {
145145 return errnoWrap(c.raise(sig));
146146}
147147
148pub fn read(fd: i32, buf: &u8, nbyte: usize) -> usize {
148pub fn read(fd: i32, buf: &u8, nbyte: usize) usize {
149149 return errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte));
150150}
151151
152pub fn stat(noalias path: &const u8, noalias buf: &stat) -> usize {
152pub fn stat(noalias path: &const u8, noalias buf: &stat) usize {
153153 return errnoWrap(c.stat(path, buf));
154154}
155155
156pub fn write(fd: i32, buf: &const u8, nbyte: usize) -> usize {
156pub fn write(fd: i32, buf: &const u8, nbyte: usize) usize {
157157 return errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte));
158158}
159159
160160pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
161 offset: isize) -> usize
161 offset: isize) usize
162162{
163163 const ptr_result = c.mmap(@ptrCast(&c_void, address), length,
164164 @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,
166166 return errnoWrap(isize_result);
167167}
168168
169pub fn munmap(address: &u8, length: usize) -> usize {
169pub fn munmap(address: &u8, length: usize) usize {
170170 return errnoWrap(c.munmap(@ptrCast(&c_void, address), length));
171171}
172172
173pub fn unlink(path: &const u8) -> usize {
173pub fn unlink(path: &const u8) usize {
174174 return errnoWrap(c.unlink(path));
175175}
176176
177pub fn getcwd(buf: &u8, size: usize) -> usize {
177pub fn getcwd(buf: &u8, size: usize) usize {
178178 return if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0;
179179}
180180
181pub fn waitpid(pid: i32, status: &i32, options: u32) -> usize {
181pub fn waitpid(pid: i32, status: &i32, options: u32) usize {
182182 comptime assert(i32.bit_count == c_int.bit_count);
183183 return errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)));
184184}
185185
186pub fn fork() -> usize {
186pub fn fork() usize {
187187 return errnoWrap(c.fork());
188188}
189189
190pub fn pipe(fds: &[2]i32) -> usize {
190pub fn pipe(fds: &[2]i32) usize {
191191 comptime assert(i32.bit_count == c_int.bit_count);
192192 return errnoWrap(c.pipe(@ptrCast(&c_int, fds)));
193193}
194194
195pub fn mkdir(path: &const u8, mode: u32) -> usize {
195pub fn mkdir(path: &const u8, mode: u32) usize {
196196 return errnoWrap(c.mkdir(path, mode));
197197}
198198
199pub fn symlink(existing: &const u8, new: &const u8) -> usize {
199pub fn symlink(existing: &const u8, new: &const u8) usize {
200200 return errnoWrap(c.symlink(existing, new));
201201}
202202
203pub fn rename(old: &const u8, new: &const u8) -> usize {
203pub fn rename(old: &const u8, new: &const u8) usize {
204204 return errnoWrap(c.rename(old, new));
205205}
206206
207pub fn chdir(path: &const u8) -> usize {
207pub fn chdir(path: &const u8) usize {
208208 return errnoWrap(c.chdir(path));
209209}
210210
211pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8)
212 -> usize
213{
211pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8) usize {
214212 return errnoWrap(c.execve(path, argv, envp));
215213}
216214
217pub fn dup2(old: i32, new: i32) -> usize {
215pub fn dup2(old: i32, new: i32) usize {
218216 return errnoWrap(c.dup2(old, new));
219217}
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 {
222220 return errnoWrap(c.readlink(path, buf_ptr, buf_len));
223221}
224222
225pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {
223pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {
226224 return errnoWrap(c.nanosleep(req, rem));
227225}
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 {
230228 return if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0;
231229}
232230
233pub fn setreuid(ruid: u32, euid: u32) -> usize {
231pub fn setreuid(ruid: u32, euid: u32) usize {
234232 return errnoWrap(c.setreuid(ruid, euid));
235233}
236234
237pub fn setregid(rgid: u32, egid: u32) -> usize {
235pub fn setregid(rgid: u32, egid: u32) usize {
238236 return errnoWrap(c.setregid(rgid, egid));
239237}
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 {
242240 return errnoWrap(c.sigprocmask(@bitCast(c_int, flags), set, oldset));
243241}
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 {
246244 assert(sig != SIGKILL);
247245 assert(sig != SIGSTOP);
248246 var cact = c.Sigaction {
249 .handler = @ptrCast(extern fn(c_int), act.handler),
247 .handler = @ptrCast(extern fn(c_int)void, act.handler),
250248 .sa_flags = @bitCast(c_int, act.flags),
251249 .sa_mask = act.mask,
252250 };
......@@ -257,7 +255,7 @@ pub fn sigaction(sig: u5, noalias act: &const Sigaction, noalias oact: ?&Sigacti
257255 }
258256 if (oact) |old| {
259257 *old = Sigaction {
260 .handler = @ptrCast(extern fn(i32), coact.handler),
258 .handler = @ptrCast(extern fn(i32)void, coact.handler),
261259 .flags = @bitCast(u32, coact.sa_flags),
262260 .mask = coact.sa_mask,
263261 };
......@@ -273,18 +271,18 @@ pub const Stat = c.Stat;
273271
274272/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
275273pub const Sigaction = struct {
276 handler: extern fn(i32),
274 handler: extern fn(i32)void,
277275 mask: sigset_t,
278276 flags: u32,
279277};
280278
281pub fn sigaddset(set: &sigset_t, signo: u5) {
279pub fn sigaddset(set: &sigset_t, signo: u5) void {
282280 *set |= u32(1) << (signo - 1);
283281}
284282
285283/// Takes the return value from a syscall and formats it back in the way
286284/// that the kernel represents it to libc. Errno was a mistake, let's make
287285/// it go away forever.
288fn errnoWrap(value: isize) -> usize {
286fn errnoWrap(value: isize) usize {
289287 return @bitCast(usize, if (value == -1) -isize(*c._errno()) else value);
290288}
std/os/get_user_id.zig+2-2
......@@ -9,7 +9,7 @@ pub const UserInfo = struct {
99};
1010
1111/// POSIX function which gets a uid from username.
12pub fn getUserInfo(name: []const u8) -> %UserInfo {
12pub fn getUserInfo(name: []const u8) %UserInfo {
1313 return switch (builtin.os) {
1414 Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),
1515 else => @compileError("Unsupported OS"),
......@@ -30,7 +30,7 @@ error CorruptPasswordFile;
3030// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else
3131// 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 {
3434 var in_stream = try io.InStream.open("/etc/passwd", null);
3535 defer in_stream.close();
3636
std/os/index.zig+82-80
......@@ -75,7 +75,7 @@ error WouldBlock;
7575/// Fills `buf` with random bytes. If linking against libc, this calls the
7676/// appropriate OS-specific library call. Otherwise it uses the zig standard
7777/// library implementation.
78pub fn getRandomBytes(buf: []u8) -> %void {
78pub fn getRandomBytes(buf: []u8) %void {
7979 switch (builtin.os) {
8080 Os.linux => while (true) {
8181 // TODO check libc version and potentially call c.getrandom.
......@@ -127,7 +127,8 @@ test "os.getRandomBytes" {
127127/// Raises a signal in the current kernel thread, ending its execution.
128128/// If linking against libc, this calls the abort() libc function. Otherwise
129129/// it uses the zig standard library implementation.
130pub coldcc fn abort() -> noreturn {
130pub fn abort() noreturn {
131 @setCold(true);
131132 if (builtin.link_libc) {
132133 c.abort();
133134 }
......@@ -148,7 +149,8 @@ pub coldcc fn abort() -> noreturn {
148149}
149150
150151/// 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);
152154 if (builtin.link_libc) {
153155 c.exit(status);
154156 }
......@@ -164,7 +166,7 @@ pub coldcc fn exit(status: u8) -> noreturn {
164166}
165167
166168/// Closes the file handle. Keeps trying if it gets interrupted by a signal.
167pub fn close(handle: FileHandle) {
169pub fn close(handle: FileHandle) void {
168170 if (is_windows) {
169171 windows_util.windowsClose(handle);
170172 } else {
......@@ -180,7 +182,7 @@ pub fn close(handle: FileHandle) {
180182}
181183
182184/// 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 {
184186 var index: usize = 0;
185187 while (index < buf.len) {
186188 const amt_written = posix.read(fd, &buf[index], buf.len - index);
......@@ -211,7 +213,7 @@ error NoSpaceLeft;
211213error BrokenPipe;
212214
213215/// 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 {
215217 while (true) {
216218 const write_ret = posix.write(fd, bytes.ptr, bytes.len);
217219 const write_err = posix.getErrno(write_ret);
......@@ -241,7 +243,7 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {
241243/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
242244/// Calls POSIX open, keeps trying if it gets interrupted, and translates
243245/// 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 {
245247 var stack_buf: [max_noalloc_path_len]u8 = undefined;
246248 var path0: []u8 = undefined;
247249 var need_free = false;
......@@ -290,7 +292,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
290292 }
291293}
292294
293pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
295pub fn posixDup2(old_fd: i32, new_fd: i32) %void {
294296 while (true) {
295297 const err = posix.getErrno(posix.dup2(old_fd, new_fd));
296298 if (err > 0) {
......@@ -305,11 +307,11 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
305307 }
306308}
307309
308pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 {
310pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) %[]?&u8 {
309311 const envp_count = env_map.count();
310312 const envp_buf = try allocator.alloc(?&u8, envp_count + 1);
311313 mem.set(?&u8, envp_buf, null);
312 %defer freeNullDelimitedEnvMap(allocator, envp_buf);
314 errdefer freeNullDelimitedEnvMap(allocator, envp_buf);
313315 {
314316 var it = env_map.iterator();
315317 var i: usize = 0;
......@@ -328,7 +330,7 @@ pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap)
328330 return envp_buf;
329331}
330332
331pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
333pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) void {
332334 for (envp_buf) |env| {
333335 const env_buf = if (env) |ptr| ptr[0 .. cstr.len(ptr) + 1] else break;
334336 allocator.free(env_buf);
......@@ -342,7 +344,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
342344/// `argv[0]` is the executable path.
343345/// This function also uses the PATH environment variable to get the full path to the executable.
344346pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
345 allocator: &Allocator) -> %void
347 allocator: &Allocator) %void
346348{
347349 const argv_buf = try allocator.alloc(?&u8, argv.len + 1);
348350 mem.set(?&u8, argv_buf, null);
......@@ -398,7 +400,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
398400 return posixExecveErrnoToErr(err);
399401}
400402
401fn posixExecveErrnoToErr(err: usize) -> error {
403fn posixExecveErrnoToErr(err: usize) error {
402404 assert(err > 0);
403405 return switch (err) {
404406 posix.EFAULT => unreachable,
......@@ -417,9 +419,9 @@ fn posixExecveErrnoToErr(err: usize) -> error {
417419pub var posix_environ_raw: []&u8 = undefined;
418420
419421/// Caller must free result when done.
420pub fn getEnvMap(allocator: &Allocator) -> %BufMap {
422pub fn getEnvMap(allocator: &Allocator) %BufMap {
421423 var result = BufMap.init(allocator);
422 %defer result.deinit();
424 errdefer result.deinit();
423425
424426 if (is_windows) {
425427 const ptr = windows.GetEnvironmentStringsA() ?? return error.OutOfMemory;
......@@ -461,7 +463,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap {
461463 }
462464}
463465
464pub fn getEnvPosix(key: []const u8) -> ?[]const u8 {
466pub fn getEnvPosix(key: []const u8) ?[]const u8 {
465467 for (posix_environ_raw) |ptr| {
466468 var line_i: usize = 0;
467469 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
......@@ -481,13 +483,13 @@ pub fn getEnvPosix(key: []const u8) -> ?[]const u8 {
481483error EnvironmentVariableNotFound;
482484
483485/// 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 {
485487 if (is_windows) {
486488 const key_with_null = try cstr.addNullByte(allocator, key);
487489 defer allocator.free(key_with_null);
488490
489491 var buf = try allocator.alloc(u8, 256);
490 %defer allocator.free(buf);
492 errdefer allocator.free(buf);
491493
492494 while (true) {
493495 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 {
515517}
516518
517519/// Caller must free the returned memory.
518pub fn getCwd(allocator: &Allocator) -> %[]u8 {
520pub fn getCwd(allocator: &Allocator) %[]u8 {
519521 switch (builtin.os) {
520522 Os.windows => {
521523 var buf = try allocator.alloc(u8, 256);
522 %defer allocator.free(buf);
524 errdefer allocator.free(buf);
523525
524526 while (true) {
525527 const result = windows.GetCurrentDirectoryA(windows.WORD(buf.len), buf.ptr);
......@@ -541,7 +543,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
541543 },
542544 else => {
543545 var buf = try allocator.alloc(u8, 1024);
544 %defer allocator.free(buf);
546 errdefer allocator.free(buf);
545547 while (true) {
546548 const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
547549 if (err == posix.ERANGE) {
......@@ -562,7 +564,7 @@ test "os.getCwd" {
562564 _ = getCwd(debug.global_allocator);
563565}
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 {
566568 if (is_windows) {
567569 return symLinkWindows(allocator, existing_path, new_path);
568570 } else {
......@@ -570,7 +572,7 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
570572 }
571573}
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 {
574576 const existing_with_null = try cstr.addNullByte(allocator, existing_path);
575577 defer allocator.free(existing_with_null);
576578 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
584586 }
585587}
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 {
588590 const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);
589591 defer allocator.free(full_buf);
590592
......@@ -621,7 +623,7 @@ const b64_fs_encoder = base64.Base64Encoder.init(
621623 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",
622624 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 {
625627 if (symLink(allocator, existing_path, new_path)) {
626628 return;
627629 } else |err| {
......@@ -650,7 +652,7 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:
650652
651653}
652654
653pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {
655pub fn deleteFile(allocator: &Allocator, file_path: []const u8) %void {
654656 if (builtin.os == Os.windows) {
655657 return deleteFileWindows(allocator, file_path);
656658 } else {
......@@ -661,7 +663,7 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {
661663error FileNotFound;
662664error AccessDenied;
663665
664pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void {
666pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) %void {
665667 const buf = try allocator.alloc(u8, file_path.len + 1);
666668 defer allocator.free(buf);
667669
......@@ -679,7 +681,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void
679681 }
680682}
681683
682pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {
684pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) %void {
683685 const buf = try allocator.alloc(u8, file_path.len + 1);
684686 defer allocator.free(buf);
685687
......@@ -706,13 +708,13 @@ pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {
706708}
707709
708710/// 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 {
710712 return copyFileMode(allocator, source_path, dest_path, 0o666);
711713}
712714
713715// TODO instead of accepting a mode argument, use the mode from fstat'ing the source path once open
714716/// 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 {
716718 var rand_buf: [12]u8 = undefined;
717719 const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
718720 defer allocator.free(tmp_path);
......@@ -722,7 +724,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [
722724
723725 var out_file = try io.File.openWriteMode(tmp_path, mode, allocator);
724726 defer out_file.close();
725 %defer _ = deleteFile(allocator, tmp_path);
727 errdefer _ = deleteFile(allocator, tmp_path);
726728
727729 var in_file = try io.File.openRead(source_path, allocator);
728730 defer in_file.close();
......@@ -736,7 +738,7 @@ pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: [
736738 }
737739}
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 {
740742 const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);
741743 defer allocator.free(full_buf);
742744
......@@ -781,7 +783,7 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
781783 }
782784}
783785
784pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {
786pub fn makeDir(allocator: &Allocator, dir_path: []const u8) %void {
785787 if (is_windows) {
786788 return makeDirWindows(allocator, dir_path);
787789 } else {
......@@ -789,7 +791,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {
789791 }
790792}
791793
792pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {
794pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) %void {
793795 const path_buf = try cstr.addNullByte(allocator, dir_path);
794796 defer allocator.free(path_buf);
795797
......@@ -803,7 +805,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {
803805 }
804806}
805807
806pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {
808pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) %void {
807809 const path_buf = try cstr.addNullByte(allocator, dir_path);
808810 defer allocator.free(path_buf);
809811
......@@ -829,7 +831,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {
829831
830832/// Calls makeDir recursively to make an entire path. Returns success if the path
831833/// 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 {
833835 const resolved_path = try path.resolve(allocator, full_path);
834836 defer allocator.free(resolved_path);
835837
......@@ -867,7 +869,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {
867869
868870/// Returns ::error.DirNotEmpty if the directory is not empty.
869871/// 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 {
871873 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
872874 defer allocator.free(path_buf);
873875
......@@ -896,7 +898,7 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {
896898/// removes it. If it cannot be removed because it is a non-empty directory,
897899/// this function recursively removes its entries and then tries again.
898900// TODO non-recursive implementation
899pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void {
901pub fn deleteTree(allocator: &Allocator, full_path: []const u8) %void {
900902 start_over: while (true) {
901903 // First, try deleting the item as a file. This way we don't follow sym links.
902904 if (deleteFile(allocator, full_path)) {
......@@ -965,7 +967,7 @@ pub const Dir = struct {
965967 };
966968 };
967969
968 pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir {
970 pub fn open(allocator: &Allocator, dir_path: []const u8) %Dir {
969971 const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);
970972 return Dir {
971973 .allocator = allocator,
......@@ -976,14 +978,14 @@ pub const Dir = struct {
976978 };
977979 }
978980
979 pub fn close(self: &Dir) {
981 pub fn close(self: &Dir) void {
980982 self.allocator.free(self.buf);
981983 os.close(self.fd);
982984 }
983985
984986 /// Memory such as file names referenced in this returned entry becomes invalid
985987 /// 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 {
987989 start_over: while (true) {
988990 if (self.index >= self.end_index) {
989991 if (self.buf.len == 0) {
......@@ -1040,7 +1042,7 @@ pub const Dir = struct {
10401042 }
10411043};
10421044
1043pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
1045pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) %void {
10441046 const path_buf = try allocator.alloc(u8, dir_path.len + 1);
10451047 defer allocator.free(path_buf);
10461048
......@@ -1064,7 +1066,7 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
10641066}
10651067
10661068/// Read value of a symbolic link.
1067pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1069pub fn readLink(allocator: &Allocator, pathname: []const u8) %[]u8 {
10681070 const path_buf = try allocator.alloc(u8, pathname.len + 1);
10691071 defer allocator.free(path_buf);
10701072
......@@ -1072,7 +1074,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
10721074 path_buf[pathname.len] = 0;
10731075
10741076 var result_buf = try allocator.alloc(u8, 1024);
1075 %defer allocator.free(result_buf);
1077 errdefer allocator.free(result_buf);
10761078 while (true) {
10771079 const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len);
10781080 const err = posix.getErrno(ret_val);
......@@ -1097,7 +1099,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
10971099 }
10981100}
10991101
1100pub fn sleep(seconds: usize, nanoseconds: usize) {
1102pub fn sleep(seconds: usize, nanoseconds: usize) void {
11011103 switch(builtin.os) {
11021104 Os.linux, Os.macosx, Os.ios => {
11031105 posixSleep(u63(seconds), u63(nanoseconds));
......@@ -1111,7 +1113,7 @@ pub fn sleep(seconds: usize, nanoseconds: usize) {
11111113}
11121114
11131115const u63 = @IntType(false, 63);
1114pub fn posixSleep(seconds: u63, nanoseconds: u63) {
1116pub fn posixSleep(seconds: u63, nanoseconds: u63) void {
11151117 var req = posix.timespec {
11161118 .tv_sec = seconds,
11171119 .tv_nsec = nanoseconds,
......@@ -1145,7 +1147,7 @@ error ResourceLimitReached;
11451147error InvalidUserId;
11461148error PermissionDenied;
11471149
1148pub fn posix_setuid(uid: u32) -> %void {
1150pub fn posix_setuid(uid: u32) %void {
11491151 const err = posix.getErrno(posix.setuid(uid));
11501152 if (err == 0) return;
11511153 return switch (err) {
......@@ -1156,7 +1158,7 @@ pub fn posix_setuid(uid: u32) -> %void {
11561158 };
11571159}
11581160
1159pub fn posix_setreuid(ruid: u32, euid: u32) -> %void {
1161pub fn posix_setreuid(ruid: u32, euid: u32) %void {
11601162 const err = posix.getErrno(posix.setreuid(ruid, euid));
11611163 if (err == 0) return;
11621164 return switch (err) {
......@@ -1167,7 +1169,7 @@ pub fn posix_setreuid(ruid: u32, euid: u32) -> %void {
11671169 };
11681170}
11691171
1170pub fn posix_setgid(gid: u32) -> %void {
1172pub fn posix_setgid(gid: u32) %void {
11711173 const err = posix.getErrno(posix.setgid(gid));
11721174 if (err == 0) return;
11731175 return switch (err) {
......@@ -1178,7 +1180,7 @@ pub fn posix_setgid(gid: u32) -> %void {
11781180 };
11791181}
11801182
1181pub fn posix_setregid(rgid: u32, egid: u32) -> %void {
1183pub fn posix_setregid(rgid: u32, egid: u32) %void {
11821184 const err = posix.getErrno(posix.setregid(rgid, egid));
11831185 if (err == 0) return;
11841186 return switch (err) {
......@@ -1190,7 +1192,7 @@ pub fn posix_setregid(rgid: u32, egid: u32) -> %void {
11901192}
11911193
11921194error NoStdHandles;
1193pub fn windowsGetStdHandle(handle_id: windows.DWORD) -> %windows.HANDLE {
1195pub fn windowsGetStdHandle(handle_id: windows.DWORD) %windows.HANDLE {
11941196 if (windows.GetStdHandle(handle_id)) |handle| {
11951197 if (handle == windows.INVALID_HANDLE_VALUE) {
11961198 const err = windows.GetLastError();
......@@ -1208,14 +1210,14 @@ pub const ArgIteratorPosix = struct {
12081210 index: usize,
12091211 count: usize,
12101212
1211 pub fn init() -> ArgIteratorPosix {
1213 pub fn init() ArgIteratorPosix {
12121214 return ArgIteratorPosix {
12131215 .index = 0,
12141216 .count = raw.len,
12151217 };
12161218 }
12171219
1218 pub fn next(self: &ArgIteratorPosix) -> ?[]const u8 {
1220 pub fn next(self: &ArgIteratorPosix) ?[]const u8 {
12191221 if (self.index == self.count)
12201222 return null;
12211223
......@@ -1224,7 +1226,7 @@ pub const ArgIteratorPosix = struct {
12241226 return cstr.toSlice(s);
12251227 }
12261228
1227 pub fn skip(self: &ArgIteratorPosix) -> bool {
1229 pub fn skip(self: &ArgIteratorPosix) bool {
12281230 if (self.index == self.count)
12291231 return false;
12301232
......@@ -1244,11 +1246,11 @@ pub const ArgIteratorWindows = struct {
12441246 quote_count: usize,
12451247 seen_quote_count: usize,
12461248
1247 pub fn init() -> ArgIteratorWindows {
1249 pub fn init() ArgIteratorWindows {
12481250 return initWithCmdLine(windows.GetCommandLineA());
12491251 }
12501252
1251 pub fn initWithCmdLine(cmd_line: &const u8) -> ArgIteratorWindows {
1253 pub fn initWithCmdLine(cmd_line: &const u8) ArgIteratorWindows {
12521254 return ArgIteratorWindows {
12531255 .index = 0,
12541256 .cmd_line = cmd_line,
......@@ -1259,7 +1261,7 @@ pub const ArgIteratorWindows = struct {
12591261 }
12601262
12611263 /// 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 {
12631265 // march forward over whitespace
12641266 while (true) : (self.index += 1) {
12651267 const byte = self.cmd_line[self.index];
......@@ -1273,7 +1275,7 @@ pub const ArgIteratorWindows = struct {
12731275 return self.internalNext(allocator);
12741276 }
12751277
1276 pub fn skip(self: &ArgIteratorWindows) -> bool {
1278 pub fn skip(self: &ArgIteratorWindows) bool {
12771279 // march forward over whitespace
12781280 while (true) : (self.index += 1) {
12791281 const byte = self.cmd_line[self.index];
......@@ -1312,7 +1314,7 @@ pub const ArgIteratorWindows = struct {
13121314 }
13131315 }
13141316
1315 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 {
1317 fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) %[]u8 {
13161318 var buf = try Buffer.initSize(allocator, 0);
13171319 defer buf.deinit();
13181320
......@@ -1356,14 +1358,14 @@ pub const ArgIteratorWindows = struct {
13561358 }
13571359 }
13581360
1359 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {
1361 fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) %void {
13601362 var i: usize = 0;
13611363 while (i < emit_count) : (i += 1) {
13621364 try buf.appendByte('\\');
13631365 }
13641366 }
13651367
1366 fn countQuotes(cmd_line: &const u8) -> usize {
1368 fn countQuotes(cmd_line: &const u8) usize {
13671369 var result: usize = 0;
13681370 var backslash_count: usize = 0;
13691371 var index: usize = 0;
......@@ -1388,14 +1390,14 @@ pub const ArgIteratorWindows = struct {
13881390pub const ArgIterator = struct {
13891391 inner: if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix,
13901392
1391 pub fn init() -> ArgIterator {
1393 pub fn init() ArgIterator {
13921394 return ArgIterator {
13931395 .inner = if (builtin.os == Os.windows) ArgIteratorWindows.init() else ArgIteratorPosix.init(),
13941396 };
13951397 }
13961398
13971399 /// 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 {
13991401 if (builtin.os == Os.windows) {
14001402 return self.inner.next(allocator);
14011403 } else {
......@@ -1404,23 +1406,23 @@ pub const ArgIterator = struct {
14041406 }
14051407
14061408 /// 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 {
14081410 return self.inner.next();
14091411 }
14101412
14111413 /// Parse past 1 argument without capturing it.
14121414 /// 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 {
14141416 return self.inner.skip();
14151417 }
14161418};
14171419
1418pub fn args() -> ArgIterator {
1420pub fn args() ArgIterator {
14191421 return ArgIterator.init();
14201422}
14211423
14221424/// Caller must call freeArgs on result.
1423pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
1425pub fn argsAlloc(allocator: &mem.Allocator) %[]const []u8 {
14241426 // TODO refactor to only make 1 allocation.
14251427 var it = args();
14261428 var contents = try Buffer.initSize(allocator, 0);
......@@ -1441,7 +1443,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
14411443 const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);
14421444 const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len);
14431445 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
1444 %defer allocator.free(buf);
1446 errdefer allocator.free(buf);
14451447
14461448 const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]);
14471449 const result_contents = buf[slice_list_bytes..];
......@@ -1457,7 +1459,7 @@ pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
14571459 return result_slice_list;
14581460}
14591461
1460pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) {
1462pub fn argsFree(allocator: &mem.Allocator, args_alloc: []const []u8) void {
14611463 var total_bytes: usize = 0;
14621464 for (args_alloc) |arg| {
14631465 total_bytes += @sizeOf([]u8) + arg.len;
......@@ -1479,7 +1481,7 @@ test "windows arg parsing" {
14791481 [][]const u8{".\\..\\zig-cache\\build", "bin\\zig.exe", ".\\..", ".\\..\\zig-cache", "--help"});
14801482}
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 {
14831485 var it = ArgIteratorWindows.initWithCmdLine(input_cmd_line);
14841486 for (expected_args) |expected_arg| {
14851487 const arg = ??it.next(debug.global_allocator) catch unreachable;
......@@ -1509,7 +1511,7 @@ const unexpected_error_tracing = false;
15091511
15101512/// Call this when you made a syscall or something that sets errno
15111513/// and you get an unexpected error.
1512pub fn unexpectedErrorPosix(errno: usize) -> error {
1514pub fn unexpectedErrorPosix(errno: usize) error {
15131515 if (unexpected_error_tracing) {
15141516 debug.warn("unexpected errno: {}\n", errno);
15151517 debug.dumpStackTrace();
......@@ -1519,7 +1521,7 @@ pub fn unexpectedErrorPosix(errno: usize) -> error {
15191521
15201522/// Call this when you made a windows DLL call or something that does SetLastError
15211523/// and you get an unexpected error.
1522pub fn unexpectedErrorWindows(err: windows.DWORD) -> error {
1524pub fn unexpectedErrorWindows(err: windows.DWORD) error {
15231525 if (unexpected_error_tracing) {
15241526 debug.warn("unexpected GetLastError(): {}\n", err);
15251527 debug.dumpStackTrace();
......@@ -1527,7 +1529,7 @@ pub fn unexpectedErrorWindows(err: windows.DWORD) -> error {
15271529 return error.Unexpected;
15281530}
15291531
1530pub fn openSelfExe() -> %io.File {
1532pub fn openSelfExe() %io.File {
15311533 switch (builtin.os) {
15321534 Os.linux => {
15331535 return io.File.openRead("/proc/self/exe", null);
......@@ -1545,7 +1547,7 @@ pub fn openSelfExe() -> %io.File {
15451547/// This function may return an error if the current executable
15461548/// was deleted after spawning.
15471549/// Caller owns returned memory.
1548pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
1550pub fn selfExePath(allocator: &mem.Allocator) %[]u8 {
15491551 switch (builtin.os) {
15501552 Os.linux => {
15511553 // If the currently executing binary has been deleted,
......@@ -1554,7 +1556,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
15541556 },
15551557 Os.windows => {
15561558 var out_path = try Buffer.initSize(allocator, 0xff);
1557 %defer out_path.deinit();
1559 errdefer out_path.deinit();
15581560 while (true) {
15591561 const dword_len = try math.cast(windows.DWORD, out_path.len());
15601562 const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);
......@@ -1577,7 +1579,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
15771579 const ret1 = c._NSGetExecutablePath(undefined, &u32_len);
15781580 assert(ret1 != 0);
15791581 const bytes = try allocator.alloc(u8, u32_len);
1580 %defer allocator.free(bytes);
1582 errdefer allocator.free(bytes);
15811583 const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len);
15821584 assert(ret2 == 0);
15831585 return bytes;
......@@ -1588,7 +1590,7 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
15881590
15891591/// Get the directory path that contains the current executable.
15901592/// Caller owns returned memory.
1591pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
1593pub fn selfExeDirPath(allocator: &mem.Allocator) %[]u8 {
15921594 switch (builtin.os) {
15931595 Os.linux => {
15941596 // If the currently executing binary has been deleted,
......@@ -1596,13 +1598,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
15961598 // This path cannot be opened, but it's valid for determining the directory
15971599 // the executable was in when it was run.
15981600 const full_exe_path = try readLink(allocator, "/proc/self/exe");
1599 %defer allocator.free(full_exe_path);
1601 errdefer allocator.free(full_exe_path);
16001602 const dir = path.dirname(full_exe_path);
16011603 return allocator.shrink(u8, full_exe_path, dir.len);
16021604 },
16031605 Os.windows, Os.macosx, Os.ios => {
16041606 const self_exe_path = try selfExePath(allocator);
1605 %defer allocator.free(self_exe_path);
1607 errdefer allocator.free(self_exe_path);
16061608 const dirname = os.path.dirname(self_exe_path);
16071609 return allocator.shrink(u8, self_exe_path, dirname.len);
16081610 },
......@@ -1610,7 +1612,7 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
16101612 }
16111613}
16121614
1613pub fn isTty(handle: FileHandle) -> bool {
1615pub fn isTty(handle: FileHandle) bool {
16141616 if (is_windows) {
16151617 return windows_util.windowsIsTty(handle);
16161618 } else {
std/os/linux.zig+83-85
......@@ -368,14 +368,14 @@ pub const TFD_CLOEXEC = O_CLOEXEC;
368368pub const TFD_TIMER_ABSTIME = 1;
369369pub const TFD_TIMER_CANCEL_ON_SET = (1 << 1);
370370
371fn unsigned(s: i32) -> u32 { return @bitCast(u32, s); }
372fn signed(s: u32) -> i32 { return @bitCast(i32, s); }
373pub fn WEXITSTATUS(s: i32) -> i32 { return signed((unsigned(s) & 0xff00) >> 8); }
374pub fn WTERMSIG(s: i32) -> i32 { return signed(unsigned(s) & 0x7f); }
375pub fn WSTOPSIG(s: i32) -> i32 { return WEXITSTATUS(s); }
376pub fn WIFEXITED(s: i32) -> bool { return WTERMSIG(s) == 0; }
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; }
371fn unsigned(s: i32) u32 { return @bitCast(u32, s); }
372fn signed(s: u32) i32 { return @bitCast(i32, s); }
373pub fn WEXITSTATUS(s: i32) i32 { return signed((unsigned(s) & 0xff00) >> 8); }
374pub fn WTERMSIG(s: i32) i32 { return signed(unsigned(s) & 0x7f); }
375pub fn WSTOPSIG(s: i32) i32 { return WEXITSTATUS(s); }
376pub fn WIFEXITED(s: i32) bool { return WTERMSIG(s) == 0; }
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; }
379379
380380
381381pub const winsize = extern struct {
......@@ -386,161 +386,159 @@ pub const winsize = extern struct {
386386};
387387
388388/// 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 {
390390 const signed_r = @bitCast(isize, r);
391391 return if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0;
392392}
393393
394pub fn dup2(old: i32, new: i32) -> usize {
394pub fn dup2(old: i32, new: i32) usize {
395395 return arch.syscall2(arch.SYS_dup2, usize(old), usize(new));
396396}
397397
398pub fn chdir(path: &const u8) -> usize {
398pub fn chdir(path: &const u8) usize {
399399 return arch.syscall1(arch.SYS_chdir, @ptrToInt(path));
400400}
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 {
403403 return arch.syscall3(arch.SYS_execve, @ptrToInt(path), @ptrToInt(argv), @ptrToInt(envp));
404404}
405405
406pub fn fork() -> usize {
406pub fn fork() usize {
407407 return arch.syscall0(arch.SYS_fork);
408408}
409409
410pub fn getcwd(buf: &u8, size: usize) -> usize {
410pub fn getcwd(buf: &u8, size: usize) usize {
411411 return arch.syscall2(arch.SYS_getcwd, @ptrToInt(buf), size);
412412}
413413
414pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize {
414pub fn getdents(fd: i32, dirp: &u8, count: usize) usize {
415415 return arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count);
416416}
417417
418pub fn isatty(fd: i32) -> bool {
418pub fn isatty(fd: i32) bool {
419419 var wsz: winsize = undefined;
420420 return arch.syscall3(arch.SYS_ioctl, usize(fd), TIOCGWINSZ, @ptrToInt(&wsz)) == 0;
421421}
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 {
424424 return arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len);
425425}
426426
427pub fn mkdir(path: &const u8, mode: u32) -> usize {
427pub fn mkdir(path: &const u8, mode: u32) usize {
428428 return arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode);
429429}
430430
431pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize)
432 -> usize
433{
431pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize) usize {
434432 return arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
435433 @bitCast(usize, offset));
436434}
437435
438pub fn munmap(address: &u8, length: usize) -> usize {
436pub fn munmap(address: &u8, length: usize) usize {
439437 return arch.syscall2(arch.SYS_munmap, @ptrToInt(address), length);
440438}
441439
442pub fn read(fd: i32, buf: &u8, count: usize) -> usize {
440pub fn read(fd: i32, buf: &u8, count: usize) usize {
443441 return arch.syscall3(arch.SYS_read, usize(fd), @ptrToInt(buf), count);
444442}
445443
446pub fn rmdir(path: &const u8) -> usize {
444pub fn rmdir(path: &const u8) usize {
447445 return arch.syscall1(arch.SYS_rmdir, @ptrToInt(path));
448446}
449447
450pub fn symlink(existing: &const u8, new: &const u8) -> usize {
448pub fn symlink(existing: &const u8, new: &const u8) usize {
451449 return arch.syscall2(arch.SYS_symlink, @ptrToInt(existing), @ptrToInt(new));
452450}
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 {
455453 return arch.syscall4(arch.SYS_pread, usize(fd), @ptrToInt(buf), count, offset);
456454}
457455
458pub fn pipe(fd: &[2]i32) -> usize {
456pub fn pipe(fd: &[2]i32) usize {
459457 return pipe2(fd, 0);
460458}
461459
462pub fn pipe2(fd: &[2]i32, flags: usize) -> usize {
460pub fn pipe2(fd: &[2]i32, flags: usize) usize {
463461 return arch.syscall2(arch.SYS_pipe2, @ptrToInt(fd), flags);
464462}
465463
466pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
464pub fn write(fd: i32, buf: &const u8, count: usize) usize {
467465 return arch.syscall3(arch.SYS_write, usize(fd), @ptrToInt(buf), count);
468466}
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 {
471469 return arch.syscall4(arch.SYS_pwrite, usize(fd), @ptrToInt(buf), count, offset);
472470}
473471
474pub fn rename(old: &const u8, new: &const u8) -> usize {
472pub fn rename(old: &const u8, new: &const u8) usize {
475473 return arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new));
476474}
477475
478pub fn open(path: &const u8, flags: u32, perm: usize) -> usize {
476pub fn open(path: &const u8, flags: u32, perm: usize) usize {
479477 return arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm);
480478}
481479
482pub fn create(path: &const u8, perm: usize) -> usize {
480pub fn create(path: &const u8, perm: usize) usize {
483481 return arch.syscall2(arch.SYS_creat, @ptrToInt(path), perm);
484482}
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 {
487485 return arch.syscall4(arch.SYS_openat, usize(dirfd), @ptrToInt(path), flags, mode);
488486}
489487
490pub fn close(fd: i32) -> usize {
488pub fn close(fd: i32) usize {
491489 return arch.syscall1(arch.SYS_close, usize(fd));
492490}
493491
494pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize {
492pub fn lseek(fd: i32, offset: isize, ref_pos: usize) usize {
495493 return arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos);
496494}
497495
498pub fn exit(status: i32) -> noreturn {
496pub fn exit(status: i32) noreturn {
499497 _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));
500498 unreachable;
501499}
502500
503pub fn getrandom(buf: &u8, count: usize, flags: u32) -> usize {
501pub fn getrandom(buf: &u8, count: usize, flags: u32) usize {
504502 return arch.syscall3(arch.SYS_getrandom, @ptrToInt(buf), count, usize(flags));
505503}
506504
507pub fn kill(pid: i32, sig: i32) -> usize {
505pub fn kill(pid: i32, sig: i32) usize {
508506 return arch.syscall2(arch.SYS_kill, @bitCast(usize, isize(pid)), usize(sig));
509507}
510508
511pub fn unlink(path: &const u8) -> usize {
509pub fn unlink(path: &const u8) usize {
512510 return arch.syscall1(arch.SYS_unlink, @ptrToInt(path));
513511}
514512
515pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize {
513pub fn waitpid(pid: i32, status: &i32, options: i32) usize {
516514 return arch.syscall4(arch.SYS_wait4, @bitCast(usize, isize(pid)), @ptrToInt(status), @bitCast(usize, isize(options)), 0);
517515}
518516
519pub fn nanosleep(req: &const timespec, rem: ?&timespec) -> usize {
517pub fn nanosleep(req: &const timespec, rem: ?&timespec) usize {
520518 return arch.syscall2(arch.SYS_nanosleep, @ptrToInt(req), @ptrToInt(rem));
521519}
522520
523pub fn setuid(uid: u32) -> usize {
521pub fn setuid(uid: u32) usize {
524522 return arch.syscall1(arch.SYS_setuid, uid);
525523}
526524
527pub fn setgid(gid: u32) -> usize {
525pub fn setgid(gid: u32) usize {
528526 return arch.syscall1(arch.SYS_setgid, gid);
529527}
530528
531pub fn setreuid(ruid: u32, euid: u32) -> usize {
529pub fn setreuid(ruid: u32, euid: u32) usize {
532530 return arch.syscall2(arch.SYS_setreuid, ruid, euid);
533531}
534532
535pub fn setregid(rgid: u32, egid: u32) -> usize {
533pub fn setregid(rgid: u32, egid: u32) usize {
536534 return arch.syscall2(arch.SYS_setregid, rgid, egid);
537535}
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 {
540538 return arch.syscall4(arch.SYS_rt_sigprocmask, flags, @ptrToInt(set), @ptrToInt(oldset), NSIG/8);
541539}
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 {
544542 assert(sig >= 1);
545543 assert(sig != SIGKILL);
546544 assert(sig != SIGSTOP);
......@@ -548,7 +546,7 @@ pub fn sigaction(sig: u6, noalias act: &const Sigaction, noalias oact: ?&Sigacti
548546 .handler = act.handler,
549547 .flags = act.flags | SA_RESTORER,
550548 .mask = undefined,
551 .restorer = @ptrCast(extern fn(), arch.restore_rt),
549 .restorer = @ptrCast(extern fn()void, arch.restore_rt),
552550 };
553551 var ksa_old: k_sigaction = undefined;
554552 @memcpy(@ptrCast(&u8, &ksa.mask), @ptrCast(&const u8, &act.mask), 8);
......@@ -571,25 +569,25 @@ const all_mask = []usize{@maxValue(usize)};
571569const app_mask = []usize{0xfffffffc7fffffff};
572570
573571const k_sigaction = extern struct {
574 handler: extern fn(i32),
572 handler: extern fn(i32)void,
575573 flags: usize,
576 restorer: extern fn(),
574 restorer: extern fn()void,
577575 mask: [2]u32,
578576};
579577
580578/// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall.
581579pub const Sigaction = struct {
582 handler: extern fn(i32),
580 handler: extern fn(i32)void,
583581 mask: sigset_t,
584582 flags: u32,
585583};
586584
587pub const SIG_ERR = @intToPtr(extern fn(i32), @maxValue(usize));
588pub const SIG_DFL = @intToPtr(extern fn(i32), 0);
589pub const SIG_IGN = @intToPtr(extern fn(i32), 1);
585pub const SIG_ERR = @intToPtr(extern fn(i32)void, @maxValue(usize));
586pub const SIG_DFL = @intToPtr(extern fn(i32)void, 0);
587pub const SIG_IGN = @intToPtr(extern fn(i32)void, 1);
590588pub const empty_sigset = []usize{0} ** sigset_t.len;
591589
592pub fn raise(sig: i32) -> usize {
590pub fn raise(sig: i32) usize {
593591 var set: sigset_t = undefined;
594592 blockAppSignals(&set);
595593 const tid = i32(arch.syscall0(arch.SYS_gettid));
......@@ -598,24 +596,24 @@ pub fn raise(sig: i32) -> usize {
598596 return ret;
599597}
600598
601fn blockAllSignals(set: &sigset_t) {
599fn blockAllSignals(set: &sigset_t) void {
602600 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&all_mask), @ptrToInt(set), NSIG/8);
603601}
604602
605fn blockAppSignals(set: &sigset_t) {
603fn blockAppSignals(set: &sigset_t) void {
606604 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_BLOCK, @ptrToInt(&app_mask), @ptrToInt(set), NSIG/8);
607605}
608606
609fn restoreSignals(set: &sigset_t) {
607fn restoreSignals(set: &sigset_t) void {
610608 _ = arch.syscall4(arch.SYS_rt_sigprocmask, SIG_SETMASK, @ptrToInt(set), 0, NSIG/8);
611609}
612610
613pub fn sigaddset(set: &sigset_t, sig: u6) {
611pub fn sigaddset(set: &sigset_t, sig: u6) void {
614612 const s = sig - 1;
615613 (*set)[usize(s) / usize.bit_count] |= usize(1) << (s & (usize.bit_count - 1));
616614}
617615
618pub fn sigismember(set: &const sigset_t, sig: u6) -> bool {
616pub fn sigismember(set: &const sigset_t, sig: u6) bool {
619617 const s = sig - 1;
620618 return ((*set)[usize(s) / usize.bit_count] & (usize(1) << (s & (usize.bit_count - 1)))) != 0;
621619}
......@@ -652,69 +650,69 @@ pub const iovec = extern struct {
652650 iov_len: usize,
653651};
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 {
656654 return arch.syscall3(arch.SYS_getsockname, usize(fd), @ptrToInt(addr), @ptrToInt(len));
657655}
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 {
660658 return arch.syscall3(arch.SYS_getpeername, usize(fd), @ptrToInt(addr), @ptrToInt(len));
661659}
662660
663pub fn socket(domain: i32, socket_type: i32, protocol: i32) -> usize {
661pub fn socket(domain: i32, socket_type: i32, protocol: i32) usize {
664662 return arch.syscall3(arch.SYS_socket, usize(domain), usize(socket_type), usize(protocol));
665663}
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 {
668666 return arch.syscall5(arch.SYS_setsockopt, usize(fd), usize(level), usize(optname), usize(optval), @ptrToInt(optlen));
669667}
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 {
672670 return arch.syscall5(arch.SYS_getsockopt, usize(fd), usize(level), usize(optname), @ptrToInt(optval), @ptrToInt(optlen));
673671}
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 {
676674 return arch.syscall3(arch.SYS_sendmsg, usize(fd), @ptrToInt(msg), flags);
677675}
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 {
680678 return arch.syscall3(arch.SYS_connect, usize(fd), @ptrToInt(addr), usize(len));
681679}
682680
683pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) -> usize {
681pub fn recvmsg(fd: i32, msg: &arch.msghdr, flags: u32) usize {
684682 return arch.syscall3(arch.SYS_recvmsg, usize(fd), @ptrToInt(msg), flags);
685683}
686684
687685pub fn recvfrom(fd: i32, noalias buf: &u8, len: usize, flags: u32,
688 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) -> usize
686 noalias addr: ?&sockaddr, noalias alen: ?&socklen_t) usize
689687{
690688 return arch.syscall6(arch.SYS_recvfrom, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), @ptrToInt(alen));
691689}
692690
693pub fn shutdown(fd: i32, how: i32) -> usize {
691pub fn shutdown(fd: i32, how: i32) usize {
694692 return arch.syscall2(arch.SYS_shutdown, usize(fd), usize(how));
695693}
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 {
698696 return arch.syscall3(arch.SYS_bind, usize(fd), @ptrToInt(addr), usize(len));
699697}
700698
701pub fn listen(fd: i32, backlog: i32) -> usize {
699pub fn listen(fd: i32, backlog: i32) usize {
702700 return arch.syscall2(arch.SYS_listen, usize(fd), usize(backlog));
703701}
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 {
706704 return arch.syscall6(arch.SYS_sendto, usize(fd), @ptrToInt(buf), len, flags, @ptrToInt(addr), usize(alen));
707705}
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 {
710708 return arch.syscall4(arch.SYS_socketpair, usize(domain), usize(socket_type), usize(protocol), @ptrToInt(&fd[0]));
711709}
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 {
714712 return accept4(fd, addr, len, 0);
715713}
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 {
718716 return arch.syscall4(arch.SYS_accept4, usize(fd), @ptrToInt(addr), @ptrToInt(len), flags);
719717}
720718
......@@ -722,7 +720,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
722720// error SystemResources;
723721// error Io;
724722//
725// pub fn if_nametoindex(name: []u8) -> %u32 {
723// pub fn if_nametoindex(name: []u8) %u32 {
726724// var ifr: ifreq = undefined;
727725//
728726// if (name.len >= ifr.ifr_name.len) {
......@@ -749,7 +747,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
749747pub const Stat = arch.Stat;
750748pub const timespec = arch.timespec;
751749
752pub fn fstat(fd: i32, stat_buf: &Stat) -> usize {
750pub fn fstat(fd: i32, stat_buf: &Stat) usize {
753751 return arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf));
754752}
755753
......@@ -760,19 +758,19 @@ pub const epoll_event = extern struct {
760758 data: epoll_data
761759};
762760
763pub fn epoll_create() -> usize {
761pub fn epoll_create() usize {
764762 return arch.syscall1(arch.SYS_epoll_create, usize(1));
765763}
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 {
768766 return arch.syscall4(arch.SYS_epoll_ctl, usize(epoll_fd), usize(op), usize(fd), @ptrToInt(ev));
769767}
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 {
772770 return arch.syscall4(arch.SYS_epoll_wait, usize(epoll_fd), @ptrToInt(events), usize(maxevents), usize(timeout));
773771}
774772
775pub fn timerfd_create(clockid: i32, flags: u32) -> usize {
773pub fn timerfd_create(clockid: i32, flags: u32) usize {
776774 return arch.syscall2(arch.SYS_timerfd_create, usize(clockid), usize(flags));
777775}
778776
......@@ -781,11 +779,11 @@ pub const itimerspec = extern struct {
781779 it_value: timespec
782780};
783781
784pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) -> usize {
782pub fn timerfd_gettime(fd: i32, curr_value: &itimerspec) usize {
785783 return arch.syscall2(arch.SYS_timerfd_gettime, usize(fd), @ptrToInt(curr_value));
786784}
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 {
789787 return arch.syscall4(arch.SYS_timerfd_settime, usize(fd), usize(flags), @ptrToInt(new_value), @ptrToInt(old_value));
790788}
791789
std/os/linux_i386.zig+7-7
......@@ -419,20 +419,20 @@ pub const F_GETOWN_EX = 16;
419419
420420pub const F_GETOWNER_UIDS = 17;
421421
422pub inline fn syscall0(number: usize) -> usize {
422pub inline fn syscall0(number: usize) usize {
423423 asm volatile ("int $0x80"
424424 : [ret] "={eax}" (-> usize)
425425 : [number] "{eax}" (number))
426426}
427427
428pub inline fn syscall1(number: usize, arg1: usize) -> usize {
428pub inline fn syscall1(number: usize, arg1: usize) usize {
429429 asm volatile ("int $0x80"
430430 : [ret] "={eax}" (-> usize)
431431 : [number] "{eax}" (number),
432432 [arg1] "{ebx}" (arg1))
433433}
434434
435pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
435pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
436436 asm volatile ("int $0x80"
437437 : [ret] "={eax}" (-> usize)
438438 : [number] "{eax}" (number),
......@@ -440,7 +440,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
440440 [arg2] "{ecx}" (arg2))
441441}
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 {
444444 asm volatile ("int $0x80"
445445 : [ret] "={eax}" (-> usize)
446446 : [number] "{eax}" (number),
......@@ -449,7 +449,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->
449449 [arg3] "{edx}" (arg3))
450450}
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 {
453453 asm volatile ("int $0x80"
454454 : [ret] "={eax}" (-> usize)
455455 : [number] "{eax}" (number),
......@@ -486,7 +486,7 @@ pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize,
486486 [arg6] "{ebp}" (arg6))
487487}
488488
489pub nakedcc fn restore() {
489pub nakedcc fn restore() void {
490490 asm volatile (
491491 \\popl %%eax
492492 \\movl $119, %%eax
......@@ -496,7 +496,7 @@ pub nakedcc fn restore() {
496496 : "rcx", "r11")
497497}
498498
499pub nakedcc fn restore_rt() {
499pub nakedcc fn restore_rt() void {
500500 asm volatile ("int $0x80"
501501 :
502502 : [number] "{eax}" (usize(SYS_rt_sigreturn))
std/os/linux_x86_64.zig+8-8
......@@ -370,14 +370,14 @@ pub const F_GETOWN_EX = 16;
370370
371371pub const F_GETOWNER_UIDS = 17;
372372
373pub fn syscall0(number: usize) -> usize {
373pub fn syscall0(number: usize) usize {
374374 return asm volatile ("syscall"
375375 : [ret] "={rax}" (-> usize)
376376 : [number] "{rax}" (number)
377377 : "rcx", "r11");
378378}
379379
380pub fn syscall1(number: usize, arg1: usize) -> usize {
380pub fn syscall1(number: usize, arg1: usize) usize {
381381 return asm volatile ("syscall"
382382 : [ret] "={rax}" (-> usize)
383383 : [number] "{rax}" (number),
......@@ -385,7 +385,7 @@ pub fn syscall1(number: usize, arg1: usize) -> usize {
385385 : "rcx", "r11");
386386}
387387
388pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
388pub fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
389389 return asm volatile ("syscall"
390390 : [ret] "={rax}" (-> usize)
391391 : [number] "{rax}" (number),
......@@ -394,7 +394,7 @@ pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
394394 : "rcx", "r11");
395395}
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 {
398398 return asm volatile ("syscall"
399399 : [ret] "={rax}" (-> usize)
400400 : [number] "{rax}" (number),
......@@ -404,7 +404,7 @@ pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
404404 : "rcx", "r11");
405405}
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 {
408408 return asm volatile ("syscall"
409409 : [ret] "={rax}" (-> usize)
410410 : [number] "{rax}" (number),
......@@ -415,7 +415,7 @@ pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
415415 : "rcx", "r11");
416416}
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 {
419419 return asm volatile ("syscall"
420420 : [ret] "={rax}" (-> usize)
421421 : [number] "{rax}" (number),
......@@ -428,7 +428,7 @@ pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
428428}
429429
430430pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
431 arg5: usize, arg6: usize) -> usize
431 arg5: usize, arg6: usize) usize
432432{
433433 return asm volatile ("syscall"
434434 : [ret] "={rax}" (-> usize)
......@@ -442,7 +442,7 @@ pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usiz
442442 : "rcx", "r11");
443443}
444444
445pub nakedcc fn restore_rt() {
445pub nakedcc fn restore_rt() void {
446446 return asm volatile ("syscall"
447447 :
448448 : [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;
2222
2323const is_windows = builtin.os == builtin.Os.windows;
2424
25pub fn isSep(byte: u8) -> bool {
25pub fn isSep(byte: u8) bool {
2626 if (is_windows) {
2727 return byte == '/' or byte == '\\';
2828 } else {
......@@ -32,7 +32,7 @@ pub fn isSep(byte: u8) -> bool {
3232
3333/// Naively combines a series of paths with the native path seperator.
3434/// 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 {
3636 if (is_windows) {
3737 return joinWindows(allocator, paths);
3838 } else {
......@@ -40,11 +40,11 @@ pub fn join(allocator: &Allocator, paths: ...) -> %[]u8 {
4040 }
4141}
4242
43pub fn joinWindows(allocator: &Allocator, paths: ...) -> %[]u8 {
43pub fn joinWindows(allocator: &Allocator, paths: ...) %[]u8 {
4444 return mem.join(allocator, sep_windows, paths);
4545}
4646
47pub fn joinPosix(allocator: &Allocator, paths: ...) -> %[]u8 {
47pub fn joinPosix(allocator: &Allocator, paths: ...) %[]u8 {
4848 return mem.join(allocator, sep_posix, paths);
4949}
5050
......@@ -69,7 +69,7 @@ test "os.path.join" {
6969 "/home/andy/dev/zig/build/lib/zig/std/io.zig"));
7070}
7171
72pub fn isAbsolute(path: []const u8) -> bool {
72pub fn isAbsolute(path: []const u8) bool {
7373 if (is_windows) {
7474 return isAbsoluteWindows(path);
7575 } else {
......@@ -77,7 +77,7 @@ pub fn isAbsolute(path: []const u8) -> bool {
7777 }
7878}
7979
80pub fn isAbsoluteWindows(path: []const u8) -> bool {
80pub fn isAbsoluteWindows(path: []const u8) bool {
8181 if (path[0] == '/')
8282 return true;
8383
......@@ -96,7 +96,7 @@ pub fn isAbsoluteWindows(path: []const u8) -> bool {
9696 return false;
9797}
9898
99pub fn isAbsolutePosix(path: []const u8) -> bool {
99pub fn isAbsolutePosix(path: []const u8) bool {
100100 return path[0] == sep_posix;
101101}
102102
......@@ -129,11 +129,11 @@ test "os.path.isAbsolutePosix" {
129129 testIsAbsolutePosix("./baz", false);
130130}
131131
132fn testIsAbsoluteWindows(path: []const u8, expected_result: bool) {
132fn testIsAbsoluteWindows(path: []const u8, expected_result: bool) void {
133133 assert(isAbsoluteWindows(path) == expected_result);
134134}
135135
136fn testIsAbsolutePosix(path: []const u8, expected_result: bool) {
136fn testIsAbsolutePosix(path: []const u8, expected_result: bool) void {
137137 assert(isAbsolutePosix(path) == expected_result);
138138}
139139
......@@ -149,7 +149,7 @@ pub const WindowsPath = struct {
149149 };
150150};
151151
152pub fn windowsParsePath(path: []const u8) -> WindowsPath {
152pub fn windowsParsePath(path: []const u8) WindowsPath {
153153 if (path.len >= 2 and path[1] == ':') {
154154 return WindowsPath {
155155 .is_abs = isAbsoluteWindows(path),
......@@ -248,7 +248,7 @@ test "os.path.windowsParsePath" {
248248 }
249249}
250250
251pub fn diskDesignator(path: []const u8) -> []const u8 {
251pub fn diskDesignator(path: []const u8) []const u8 {
252252 if (is_windows) {
253253 return diskDesignatorWindows(path);
254254 } else {
......@@ -256,11 +256,11 @@ pub fn diskDesignator(path: []const u8) -> []const u8 {
256256 }
257257}
258258
259pub fn diskDesignatorWindows(path: []const u8) -> []const u8 {
259pub fn diskDesignatorWindows(path: []const u8) []const u8 {
260260 return windowsParsePath(path).disk_designator;
261261}
262262
263fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool {
263fn networkShareServersEql(ns1: []const u8, ns2: []const u8) bool {
264264 const sep1 = ns1[0];
265265 const sep2 = ns2[0];
266266
......@@ -271,7 +271,7 @@ fn networkShareServersEql(ns1: []const u8, ns2: []const u8) -> bool {
271271 return asciiEqlIgnoreCase(??it1.next(), ??it2.next());
272272}
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 {
275275 switch (kind) {
276276 WindowsPath.Kind.None => {
277277 assert(p1.len == 0);
......@@ -294,14 +294,14 @@ fn compareDiskDesignators(kind: WindowsPath.Kind, p1: []const u8, p2: []const u8
294294 }
295295}
296296
297fn asciiUpper(byte: u8) -> u8 {
297fn asciiUpper(byte: u8) u8 {
298298 return switch (byte) {
299299 'a' ... 'z' => 'A' + (byte - 'a'),
300300 else => byte,
301301 };
302302}
303303
304fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) -> bool {
304fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
305305 if (s1.len != s2.len)
306306 return false;
307307 var i: usize = 0;
......@@ -313,7 +313,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) -> bool {
313313}
314314
315315/// 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 {
317317 var paths: [args.len][]const u8 = undefined;
318318 comptime var arg_i = 0;
319319 inline while (arg_i < args.len) : (arg_i += 1) {
......@@ -323,7 +323,7 @@ pub fn resolve(allocator: &Allocator, args: ...) -> %[]u8 {
323323}
324324
325325/// 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 {
327327 if (is_windows) {
328328 return resolveWindows(allocator, paths);
329329 } else {
......@@ -337,7 +337,7 @@ pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
337337/// If all paths are relative it uses the current working directory as a starting point.
338338/// Each drive has its own current working directory.
339339/// 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 {
341341 if (paths.len == 0) {
342342 assert(is_windows); // resolveWindows called on non windows can't use getCwd
343343 return os.getCwd(allocator);
......@@ -468,7 +468,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
468468 }
469469 have_drive_kind = parsed_cwd.kind;
470470 }
471 %defer allocator.free(result);
471 errdefer allocator.free(result);
472472
473473 // Now we know the disk designator to use, if any, and what kind it is. And our result
474474 // is big enough to append all the paths to.
......@@ -520,7 +520,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
520520/// It resolves "." and "..".
521521/// The result does not have a trailing path separator.
522522/// 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 {
524524 if (paths.len == 0) {
525525 assert(!is_windows); // resolvePosix called on windows can't use getCwd
526526 return os.getCwd(allocator);
......@@ -551,7 +551,7 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
551551 mem.copy(u8, result, cwd);
552552 result_index += cwd.len;
553553 }
554 %defer allocator.free(result);
554 errdefer allocator.free(result);
555555
556556 for (paths[first_index..]) |p, i| {
557557 var it = mem.split(p, "/");
......@@ -648,15 +648,15 @@ test "os.path.resolvePosix" {
648648 assert(mem.eql(u8, testResolvePosix([][]const u8{"/foo/tmp.3/", "../tmp.3/cycles/root.js"}), "/foo/tmp.3/cycles/root.js"));
649649}
650650
651fn testResolveWindows(paths: []const []const u8) -> []u8 {
651fn testResolveWindows(paths: []const []const u8) []u8 {
652652 return resolveWindows(debug.global_allocator, paths) catch unreachable;
653653}
654654
655fn testResolvePosix(paths: []const []const u8) -> []u8 {
655fn testResolvePosix(paths: []const []const u8) []u8 {
656656 return resolvePosix(debug.global_allocator, paths) catch unreachable;
657657}
658658
659pub fn dirname(path: []const u8) -> []const u8 {
659pub fn dirname(path: []const u8) []const u8 {
660660 if (is_windows) {
661661 return dirnameWindows(path);
662662 } else {
......@@ -664,7 +664,7 @@ pub fn dirname(path: []const u8) -> []const u8 {
664664 }
665665}
666666
667pub fn dirnameWindows(path: []const u8) -> []const u8 {
667pub fn dirnameWindows(path: []const u8) []const u8 {
668668 if (path.len == 0)
669669 return path[0..0];
670670
......@@ -695,7 +695,7 @@ pub fn dirnameWindows(path: []const u8) -> []const u8 {
695695 return path[0..end_index];
696696}
697697
698pub fn dirnamePosix(path: []const u8) -> []const u8 {
698pub fn dirnamePosix(path: []const u8) []const u8 {
699699 if (path.len == 0)
700700 return path[0..0];
701701
......@@ -766,15 +766,15 @@ test "os.path.dirnameWindows" {
766766 testDirnameWindows("foo", "");
767767}
768768
769fn testDirnamePosix(input: []const u8, expected_output: []const u8) {
769fn testDirnamePosix(input: []const u8, expected_output: []const u8) void {
770770 assert(mem.eql(u8, dirnamePosix(input), expected_output));
771771}
772772
773fn testDirnameWindows(input: []const u8, expected_output: []const u8) {
773fn testDirnameWindows(input: []const u8, expected_output: []const u8) void {
774774 assert(mem.eql(u8, dirnameWindows(input), expected_output));
775775}
776776
777pub fn basename(path: []const u8) -> []const u8 {
777pub fn basename(path: []const u8) []const u8 {
778778 if (is_windows) {
779779 return basenameWindows(path);
780780 } else {
......@@ -782,7 +782,7 @@ pub fn basename(path: []const u8) -> []const u8 {
782782 }
783783}
784784
785pub fn basenamePosix(path: []const u8) -> []const u8 {
785pub fn basenamePosix(path: []const u8) []const u8 {
786786 if (path.len == 0)
787787 return []u8{};
788788
......@@ -803,7 +803,7 @@ pub fn basenamePosix(path: []const u8) -> []const u8 {
803803 return path[start_index + 1..end_index];
804804}
805805
806pub fn basenameWindows(path: []const u8) -> []const u8 {
806pub fn basenameWindows(path: []const u8) []const u8 {
807807 if (path.len == 0)
808808 return []u8{};
809809
......@@ -874,15 +874,15 @@ test "os.path.basename" {
874874 testBasenameWindows("file:stream", "file:stream");
875875}
876876
877fn testBasename(input: []const u8, expected_output: []const u8) {
877fn testBasename(input: []const u8, expected_output: []const u8) void {
878878 assert(mem.eql(u8, basename(input), expected_output));
879879}
880880
881fn testBasenamePosix(input: []const u8, expected_output: []const u8) {
881fn testBasenamePosix(input: []const u8, expected_output: []const u8) void {
882882 assert(mem.eql(u8, basenamePosix(input), expected_output));
883883}
884884
885fn testBasenameWindows(input: []const u8, expected_output: []const u8) {
885fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
886886 assert(mem.eql(u8, basenameWindows(input), expected_output));
887887}
888888
......@@ -890,7 +890,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) {
890890/// resolve to the same path (after calling `resolve` on each), a zero-length
891891/// string is returned.
892892/// 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 {
894894 if (is_windows) {
895895 return relativeWindows(allocator, from, to);
896896 } else {
......@@ -898,7 +898,7 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u
898898 }
899899}
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 {
902902 const resolved_from = try resolveWindows(allocator, [][]const u8{from});
903903 defer allocator.free(resolved_from);
904904
......@@ -943,7 +943,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
943943 }
944944 const up_index_end = up_count * "..\\".len;
945945 const result = try allocator.alloc(u8, up_index_end + to_rest.len);
946 %defer allocator.free(result);
946 errdefer allocator.free(result);
947947
948948 var result_index: usize = 0;
949949 while (result_index < up_index_end) {
......@@ -971,7 +971,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
971971 return []u8{};
972972}
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 {
975975 const resolved_from = try resolvePosix(allocator, [][]const u8{from});
976976 defer allocator.free(resolved_from);
977977
......@@ -993,7 +993,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ->
993993 }
994994 const up_index_end = up_count * "../".len;
995995 const result = try allocator.alloc(u8, up_index_end + to_rest.len);
996 %defer allocator.free(result);
996 errdefer allocator.free(result);
997997
998998 var result_index: usize = 0;
999999 while (result_index < up_index_end) {
......@@ -1056,12 +1056,12 @@ test "os.path.relative" {
10561056 testRelativePosix("/baz", "/baz-quux", "../baz-quux");
10571057}
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 {
10601060 const result = relativePosix(debug.global_allocator, from, to) catch unreachable;
10611061 assert(mem.eql(u8, result, expected_output));
10621062}
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 {
10651065 const result = relativeWindows(debug.global_allocator, from, to) catch unreachable;
10661066 assert(mem.eql(u8, result, expected_output));
10671067}
......@@ -1077,7 +1077,7 @@ error InputOutput;
10771077/// Expands all symbolic links and resolves references to `.`, `..`, and
10781078/// extra `/` characters in ::pathname.
10791079/// Caller must deallocate result.
1080pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
1080pub fn real(allocator: &Allocator, pathname: []const u8) %[]u8 {
10811081 switch (builtin.os) {
10821082 Os.windows => {
10831083 const pathname_buf = try allocator.alloc(u8, pathname.len + 1);
......@@ -1100,7 +1100,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
11001100 }
11011101 defer os.close(h_file);
11021102 var buf = try allocator.alloc(u8, 256);
1103 %defer allocator.free(buf);
1103 errdefer allocator.free(buf);
11041104 while (true) {
11051105 const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong;
11061106 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 {
11441144 defer allocator.free(pathname_buf);
11451145
11461146 const result_buf = try allocator.alloc(u8, posix.PATH_MAX);
1147 %defer allocator.free(result_buf);
1147 errdefer allocator.free(result_buf);
11481148
11491149 mem.copy(u8, pathname_buf, pathname);
11501150 pathname_buf[pathname.len] = 0;
std/os/windows/index.zig+44-37
......@@ -1,97 +1,100 @@
11pub const ERROR = @import("error.zig");
22
33pub 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
1313pub extern "kernel32" stdcallcc fn CreateDirectoryA(lpPathName: LPCSTR,
14 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES) -> BOOL;
14 lpSecurityAttributes: ?&SECURITY_ATTRIBUTES) BOOL;
1515
1616pub extern "kernel32" stdcallcc fn CreateFileA(lpFileName: LPCSTR, dwDesiredAccess: DWORD,
1717 dwShareMode: DWORD, lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, dwCreationDisposition: DWORD,
18 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) -> HANDLE;
18 dwFlagsAndAttributes: DWORD, hTemplateFile: ?HANDLE) HANDLE;
1919
2020pub 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
2323pub extern "kernel32" stdcallcc fn CreateProcessA(lpApplicationName: ?LPCSTR, lpCommandLine: LPSTR,
2424 lpProcessAttributes: ?&SECURITY_ATTRIBUTES, lpThreadAttributes: ?&SECURITY_ATTRIBUTES, bInheritHandles: BOOL,
2525 dwCreationFlags: DWORD, lpEnvironment: ?LPVOID, lpCurrentDirectory: ?LPCSTR, lpStartupInfo: &STARTUPINFOA,
26 lpProcessInformation: &PROCESS_INFORMATION) -> BOOL;
26 lpProcessInformation: &PROCESS_INFORMATION) BOOL;
2727
2828pub 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
5555pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(in_hFile: HANDLE,
5656 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, out_lpFileInformation: &c_void,
57 in_dwBufferSize: DWORD) -> BOOL;
57 in_dwBufferSize: DWORD) BOOL;
5858
5959pub 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
7070pub extern "kernel32" stdcallcc fn MoveFileExA(lpExistingFileName: LPCSTR, lpNewFileName: LPCSTR,
71 dwFlags: DWORD) -> BOOL;
71 dwFlags: DWORD) BOOL;
7272
7373pub extern "kernel32" stdcallcc fn ReadFile(in_hFile: HANDLE, out_lpBuffer: LPVOID,
7474 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
8588pub extern "kernel32" stdcallcc fn WriteFile(in_hFile: HANDLE, in_lpBuffer: &const c_void,
8689 in_nNumberOfBytesToWrite: DWORD, out_lpNumberOfBytesWritten: ?&DWORD,
87 in_out_lpOverlapped: ?&OVERLAPPED) -> BOOL;
90 in_out_lpOverlapped: ?&OVERLAPPED) BOOL;
8891
8992//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
9699pub const PROV_RSA_FULL = 1;
97100
......@@ -289,3 +292,7 @@ pub const MOVEFILE_DELAY_UNTIL_REBOOT = 4;
289292pub const MOVEFILE_FAIL_IF_NOT_TRACKABLE = 32;
290293pub const MOVEFILE_REPLACE_EXISTING = 1;
291294pub 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;
1010error WaitTimeOut;
1111error Unexpected;
1212
13pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) -> %void {
13pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) %void {
1414 const result = windows.WaitForSingleObject(handle, milliseconds);
1515 return switch (result) {
1616 windows.WAIT_ABANDONED => error.WaitAbandoned,
......@@ -26,7 +26,7 @@ pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) ->
2626 };
2727}
2828
29pub fn windowsClose(handle: windows.HANDLE) {
29pub fn windowsClose(handle: windows.HANDLE) void {
3030 assert(windows.CloseHandle(handle) != 0);
3131}
3232
......@@ -35,7 +35,7 @@ error OperationAborted;
3535error IoPending;
3636error BrokenPipe;
3737
38pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {
38pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) %void {
3939 if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
4040 const err = windows.GetLastError();
4141 return switch (err) {
......@@ -50,7 +50,7 @@ pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) -> %void {
5050 }
5151}
5252
53pub fn windowsIsTty(handle: windows.HANDLE) -> bool {
53pub fn windowsIsTty(handle: windows.HANDLE) bool {
5454 if (windowsIsCygwinPty(handle))
5555 return true;
5656
......@@ -58,7 +58,7 @@ pub fn windowsIsTty(handle: windows.HANDLE) -> bool {
5858 return windows.GetConsoleMode(handle, &out) != 0;
5959}
6060
61pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {
61pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
6262 const size = @sizeOf(windows.FILE_NAME_INFO);
6363 var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
6464
......@@ -83,7 +83,7 @@ error PipeBusy;
8383/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.
8484/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
8585pub 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.HANDLE
86 creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD, allocator: ?&mem.Allocator) %windows.HANDLE
8787{
8888 var stack_buf: [os.max_noalloc_path_len]u8 = undefined;
8989 var path0: []u8 = undefined;
......@@ -120,7 +120,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
120120}
121121
122122/// 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 {
124124 // count bytes needed
125125 const bytes_needed = x: {
126126 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)
133133 break :x bytes_needed;
134134 };
135135 const result = try allocator.alloc(u8, bytes_needed);
136 %defer allocator.free(result);
136 errdefer allocator.free(result);
137137
138138 var it = env_map.iterator();
139139 var i: usize = 0;
......@@ -152,13 +152,13 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
152152}
153153
154154error 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 {
156156 const padded_buff = try cstr.addNullByte(allocator, dll_path);
157157 defer allocator.free(padded_buff);
158158 return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;
159159}
160160
161pub fn windowsUnloadDll(hModule: windows.HMODULE) {
161pub fn windowsUnloadDll(hModule: windows.HMODULE) void {
162162 assert(windows.FreeLibrary(hModule)!= 0);
163163}
164164
std/os/zen.zig+12-12
......@@ -21,28 +21,28 @@ pub const SYS_createThread = 5;
2121//// Syscalls ////
2222////////////////////
2323
24pub fn exit(status: i32) -> noreturn {
24pub fn exit(status: i32) noreturn {
2525 _ = syscall1(SYS_exit, @bitCast(usize, isize(status)));
2626 unreachable;
2727}
2828
29pub fn createMailbox(id: u16) {
29pub fn createMailbox(id: u16) void {
3030 _ = syscall1(SYS_createMailbox, id);
3131}
3232
33pub fn send(mailbox_id: u16, data: usize) {
33pub fn send(mailbox_id: u16, data: usize) void {
3434 _ = syscall2(SYS_send, mailbox_id, data);
3535}
3636
37pub fn receive(mailbox_id: u16) -> usize {
37pub fn receive(mailbox_id: u16) usize {
3838 return syscall1(SYS_receive, mailbox_id);
3939}
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 {
4242 return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0;
4343}
4444
45pub fn createThread(function: fn()) -> u16 {
45pub fn createThread(function: fn()) u16 {
4646 return u16(syscall1(SYS_createThread, @ptrToInt(function)));
4747}
4848
......@@ -51,20 +51,20 @@ pub fn createThread(function: fn()) -> u16 {
5151//// Syscall stubs ////
5252/////////////////////////
5353
54pub inline fn syscall0(number: usize) -> usize {
54pub inline fn syscall0(number: usize) usize {
5555 return asm volatile ("int $0x80"
5656 : [ret] "={eax}" (-> usize)
5757 : [number] "{eax}" (number));
5858}
5959
60pub inline fn syscall1(number: usize, arg1: usize) -> usize {
60pub inline fn syscall1(number: usize, arg1: usize) usize {
6161 return asm volatile ("int $0x80"
6262 : [ret] "={eax}" (-> usize)
6363 : [number] "{eax}" (number),
6464 [arg1] "{ecx}" (arg1));
6565}
6666
67pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
67pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) usize {
6868 return asm volatile ("int $0x80"
6969 : [ret] "={eax}" (-> usize)
7070 : [number] "{eax}" (number),
......@@ -72,7 +72,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
7272 [arg2] "{edx}" (arg2));
7373}
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 {
7676 return asm volatile ("int $0x80"
7777 : [ret] "={eax}" (-> usize)
7878 : [number] "{eax}" (number),
......@@ -81,7 +81,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->
8181 [arg3] "{ebx}" (arg3));
8282}
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 {
8585 return asm volatile ("int $0x80"
8686 : [ret] "={eax}" (-> usize)
8787 : [number] "{eax}" (number),
......@@ -92,7 +92,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
9292}
9393
9494pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize,
95 arg4: usize, arg5: usize) -> usize
95 arg4: usize, arg5: usize) usize
9696{
9797 return asm volatile ("int $0x80"
9898 : [ret] "={eax}" (-> usize)
std/rand.zig+9-9
......@@ -28,14 +28,14 @@ pub const Rand = struct {
2828 rng: Rng,
2929
3030 /// Initialize random state with the given seed.
31 pub fn init(seed: usize) -> Rand {
31 pub fn init(seed: usize) Rand {
3232 return Rand {
3333 .rng = Rng.init(seed),
3434 };
3535 }
3636
3737 /// 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 {
3939 if (T == usize) {
4040 return r.rng.get();
4141 } else if (T == bool) {
......@@ -48,7 +48,7 @@ pub const Rand = struct {
4848 }
4949
5050 /// Fill `buf` with randomness.
51 pub fn fillBytes(r: &Rand, buf: []u8) {
51 pub fn fillBytes(r: &Rand, buf: []u8) void {
5252 var bytes_left = buf.len;
5353 while (bytes_left >= @sizeOf(usize)) {
5454 mem.writeInt(buf[buf.len - bytes_left..], r.rng.get(), builtin.Endian.Little);
......@@ -66,7 +66,7 @@ pub const Rand = struct {
6666
6767 /// Get a random unsigned integer with even distribution between `start`
6868 /// 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 {
7070 assert(start <= end);
7171 if (T.is_signed) {
7272 const uint = @IntType(false, T.bit_count);
......@@ -108,7 +108,7 @@ pub const Rand = struct {
108108 }
109109
110110 /// 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 {
112112 // TODO Implement this way instead:
113113 // const int = @int_type(false, @sizeOf(T) * 8);
114114 // const mask = ((1 << @float_mantissa_bit_count(T)) - 1);
......@@ -132,7 +132,7 @@ fn MersenneTwister(
132132 comptime u: math.Log2Int(int), comptime d: int,
133133 comptime s: math.Log2Int(int), comptime b: int,
134134 comptime t: math.Log2Int(int), comptime c: int,
135 comptime l: math.Log2Int(int), comptime f: int) -> type
135 comptime l: math.Log2Int(int), comptime f: int) type
136136{
137137 return struct {
138138 const Self = this;
......@@ -140,7 +140,7 @@ fn MersenneTwister(
140140 array: [n]int,
141141 index: usize,
142142
143 pub fn init(seed: int) -> Self {
143 pub fn init(seed: int) Self {
144144 var mt = Self {
145145 .array = undefined,
146146 .index = n,
......@@ -156,7 +156,7 @@ fn MersenneTwister(
156156 return mt;
157157 }
158158
159 pub fn get(mt: &Self) -> int {
159 pub fn get(mt: &Self) int {
160160 const mag01 = []int{0, a};
161161 const LM: int = (1 << r) - 1;
162162 const UM = ~LM;
......@@ -224,7 +224,7 @@ test "rand.Rand.range" {
224224 testRange(&r, 10, 14);
225225}
226226
227fn testRange(r: &Rand, start: i32, end: i32) {
227fn testRange(r: &Rand, start: i32, end: i32) void {
228228 const count = usize(end - start);
229229 var values_buffer = []bool{false} ** 20;
230230 const values = values_buffer[0..count];
std/sort.zig+31-31
......@@ -5,7 +5,7 @@ const math = std.math;
55const builtin = @import("builtin");
66
77/// 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 {
99 {var i: usize = 1; while (i < items.len) : (i += 1) {
1010 const x = items[i];
1111 var j: usize = i;
......@@ -20,11 +20,11 @@ const Range = struct {
2020 start: usize,
2121 end: usize,
2222
23 fn init(start: usize, end: usize) -> Range {
23 fn init(start: usize, end: usize) Range {
2424 return Range { .start = start, .end = end };
2525 }
2626
27 fn length(self: &const Range) -> usize {
27 fn length(self: &const Range) usize {
2828 return self.end - self.start;
2929 }
3030};
......@@ -39,7 +39,7 @@ const Iterator = struct {
3939 decimal_step: usize,
4040 numerator_step: usize,
4141
42 fn init(size2: usize, min_level: usize) -> Iterator {
42 fn init(size2: usize, min_level: usize) Iterator {
4343 const power_of_two = math.floorPowerOfTwo(usize, size2);
4444 const denominator = power_of_two / min_level;
4545 return Iterator {
......@@ -53,12 +53,12 @@ const Iterator = struct {
5353 };
5454 }
5555
56 fn begin(self: &Iterator) {
56 fn begin(self: &Iterator) void {
5757 self.numerator = 0;
5858 self.decimal = 0;
5959 }
6060
61 fn nextRange(self: &Iterator) -> Range {
61 fn nextRange(self: &Iterator) Range {
6262 const start = self.decimal;
6363
6464 self.decimal += self.decimal_step;
......@@ -71,11 +71,11 @@ const Iterator = struct {
7171 return Range {.start = start, .end = self.decimal};
7272 }
7373
74 fn finished(self: &Iterator) -> bool {
74 fn finished(self: &Iterator) bool {
7575 return self.decimal >= self.size;
7676 }
7777
78 fn nextLevel(self: &Iterator) -> bool {
78 fn nextLevel(self: &Iterator) bool {
7979 self.decimal_step += self.decimal_step;
8080 self.numerator_step += self.numerator_step;
8181 if (self.numerator_step >= self.denominator) {
......@@ -86,7 +86,7 @@ const Iterator = struct {
8686 return (self.decimal_step < self.size);
8787 }
8888
89 fn length(self: &Iterator) -> usize {
89 fn length(self: &Iterator) usize {
9090 return self.decimal_step;
9191 }
9292};
......@@ -100,7 +100,7 @@ const Pull = struct {
100100
101101/// Stable in-place sort. O(n) best case, O(n*log(n)) worst case and average case. O(1) memory (no allocator required).
102102/// 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 {
104104 // Implementation ported from https://github.com/BonzaiThePenguin/WikiSort/blob/master/WikiSort.c
105105 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
709709}
710710
711711// 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 {
713713 if (A_arg.length() == 0 or B_arg.length() == 0) return;
714714
715715 // 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
751751}
752752
753753// 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 {
755755 // whenever we find a value to add to the final array, swap it with the value that's already in that spot
756756 // when this algorithm is finished, 'buffer' will contain its original contents, but in a different order
757757 var A_count: usize = 0;
......@@ -778,7 +778,7 @@ fn mergeInternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
778778 blockSwap(T, items, buffer.start + A_count, A.start + insert, A.length() - A_count);
779779}
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 {
782782 var index: usize = 0;
783783 while (index < block_size) : (index += 1) {
784784 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
787787
788788// combine a linear search with a binary search to reduce the number of comparisons in situations
789789// 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 {
791791 if (range.length() == 0) return range.start;
792792 const skip = math.max(range.length()/unique, usize(1));
793793
......@@ -801,7 +801,7 @@ fn findFirstForward(comptime T: type, items: []T, value: &const T, range: &const
801801 return binaryFirst(T, items, value, Range.init(index - skip, index), lessThan);
802802}
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 {
805805 if (range.length() == 0) return range.start;
806806 const skip = math.max(range.length()/unique, usize(1));
807807
......@@ -815,7 +815,7 @@ fn findFirstBackward(comptime T: type, items: []T, value: &const T, range: &cons
815815 return binaryFirst(T, items, value, Range.init(index, index + skip), lessThan);
816816}
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 {
819819 if (range.length() == 0) return range.start;
820820 const skip = math.max(range.length()/unique, usize(1));
821821
......@@ -829,7 +829,7 @@ fn findLastForward(comptime T: type, items: []T, value: &const T, range: &const
829829 return binaryLast(T, items, value, Range.init(index - skip, index), lessThan);
830830}
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 {
833833 if (range.length() == 0) return range.start;
834834 const skip = math.max(range.length()/unique, usize(1));
835835
......@@ -843,7 +843,7 @@ fn findLastBackward(comptime T: type, items: []T, value: &const T, range: &const
843843 return binaryLast(T, items, value, Range.init(index, index + skip), lessThan);
844844}
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 {
847847 var start = range.start;
848848 var end = range.end - 1;
849849 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
861861 return start;
862862}
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 {
865865 var start = range.start;
866866 var end = range.end - 1;
867867 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
879879 return start;
880880}
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 {
883883 var A_index: usize = A.start;
884884 var B_index: usize = B.start;
885885 const A_last = A.end;
......@@ -909,7 +909,7 @@ fn mergeInto(comptime T: type, from: []T, A: &const Range, B: &const Range, less
909909 }
910910}
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 {
913913 // A fits into the cache, so use that instead of the internal buffer
914914 var A_index: usize = 0;
915915 var B_index: usize = B.start;
......@@ -937,7 +937,7 @@ fn mergeExternal(comptime T: type, items: []T, A: &const Range, B: &const Range,
937937 mem.copy(T, items[insert_index..], cache[A_index..A_last]);
938938}
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 {
941941 if (lessThan(items[y], items[x]) or
942942 ((*order)[x] > (*order)[y] and !lessThan(items[x], items[y])))
943943 {
......@@ -946,19 +946,19 @@ fn swap(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const T)
946946 }
947947}
948948
949fn i32asc(lhs: &const i32, rhs: &const i32) -> bool {
949fn i32asc(lhs: &const i32, rhs: &const i32) bool {
950950 return *lhs < *rhs;
951951}
952952
953fn i32desc(lhs: &const i32, rhs: &const i32) -> bool {
953fn i32desc(lhs: &const i32, rhs: &const i32) bool {
954954 return *rhs < *lhs;
955955}
956956
957fn u8asc(lhs: &const u8, rhs: &const u8) -> bool {
957fn u8asc(lhs: &const u8, rhs: &const u8) bool {
958958 return *lhs < *rhs;
959959}
960960
961fn u8desc(lhs: &const u8, rhs: &const u8) -> bool {
961fn u8desc(lhs: &const u8, rhs: &const u8) bool {
962962 return *rhs < *lhs;
963963}
964964
......@@ -967,7 +967,7 @@ test "stable sort" {
967967 // TODO: uncomment this after https://github.com/zig-lang/zig/issues/639
968968 //comptime testStableSort();
969969}
970fn testStableSort() {
970fn testStableSort() void {
971971 var expected = []IdAndValue {
972972 IdAndValue{.id = 0, .value = 0},
973973 IdAndValue{.id = 1, .value = 0},
......@@ -1015,7 +1015,7 @@ const IdAndValue = struct {
10151015 id: usize,
10161016 value: i32,
10171017};
1018fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) -> bool {
1018fn cmpByValue(a: &const IdAndValue, b: &const IdAndValue) bool {
10191019 return i32asc(a.value, b.value);
10201020}
10211021
......@@ -1092,7 +1092,7 @@ test "sort fuzz testing" {
10921092
10931093var fixed_buffer_mem: [100 * 1024]u8 = undefined;
10941094
1095fn fuzzTest(rng: &std.rand.Rand) {
1095fn fuzzTest(rng: &std.rand.Rand) void {
10961096 const array_size = rng.range(usize, 0, 1000);
10971097 var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
10981098 var array = fixed_allocator.allocator.alloc(IdAndValue, array_size) catch unreachable;
......@@ -1113,7 +1113,7 @@ fn fuzzTest(rng: &std.rand.Rand) {
11131113 }
11141114}
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 {
11171117 var i: usize = 0;
11181118 var smallest = items[0];
11191119 for (items[1..]) |item| {
......@@ -1124,7 +1124,7 @@ pub fn min(comptime T: type, items: []T, lessThan: fn(lhs: &const T, rhs: &const
11241124 return smallest;
11251125}
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 {
11281128 var i: usize = 0;
11291129 var biggest = items[0];
11301130 for (items[1..]) |item| {
std/special/bootstrap.zig+7-7
......@@ -20,11 +20,11 @@ comptime {
2020 }
2121}
2222
23extern fn zenMain() -> noreturn {
23extern fn zenMain() noreturn {
2424 std.os.posix.exit(callMain());
2525}
2626
27nakedcc fn _start() -> noreturn {
27nakedcc fn _start() noreturn {
2828 switch (builtin.arch) {
2929 builtin.Arch.x86_64 => {
3030 argc_ptr = asm("lea (%%rsp), %[argc]": [argc] "=r" (-> &usize));
......@@ -39,20 +39,20 @@ nakedcc fn _start() -> noreturn {
3939 @noInlineCall(posixCallMainAndExit);
4040}
4141
42extern fn WinMainCRTStartup() -> noreturn {
42extern fn WinMainCRTStartup() noreturn {
4343 @setAlignStack(16);
4444
4545 std.os.windows.ExitProcess(callMain());
4646}
4747
48fn posixCallMainAndExit() -> noreturn {
48fn posixCallMainAndExit() noreturn {
4949 const argc = *argc_ptr;
5050 const argv = @ptrCast(&&u8, &argc_ptr[1]);
5151 const envp = @ptrCast(&?&u8, &argv[argc + 1]);
5252 std.os.posix.exit(callMainWithArgs(argc, argv, envp));
5353}
5454
55fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 {
55fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) u8 {
5656 std.os.ArgIteratorPosix.raw = argv[0..argc];
5757
5858 var env_count: usize = 0;
......@@ -62,11 +62,11 @@ fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 {
6262 return callMain();
6363}
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 {
6666 return callMainWithArgs(usize(c_argc), c_argv, c_envp);
6767}
6868
69fn callMain() -> u8 {
69fn callMain() u8 {
7070 switch (@typeId(@typeOf(root.main).ReturnType)) {
7171 builtin.TypeId.NoReturn => {
7272 root.main();
std/special/bootstrap_lib.zig+1-1
......@@ -7,7 +7,7 @@ comptime {
77}
88
99stdcallcc fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD,
10 lpReserved: std.os.windows.LPVOID) -> std.os.windows.BOOL
10 lpReserved: std.os.windows.LPVOID) std.os.windows.BOOL
1111{
1212 return std.os.windows.TRUE;
1313}
std/special/build_file_template.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) {
3pub fn build(b: &Builder) %void {
44 const mode = b.standardReleaseOptions();
55 const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");
66 exe.setBuildMode(mode);
std/special/build_runner.zig+4-4
......@@ -10,7 +10,7 @@ const warn = std.debug.warn;
1010
1111error InvalidArgs;
1212
13pub fn main() -> %void {
13pub fn main() %void {
1414 var arg_it = os.args();
1515
1616 // TODO use a more general purpose allocator here
......@@ -125,7 +125,7 @@ pub fn main() -> %void {
125125 };
126126}
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 {
129129 // run the build script to collect the options
130130 if (!already_ran_build) {
131131 builder.setInstallPrefix(null);
......@@ -183,12 +183,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
183183 );
184184}
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 {
187187 usage(builder, already_ran_build, out_stream) catch {};
188188 return error.InvalidArgs;
189189}
190190
191fn unwrapArg(arg: %[]u8) -> %[]u8 {
191fn unwrapArg(arg: %[]u8) %[]u8 {
192192 return arg catch |err| {
193193 warn("Unable to parse command line: {}\n", err);
194194 return err;
std/special/builtin.zig+17-16
......@@ -3,10 +3,11 @@
33
44const 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,
77// 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 {
99 if (builtin.is_test) {
10 @setCold(true);
1011 @import("std").debug.panic("{}", msg);
1112 } else {
1213 unreachable;
......@@ -16,8 +17,8 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -
1617// Note that memset does not return `dest`, like the libc API.
1718// The semantics of memset is dictated by the corresponding
1819// LLVM intrinsics, not by the libc API.
19export fn memset(dest: ?&u8, c: u8, n: usize) {
20 @setDebugSafety(this, false);
20export fn memset(dest: ?&u8, c: u8, n: usize) void {
21 @setRuntimeSafety(false);
2122
2223 var index: usize = 0;
2324 while (index != n) : (index += 1)
......@@ -27,8 +28,8 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {
2728// Note that memcpy does not return `dest`, like the libc API.
2829// The semantics of memcpy is dictated by the corresponding
2930// LLVM intrinsics, not by the libc API.
30export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
31 @setDebugSafety(this, false);
31export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) void {
32 @setRuntimeSafety(false);
3233
3334 var index: usize = 0;
3435 while (index != n) : (index += 1)
......@@ -40,24 +41,24 @@ comptime {
4041 @export("__stack_chk_fail", __stack_chk_fail, builtin.GlobalLinkage.Strong);
4142 }
4243}
43extern fn __stack_chk_fail() -> noreturn {
44extern fn __stack_chk_fail() noreturn {
4445 @panic("stack smashing detected");
4546}
4647
4748const math = @import("../math/index.zig");
4849
49export 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); }
50export fn fmodf(x: f32, y: f32) f32 { return generic_fmod(f32, x, y); }
51export fn fmod(x: f64, y: f64) f64 { return generic_fmod(f64, x, y); }
5152
5253// TODO add intrinsics for these (and probably the double version too)
5354// 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 ceilf(x: f32) -> f32 { return math.ceil(x); }
56export fn floor(x: f64) -> f64 { return math.floor(x); }
57export fn ceil(x: f64) -> f64 { return math.ceil(x); }
55export fn floorf(x: f32) f32 { return math.floor(x); }
56export fn ceilf(x: f32) f32 { return math.ceil(x); }
57export fn floor(x: f64) f64 { return math.floor(x); }
58export fn ceil(x: f64) f64 { return math.ceil(x); }
5859
59fn generic_fmod(comptime T: type, x: T, y: T) -> T {
60 @setDebugSafety(this, false);
60fn generic_fmod(comptime T: type, x: T, y: T) T {
61 @setRuntimeSafety(false);
6162
6263 const uint = @IntType(false, T.bit_count);
6364 const log2uint = math.Log2Int(uint);
......@@ -132,7 +133,7 @@ fn generic_fmod(comptime T: type, x: T, y: T) -> T {
132133 return @bitCast(T, ux);
133134}
134135
135fn isNan(comptime T: type, bits: T) -> bool {
136fn isNan(comptime T: type, bits: T) bool {
136137 if (T == u32) {
137138 return (bits & 0x7fffffff) > 0x7f800000;
138139 } else if (T == u64) {
std/special/compiler_rt/aulldiv.zig+2-2
......@@ -1,5 +1,5 @@
1pub nakedcc fn _aulldiv() {
2 @setDebugSafety(this, false);
1pub nakedcc fn _aulldiv() void {
2 @setRuntimeSafety(false);
33 asm volatile (
44 \\.intel_syntax noprefix
55 \\
std/special/compiler_rt/aullrem.zig+2-2
......@@ -1,5 +1,5 @@
1pub nakedcc fn _aullrem() {
2 @setDebugSafety(this, false);
1pub nakedcc fn _aullrem() void {
2 @setRuntimeSafety(false);
33 asm volatile (
44 \\.intel_syntax noprefix
55 \\
std/special/compiler_rt/comparetf2.zig+6-6
......@@ -21,8 +21,8 @@ const infRep = exponentMask;
2121const builtin = @import("builtin");
2222const is_test = builtin.is_test;
2323
24pub extern fn __letf2(a: f128, b: f128) -> c_int {
25 @setDebugSafety(this, is_test);
24pub extern fn __letf2(a: f128, b: f128) c_int {
25 @setRuntimeSafety(is_test);
2626
2727 const aInt = @bitCast(rep_t, a);
2828 const bInt = @bitCast(rep_t, b);
......@@ -66,8 +66,8 @@ const GE_EQUAL = c_int(0);
6666const GE_GREATER = c_int(1);
6767const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
6868
69pub extern fn __getf2(a: f128, b: f128) -> c_int {
70 @setDebugSafety(this, is_test);
69pub extern fn __getf2(a: f128, b: f128) c_int {
70 @setRuntimeSafety(is_test);
7171
7272 const aInt = @bitCast(srep_t, a);
7373 const bInt = @bitCast(srep_t, b);
......@@ -93,8 +93,8 @@ pub extern fn __getf2(a: f128, b: f128) -> c_int {
9393 ;
9494}
9595
96pub extern fn __unordtf2(a: f128, b: f128) -> c_int {
97 @setDebugSafety(this, is_test);
96pub extern fn __unordtf2(a: f128, b: f128) c_int {
97 @setRuntimeSafety(is_test);
9898
9999 const aAbs = @bitCast(rep_t, a) & absMask;
100100 const bAbs = @bitCast(rep_t, b) & absMask;
std/special/compiler_rt/fixuint.zig+4-4
......@@ -1,8 +1,8 @@
11const is_test = @import("builtin").is_test;
22const Log2Int = @import("../../math/index.zig").Log2Int;
33
4pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuint_t {
5 @setDebugSafety(this, is_test);
4pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t {
5 @setRuntimeSafety(is_test);
66
77 const rep_t = switch (fp_t) {
88 f32 => u32,
......@@ -48,12 +48,12 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuin
4848 if (exponent < significandBits) {
4949 // TODO this is a workaround for the mysterious "integer cast truncated bits"
5050 // happening on the next line
51 @setDebugSafety(this, false);
51 @setRuntimeSafety(false);
5252 return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent));
5353 } else {
5454 // TODO this is a workaround for the mysterious "integer cast truncated bits"
5555 // happening on the next line
56 @setDebugSafety(this, false);
56 @setRuntimeSafety(false);
5757 return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits);
5858 }
5959}
std/special/compiler_rt/fixunsdfdi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunsdfdi(a: f64) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunsdfdi(a: f64) u64 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u64, a);
77}
88
std/special/compiler_rt/fixunsdfdi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunsdfdi = @import("fixunsdfdi.zig").__fixunsdfdi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfdi(a: f64, expected: u64) {
4fn test__fixunsdfdi(a: f64, expected: u64) void {
55 const x = __fixunsdfdi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunsdfsi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunsdfsi(a: f64) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunsdfsi(a: f64) u32 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u32, a);
77}
88
std/special/compiler_rt/fixunsdfsi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunsdfsi = @import("fixunsdfsi.zig").__fixunsdfsi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfsi(a: f64, expected: u32) {
4fn test__fixunsdfsi(a: f64, expected: u32) void {
55 const x = __fixunsdfsi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunsdfti.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunsdfti(a: f64) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunsdfti(a: f64) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u128, a);
77}
88
std/special/compiler_rt/fixunsdfti_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunsdfti = @import("fixunsdfti.zig").__fixunsdfti;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunsdfti(a: f64, expected: u128) {
4fn test__fixunsdfti(a: f64, expected: u128) void {
55 const x = __fixunsdfti(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunssfdi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunssfdi(a: f32) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunssfdi(a: f32) u64 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u64, a);
77}
88
std/special/compiler_rt/fixunssfdi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunssfdi = @import("fixunssfdi.zig").__fixunssfdi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfdi(a: f32, expected: u64) {
4fn test__fixunssfdi(a: f32, expected: u64) void {
55 const x = __fixunssfdi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunssfsi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunssfsi(a: f32) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunssfsi(a: f32) u32 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u32, a);
77}
88
std/special/compiler_rt/fixunssfsi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunssfsi = @import("fixunssfsi.zig").__fixunssfsi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfsi(a: f32, expected: u32) {
4fn test__fixunssfsi(a: f32, expected: u32) void {
55 const x = __fixunssfsi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunssfti.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunssfti(a: f32) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunssfti(a: f32) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u128, a);
77}
88
std/special/compiler_rt/fixunssfti_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunssfti = @import("fixunssfti.zig").__fixunssfti;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunssfti(a: f32, expected: u128) {
4fn test__fixunssfti(a: f32, expected: u128) void {
55 const x = __fixunssfti(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunstfdi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunstfdi(a: f128) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunstfdi(a: f128) u64 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u64, a);
77}
88
std/special/compiler_rt/fixunstfdi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunstfdi = @import("fixunstfdi.zig").__fixunstfdi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfdi(a: f128, expected: u64) {
4fn test__fixunstfdi(a: f128, expected: u64) void {
55 const x = __fixunstfdi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunstfsi.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunstfsi(a: f128) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunstfsi(a: f128) u32 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u32, a);
77}
88
std/special/compiler_rt/fixunstfsi_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunstfsi = @import("fixunstfsi.zig").__fixunstfsi;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfsi(a: f128, expected: u32) {
4fn test__fixunstfsi(a: f128, expected: u32) void {
55 const x = __fixunstfsi(a);
66 assert(x == expected);
77}
std/special/compiler_rt/fixunstfti.zig+2-2
......@@ -1,8 +1,8 @@
11const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
4pub extern fn __fixunstfti(a: f128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __fixunstfti(a: f128) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u128, a);
77}
88
std/special/compiler_rt/fixunstfti_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __fixunstfti = @import("fixunstfti.zig").__fixunstfti;
22const assert = @import("../../index.zig").debug.assert;
33
4fn test__fixunstfti(a: f128, expected: u128) {
4fn test__fixunstfti(a: f128, expected: u128) void {
55 const x = __fixunstfti(a);
66 assert(x == expected);
77}
std/special/compiler_rt/index.zig+26-25
......@@ -72,9 +72,10 @@ const assert = @import("../../index.zig").debug.assert;
7272
7373const __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,
7676// 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);
7879 if (is_test) {
7980 @import("std").debug.panic("{}", msg);
8081 } else {
......@@ -82,13 +83,13 @@ pub coldcc fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -
8283 }
8384}
8485
85extern fn __udivdi3(a: u64, b: u64) -> u64 {
86 @setDebugSafety(this, is_test);
86extern fn __udivdi3(a: u64, b: u64) u64 {
87 @setRuntimeSafety(is_test);
8788 return __udivmoddi4(a, b, null);
8889}
8990
90extern fn __umoddi3(a: u64, b: u64) -> u64 {
91 @setDebugSafety(this, is_test);
91extern fn __umoddi3(a: u64, b: u64) u64 {
92 @setRuntimeSafety(is_test);
9293
9394 var r: u64 = undefined;
9495 _ = __udivmoddi4(a, b, &r);
......@@ -99,14 +100,14 @@ const AeabiUlDivModResult = extern struct {
99100 quot: u64,
100101 rem: u64,
101102};
102extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
103 @setDebugSafety(this, is_test);
103extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) AeabiUlDivModResult {
104 @setRuntimeSafety(is_test);
104105 var result: AeabiUlDivModResult = undefined;
105106 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
106107 return result;
107108}
108109
109fn isArmArch() -> bool {
110fn isArmArch() bool {
110111 return switch (builtin.arch) {
111112 builtin.Arch.armv8_2a,
112113 builtin.Arch.armv8_1a,
......@@ -148,8 +149,8 @@ fn isArmArch() -> bool {
148149 };
149150}
150151
151nakedcc fn __aeabi_uidivmod() {
152 @setDebugSafety(this, false);
152nakedcc fn __aeabi_uidivmod() void {
153 @setRuntimeSafety(false);
153154 asm volatile (
154155 \\ push { lr }
155156 \\ sub sp, sp, #4
......@@ -165,8 +166,8 @@ nakedcc fn __aeabi_uidivmod() {
165166// then decrement %esp by %eax. Preserves all registers except %esp and flags.
166167// This routine is windows specific
167168// http://msdn.microsoft.com/en-us/library/ms648426.aspx
168nakedcc fn _chkstk() align(4) {
169 @setDebugSafety(this, false);
169nakedcc fn _chkstk() align(4) void {
170 @setRuntimeSafety(false);
170171
171172 asm volatile (
172173 \\ push %%ecx
......@@ -189,8 +190,8 @@ nakedcc fn _chkstk() align(4) {
189190 );
190191}
191192
192nakedcc fn __chkstk() align(4) {
193 @setDebugSafety(this, false);
193nakedcc fn __chkstk() align(4) void {
194 @setRuntimeSafety(false);
194195
195196 asm volatile (
196197 \\ push %%rcx
......@@ -216,8 +217,8 @@ nakedcc fn __chkstk() align(4) {
216217// _chkstk routine
217218// This routine is windows specific
218219// http://msdn.microsoft.com/en-us/library/ms648426.aspx
219nakedcc fn __chkstk_ms() align(4) {
220 @setDebugSafety(this, false);
220nakedcc fn __chkstk_ms() align(4) void {
221 @setRuntimeSafety(false);
221222
222223 asm volatile (
223224 \\ push %%ecx
......@@ -240,8 +241,8 @@ nakedcc fn __chkstk_ms() align(4) {
240241 );
241242}
242243
243nakedcc fn ___chkstk_ms() align(4) {
244 @setDebugSafety(this, false);
244nakedcc fn ___chkstk_ms() align(4) void {
245 @setRuntimeSafety(false);
245246
246247 asm volatile (
247248 \\ push %%rcx
......@@ -264,8 +265,8 @@ nakedcc fn ___chkstk_ms() align(4) {
264265 );
265266}
266267
267extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
268 @setDebugSafety(this, is_test);
268extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) u32 {
269 @setRuntimeSafety(is_test);
269270
270271 const d = __udivsi3(a, b);
271272 *rem = u32(i32(a) -% (i32(d) * i32(b)));
......@@ -273,8 +274,8 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
273274}
274275
275276
276extern fn __udivsi3(n: u32, d: u32) -> u32 {
277 @setDebugSafety(this, is_test);
277extern fn __udivsi3(n: u32, d: u32) u32 {
278 @setRuntimeSafety(is_test);
278279
279280 const n_uword_bits: c_uint = u32.bit_count;
280281 // special cases
......@@ -320,7 +321,7 @@ test "test_umoddi3" {
320321 test_one_umoddi3(0xFFFFFFFFFFFFFFFF, 2, 0x1);
321322}
322323
323fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) {
324fn test_one_umoddi3(a: u64, b: u64, expected_r: u64) void {
324325 const r = __umoddi3(a, b);
325326 assert(r == expected_r);
326327}
......@@ -466,7 +467,7 @@ test "test_udivsi3" {
466467 }
467468}
468469
469fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) {
470fn test_one_udivsi3(a: u32, b: u32, expected_q: u32) void {
470471 const q: u32 = __udivsi3(a, b);
471472 assert(q == expected_q);
472473}
std/special/compiler_rt/udivmod.zig+2-2
......@@ -4,8 +4,8 @@ const is_test = builtin.is_test;
44const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Little => 0 };
55const high = 1 - low;
66
7pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) -> DoubleInt {
8 @setDebugSafety(this, is_test);
7pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) DoubleInt {
8 @setRuntimeSafety(is_test);
99
1010 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));
1111 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
std/special/compiler_rt/udivmoddi4.zig+2-2
......@@ -1,8 +1,8 @@
11const udivmod = @import("udivmod.zig").udivmod;
22const builtin = @import("builtin");
33
4pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) u64 {
5 @setRuntimeSafety(builtin.is_test);
66 return udivmod(u64, a, b, maybe_rem);
77}
88
std/special/compiler_rt/udivmoddi4_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
22const 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 {
55 var r: u64 = undefined;
66 const q = __udivmoddi4(a, b, &r);
77 assert(q == expected_q);
std/special/compiler_rt/udivmodti4.zig+2-2
......@@ -1,8 +1,8 @@
11const udivmod = @import("udivmod.zig").udivmod;
22const builtin = @import("builtin");
33
4pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 return udivmod(u128, a, b, maybe_rem);
77}
88
std/special/compiler_rt/udivmodti4_test.zig+1-1
......@@ -1,7 +1,7 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const 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 {
55 var r: u128 = undefined;
66 const q = __udivmodti4(a, b, &r);
77 assert(q == expected_q);
std/special/compiler_rt/udivti3.zig+2-2
......@@ -1,7 +1,7 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const builtin = @import("builtin");
33
4pub extern fn __udivti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __udivti3(a: u128, b: u128) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 return __udivmodti4(a, b, null);
77}
std/special/compiler_rt/umodti3.zig+2-2
......@@ -1,8 +1,8 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const builtin = @import("builtin");
33
4pub extern fn __umodti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
4pub extern fn __umodti3(a: u128, b: u128) u128 {
5 @setRuntimeSafety(builtin.is_test);
66 var r: u128 = undefined;
77 _ = __udivmodti4(a, b, &r);
88 return r;
std/special/panic.zig+2-1
......@@ -6,7 +6,8 @@
66const builtin = @import("builtin");
77const 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);
1011 switch (builtin.os) {
1112 // TODO: fix panic in zen.
1213 builtin.Os.freestanding, builtin.Os.zen => {
std/special/test_runner.zig+1-1
......@@ -4,7 +4,7 @@ const builtin = @import("builtin");
44const test_fn_list = builtin.__zig_test_fn_slice;
55const warn = std.debug.warn;
66
7pub fn main() -> %void {
7pub fn main() %void {
88 for (test_fn_list) |test_fn, i| {
99 warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name);
1010
std/unicode.zig+8-8
......@@ -5,7 +5,7 @@ error Utf8InvalidStartByte;
55/// Given the first byte of a UTF-8 codepoint,
66/// returns a number 1-4 indicating the total length of the codepoint in bytes.
77/// 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 {
99 if (first_byte < 0b10000000) return u3(1);
1010 if (first_byte & 0b11100000 == 0b11000000) return u3(2);
1111 if (first_byte & 0b11110000 == 0b11100000) return u3(3);
......@@ -22,7 +22,7 @@ error Utf8CodepointTooLarge;
2222/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.
2323/// If you already know the length at comptime, you can call one of
2424/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
25pub fn utf8Decode(bytes: []const u8) -> %u32 {
25pub fn utf8Decode(bytes: []const u8) %u32 {
2626 return switch (bytes.len) {
2727 1 => u32(bytes[0]),
2828 2 => utf8Decode2(bytes),
......@@ -31,7 +31,7 @@ pub fn utf8Decode(bytes: []const u8) -> %u32 {
3131 else => unreachable,
3232 };
3333}
34pub fn utf8Decode2(bytes: []const u8) -> %u32 {
34pub fn utf8Decode2(bytes: []const u8) %u32 {
3535 std.debug.assert(bytes.len == 2);
3636 std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);
3737 var value: u32 = bytes[0] & 0b00011111;
......@@ -44,7 +44,7 @@ pub fn utf8Decode2(bytes: []const u8) -> %u32 {
4444
4545 return value;
4646}
47pub fn utf8Decode3(bytes: []const u8) -> %u32 {
47pub fn utf8Decode3(bytes: []const u8) %u32 {
4848 std.debug.assert(bytes.len == 3);
4949 std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);
5050 var value: u32 = bytes[0] & 0b00001111;
......@@ -62,7 +62,7 @@ pub fn utf8Decode3(bytes: []const u8) -> %u32 {
6262
6363 return value;
6464}
65pub fn utf8Decode4(bytes: []const u8) -> %u32 {
65pub fn utf8Decode4(bytes: []const u8) %u32 {
6666 std.debug.assert(bytes.len == 4);
6767 std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);
6868 var value: u32 = bytes[0] & 0b00000111;
......@@ -149,7 +149,7 @@ test "misc invalid utf8" {
149149 testValid("\xee\x80\x80", 0xe000);
150150}
151151
152fn testError(bytes: []const u8, expected_err: error) {
152fn testError(bytes: []const u8, expected_err: error) void {
153153 if (testDecode(bytes)) |_| {
154154 unreachable;
155155 } else |err| {
......@@ -157,11 +157,11 @@ fn testError(bytes: []const u8, expected_err: error) {
157157 }
158158}
159159
160fn testValid(bytes: []const u8, expected_codepoint: u32) {
160fn testValid(bytes: []const u8, expected_codepoint: u32) void {
161161 std.debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);
162162}
163163
164fn testDecode(bytes: []const u8) -> %u32 {
164fn testDecode(bytes: []const u8) %u32 {
165165 const length = try utf8ByteSequenceLength(bytes[0]);
166166 if (bytes.len < length) return error.UnexpectedEof;
167167 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 @@
11const builtin = @import("builtin");
22const tests = @import("tests.zig");
33
4pub fn addCases(cases: &tests.CompareOutputContext) {
4pub fn addCases(cases: &tests.CompareOutputContext) void {
55 if (builtin.os == builtin.Os.linux and builtin.arch == builtin.Arch.x86_64) {
66 cases.addAsm("hello world linux x86_64",
77 \\.text
test/build_examples.zig+1-1
......@@ -2,7 +2,7 @@ const tests = @import("tests.zig");
22const builtin = @import("builtin");
33const is_windows = builtin.os == builtin.Os.windows;
44
5pub fn addCases(cases: &tests.BuildExamplesContext) {
5pub fn addCases(cases: &tests.BuildExamplesContext) void {
66 cases.add("example/hello_world/hello.zig");
77 cases.addC("example/hello_world/hello_libc.zig");
88 cases.add("example/cat/main.zig");
test/cases/align.zig+23-23
......@@ -10,14 +10,14 @@ test "global variable alignment" {
1010 assert(@typeOf(slice) == []align(4) u8);
1111}
1212
13fn derp() align(@sizeOf(usize) * 2) -> i32 { return 1234; }
14fn noop1() align(1) {}
15fn noop4() align(4) {}
13fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
14fn noop1() align(1) void {}
15fn noop4() align(4) void {}
1616
1717test "function alignment" {
1818 assert(derp() == 1234);
19 assert(@typeOf(noop1) == fn() align(1));
20 assert(@typeOf(noop4) == fn() align(4));
19 assert(@typeOf(noop1) == fn() align(1) void);
20 assert(@typeOf(noop4) == fn() align(4) void);
2121 noop1();
2222 noop4();
2323}
......@@ -53,19 +53,19 @@ test "implicitly decreasing pointer alignment" {
5353 assert(addUnaligned(&a, &b) == 7);
5454}
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
5858test "implicitly decreasing slice alignment" {
5959 const a: u32 align(4) = 3;
6060 const b: u32 align(8) = 4;
6161 assert(addUnalignedSlice((&a)[0..1], (&b)[0..1]) == 7);
6262}
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
6565test "specifying alignment allows pointer cast" {
6666 testBytesAlign(0x33);
6767}
68fn testBytesAlign(b: u8) {
68fn testBytesAlign(b: u8) void {
6969 var bytes align(4) = []u8{b, b, b, b};
7070 const ptr = @ptrCast(&u32, &bytes[0]);
7171 assert(*ptr == 0x33333333);
......@@ -74,7 +74,7 @@ fn testBytesAlign(b: u8) {
7474test "specifying alignment allows slice cast" {
7575 testBytesAlignSlice(0x33);
7676}
77fn testBytesAlignSlice(b: u8) {
77fn testBytesAlignSlice(b: u8) void {
7878 var bytes align(4) = []u8{b, b, b, b};
7979 const slice = ([]u32)(bytes[0..]);
8080 assert(slice[0] == 0x33333333);
......@@ -85,10 +85,10 @@ test "@alignCast pointers" {
8585 expectsOnly1(&x);
8686 assert(x == 2);
8787}
88fn expectsOnly1(x: &align(1) u32) {
88fn expectsOnly1(x: &align(1) u32) void {
8989 expects4(@alignCast(4, x));
9090}
91fn expects4(x: &align(4) u32) {
91fn expects4(x: &align(4) u32) void {
9292 *x += 1;
9393}
9494
......@@ -98,10 +98,10 @@ test "@alignCast slices" {
9898 sliceExpectsOnly1(slice);
9999 assert(slice[0] == 2);
100100}
101fn sliceExpectsOnly1(slice: []align(1) u32) {
101fn sliceExpectsOnly1(slice: []align(1) u32) void {
102102 sliceExpects4(@alignCast(4, slice));
103103}
104fn sliceExpects4(slice: []align(4) u32) {
104fn sliceExpects4(slice: []align(4) u32) void {
105105 slice[0] += 1;
106106}
107107
......@@ -111,24 +111,24 @@ test "implicitly decreasing fn alignment" {
111111 testImplicitlyDecreaseFnAlign(alignedBig, 5678);
112112}
113113
114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) -> i32, answer: i32) {
114fn testImplicitlyDecreaseFnAlign(ptr: fn () align(1) i32, answer: i32) void {
115115 assert(ptr() == answer);
116116}
117117
118fn alignedSmall() align(8) -> i32 { return 1234; }
119fn alignedBig() align(16) -> i32 { return 5678; }
118fn alignedSmall() align(8) i32 { return 1234; }
119fn alignedBig() align(16) i32 { return 5678; }
120120
121121
122122test "@alignCast functions" {
123123 assert(fnExpectsOnly1(simple4) == 0x19);
124124}
125fn fnExpectsOnly1(ptr: fn()align(1) -> i32) -> i32 {
125fn fnExpectsOnly1(ptr: fn()align(1) i32) i32 {
126126 return fnExpects4(@alignCast(4, ptr));
127127}
128fn fnExpects4(ptr: fn()align(4) -> i32) -> i32 {
128fn fnExpects4(ptr: fn()align(4) i32) i32 {
129129 return ptr();
130130}
131fn simple4() align(4) -> i32 { return 0x19; }
131fn simple4() align(4) i32 { return 0x19; }
132132
133133
134134test "generic function with align param" {
......@@ -137,7 +137,7 @@ test "generic function with align param" {
137137 assert(whyWouldYouEverDoThis(8) == 0x1);
138138}
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
143143test "@ptrCast preserves alignment of bigger source" {
......@@ -175,10 +175,10 @@ test "compile-time known array index has best alignment possible" {
175175 testIndex2(&array[0], 2, &u8);
176176 testIndex2(&array[0], 3, &u8);
177177}
178fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) {
178fn testIndex(smaller: &align(2) u32, index: usize, comptime T: type) void {
179179 assert(@typeOf(&smaller[index]) == T);
180180}
181fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) {
181fn testIndex2(ptr: &align(4) u8, index: usize, comptime T: type) void {
182182 assert(@typeOf(&ptr[index]) == T);
183183}
184184
......@@ -187,7 +187,7 @@ test "alignstack" {
187187 assert(fnWithAlignedStack() == 1234);
188188}
189189
190fn fnWithAlignedStack() -> i32 {
190fn fnWithAlignedStack() i32 {
191191 @setAlignStack(256);
192192 return 1234;
193193}
test/cases/array.zig+1-1
......@@ -21,7 +21,7 @@ test "arrays" {
2121 assert(accumulator == 15);
2222 assert(getArrayLen(array) == 5);
2323}
24fn getArrayLen(a: []const u32) -> usize {
24fn getArrayLen(a: []const u32) usize {
2525 return a.len;
2626}
2727
test/cases/asm.zig+2-2
......@@ -17,8 +17,8 @@ test "module level assembly" {
1717 }
1818}
1919
20extern fn aoeu() -> i32;
20extern fn aoeu() i32;
2121
22export fn derp() -> i32 {
22export fn derp() i32 {
2323 return 1234;
2424}
test/cases/bitcast.zig+3-3
......@@ -5,10 +5,10 @@ test "@bitCast i32 -> u32" {
55 comptime testBitCast_i32_u32();
66}
77
8fn testBitCast_i32_u32() {
8fn testBitCast_i32_u32() void {
99 assert(conv(-1) == @maxValue(u32));
1010 assert(conv2(@maxValue(u32)) == -1);
1111}
1212
13fn conv(x: i32) -> u32 { return @bitCast(u32, x); }
14fn conv2(x: u32) -> i32 { return @bitCast(i32, x); }
13fn conv(x: i32) u32 { return @bitCast(u32, 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" {
1313 nonConstCastBoolToInt(t, f);
1414}
1515
16fn nonConstCastBoolToInt(t: bool, f: bool) {
16fn nonConstCastBoolToInt(t: bool, f: bool) void {
1717 assert(i32(t) == i32(1));
1818 assert(i32(f) == i32(0));
1919}
......@@ -21,7 +21,7 @@ fn nonConstCastBoolToInt(t: bool, f: bool) {
2121test "bool cmp" {
2222 assert(testBoolCmp(true, false) == false);
2323}
24fn testBoolCmp(a: bool, b: bool) -> bool {
24fn testBoolCmp(a: bool, b: bool) bool {
2525 return a == b;
2626}
2727
test/cases/bugs/655.zig+1-1
......@@ -7,6 +7,6 @@ test "function with &const parameter with type dereferenced by namespace" {
77 foo(x);
88}
99
10fn foo(x: &const other_file.Integer) {
10fn foo(x: &const other_file.Integer) void {
1111 std.debug.assert(*x == 1234);
1212}
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
1313 foo(false, true);
1414}
1515
16fn foo(a: bool, b: bool) {
16fn foo(a: bool, b: bool) void {
1717 var prefix_op = PrefixOp { .AddrOf = Value { .align_expr = 1234 } };
1818 if (a) {
1919 } else {
test/cases/cast.zig+23-23
......@@ -28,7 +28,7 @@ test "implicitly cast a pointer to a const pointer of it" {
2828 assert(x == 2);
2929}
3030
31fn funcWithConstPtrPtr(x: &const &i32) {
31fn funcWithConstPtrPtr(x: &const &i32) void {
3232 **x += 1;
3333}
3434
......@@ -37,7 +37,7 @@ test "explicit cast from integer to error type" {
3737 testCastIntToErr(error.ItBroke);
3838 comptime testCastIntToErr(error.ItBroke);
3939}
40fn testCastIntToErr(err: error) {
40fn testCastIntToErr(err: error) void {
4141 const x = usize(err);
4242 const y = error(x);
4343 assert(error.ItBroke == y);
......@@ -49,7 +49,7 @@ test "peer resolve arrays of different size to const slice" {
4949 comptime assert(mem.eql(u8, boolToStr(true), "true"));
5050 comptime assert(mem.eql(u8, boolToStr(false), "false"));
5151}
52fn boolToStr(b: bool) -> []const u8 {
52fn boolToStr(b: bool) []const u8 {
5353 return if (b) "true" else "false";
5454}
5555
......@@ -58,7 +58,7 @@ test "peer resolve array and const slice" {
5858 testPeerResolveArrayConstSlice(true);
5959 comptime testPeerResolveArrayConstSlice(true);
6060}
61fn testPeerResolveArrayConstSlice(b: bool) {
61fn testPeerResolveArrayConstSlice(b: bool) void {
6262 const value1 = if (b) "aoeu" else ([]const u8)("zz");
6363 const value2 = if (b) ([]const u8)("zz") else "aoeu";
6464 assert(mem.eql(u8, value1, "aoeu"));
......@@ -82,7 +82,7 @@ test "implicitly cast from T to %?T" {
8282const A = struct {
8383 a: i32,
8484};
85fn castToMaybeTypeError(z: i32) {
85fn castToMaybeTypeError(z: i32) void {
8686 const x = i32(1);
8787 const y: %?i32 = x;
8888 assert(??(try y) == 1);
......@@ -99,22 +99,22 @@ test "implicitly cast from int to %?T" {
9999 implicitIntLitToMaybe();
100100 comptime implicitIntLitToMaybe();
101101}
102fn implicitIntLitToMaybe() {
102fn implicitIntLitToMaybe() void {
103103 const f: ?i32 = 1;
104104 const g: %?i32 = 1;
105105}
106106
107107
108test "return null from fn() -> %?&T" {
108test "return null from fn() %?&T" {
109109 const a = returnNullFromMaybeTypeErrorRef();
110110 const b = returnNullLitFromMaybeTypeErrorRef();
111111 assert((try a) == null and (try b) == null);
112112}
113fn returnNullFromMaybeTypeErrorRef() -> %?&A {
113fn returnNullFromMaybeTypeErrorRef() %?&A {
114114 const a: ?&A = null;
115115 return a;
116116}
117fn returnNullLitFromMaybeTypeErrorRef() -> %?&A {
117fn returnNullLitFromMaybeTypeErrorRef() %?&A {
118118 return null;
119119}
120120
......@@ -126,7 +126,7 @@ test "peer type resolution: ?T and T" {
126126 assert(??peerTypeTAndMaybeT(false, false) == 3);
127127 }
128128}
129fn peerTypeTAndMaybeT(c: bool, b: bool) -> ?usize {
129fn peerTypeTAndMaybeT(c: bool, b: bool) ?usize {
130130 if (c) {
131131 return if (b) null else usize(0);
132132 }
......@@ -143,7 +143,7 @@ test "peer type resolution: [0]u8 and []const u8" {
143143 assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
144144 }
145145}
146fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) -> []const u8 {
146fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
147147 if (a) {
148148 return []const u8 {};
149149 }
......@@ -156,7 +156,7 @@ test "implicitly cast from [N]T to ?[]const T" {
156156 comptime assert(mem.eql(u8, ??castToMaybeSlice(), "hi"));
157157}
158158
159fn castToMaybeSlice() -> ?[]const u8 {
159fn castToMaybeSlice() ?[]const u8 {
160160 return "hi";
161161}
162162
......@@ -166,11 +166,11 @@ test "implicitly cast from [0]T to %[]T" {
166166 comptime testCastZeroArrayToErrSliceMut();
167167}
168168
169fn testCastZeroArrayToErrSliceMut() {
169fn testCastZeroArrayToErrSliceMut() void {
170170 assert((gimmeErrOrSlice() catch unreachable).len == 0);
171171}
172172
173fn gimmeErrOrSlice() -> %[]u8 {
173fn gimmeErrOrSlice() %[]u8 {
174174 return []u8{};
175175}
176176
......@@ -188,7 +188,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
188188 assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
189189 }
190190}
191fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) -> %[]u8 {
191fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) %[]u8 {
192192 if (a) {
193193 return []u8{};
194194 }
......@@ -200,7 +200,7 @@ test "resolve undefined with integer" {
200200 testResolveUndefWithInt(true, 1234);
201201 comptime testResolveUndefWithInt(true, 1234);
202202}
203fn testResolveUndefWithInt(b: bool, x: i32) {
203fn testResolveUndefWithInt(b: bool, x: i32) void {
204204 const value = if (b) x else undefined;
205205 if (b) {
206206 assert(value == x);
......@@ -212,7 +212,7 @@ test "implicit cast from &const [N]T to []const T" {
212212 comptime testCastConstArrayRefToConstSlice();
213213}
214214
215fn testCastConstArrayRefToConstSlice() {
215fn testCastConstArrayRefToConstSlice() void {
216216 const blah = "aoeu";
217217 const const_array_ref = &blah;
218218 assert(@typeOf(const_array_ref) == &const [4]u8);
......@@ -224,7 +224,7 @@ test "var args implicitly casts by value arg to const ref" {
224224 foo("hello");
225225}
226226
227fn foo(args: ...) {
227fn foo(args: ...) void {
228228 assert(@typeOf(args[0]) == &const [5]u8);
229229}
230230
......@@ -239,13 +239,13 @@ test "peer type resolution: error and [N]T" {
239239}
240240
241241error BadValue;
242//fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
242//fn testPeerErrorAndArray(x: u8) %[]const u8 {
243243// return switch (x) {
244244// 0x00 => "OK",
245245// else => error.BadValue,
246246// };
247247//}
248fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
248fn testPeerErrorAndArray2(x: u8) %[]const u8 {
249249 return switch (x) {
250250 0x00 => "OK",
251251 0x01 => "OKK",
......@@ -265,15 +265,15 @@ test "cast u128 to f128 and back" {
265265 testCast128();
266266}
267267
268fn testCast128() {
268fn testCast128() void {
269269 assert(cast128Int(cast128Float(0x7fff0000000000000000000000000000)) == 0x7fff0000000000000000000000000000);
270270}
271271
272fn cast128Int(x: f128) -> u128 {
272fn cast128Int(x: f128) u128 {
273273 return @bitCast(u128, x);
274274}
275275
276fn cast128Float(x: u128) -> f128 {
276fn cast128Float(x: u128) f128 {
277277 return @bitCast(f128, x);
278278}
279279
test/cases/const_slice_child.zig+4-4
......@@ -13,14 +13,14 @@ test "const slice child" {
1313 bar(strs.len);
1414}
1515
16fn foo(args: [][]const u8) {
16fn foo(args: [][]const u8) void {
1717 assert(args.len == 3);
1818 assert(streql(args[0], "one"));
1919 assert(streql(args[1], "two"));
2020 assert(streql(args[2], "three"));
2121}
2222
23fn bar(argc: usize) {
23fn bar(argc: usize) void {
2424 const args = debug.global_allocator.alloc([]const u8, argc) catch unreachable;
2525 for (args) |_, i| {
2626 const ptr = argv[i];
......@@ -29,13 +29,13 @@ fn bar(argc: usize) {
2929 foo(args);
3030}
3131
32fn strlen(ptr: &const u8) -> usize {
32fn strlen(ptr: &const u8) usize {
3333 var count: usize = 0;
3434 while (ptr[count] != 0) : (count += 1) {}
3535 return count;
3636}
3737
38fn streql(a: []const u8, b: []const u8) -> bool {
38fn streql(a: []const u8, b: []const u8) bool {
3939 if (a.len != b.len) return false;
4040 for (a) |item, index| {
4141 if (b[index] != item) return false;
test/cases/defer.zig+3-3
......@@ -5,10 +5,10 @@ var index: usize = undefined;
55
66error FalseNotAllowed;
77
8fn runSomeErrorDefers(x: bool) -> %bool {
8fn runSomeErrorDefers(x: bool) %bool {
99 index = 0;
1010 defer {result[index] = 'a'; index += 1;}
11 %defer {result[index] = 'b'; index += 1;}
11 errdefer {result[index] = 'b'; index += 1;}
1212 defer {result[index] = 'c'; index += 1;}
1313 return if (x) x else error.FalseNotAllowed;
1414}
......@@ -33,7 +33,7 @@ test "break and continue inside loop inside defer expression" {
3333 comptime testBreakContInDefer(10);
3434}
3535
36fn testBreakContInDefer(x: usize) {
36fn testBreakContInDefer(x: usize) void {
3737 defer {
3838 var i: usize = 0;
3939 while (i < x) : (i += 1) {
test/cases/enum.zig+13-13
......@@ -40,7 +40,7 @@ const Bar = enum {
4040 D,
4141};
4242
43fn returnAnInt(x: i32) -> Foo {
43fn returnAnInt(x: i32) Foo {
4444 return Foo { .One = x };
4545}
4646
......@@ -52,14 +52,14 @@ test "constant enum with payload" {
5252 shouldBeNotEmpty(full);
5353}
5454
55fn shouldBeEmpty(x: &const AnEnumWithPayload) {
55fn shouldBeEmpty(x: &const AnEnumWithPayload) void {
5656 switch (*x) {
5757 AnEnumWithPayload.Empty => {},
5858 else => unreachable,
5959 }
6060}
6161
62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) {
62fn shouldBeNotEmpty(x: &const AnEnumWithPayload) void {
6363 switch (*x) {
6464 AnEnumWithPayload.Empty => unreachable,
6565 else => {},
......@@ -89,7 +89,7 @@ test "enum to int" {
8989 shouldEqual(Number.Four, 4);
9090}
9191
92fn shouldEqual(n: Number, expected: u3) {
92fn shouldEqual(n: Number, expected: u3) void {
9393 assert(u3(n) == expected);
9494}
9595
......@@ -97,7 +97,7 @@ fn shouldEqual(n: Number, expected: u3) {
9797test "int to enum" {
9898 testIntToEnumEval(3);
9999}
100fn testIntToEnumEval(x: i32) {
100fn testIntToEnumEval(x: i32) void {
101101 assert(IntToEnumNumber(u3(x)) == IntToEnumNumber.Three);
102102}
103103const IntToEnumNumber = enum {
......@@ -114,7 +114,7 @@ test "@tagName" {
114114 comptime assert(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
115115}
116116
117fn testEnumTagNameBare(n: BareNumber) -> []const u8 {
117fn testEnumTagNameBare(n: BareNumber) []const u8 {
118118 return @tagName(n);
119119}
120120
......@@ -270,15 +270,15 @@ test "bit field access with enum fields" {
270270 assert(data.b == B.Four3);
271271}
272272
273fn getA(data: &const BitFieldOfEnums) -> A {
273fn getA(data: &const BitFieldOfEnums) A {
274274 return data.a;
275275}
276276
277fn getB(data: &const BitFieldOfEnums) -> B {
277fn getB(data: &const BitFieldOfEnums) B {
278278 return data.b;
279279}
280280
281fn getC(data: &const BitFieldOfEnums) -> C {
281fn getC(data: &const BitFieldOfEnums) C {
282282 return data.c;
283283}
284284
......@@ -287,7 +287,7 @@ test "casting enum to its tag type" {
287287 comptime testCastEnumToTagType(Small2.Two);
288288}
289289
290fn testCastEnumToTagType(value: Small2) {
290fn testCastEnumToTagType(value: Small2) void {
291291 assert(u2(value) == 1);
292292}
293293
......@@ -303,7 +303,7 @@ test "enum with specified tag values" {
303303 comptime testEnumWithSpecifiedTagValues(MultipleChoice.C);
304304}
305305
306fn testEnumWithSpecifiedTagValues(x: MultipleChoice) {
306fn testEnumWithSpecifiedTagValues(x: MultipleChoice) void {
307307 assert(u32(x) == 60);
308308 assert(1234 == switch (x) {
309309 MultipleChoice.A => 1,
......@@ -330,7 +330,7 @@ test "enum with specified and unspecified tag values" {
330330 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2.D);
331331}
332332
333fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) {
333fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void {
334334 assert(u32(x) == 1000);
335335 assert(1234 == switch (x) {
336336 MultipleChoice2.A => 1,
......@@ -354,7 +354,7 @@ const EnumWithOneMember = enum {
354354 Eof,
355355};
356356
357fn doALoopThing(id: EnumWithOneMember) {
357fn doALoopThing(id: EnumWithOneMember) void {
358358 while (true) {
359359 if (id == EnumWithOneMember.Eof) {
360360 break;
test/cases/enum_with_members.zig+1-1
......@@ -6,7 +6,7 @@ const ET = union(enum) {
66 SINT: i32,
77 UINT: u32,
88
9 pub fn print(a: &const ET, buf: []u8) -> %usize {
9 pub fn print(a: &const ET, buf: []u8) %usize {
1010 return switch (*a) {
1111 ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
1212 ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
test/cases/error.zig+9-9
......@@ -1,16 +1,16 @@
11const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
33
4pub fn foo() -> %i32 {
4pub fn foo() %i32 {
55 const x = try bar();
66 return x + 1;
77}
88
9pub fn bar() -> %i32 {
9pub fn bar() %i32 {
1010 return 13;
1111}
1212
13pub fn baz() -> %i32 {
13pub fn baz() %i32 {
1414 const y = foo() catch 1234;
1515 return y + 1;
1616}
......@@ -20,7 +20,7 @@ test "error wrapping" {
2020}
2121
2222error ItBroke;
23fn gimmeItBroke() -> []const u8 {
23fn gimmeItBroke() []const u8 {
2424 return @errorName(error.ItBroke);
2525}
2626
......@@ -47,7 +47,7 @@ test "redefinition of error values allowed" {
4747error AnError;
4848error AnError;
4949error SecondError;
50fn shouldBeNotEqual(a: error, b: error) {
50fn shouldBeNotEqual(a: error, b: error) void {
5151 if (a == b) unreachable;
5252}
5353
......@@ -59,7 +59,7 @@ test "error binary operator" {
5959 assert(b == 10);
6060}
6161error ItBroke;
62fn errBinaryOperatorG(x: bool) -> %isize {
62fn errBinaryOperatorG(x: bool) %isize {
6363 return if (x) error.ItBroke else isize(10);
6464}
6565
......@@ -68,18 +68,18 @@ test "unwrap simple value from error" {
6868 const i = unwrapSimpleValueFromErrorDo() catch unreachable;
6969 assert(i == 13);
7070}
71fn unwrapSimpleValueFromErrorDo() -> %isize { return 13; }
71fn unwrapSimpleValueFromErrorDo() %isize { return 13; }
7272
7373
7474test "error return in assignment" {
7575 doErrReturnInAssignment() catch unreachable;
7676}
7777
78fn doErrReturnInAssignment() -> %void {
78fn doErrReturnInAssignment() %void {
7979 var x : i32 = undefined;
8080 x = try makeANonErr();
8181}
8282
83fn makeANonErr() -> %i32 {
83fn makeANonErr() %i32 {
8484 return 1;
8585}
test/cases/eval.zig+25-25
......@@ -5,14 +5,14 @@ test "compile time recursion" {
55 assert(some_data.len == 21);
66}
77var some_data: [usize(fibonacci(7))]u8 = undefined;
8fn fibonacci(x: i32) -> i32 {
8fn fibonacci(x: i32) i32 {
99 if (x <= 1) return 1;
1010 return fibonacci(x - 1) + fibonacci(x - 2);
1111}
1212
1313
1414
15fn unwrapAndAddOne(blah: ?i32) -> i32 {
15fn unwrapAndAddOne(blah: ?i32) i32 {
1616 return ??blah + 1;
1717}
1818const should_be_1235 = unwrapAndAddOne(1234);
......@@ -28,7 +28,7 @@ test "inlined loop" {
2828 assert(sum == 15);
2929}
3030
31fn gimme1or2(comptime a: bool) -> i32 {
31fn gimme1or2(comptime a: bool) i32 {
3232 const x: i32 = 1;
3333 const y: i32 = 2;
3434 comptime var z: i32 = if (a) x else y;
......@@ -44,14 +44,14 @@ test "static function evaluation" {
4444 assert(statically_added_number == 3);
4545}
4646const 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
5050test "const expr eval on single expr blocks" {
5151 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
5252}
5353
54fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {
54fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) i32 {
5555 const literal = 3;
5656
5757 const result = if (b) b: {
......@@ -77,7 +77,7 @@ const Point = struct {
7777 y: i32,
7878};
7979const static_point_list = []Point { makePoint(1, 2), makePoint(3, 4) };
80fn makePoint(x: i32, y: i32) -> Point {
80fn makePoint(x: i32, y: i32) Point {
8181 return Point {
8282 .x = x,
8383 .y = y,
......@@ -93,7 +93,7 @@ const static_vec3 = vec3(0.0, 0.0, 1.0);
9393pub const Vec3 = struct {
9494 data: [3]f32,
9595};
96pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
96pub fn vec3(x: f32, y: f32, z: f32) Vec3 {
9797 return Vec3 {
9898 .data = []f32 { x, y, z, },
9999 };
......@@ -156,7 +156,7 @@ test "try to trick eval with runtime if" {
156156 assert(testTryToTrickEvalWithRuntimeIf(true) == 10);
157157}
158158
159fn testTryToTrickEvalWithRuntimeIf(b: bool) -> usize {
159fn testTryToTrickEvalWithRuntimeIf(b: bool) usize {
160160 comptime var i: usize = 0;
161161 inline while (i < 10) : (i += 1) {
162162 const result = if (b) false else true;
......@@ -166,7 +166,7 @@ fn testTryToTrickEvalWithRuntimeIf(b: bool) -> usize {
166166 }
167167}
168168
169fn max(comptime T: type, a: T, b: T) -> T {
169fn max(comptime T: type, a: T, b: T) T {
170170 if (T == bool) {
171171 return a or b;
172172 } else if (a > b) {
......@@ -175,7 +175,7 @@ fn max(comptime T: type, a: T, b: T) -> T {
175175 return b;
176176 }
177177}
178fn letsTryToCompareBools(a: bool, b: bool) -> bool {
178fn letsTryToCompareBools(a: bool, b: bool) bool {
179179 return max(bool, a, b);
180180}
181181test "inlined block and runtime block phi" {
......@@ -194,7 +194,7 @@ test "inlined block and runtime block phi" {
194194
195195const CmdFn = struct {
196196 name: []const u8,
197 func: fn(i32) -> i32,
197 func: fn(i32) i32,
198198};
199199
200200const cmd_fns = []CmdFn{
......@@ -202,11 +202,11 @@ const cmd_fns = []CmdFn{
202202 CmdFn {.name = "two", .func = two},
203203 CmdFn {.name = "three", .func = three},
204204};
205fn one(value: i32) -> i32 { return value + 1; }
206fn two(value: i32) -> i32 { return value + 2; }
207fn three(value: i32) -> i32 { return value + 3; }
205fn one(value: i32) i32 { return value + 1; }
206fn two(value: i32) i32 { return value + 2; }
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 {
210210 var result: i32 = start_value;
211211 comptime var i = 0;
212212 inline while (i < cmd_fns.len) : (i += 1) {
......@@ -223,13 +223,13 @@ test "comptime iterate over fn ptr list" {
223223 assert(performFn('w', 99) == 99);
224224}
225225
226test "eval @setDebugSafety at compile-time" {
227 const result = comptime fnWithSetDebugSafety();
226test "eval @setRuntimeSafety at compile-time" {
227 const result = comptime fnWithSetRuntimeSafety();
228228 assert(result == 1234);
229229}
230230
231fn fnWithSetDebugSafety() -> i32{
232 @setDebugSafety(this, true);
231fn fnWithSetRuntimeSafety() i32{
232 @setRuntimeSafety(true);
233233 return 1234;
234234}
235235
......@@ -238,7 +238,7 @@ test "eval @setFloatMode at compile-time" {
238238 assert(result == 1234.0);
239239}
240240
241fn fnWithFloatMode() -> f32 {
241fn fnWithFloatMode() f32 {
242242 @setFloatMode(this, builtin.FloatMode.Strict);
243243 return 1234.0;
244244}
......@@ -247,7 +247,7 @@ fn fnWithFloatMode() -> f32 {
247247const SimpleStruct = struct {
248248 field: i32,
249249
250 fn method(self: &const SimpleStruct) -> i32 {
250 fn method(self: &const SimpleStruct) i32 {
251251 return self.field + 3;
252252 }
253253};
......@@ -271,7 +271,7 @@ test "ptr to local array argument at comptime" {
271271 }
272272}
273273
274fn modifySomeBytes(bytes: []u8) {
274fn modifySomeBytes(bytes: []u8) void {
275275 bytes[0] = 'a';
276276 bytes[9] = 'b';
277277}
......@@ -280,7 +280,7 @@ fn modifySomeBytes(bytes: []u8) {
280280test "comparisons 0 <= uint and 0 > uint should be comptime" {
281281 testCompTimeUIntComparisons(1234);
282282}
283fn testCompTimeUIntComparisons(x: u32) {
283fn testCompTimeUIntComparisons(x: u32) void {
284284 if (!(0 <= x)) {
285285 @compileError("this condition should be comptime known");
286286 }
......@@ -339,7 +339,7 @@ test "const global shares pointer with other same one" {
339339 assertEqualPtrs(&hi1[0], &hi2[0]);
340340 comptime assert(&hi1[0] == &hi2[0]);
341341}
342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) {
342fn assertEqualPtrs(ptr1: &const u8, ptr2: &const u8) void {
343343 assert(ptr1 == ptr2);
344344}
345345
......@@ -376,7 +376,7 @@ test "f128 at compile time is lossy" {
376376// TODO need a better implementation of bigfloat_init_bigint
377377// assert(f128(1 << 113) == 10384593717069655257060992658440192);
378378
379pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) -> type {
379pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) type {
380380 return struct {
381381 pub const Node = struct { };
382382 };
test/cases/field_parent_ptr.zig+2-2
......@@ -24,7 +24,7 @@ const foo = Foo {
2424 .d = -10,
2525};
2626
27fn testParentFieldPtr(c: &const i32) {
27fn testParentFieldPtr(c: &const i32) void {
2828 assert(c == &foo.c);
2929
3030 const base = @fieldParentPtr(Foo, "c", c);
......@@ -32,7 +32,7 @@ fn testParentFieldPtr(c: &const i32) {
3232 assert(&base.c == c);
3333}
3434
35fn testParentFieldPtrFirst(a: &const bool) {
35fn testParentFieldPtrFirst(a: &const bool) void {
3636 assert(a == &foo.a);
3737
3838 const base = @fieldParentPtr(Foo, "a", a);
test/cases/fn.zig+12-12
......@@ -3,7 +3,7 @@ const assert = @import("std").debug.assert;
33test "params" {
44 assert(testParamsAdd(22, 11) == 33);
55}
6fn testParamsAdd(a: i32, b: i32) -> i32 {
6fn testParamsAdd(a: i32, b: i32) i32 {
77 return a + b;
88}
99
......@@ -11,7 +11,7 @@ fn testParamsAdd(a: i32, b: i32) -> i32 {
1111test "local variables" {
1212 testLocVars(2);
1313}
14fn testLocVars(b: i32) {
14fn testLocVars(b: i32) void {
1515 const a: i32 = 1;
1616 if (a + b != 3) unreachable;
1717}
......@@ -20,7 +20,7 @@ fn testLocVars(b: i32) {
2020test "void parameters" {
2121 voidFun(1, void{}, 2, {});
2222}
23fn voidFun(a: i32, b: void, c: i32, d: void) {
23fn voidFun(a: i32, b: void, c: i32, d: void) void {
2424 const v = b;
2525 const vv: void = if (a == 1) v else {};
2626 assert(a + c == 3);
......@@ -56,10 +56,10 @@ test "call function with empty string" {
5656 acceptsString("");
5757}
5858
59fn acceptsString(foo: []u8) { }
59fn acceptsString(foo: []u8) void { }
6060
6161
62fn @"weird function name"() -> i32 {
62fn @"weird function name"() i32 {
6363 return 1234;
6464}
6565test "weird function name" {
......@@ -70,9 +70,9 @@ test "implicit cast function unreachable return" {
7070 wantsFnWithVoid(fnWithUnreachable);
7171}
7272
73fn wantsFnWithVoid(f: fn()) { }
73fn wantsFnWithVoid(f: fn() void) void { }
7474
75fn fnWithUnreachable() -> noreturn {
75fn fnWithUnreachable() noreturn {
7676 unreachable;
7777}
7878
......@@ -83,14 +83,14 @@ test "function pointers" {
8383 assert(f() == u32(i) + 5);
8484 }
8585}
86fn fn1() -> u32 {return 5;}
87fn fn2() -> u32 {return 6;}
88fn fn3() -> u32 {return 7;}
89fn fn4() -> u32 {return 8;}
86fn fn1() u32 {return 5;}
87fn fn2() u32 {return 6;}
88fn fn3() u32 {return 7;}
89fn fn4() u32 {return 8;}
9090
9191
9292test "inline function call" {
9393 assert(@inlineCall(add, 3, 9) == 12);
9494}
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" {
2222 mangleString(target[0..]);
2323 assert(mem.eql(u8, target, "bcdefgh"));
2424}
25fn mangleString(s: []u8) {
25fn mangleString(s: []u8) void {
2626 for (s) |*c| {
2727 *c += 1;
2828 }
......@@ -61,7 +61,7 @@ test "break from outer for loop" {
6161 comptime testBreakOuter();
6262}
6363
64fn testBreakOuter() {
64fn testBreakOuter() void {
6565 var array = "aoeu";
6666 var count: usize = 0;
6767 outer: for (array) |_| {
......@@ -78,7 +78,7 @@ test "continue outer for loop" {
7878 comptime testContinueOuter();
7979}
8080
81fn testContinueOuter() {
81fn testContinueOuter() void {
8282 var array = "aoeu";
8383 var counter: usize = 0;
8484 outer: for (array) |_| {
test/cases/generics.zig+19-19
......@@ -6,11 +6,11 @@ test "simple generic fn" {
66 assert(add(2, 3) == 5);
77}
88
9fn max(comptime T: type, a: T, b: T) -> T {
9fn max(comptime T: type, a: T, b: T) T {
1010 return if (a > b) a else b;
1111}
1212
13fn add(comptime a: i32, b: i32) -> i32 {
13fn add(comptime a: i32, b: i32) i32 {
1414 return (comptime a) + b;
1515}
1616
......@@ -19,15 +19,15 @@ test "compile time generic eval" {
1919 assert(the_max == 5678);
2020}
2121
22fn gimmeTheBigOne(a: u32, b: u32) -> u32 {
22fn gimmeTheBigOne(a: u32, b: u32) u32 {
2323 return max(u32, a, b);
2424}
2525
26fn shouldCallSameInstance(a: u32, b: u32) -> u32 {
26fn shouldCallSameInstance(a: u32, b: u32) u32 {
2727 return max(u32, a, b);
2828}
2929
30fn sameButWithFloats(a: f64, b: f64) -> f64 {
30fn sameButWithFloats(a: f64, b: f64) f64 {
3131 return max(f64, a, b);
3232}
3333
......@@ -48,24 +48,24 @@ comptime {
4848 assert(max_f64(1.2, 3.4) == 3.4);
4949}
5050
51fn max_var(a: var, b: var) -> @typeOf(a + b) {
51fn max_var(a: var, b: var) @typeOf(a + b) {
5252 return if (a > b) a else b;
5353}
5454
55fn max_i32(a: i32, b: i32) -> i32 {
55fn max_i32(a: i32, b: i32) i32 {
5656 return max_var(a, b);
5757}
5858
59fn max_f64(a: f64, b: f64) -> f64 {
59fn max_f64(a: f64, b: f64) f64 {
6060 return max_var(a, b);
6161}
6262
6363
64pub fn List(comptime T: type) -> type {
64pub fn List(comptime T: type) type {
6565 return SmallList(T, 8);
6666}
6767
68pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
68pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type {
6969 return struct {
7070 items: []T,
7171 length: usize,
......@@ -90,18 +90,18 @@ test "generic struct" {
9090 assert(a1.value == a1.getVal());
9191 assert(b1.getVal());
9292}
93fn GenNode(comptime T: type) -> type {
93fn GenNode(comptime T: type) type {
9494 return struct {
9595 value: T,
9696 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; }
9898 };
9999}
100100
101101test "const decls in struct" {
102102 assert(GenericDataThing(3).count_plus_one == 4);
103103}
104fn GenericDataThing(comptime count: isize) -> type {
104fn GenericDataThing(comptime count: isize) type {
105105 return struct {
106106 const count_plus_one = count + 1;
107107 };
......@@ -111,7 +111,7 @@ fn GenericDataThing(comptime count: isize) -> type {
111111test "use generic param in generic param" {
112112 assert(aGenericFn(i32, 3, 4) == 7);
113113}
114fn aGenericFn(comptime T: type, comptime a: T, b: T) -> T {
114fn aGenericFn(comptime T: type, comptime a: T, b: T) T {
115115 return a + b;
116116}
117117
......@@ -120,16 +120,16 @@ test "generic fn with implicit cast" {
120120 assert(getFirstByte(u8, []u8 {13}) == 13);
121121 assert(getFirstByte(u16, []u16 {0, 13}) == 0);
122122}
123fn getByte(ptr: ?&const u8) -> u8 {return *??ptr;}
124fn getFirstByte(comptime T: type, mem: []const T) -> u8 {
123fn getByte(ptr: ?&const u8) u8 {return *??ptr;}
124fn getFirstByte(comptime T: type, mem: []const T) u8 {
125125 return getByte(@ptrCast(&const u8, &mem[0]));
126126}
127127
128128
129const foos = []fn(var) -> bool { foo1, foo2 };
129const foos = []fn(var) bool { foo1, foo2 };
130130
131fn foo1(arg: var) -> bool { return arg; }
132fn foo2(arg: var) -> bool { return !arg; }
131fn foo1(arg: var) bool { return arg; }
132fn foo2(arg: var) bool { return !arg; }
133133
134134test "array of generic fns" {
135135 assert(foos[0](true));
test/cases/if.zig+3-3
......@@ -4,14 +4,14 @@ test "if statements" {
44 shouldBeEqual(1, 1);
55 firstEqlThird(2, 1, 2);
66}
7fn shouldBeEqual(a: i32, b: i32) {
7fn shouldBeEqual(a: i32, b: i32) void {
88 if (a != b) {
99 unreachable;
1010 } else {
1111 return;
1212 }
1313}
14fn firstEqlThird(a: i32, b: i32, c: i32) {
14fn firstEqlThird(a: i32, b: i32, c: i32) void {
1515 if (a == b) {
1616 unreachable;
1717 } else if (b == c) {
......@@ -27,7 +27,7 @@ fn firstEqlThird(a: i32, b: i32, c: i32) {
2727test "else if expression" {
2828 assert(elseIfExpressionF(1) == 1);
2929}
30fn elseIfExpressionF(c: u8) -> u8 {
30fn elseIfExpressionF(c: u8) u8 {
3131 if (c == 0) {
3232 return 0;
3333 } else if (c == 1) {
test/cases/import/a_namespace.zig+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 {
1111const C = struct {
1212 x: i32,
1313
14 fn d(c: &const C) -> i32 {
14 fn d(c: &const C) i32 {
1515 return c.x;
1616 }
1717};
1818
19fn foo(a: &const A) -> i32 {
19fn foo(a: &const A) i32 {
2020 return a.b.c.d();
2121}
2222
test/cases/ir_block_deps.zig+2-2
......@@ -1,6 +1,6 @@
11const assert = @import("std").debug.assert;
22
3fn foo(id: u64) -> %i32 {
3fn foo(id: u64) %i32 {
44 return switch (id) {
55 1 => getErrInt(),
66 2 => {
......@@ -11,7 +11,7 @@ fn foo(id: u64) -> %i32 {
1111 };
1212}
1313
14fn getErrInt() -> %i32 { return 0; }
14fn getErrInt() %i32 { return 0; }
1515
1616error ItBroke;
1717
test/cases/math.zig+26-26
......@@ -4,7 +4,7 @@ test "division" {
44 testDivision();
55 comptime testDivision();
66}
7fn testDivision() {
7fn testDivision() void {
88 assert(div(u32, 13, 3) == 4);
99 assert(div(f32, 1.0, 2.0) == 0.5);
1010
......@@ -50,16 +50,16 @@ fn testDivision() {
5050 assert(4126227191251978491697987544882340798050766755606969681711 % 10 == 1);
5151 }
5252}
53fn div(comptime T: type, a: T, b: T) -> T {
53fn div(comptime T: type, a: T, b: T) T {
5454 return a / b;
5555}
56fn divExact(comptime T: type, a: T, b: T) -> T {
56fn divExact(comptime T: type, a: T, b: T) T {
5757 return @divExact(a, b);
5858}
59fn divFloor(comptime T: type, a: T, b: T) -> T {
59fn divFloor(comptime T: type, a: T, b: T) T {
6060 return @divFloor(a, b);
6161}
62fn divTrunc(comptime T: type, a: T, b: T) -> T {
62fn divTrunc(comptime T: type, a: T, b: T) T {
6363 return @divTrunc(a, b);
6464}
6565
......@@ -85,7 +85,7 @@ test "@clz" {
8585 comptime testClz();
8686}
8787
88fn testClz() {
88fn testClz() void {
8989 assert(clz(u8(0b00001010)) == 4);
9090 assert(clz(u8(0b10001010)) == 0);
9191 assert(clz(u8(0b00000000)) == 8);
......@@ -93,7 +93,7 @@ fn testClz() {
9393 assert(clz(u128(0x10000000000000000)) == 63);
9494}
9595
96fn clz(x: var) -> usize {
96fn clz(x: var) usize {
9797 return @clz(x);
9898}
9999
......@@ -102,13 +102,13 @@ test "@ctz" {
102102 comptime testCtz();
103103}
104104
105fn testCtz() {
105fn testCtz() void {
106106 assert(ctz(u8(0b10100000)) == 5);
107107 assert(ctz(u8(0b10001010)) == 1);
108108 assert(ctz(u8(0b00000000)) == 8);
109109}
110110
111fn ctz(x: var) -> usize {
111fn ctz(x: var) usize {
112112 return @ctz(x);
113113}
114114
......@@ -132,7 +132,7 @@ test "three expr in a row" {
132132 testThreeExprInARow(false, true);
133133 comptime testThreeExprInARow(false, true);
134134}
135fn testThreeExprInARow(f: bool, t: bool) {
135fn testThreeExprInARow(f: bool, t: bool) void {
136136 assertFalse(f or f or f);
137137 assertFalse(t and t and f);
138138 assertFalse(1 | 2 | 4 != 7);
......@@ -146,7 +146,7 @@ fn testThreeExprInARow(f: bool, t: bool) {
146146 assertFalse(!!false);
147147 assertFalse(i32(7) != --(i32(7)));
148148}
149fn assertFalse(b: bool) {
149fn assertFalse(b: bool) void {
150150 assert(!b);
151151}
152152
......@@ -165,7 +165,7 @@ test "unsigned wrapping" {
165165 testUnsignedWrappingEval(@maxValue(u32));
166166 comptime testUnsignedWrappingEval(@maxValue(u32));
167167}
168fn testUnsignedWrappingEval(x: u32) {
168fn testUnsignedWrappingEval(x: u32) void {
169169 const zero = x +% 1;
170170 assert(zero == 0);
171171 const orig = zero -% 1;
......@@ -176,7 +176,7 @@ test "signed wrapping" {
176176 testSignedWrappingEval(@maxValue(i32));
177177 comptime testSignedWrappingEval(@maxValue(i32));
178178}
179fn testSignedWrappingEval(x: i32) {
179fn testSignedWrappingEval(x: i32) void {
180180 const min_val = x +% 1;
181181 assert(min_val == @minValue(i32));
182182 const max_val = min_val -% 1;
......@@ -187,7 +187,7 @@ test "negation wrapping" {
187187 testNegationWrappingEval(@minValue(i16));
188188 comptime testNegationWrappingEval(@minValue(i16));
189189}
190fn testNegationWrappingEval(x: i16) {
190fn testNegationWrappingEval(x: i16) void {
191191 assert(x == -32768);
192192 const neg = -%x;
193193 assert(neg == -32768);
......@@ -197,12 +197,12 @@ test "unsigned 64-bit division" {
197197 test_u64_div();
198198 comptime test_u64_div();
199199}
200fn test_u64_div() {
200fn test_u64_div() void {
201201 const result = divWithResult(1152921504606846976, 34359738365);
202202 assert(result.quotient == 33554432);
203203 assert(result.remainder == 100663296);
204204}
205fn divWithResult(a: u64, b: u64) -> DivResult {
205fn divWithResult(a: u64, b: u64) DivResult {
206206 return DivResult {
207207 .quotient = a / b,
208208 .remainder = a % b,
......@@ -219,7 +219,7 @@ test "binary not" {
219219 testBinaryNot(0b1010101010101010);
220220}
221221
222fn testBinaryNot(x: u16) {
222fn testBinaryNot(x: u16) void {
223223 assert(~x == 0b0101010101010101);
224224}
225225
......@@ -250,7 +250,7 @@ test "float equality" {
250250 comptime testFloatEqualityImpl(x, y);
251251}
252252
253fn testFloatEqualityImpl(x: f64, y: f64) {
253fn testFloatEqualityImpl(x: f64, y: f64) void {
254254 const y2 = x + 1.0;
255255 assert(y == y2);
256256}
......@@ -285,7 +285,7 @@ test "truncating shift left" {
285285 testShlTrunc(@maxValue(u16));
286286 comptime testShlTrunc(@maxValue(u16));
287287}
288fn testShlTrunc(x: u16) {
288fn testShlTrunc(x: u16) void {
289289 const shifted = x << 1;
290290 assert(shifted == 65534);
291291}
......@@ -294,7 +294,7 @@ test "truncating shift right" {
294294 testShrTrunc(@maxValue(u16));
295295 comptime testShrTrunc(@maxValue(u16));
296296}
297fn testShrTrunc(x: u16) {
297fn testShrTrunc(x: u16) void {
298298 const shifted = x >> 1;
299299 assert(shifted == 32767);
300300}
......@@ -303,7 +303,7 @@ test "exact shift left" {
303303 testShlExact(0b00110101);
304304 comptime testShlExact(0b00110101);
305305}
306fn testShlExact(x: u8) {
306fn testShlExact(x: u8) void {
307307 const shifted = @shlExact(x, 2);
308308 assert(shifted == 0b11010100);
309309}
......@@ -312,7 +312,7 @@ test "exact shift right" {
312312 testShrExact(0b10110100);
313313 comptime testShrExact(0b10110100);
314314}
315fn testShrExact(x: u8) {
315fn testShrExact(x: u8) void {
316316 const shifted = @shrExact(x, 2);
317317 assert(shifted == 0b00101101);
318318}
......@@ -354,7 +354,7 @@ test "xor" {
354354 comptime test_xor();
355355}
356356
357fn test_xor() {
357fn test_xor() void {
358358 assert(0xFF ^ 0x00 == 0xFF);
359359 assert(0xF0 ^ 0x0F == 0xFF);
360360 assert(0xFF ^ 0xF0 == 0x0F);
......@@ -380,9 +380,9 @@ test "f128" {
380380 comptime test_f128();
381381}
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 {
386386 assert(@sizeOf(f128) == 16);
387387 assert(make_f128(1.0) == 1.0);
388388 assert(make_f128(1.0) != 1.1);
......@@ -392,6 +392,6 @@ fn test_f128() {
392392 should_not_be_zero(1.0);
393393}
394394
395fn should_not_be_zero(x: f128) {
395fn should_not_be_zero(x: f128) void {
396396 assert(x != 0.0);
397397}
\ No newline at end of file
test/cases/misc.zig+39-30
......@@ -6,7 +6,7 @@ const builtin = @import("builtin");
66// normal comment
77/// this is a documentation comment
88/// doc comment line 2
9fn emptyFunctionWithComments() {}
9fn emptyFunctionWithComments() void {}
1010
1111test "empty function with comments" {
1212 emptyFunctionWithComments();
......@@ -16,7 +16,7 @@ comptime {
1616 @export("disabledExternFn", disabledExternFn, builtin.GlobalLinkage.Internal);
1717}
1818
19extern fn disabledExternFn() {
19extern fn disabledExternFn() void {
2020}
2121
2222test "call disabled extern fn" {
......@@ -104,7 +104,7 @@ test "short circuit" {
104104 comptime testShortCircuit(false, true);
105105}
106106
107fn testShortCircuit(f: bool, t: bool) {
107fn testShortCircuit(f: bool, t: bool) void {
108108 var hit_1 = f;
109109 var hit_2 = f;
110110 var hit_3 = f;
......@@ -134,11 +134,11 @@ fn testShortCircuit(f: bool, t: bool) {
134134test "truncate" {
135135 assert(testTruncate(0x10fd) == 0xfd);
136136}
137fn testTruncate(x: u32) -> u8 {
137fn testTruncate(x: u32) u8 {
138138 return @truncate(u8, x);
139139}
140140
141fn first4KeysOfHomeRow() -> []const u8 {
141fn first4KeysOfHomeRow() []const u8 {
142142 return "aoeu";
143143}
144144
......@@ -193,7 +193,7 @@ test "constant equal function pointers" {
193193 assert(comptime x: {break :x emptyFn == alias;});
194194}
195195
196fn emptyFn() {}
196fn emptyFn() void {}
197197
198198
199199test "hex escape" {
......@@ -262,10 +262,10 @@ test "generic malloc free" {
262262 memFree(u8, a);
263263}
264264const some_mem : [100]u8 = undefined;
265fn memAlloc(comptime T: type, n: usize) -> %[]T {
265fn memAlloc(comptime T: type, n: usize) %[]T {
266266 return @ptrCast(&T, &some_mem[0])[0..n];
267267}
268fn memFree(comptime T: type, memory: []T) { }
268fn memFree(comptime T: type, memory: []T) void { }
269269
270270
271271test "cast undefined" {
......@@ -273,22 +273,22 @@ test "cast undefined" {
273273 const slice = ([]const u8)(array);
274274 testCastUndefined(slice);
275275}
276fn testCastUndefined(x: []const u8) {}
276fn testCastUndefined(x: []const u8) void {}
277277
278278
279279test "cast small unsigned to larger signed" {
280280 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
281281 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
282282}
283fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { return x; }
284fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { return x; }
283fn castSmallUnsignedToLargerSigned1(x: u8) i16 { return x; }
284fn castSmallUnsignedToLargerSigned2(x: u16) i64 { return x; }
285285
286286
287287test "implicit cast after unreachable" {
288288 assert(outer() == 1234);
289289}
290fn inner() -> i32 { return 1234; }
291fn outer() -> i64 {
290fn inner() i32 { return 1234; }
291fn outer() i64 {
292292 return inner();
293293}
294294
......@@ -307,11 +307,11 @@ test "call result of if else expression" {
307307 assert(mem.eql(u8, f2(true), "a"));
308308 assert(mem.eql(u8, f2(false), "b"));
309309}
310fn f2(x: bool) -> []const u8 {
310fn f2(x: bool) []const u8 {
311311 return (if (x) fA else fB)();
312312}
313fn fA() -> []const u8 { return "a"; }
314fn fB() -> []const u8 { return "b"; }
313fn fA() []const u8 { return "a"; }
314fn fB() []const u8 { return "b"; }
315315
316316
317317test "const expression eval handling of variables" {
......@@ -338,7 +338,7 @@ const Test3Point = struct {
338338};
339339const test3_foo = Test3Foo { .Three = Test3Point {.x = 3, .y = 4}};
340340const test3_bar = Test3Foo { .Two = 13};
341fn test3_1(f: &const Test3Foo) {
341fn test3_1(f: &const Test3Foo) void {
342342 switch (*f) {
343343 Test3Foo.Three => |pt| {
344344 assert(pt.x == 3);
......@@ -347,7 +347,7 @@ fn test3_1(f: &const Test3Foo) {
347347 else => unreachable,
348348 }
349349}
350fn test3_2(f: &const Test3Foo) {
350fn test3_2(f: &const Test3Foo) void {
351351 switch (*f) {
352352 Test3Foo.Two => |x| {
353353 assert(x == 13);
......@@ -367,7 +367,7 @@ const single_quote = '\'';
367367test "take address of parameter" {
368368 testTakeAddressOfParameter(12.34);
369369}
370fn testTakeAddressOfParameter(f: f32) {
370fn testTakeAddressOfParameter(f: f32) void {
371371 const f_ptr = &f;
372372 assert(*f_ptr == 12.34);
373373}
......@@ -378,7 +378,7 @@ test "pointer comparison" {
378378 const b = &a;
379379 assert(ptrEql(b, b));
380380}
381fn ptrEql(a: &const []const u8, b: &const []const u8) -> bool {
381fn ptrEql(a: &const []const u8, b: &const []const u8) bool {
382382 return a == b;
383383}
384384
......@@ -419,12 +419,12 @@ test "cast slice to u8 slice" {
419419test "pointer to void return type" {
420420 testPointerToVoidReturnType() catch unreachable;
421421}
422fn testPointerToVoidReturnType() -> %void {
422fn testPointerToVoidReturnType() %void {
423423 const a = testPointerToVoidReturnType2();
424424 return *a;
425425}
426426const test_pointer_to_void_return_type_x = void{};
427fn testPointerToVoidReturnType2() -> &const void {
427fn testPointerToVoidReturnType2() &const void {
428428 return &test_pointer_to_void_return_type_x;
429429}
430430
......@@ -444,7 +444,7 @@ test "array 2D const double ptr" {
444444 testArray2DConstDoublePtr(&rect_2d_vertexes[0][0]);
445445}
446446
447fn testArray2DConstDoublePtr(ptr: &const f32) {
447fn testArray2DConstDoublePtr(ptr: &const f32) void {
448448 assert(ptr[0] == 1.0);
449449 assert(ptr[1] == 2.0);
450450}
......@@ -481,7 +481,7 @@ test "@typeId" {
481481 assert(@typeId(@typeOf(AUnionEnum.One)) == Tid.Enum);
482482 assert(@typeId(AUnionEnum) == Tid.Union);
483483 assert(@typeId(AUnion) == Tid.Union);
484 assert(@typeId(fn()) == Tid.Fn);
484 assert(@typeId(fn()void) == Tid.Fn);
485485 assert(@typeId(@typeOf(builtin)) == Tid.Namespace);
486486 assert(@typeId(@typeOf(x: {break :x this;})) == Tid.Block);
487487 // TODO bound fn
......@@ -536,7 +536,7 @@ var global_ptr = &gdt[0];
536536// can't really run this test but we can make sure it has no compile error
537537// and generates code
538538const vram = @intToPtr(&volatile u8, 0x20000000)[0..0x8000];
539export fn writeToVRam() {
539export fn writeToVRam() void {
540540 vram[0] = 'X';
541541}
542542
......@@ -556,7 +556,7 @@ test "variable is allowed to be a pointer to an opaque type" {
556556 var x: i32 = 1234;
557557 _ = hereIsAnOpaqueType(@ptrCast(&OpaqueA, &x));
558558}
559fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {
559fn hereIsAnOpaqueType(ptr: &OpaqueA) &OpaqueA {
560560 var a = ptr;
561561 return a;
562562}
......@@ -565,7 +565,7 @@ test "comptime if inside runtime while which unconditionally breaks" {
565565 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
566566 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
567567}
568fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) {
568fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) void {
569569 while (cond) {
570570 if (false) { }
571571 break;
......@@ -583,7 +583,7 @@ test "struct inside function" {
583583 comptime testStructInFn();
584584}
585585
586fn testStructInFn() {
586fn testStructInFn() void {
587587 const BlockKind = u32;
588588
589589 const Block = struct {
......@@ -597,10 +597,10 @@ fn testStructInFn() {
597597 assert(block.kind == 1235);
598598}
599599
600fn fnThatClosesOverLocalConst() -> type {
600fn fnThatClosesOverLocalConst() type {
601601 const c = 1;
602602 return struct {
603 fn g() -> i32 { return c; }
603 fn g() i32 { return c; }
604604 };
605605}
606606
......@@ -608,3 +608,12 @@ test "function closes over local const" {
608608 const x = fnThatClosesOverLocalConst().g();
609609 assert(x == 1);
610610}
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" {
4848 comptime maybeReturnImpl();
4949}
5050
51fn maybeReturnImpl() {
51fn maybeReturnImpl() void {
5252 assert(??foo(1235));
5353 if (foo(null) != null)
5454 unreachable;
5555 assert(!??foo(1234));
5656}
5757
58fn foo(x: ?i32) -> ?bool {
58fn foo(x: ?i32) ?bool {
5959 const value = x ?? return null;
6060 return value > 1234;
6161}
......@@ -64,7 +64,7 @@ fn foo(x: ?i32) -> ?bool {
6464test "if var maybe pointer" {
6565 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
6666}
67fn shouldBeAPlus1(p: &const Particle) -> u64 {
67fn shouldBeAPlus1(p: &const Particle) u64 {
6868 var maybe_particle: ?Particle = *p;
6969 if (maybe_particle) |*particle| {
7070 particle.a += 1;
......@@ -100,7 +100,7 @@ const here_is_a_null_literal = SillyStruct {
100100test "test null runtime" {
101101 testTestNullRuntime(null);
102102}
103fn testTestNullRuntime(x: ?i32) {
103fn testTestNullRuntime(x: ?i32) void {
104104 assert(x == null);
105105 assert(!(x != null));
106106}
......@@ -110,12 +110,12 @@ test "nullable void" {
110110 comptime nullableVoidImpl();
111111}
112112
113fn nullableVoidImpl() {
113fn nullableVoidImpl() void {
114114 assert(bar(null) == null);
115115 assert(bar({}) != null);
116116}
117117
118fn bar(x: ?void) -> ?void {
118fn bar(x: ?void) ?void {
119119 if (x) |_| {
120120 return {};
121121 } else {
test/cases/pub_enum/index.zig+1-1
......@@ -4,7 +4,7 @@ const assert = @import("std").debug.assert;
44test "pub enum" {
55 pubEnumTest(other.APubEnum.Two);
66}
7fn pubEnumTest(foo: other.APubEnum) {
7fn pubEnumTest(foo: other.APubEnum) void {
88 assert(foo == other.APubEnum.Two);
99}
1010
test/cases/ref_var_in_if_after_if_2nd_switch_prong.zig+2-2
......@@ -16,7 +16,7 @@ const Num = enum {
1616 Two,
1717};
1818
19fn foo(c: bool, k: Num, c2: bool, b: []const u8) {
19fn foo(c: bool, k: Num, c2: bool, b: []const u8) void {
2020 switch (k) {
2121 Num.Two => {},
2222 Num.One => {
......@@ -31,7 +31,7 @@ fn foo(c: bool, k: Num, c2: bool, b: []const u8) {
3131 }
3232}
3333
34fn a(x: []const u8) {
34fn a(x: []const u8) void {
3535 assert(mem.eql(u8, x, "aoeu"));
3636 ok = true;
3737}
test/cases/reflection.zig+2-2
......@@ -22,8 +22,8 @@ test "reflection: function return type, var args, and param types" {
2222 }
2323}
2424
25fn dummy(a: bool, b: i32, c: f32) -> i32 { return 1234; }
26fn dummy_varargs(args: ...) {}
25fn dummy(a: bool, b: i32, c: f32) i32 { return 1234; }
26fn dummy_varargs(args: ...) void {}
2727
2828test "reflection: struct member types and names" {
2929 comptime {
test/cases/slice.zig+3-3
......@@ -17,12 +17,12 @@ test "slice child property" {
1717 assert(@typeOf(slice).Child == i32);
1818}
1919
20test "debug safety lets us slice from len..len" {
20test "runtime safety lets us slice from len..len" {
2121 var an_array = []u8{1, 2, 3};
2222 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
2323}
2424
25fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) -> []u8 {
25fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
2626 return a_slice[start..end];
2727}
2828
......@@ -31,6 +31,6 @@ test "implicitly cast array of size 0 to slice" {
3131 assertLenIsZero(msg);
3232}
3333
34fn assertLenIsZero(msg: []const u8) {
34fn assertLenIsZero(msg: []const u8) void {
3535 assert(msg.len == 0);
3636}
test/cases/struct.zig+17-17
......@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22const builtin = @import("builtin");
33
44const StructWithNoFields = struct {
5 fn add(a: i32, b: i32) -> i32 { return a + b; }
5 fn add(a: i32, b: i32) i32 { return a + b; }
66};
77const empty_global_instance = StructWithNoFields {};
88
......@@ -14,7 +14,7 @@ test "call struct static method" {
1414test "return empty struct instance" {
1515 _ = returnEmptyStructInstance();
1616}
17fn returnEmptyStructInstance() -> StructWithNoFields {
17fn returnEmptyStructInstance() StructWithNoFields {
1818 return empty_global_instance;
1919}
2020
......@@ -54,10 +54,10 @@ const StructFoo = struct {
5454 b : bool,
5555 c : f32,
5656};
57fn testFoo(foo: &const StructFoo) {
57fn testFoo(foo: &const StructFoo) void {
5858 assert(foo.b);
5959}
60fn testMutation(foo: &StructFoo) {
60fn testMutation(foo: &StructFoo) void {
6161 foo.c = 100;
6262}
6363
......@@ -95,7 +95,7 @@ test "struct byval assign" {
9595 assert(foo2.a == 1234);
9696}
9797
98fn structInitializer() {
98fn structInitializer() void {
9999 const val = Val { .x = 42 };
100100 assert(val.x == 42);
101101}
......@@ -106,12 +106,12 @@ test "fn call of struct field" {
106106}
107107
108108const Foo = struct {
109 ptr: fn() -> i32,
109 ptr: fn() i32,
110110};
111111
112fn aFunc() -> i32 { return 13; }
112fn aFunc() i32 { return 13; }
113113
114fn callStructField(foo: &const Foo) -> i32 {
114fn callStructField(foo: &const Foo) i32 {
115115 return foo.ptr();
116116}
117117
......@@ -124,7 +124,7 @@ test "store member function in variable" {
124124}
125125const MemberFnTestFoo = struct {
126126 x: i32,
127 fn member(foo: &const MemberFnTestFoo) -> i32 { return foo.x; }
127 fn member(foo: &const MemberFnTestFoo) i32 { return foo.x; }
128128};
129129
130130
......@@ -140,7 +140,7 @@ test "member functions" {
140140}
141141const MemberFnRand = struct {
142142 seed: u32,
143 pub fn getSeed(r: &const MemberFnRand) -> u32 {
143 pub fn getSeed(r: &const MemberFnRand) u32 {
144144 return r.seed;
145145 }
146146};
......@@ -153,7 +153,7 @@ const Bar = struct {
153153 x: i32,
154154 y: i32,
155155};
156fn makeBar(x: i32, y: i32) -> Bar {
156fn makeBar(x: i32, y: i32) Bar {
157157 return Bar {
158158 .x = x,
159159 .y = y,
......@@ -165,7 +165,7 @@ test "empty struct method call" {
165165 assert(es.method() == 1234);
166166}
167167const EmptyStruct = struct {
168 fn method(es: &const EmptyStruct) -> i32 {
168 fn method(es: &const EmptyStruct) i32 {
169169 return 1234;
170170 }
171171};
......@@ -175,14 +175,14 @@ test "return empty struct from fn" {
175175 _ = testReturnEmptyStructFromFn();
176176}
177177const EmptyStruct2 = struct {};
178fn testReturnEmptyStructFromFn() -> EmptyStruct2 {
178fn testReturnEmptyStructFromFn() EmptyStruct2 {
179179 return EmptyStruct2 {};
180180}
181181
182182test "pass slice of empty struct to fn" {
183183 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
184184}
185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) -> usize {
185fn testPassSliceOfEmptyStructToFn(slice: []const EmptyStruct2) usize {
186186 return slice.len;
187187}
188188
......@@ -229,15 +229,15 @@ test "bit field access" {
229229 assert(data.b == 3);
230230}
231231
232fn getA(data: &const BitField1) -> u3 {
232fn getA(data: &const BitField1) u3 {
233233 return data.a;
234234}
235235
236fn getB(data: &const BitField1) -> u3 {
236fn getB(data: &const BitField1) u3 {
237237 return data.b;
238238}
239239
240fn getC(data: &const BitField1) -> u2 {
240fn getC(data: &const BitField1) u2 {
241241 return data.c;
242242}
243243
test/cases/switch.zig+15-15
......@@ -4,7 +4,7 @@ test "switch with numbers" {
44 testSwitchWithNumbers(13);
55}
66
7fn testSwitchWithNumbers(x: u32) {
7fn testSwitchWithNumbers(x: u32) void {
88 const result = switch (x) {
99 1, 2, 3, 4 ... 8 => false,
1010 13 => true,
......@@ -20,7 +20,7 @@ test "switch with all ranges" {
2020 assert(testSwitchWithAllRanges(301, 6) == 6);
2121}
2222
23fn testSwitchWithAllRanges(x: u32, y: u32) -> u32 {
23fn testSwitchWithAllRanges(x: u32, y: u32) u32 {
2424 return switch (x) {
2525 0 ... 100 => 1,
2626 101 ... 200 => 2,
......@@ -53,7 +53,7 @@ const Fruit = enum {
5353 Orange,
5454 Banana,
5555};
56fn nonConstSwitchOnEnum(fruit: Fruit) {
56fn nonConstSwitchOnEnum(fruit: Fruit) void {
5757 switch (fruit) {
5858 Fruit.Apple => unreachable,
5959 Fruit.Orange => {},
......@@ -65,7 +65,7 @@ fn nonConstSwitchOnEnum(fruit: Fruit) {
6565test "switch statement" {
6666 nonConstSwitch(SwitchStatmentFoo.C);
6767}
68fn nonConstSwitch(foo: SwitchStatmentFoo) {
68fn nonConstSwitch(foo: SwitchStatmentFoo) void {
6969 const val = switch (foo) {
7070 SwitchStatmentFoo.A => i32(1),
7171 SwitchStatmentFoo.B => 2,
......@@ -92,7 +92,7 @@ const SwitchProngWithVarEnum = union(enum) {
9292 Two: f32,
9393 Meh: void,
9494};
95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) {
95fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) void {
9696 switch(*a) {
9797 SwitchProngWithVarEnum.One => |x| {
9898 assert(x == 13);
......@@ -111,7 +111,7 @@ test "switch on enum using pointer capture" {
111111 comptime testSwitchEnumPtrCapture();
112112}
113113
114fn testSwitchEnumPtrCapture() {
114fn testSwitchEnumPtrCapture() void {
115115 var value = SwitchProngWithVarEnum { .One = 1234 };
116116 switch (value) {
117117 SwitchProngWithVarEnum.One => |*x| *x += 1,
......@@ -131,7 +131,7 @@ test "switch with multiple expressions" {
131131 };
132132 assert(x == 2);
133133}
134fn returnsFive() -> i32 {
134fn returnsFive() i32 {
135135 return 5;
136136}
137137
......@@ -144,7 +144,7 @@ const Number = union(enum) {
144144
145145const number = Number { .Three = 1.23 };
146146
147fn returnsFalse() -> bool {
147fn returnsFalse() bool {
148148 switch (number) {
149149 Number.One => |x| return x > 1234,
150150 Number.Two => |x| return x == 'a',
......@@ -160,7 +160,7 @@ test "switch on type" {
160160 assert(!trueIfBoolFalseOtherwise(i32));
161161}
162162
163fn trueIfBoolFalseOtherwise(comptime T: type) -> bool {
163fn trueIfBoolFalseOtherwise(comptime T: type) bool {
164164 return switch (T) {
165165 bool => true,
166166 else => false,
......@@ -172,7 +172,7 @@ test "switch handles all cases of number" {
172172 comptime testSwitchHandleAllCases();
173173}
174174
175fn testSwitchHandleAllCases() {
175fn testSwitchHandleAllCases() void {
176176 assert(testSwitchHandleAllCasesExhaustive(0) == 3);
177177 assert(testSwitchHandleAllCasesExhaustive(1) == 2);
178178 assert(testSwitchHandleAllCasesExhaustive(2) == 1);
......@@ -185,7 +185,7 @@ fn testSwitchHandleAllCases() {
185185 assert(testSwitchHandleAllCasesRange(230) == 3);
186186}
187187
188fn testSwitchHandleAllCasesExhaustive(x: u2) -> u2 {
188fn testSwitchHandleAllCasesExhaustive(x: u2) u2 {
189189 return switch (x) {
190190 0 => u2(3),
191191 1 => 2,
......@@ -194,7 +194,7 @@ fn testSwitchHandleAllCasesExhaustive(x: u2) -> u2 {
194194 };
195195}
196196
197fn testSwitchHandleAllCasesRange(x: u8) -> u8 {
197fn testSwitchHandleAllCasesRange(x: u8) u8 {
198198 return switch (x) {
199199 0 ... 100 => u8(0),
200200 101 ... 200 => 1,
......@@ -209,12 +209,12 @@ test "switch all prongs unreachable" {
209209 comptime testAllProngsUnreachable();
210210}
211211
212fn testAllProngsUnreachable() {
212fn testAllProngsUnreachable() void {
213213 assert(switchWithUnreachable(1) == 2);
214214 assert(switchWithUnreachable(2) == 10);
215215}
216216
217fn switchWithUnreachable(x: i32) -> i32 {
217fn switchWithUnreachable(x: i32) i32 {
218218 while (true) {
219219 switch (x) {
220220 1 => return 2,
......@@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) -> i32 {
225225 return 10;
226226}
227227
228fn return_a_number() -> %i32 {
228fn return_a_number() %i32 {
229229 return 1;
230230}
231231
test/cases/switch_prong_err_enum.zig+2-2
......@@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
22
33var read_count: u64 = 0;
44
5fn readOnce() -> %u64 {
5fn readOnce() %u64 {
66 read_count += 1;
77 return read_count;
88}
......@@ -14,7 +14,7 @@ const FormValue = union(enum) {
1414 Other: bool,
1515};
1616
17fn doThing(form_id: u64) -> %FormValue {
17fn doThing(form_id: u64) %FormValue {
1818 return switch (form_id) {
1919 17 => FormValue { .Address = try readOnce() },
2020 else => error.InvalidDebugInfo,
test/cases/switch_prong_implicit_cast.zig+1-1
......@@ -7,7 +7,7 @@ const FormValue = union(enum) {
77
88error Whatever;
99
10fn foo(id: u64) -> %FormValue {
10fn foo(id: u64) %FormValue {
1111 return switch (id) {
1212 2 => FormValue { .Two = true },
1313 1 => FormValue { .One = {} },
test/cases/syntax.zig+11-11
......@@ -3,18 +3,18 @@
33const struct_trailing_comma = struct { x: i32, y: i32, };
44const struct_no_comma = struct { x: i32, y: i32 };
55const 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
88const enum_no_comma = enum { A, B };
99const enum_no_comma_type = enum { A, B: i32 };
1010
11fn container_init() {
11fn container_init() void {
1212 const S = struct { x: i32, y: i32 };
1313 _ = S { .x = 1, .y = 2 };
1414 _ = S { .x = 1, .y = 2, };
1515}
1616
17fn switch_cases(x: i32) {
17fn switch_cases(x: i32) void {
1818 switch (x) {
1919 1,2,3 => {},
2020 4,5, => {},
......@@ -23,7 +23,7 @@ fn switch_cases(x: i32) {
2323 }
2424}
2525
26fn switch_prongs(x: i32) {
26fn switch_prongs(x: i32) void {
2727 switch (x) {
2828 0 => {},
2929 else => {},
......@@ -34,21 +34,21 @@ fn switch_prongs(x: i32) {
3434 }
3535}
3636
37const fn_no_comma = fn(i32, i32);
38const fn_trailing_comma = fn(i32, i32,);
39const fn_vararg_trailing_comma = fn(i32, i32, ...,);
37const fn_no_comma = fn(i32, i32)void;
38const fn_trailing_comma = fn(i32, i32,)void;
39const fn_vararg_trailing_comma = fn(i32, i32, ...,)void;
4040
41fn fn_calls() {
42 fn add(x: i32, y: i32,) -> i32 { x + y };
41fn fn_calls() void {
42 fn add(x: i32, y: i32,) i32 { x + y };
4343 _ = add(1, 2);
4444 _ = add(1, 2,);
4545
46 fn swallow(x: ...,) {};
46 fn swallow(x: ...,) void {};
4747 _ = swallow(1,2,3,);
4848 _ = swallow();
4949}
5050
51fn asm_lists() {
51fn asm_lists() void {
5252 if (false) { // Build AST but don't analyze
5353 asm ("not real assembly"
5454 :[a] "x" (x),);
test/cases/this.zig+4-4
......@@ -2,24 +2,24 @@ const assert = @import("std").debug.assert;
22
33const module = this;
44
5fn Point(comptime T: type) -> type {
5fn Point(comptime T: type) type {
66 return struct {
77 const Self = this;
88 x: T,
99 y: T,
1010
11 fn addOne(self: &Self) {
11 fn addOne(self: &Self) void {
1212 self.x += 1;
1313 self.y += 1;
1414 }
1515 };
1616}
1717
18fn add(x: i32, y: i32) -> i32 {
18fn add(x: i32, y: i32) i32 {
1919 return x + y;
2020}
2121
22fn factorial(x: i32) -> i32 {
22fn factorial(x: i32) i32 {
2323 const selfFn = this;
2424 return if (x == 0) 1 else x * selfFn(x - 1);
2525}
test/cases/try.zig+3-3
......@@ -6,7 +6,7 @@ test "try on error union" {
66
77}
88
9fn tryOnErrorUnionImpl() {
9fn tryOnErrorUnionImpl() void {
1010 const x = if (returnsTen()) |val|
1111 val + 1
1212 else |err| switch (err) {
......@@ -20,7 +20,7 @@ fn tryOnErrorUnionImpl() {
2020error ItBroke;
2121error NoMem;
2222error CrappedOut;
23fn returnsTen() -> %i32 {
23fn returnsTen() %i32 {
2424 return 10;
2525}
2626
......@@ -32,7 +32,7 @@ test "try without vars" {
3232 assert(result2 == 1);
3333}
3434
35fn failIfTrue(ok: bool) -> %void {
35fn failIfTrue(ok: bool) %void {
3636 if (ok) {
3737 return error.ItBroke;
3838 } else {
test/cases/undefined.zig+3-3
......@@ -1,7 +1,7 @@
11const assert = @import("std").debug.assert;
22const mem = @import("std").mem;
33
4fn initStaticArray() -> [10]i32 {
4fn initStaticArray() [10]i32 {
55 var array: [10]i32 = undefined;
66 array[0] = 1;
77 array[4] = 2;
......@@ -27,12 +27,12 @@ test "init static array to undefined" {
2727const Foo = struct {
2828 x: i32,
2929
30 fn setFooXMethod(foo: &Foo) {
30 fn setFooXMethod(foo: &Foo) void {
3131 foo.x = 3;
3232 }
3333};
3434
35fn setFooX(foo: &Foo) {
35fn setFooX(foo: &Foo) void {
3636 foo.x = 2;
3737}
3838
test/cases/union.zig+36-9
......@@ -55,11 +55,11 @@ test "init union with runtime value" {
5555 assert(foo.int == 42);
5656}
5757
58fn setFloat(foo: &Foo, x: f64) {
58fn setFloat(foo: &Foo, x: f64) void {
5959 *foo = Foo { .float = x };
6060}
6161
62fn setInt(foo: &Foo, x: i32) {
62fn setInt(foo: &Foo, x: i32) void {
6363 *foo = Foo { .int = x };
6464}
6565
......@@ -92,11 +92,11 @@ test "union with specified enum tag" {
9292 comptime doTest();
9393}
9494
95fn doTest() {
95fn doTest() void {
9696 assert(bar(Payload {.A = 1234}) == -10);
9797}
9898
99fn bar(value: &const Payload) -> i32 {
99fn bar(value: &const Payload) i32 {
100100 assert(Letter(*value) == Letter.A);
101101 return switch (*value) {
102102 Payload.A => |x| return x - 1244,
......@@ -135,7 +135,7 @@ test "union(enum(u32)) with specified and unspecified tag values" {
135135 comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2 { .C = 123} );
136136}
137137
138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) {
138fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: &const MultipleChoice2) void {
139139 assert(u32(@TagType(MultipleChoice2)(*x)) == 60);
140140 assert(1123 == switch (*x) {
141141 MultipleChoice2.A => 1,
......@@ -187,7 +187,7 @@ test "cast union to tag type of union" {
187187 comptime testCastUnionToTagType(TheUnion {.B = 1234});
188188}
189189
190fn testCastUnionToTagType(x: &const TheUnion) {
190fn testCastUnionToTagType(x: &const TheUnion) void {
191191 assert(TheTag(*x) == TheTag.B);
192192}
193193
......@@ -203,7 +203,7 @@ test "implicit cast union to its tag type" {
203203 assert(x == Letter2.B);
204204 giveMeLetterB(x);
205205}
206fn giveMeLetterB(x: Letter2) {
206fn giveMeLetterB(x: Letter2) void {
207207 assert(x == Value2.B);
208208}
209209
......@@ -216,7 +216,7 @@ const TheUnion2 = union(enum) {
216216 Item2: i32,
217217};
218218
219fn assertIsTheUnion2Item1(value: &const TheUnion2) {
219fn assertIsTheUnion2Item1(value: &const TheUnion2) void {
220220 assert(*value == TheUnion2.Item1);
221221}
222222
......@@ -232,6 +232,33 @@ test "constant packed union" {
232232 });
233233}
234234
235fn testConstPackedUnion(expected_tokens: []const PackThis) {
235fn testConstPackedUnion(expected_tokens: []const PackThis) void {
236236 assert(expected_tokens[0].StringLiteral == 1);
237237}
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 @@
11const assert = @import("std").debug.assert;
22
3fn add(args: ...) -> i32 {
3fn add(args: ...) i32 {
44 var sum = i32(0);
55 {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
66 sum += args[i];
......@@ -14,7 +14,7 @@ test "add arbitrary args" {
1414 assert(add() == 0);
1515}
1616
17fn readFirstVarArg(args: ...) {
17fn readFirstVarArg(args: ...) void {
1818 const value = args[0];
1919}
2020
......@@ -28,7 +28,7 @@ test "pass args directly" {
2828 assert(addSomeStuff() == 0);
2929}
3030
31fn addSomeStuff(args: ...) -> i32 {
31fn addSomeStuff(args: ...) i32 {
3232 return add(args);
3333}
3434
......@@ -45,7 +45,7 @@ test "runtime parameter before var args" {
4545 //}
4646}
4747
48fn extraFn(extra: u32, args: ...) -> usize {
48fn extraFn(extra: u32, args: ...) usize {
4949 if (args.len >= 1) {
5050 assert(args[0] == false);
5151 }
......@@ -56,10 +56,10 @@ fn extraFn(extra: u32, args: ...) -> usize {
5656}
5757
5858
59const foos = []fn(...) -> bool { foo1, foo2 };
59const foos = []fn(...) bool { foo1, foo2 };
6060
61fn foo1(args: ...) -> bool { return true; }
62fn foo2(args: ...) -> bool { return false; }
61fn foo1(args: ...) bool { return true; }
62fn foo2(args: ...) bool { return false; }
6363
6464test "array of var args functions" {
6565 assert(foos[0]());
......@@ -73,9 +73,17 @@ test "pass array and slice of same array to var args should have same pointers"
7373 return assertSlicePtrsEql(array, slice);
7474}
7575
76fn assertSlicePtrsEql(args: ...) {
76fn assertSlicePtrsEql(args: ...) void {
7777 const s1 = ([]const u8)(args[0]);
7878 const s2 = args[1];
7979 assert(s1.ptr == s2.ptr);
8080}
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" {
88 assert(i == 4);
99 assert(whileLoop1() == 1);
1010}
11fn whileLoop1() -> i32 {
11fn whileLoop1() i32 {
1212 return whileLoop2();
1313}
14fn whileLoop2() -> i32 {
14fn whileLoop2() i32 {
1515 while (true) {
1616 return 1;
1717 }
......@@ -20,10 +20,10 @@ test "static eval while" {
2020 assert(static_eval_while_number == 1);
2121}
2222const static_eval_while_number = staticWhileLoop1();
23fn staticWhileLoop1() -> i32 {
23fn staticWhileLoop1() i32 {
2424 return whileLoop2();
2525}
26fn staticWhileLoop2() -> i32 {
26fn staticWhileLoop2() i32 {
2727 while (true) {
2828 return 1;
2929 }
......@@ -34,7 +34,7 @@ test "continue and break" {
3434 assert(continue_and_break_counter == 8);
3535}
3636var continue_and_break_counter: i32 = 0;
37fn runContinueAndBreakTest() {
37fn runContinueAndBreakTest() void {
3838 var i : i32 = 0;
3939 while (true) {
4040 continue_and_break_counter += 2;
......@@ -50,7 +50,7 @@ fn runContinueAndBreakTest() {
5050test "return with implicit cast from while loop" {
5151 returnWithImplicitCastFromWhileLoopTest() catch unreachable;
5252}
53fn returnWithImplicitCastFromWhileLoopTest() -> %void {
53fn returnWithImplicitCastFromWhileLoopTest() %void {
5454 while (true) {
5555 return;
5656 }
......@@ -117,7 +117,7 @@ test "while with error union condition" {
117117
118118var numbers_left: i32 = undefined;
119119error OutOfNumbers;
120fn getNumberOrErr() -> %i32 {
120fn getNumberOrErr() %i32 {
121121 return if (numbers_left == 0)
122122 error.OutOfNumbers
123123 else x: {
......@@ -125,7 +125,7 @@ fn getNumberOrErr() -> %i32 {
125125 break :x numbers_left;
126126 };
127127}
128fn getNumberOrNull() -> ?i32 {
128fn getNumberOrNull() ?i32 {
129129 return if (numbers_left == 0)
130130 null
131131 else x: {
......@@ -181,7 +181,7 @@ test "break from outer while loop" {
181181 comptime testBreakOuter();
182182}
183183
184fn testBreakOuter() {
184fn testBreakOuter() void {
185185 outer: while (true) {
186186 while (true) {
187187 break :outer;
......@@ -194,7 +194,7 @@ test "continue outer while loop" {
194194 comptime testContinueOuter();
195195}
196196
197fn testContinueOuter() {
197fn testContinueOuter() void {
198198 var i: usize = 0;
199199 outer: while (i < 10) : (i += 1) {
200200 while (true) {
......@@ -203,10 +203,10 @@ fn testContinueOuter() {
203203 }
204204}
205205
206fn returnNull() -> ?i32 { return null; }
207fn returnMaybe(x: i32) -> ?i32 { return x; }
206fn returnNull() ?i32 { return null; }
207fn returnMaybe(x: i32) ?i32 { return x; }
208208error YouWantedAnError;
209fn returnError() -> %i32 { return error.YouWantedAnError; }
210fn returnSuccess(x: i32) -> %i32 { return x; }
211fn returnFalse() -> bool { return false; }
212fn returnTrue() -> bool { return true; }
209fn returnError() %i32 { return error.YouWantedAnError; }
210fn returnSuccess(x: i32) %i32 { return x; }
211fn returnFalse() bool { return false; }
212fn returnTrue() bool { return true; }
test/compare_output.zig+37-37
......@@ -1,10 +1,10 @@
11const os = @import("std").os;
22const tests = @import("tests.zig");
33
4pub fn addCases(cases: &tests.CompareOutputContext) {
4pub fn addCases(cases: &tests.CompareOutputContext) void {
55 cases.addC("hello world with libc",
66 \\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 {
88 \\ _ = c.puts(c"Hello, world!");
99 \\ return 0;
1010 \\}
......@@ -15,13 +15,13 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
1515 \\use @import("std").io;
1616 \\use @import("foo.zig");
1717 \\
18 \\pub fn main() -> %void {
18 \\pub fn main() %void {
1919 \\ privateFunction();
2020 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
2121 \\ stdout.print("OK 2\n") catch unreachable;
2222 \\}
2323 \\
24 \\fn privateFunction() {
24 \\fn privateFunction() void {
2525 \\ printText();
2626 \\}
2727 , "OK 1\nOK 2\n");
......@@ -31,12 +31,12 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
3131 \\
3232 \\// purposefully conflicting function with main.zig
3333 \\// but it's private so it should be OK
34 \\fn privateFunction() {
34 \\fn privateFunction() void {
3535 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
3636 \\ stdout.print("OK 1\n") catch unreachable;
3737 \\}
3838 \\
39 \\pub fn printText() {
39 \\pub fn printText() void {
4040 \\ privateFunction();
4141 \\}
4242 );
......@@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
4949 \\use @import("foo.zig");
5050 \\use @import("bar.zig");
5151 \\
52 \\pub fn main() -> %void {
52 \\pub fn main() %void {
5353 \\ foo_function();
5454 \\ bar_function();
5555 \\}
......@@ -57,7 +57,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
5757
5858 tc.addSourceFile("foo.zig",
5959 \\use @import("std").io;
60 \\pub fn foo_function() {
60 \\pub fn foo_function() void {
6161 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
6262 \\ stdout.print("OK\n") catch unreachable;
6363 \\}
......@@ -67,7 +67,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
6767 \\use @import("other.zig");
6868 \\use @import("std").io;
6969 \\
70 \\pub fn bar_function() {
70 \\pub fn bar_function() void {
7171 \\ if (foo_function()) {
7272 \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
7373 \\ stdout.print("OK\n") catch unreachable;
......@@ -76,7 +76,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
7676 );
7777
7878 tc.addSourceFile("other.zig",
79 \\pub fn foo_function() -> bool {
79 \\pub fn foo_function() bool {
8080 \\ // this one conflicts with the one from foo
8181 \\ return true;
8282 \\}
......@@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
8989 var tc = cases.create("two files use import each other",
9090 \\use @import("a.zig");
9191 \\
92 \\pub fn main() -> %void {
92 \\pub fn main() %void {
9393 \\ ok();
9494 \\}
9595 , "OK\n");
......@@ -100,7 +100,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
100100 \\
101101 \\pub const a_text = "OK\n";
102102 \\
103 \\pub fn ok() {
103 \\pub fn ok() void {
104104 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
105105 \\ stdout.print(b_text) catch unreachable;
106106 \\}
......@@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
118118 cases.add("hello world without libc",
119119 \\const io = @import("std").io;
120120 \\
121 \\pub fn main() -> %void {
121 \\pub fn main() %void {
122122 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
123123 \\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
124124 \\}
......@@ -137,7 +137,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
137137 \\ @cInclude("stdio.h");
138138 \\});
139139 \\
140 \\export fn main(argc: c_int, argv: &&u8) -> c_int {
140 \\export fn main(argc: c_int, argv: &&u8) c_int {
141141 \\ if (is_windows) {
142142 \\ // we want actual \n, not \r\n
143143 \\ _ = c._setmode(1, c._O_BINARY);
......@@ -268,10 +268,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
268268 \\const z = io.stdin_fileno;
269269 \\const x : @typeOf(y) = 1234;
270270 \\const y : u16 = 5678;
271 \\pub fn main() -> %void {
271 \\pub fn main() %void {
272272 \\ var x_local : i32 = print_ok(x);
273273 \\}
274 \\fn print_ok(val: @typeOf(x)) -> @typeOf(foo) {
274 \\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
275275 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
276276 \\ stdout.print("OK\n") catch unreachable;
277277 \\ return 0;
......@@ -282,7 +282,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
282282 cases.addC("expose function pointer to C land",
283283 \\const c = @cImport(@cInclude("stdlib.h"));
284284 \\
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 {
286286 \\ const a_int = @ptrCast(&align(1) i32, a ?? unreachable);
287287 \\ const b_int = @ptrCast(&align(1) i32, b ?? unreachable);
288288 \\ if (*a_int < *b_int) {
......@@ -294,7 +294,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
294294 \\ }
295295 \\}
296296 \\
297 \\export fn main() -> c_int {
297 \\export fn main() c_int {
298298 \\ var array = []u32 { 1, 7, 3, 2, 0, 9, 4, 8, 6, 5 };
299299 \\
300300 \\ 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) {
322322 \\ @cInclude("stdio.h");
323323 \\});
324324 \\
325 \\export fn main(argc: c_int, argv: &&u8) -> c_int {
325 \\export fn main(argc: c_int, argv: &&u8) c_int {
326326 \\ if (is_windows) {
327327 \\ // we want actual \n, not \r\n
328328 \\ _ = c._setmode(1, c._O_BINARY);
......@@ -342,16 +342,16 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
342342 \\const Foo = struct {
343343 \\ field1: Bar,
344344 \\
345 \\ fn method(a: &const Foo) -> bool { return true; }
345 \\ fn method(a: &const Foo) bool { return true; }
346346 \\};
347347 \\
348348 \\const Bar = struct {
349349 \\ field2: i32,
350350 \\
351 \\ fn method(b: &const Bar) -> bool { return true; }
351 \\ fn method(b: &const Bar) bool { return true; }
352352 \\};
353353 \\
354 \\pub fn main() -> %void {
354 \\pub fn main() %void {
355355 \\ const bar = Bar {.field2 = 13,};
356356 \\ const foo = Foo {.field1 = bar,};
357357 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
......@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
367367
368368 cases.add("defer with only fallthrough",
369369 \\const io = @import("std").io;
370 \\pub fn main() -> %void {
370 \\pub fn main() %void {
371371 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
372372 \\ stdout.print("before\n") catch unreachable;
373373 \\ defer stdout.print("defer1\n") catch unreachable;
......@@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
380380 cases.add("defer with return",
381381 \\const io = @import("std").io;
382382 \\const os = @import("std").os;
383 \\pub fn main() -> %void {
383 \\pub fn main() %void {
384384 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
385385 \\ stdout.print("before\n") catch unreachable;
386386 \\ defer stdout.print("defer1\n") catch unreachable;
......@@ -392,41 +392,41 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
392392 \\}
393393 , "before\ndefer2\ndefer1\n");
394394
395 cases.add("%defer and it fails",
395 cases.add("errdefer and it fails",
396396 \\const io = @import("std").io;
397 \\pub fn main() -> %void {
397 \\pub fn main() %void {
398398 \\ do_test() catch return;
399399 \\}
400 \\fn do_test() -> %void {
400 \\fn do_test() %void {
401401 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
402402 \\ stdout.print("before\n") catch unreachable;
403403 \\ defer stdout.print("defer1\n") catch unreachable;
404 \\ %defer stdout.print("deferErr\n") catch unreachable;
404 \\ errdefer stdout.print("deferErr\n") catch unreachable;
405405 \\ try its_gonna_fail();
406406 \\ defer stdout.print("defer3\n") catch unreachable;
407407 \\ stdout.print("after\n") catch unreachable;
408408 \\}
409409 \\error IToldYouItWouldFail;
410 \\fn its_gonna_fail() -> %void {
410 \\fn its_gonna_fail() %void {
411411 \\ return error.IToldYouItWouldFail;
412412 \\}
413413 , "before\ndeferErr\ndefer1\n");
414414
415 cases.add("%defer and it passes",
415 cases.add("errdefer and it passes",
416416 \\const io = @import("std").io;
417 \\pub fn main() -> %void {
417 \\pub fn main() %void {
418418 \\ do_test() catch return;
419419 \\}
420 \\fn do_test() -> %void {
420 \\fn do_test() %void {
421421 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
422422 \\ stdout.print("before\n") catch unreachable;
423423 \\ defer stdout.print("defer1\n") catch unreachable;
424 \\ %defer stdout.print("deferErr\n") catch unreachable;
424 \\ errdefer stdout.print("deferErr\n") catch unreachable;
425425 \\ try its_gonna_pass();
426426 \\ defer stdout.print("defer3\n") catch unreachable;
427427 \\ stdout.print("after\n") catch unreachable;
428428 \\}
429 \\fn its_gonna_pass() -> %void { }
429 \\fn its_gonna_pass() %void { }
430430 , "before\nafter\ndefer3\ndefer1\n");
431431
432432 cases.addCase(x: {
......@@ -434,7 +434,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
434434 \\const foo_txt = @embedFile("foo.txt");
435435 \\const io = @import("std").io;
436436 \\
437 \\pub fn main() -> %void {
437 \\pub fn main() %void {
438438 \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
439439 \\ stdout.print(foo_txt) catch unreachable;
440440 \\}
......@@ -452,7 +452,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
452452 \\const os = std.os;
453453 \\const allocator = std.debug.global_allocator;
454454 \\
455 \\pub fn main() -> %void {
455 \\pub fn main() %void {
456456 \\ var args_it = os.args();
457457 \\ var stdout_file = try io.getStdOut();
458458 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
......@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
493493 \\const os = std.os;
494494 \\const allocator = std.debug.global_allocator;
495495 \\
496 \\pub fn main() -> %void {
496 \\pub fn main() %void {
497497 \\ var args_it = os.args();
498498 \\ var stdout_file = try io.getStdOut();
499499 \\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
test/compile_errors.zig+459-413
......@@ -1,17 +1,63 @@
11const 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
450 cases.add("wrong return type for main",
5 \\pub fn main() -> f32 { }
51 \\pub fn main() f32 { }
652 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");
753
854 cases.add("double ?? on main return value",
9 \\pub fn main() -> ??void {
55 \\pub fn main() ??void {
1056 \\}
1157 , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'");
1258
1359 cases.add("bad identifier in function with struct defined inside function which references local const",
14 \\export fn entry() {
60 \\export fn entry() void {
1561 \\ const BlockKind = u32;
1662 \\
1763 \\ const Block = struct {
......@@ -23,7 +69,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
2369 , ".tmp_source.zig:8:5: error: use of undeclared identifier 'bogus'");
2470
2571 cases.add("labeled break not found",
26 \\export fn entry() {
72 \\export fn entry() void {
2773 \\ blah: while (true) {
2874 \\ while (true) {
2975 \\ break :outer;
......@@ -33,7 +79,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
3379 , ".tmp_source.zig:4:13: error: label not found: 'outer'");
3480
3581 cases.add("labeled continue not found",
36 \\export fn entry() {
82 \\export fn entry() void {
3783 \\ var i: usize = 0;
3884 \\ blah: while (i < 10) : (i += 1) {
3985 \\ while (true) {
......@@ -44,17 +90,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
4490 , ".tmp_source.zig:5:13: error: labeled loop not found: 'outer'");
4591
4692 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;
4894 \\
49 \\export fn entry() {
95 \\export fn entry() void {
5096 \\ foo(bar);
5197 \\}
5298 \\
53 \\extern fn bar(x: &void) { }
99 \\extern fn bar(x: &void) void { }
54100 , ".tmp_source.zig:7:18: error: parameter of type '&void' has 0 bits; not allowed in function with calling convention 'ccc'");
55101
56102 cases.add("implicit semicolon - block statement",
57 \\export fn entry() {
103 \\export fn entry() void {
58104 \\ {}
59105 \\ var good = {};
60106 \\ ({})
......@@ -63,7 +109,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
63109 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
64110
65111 cases.add("implicit semicolon - block expr",
66 \\export fn entry() {
112 \\export fn entry() void {
67113 \\ _ = {};
68114 \\ var good = {};
69115 \\ _ = {}
......@@ -72,7 +118,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
72118 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
73119
74120 cases.add("implicit semicolon - comptime statement",
75 \\export fn entry() {
121 \\export fn entry() void {
76122 \\ comptime {}
77123 \\ var good = {};
78124 \\ comptime ({})
......@@ -81,7 +127,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
81127 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
82128
83129 cases.add("implicit semicolon - comptime expression",
84 \\export fn entry() {
130 \\export fn entry() void {
85131 \\ _ = comptime {};
86132 \\ var good = {};
87133 \\ _ = comptime {}
......@@ -90,7 +136,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
90136 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
91137
92138 cases.add("implicit semicolon - defer",
93 \\export fn entry() {
139 \\export fn entry() void {
94140 \\ defer {}
95141 \\ var good = {};
96142 \\ defer ({})
......@@ -99,7 +145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
99145 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
100146
101147 cases.add("implicit semicolon - if statement",
102 \\export fn entry() {
148 \\export fn entry() void {
103149 \\ if(true) {}
104150 \\ var good = {};
105151 \\ if(true) ({})
......@@ -108,7 +154,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
108154 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
109155
110156 cases.add("implicit semicolon - if expression",
111 \\export fn entry() {
157 \\export fn entry() void {
112158 \\ _ = if(true) {};
113159 \\ var good = {};
114160 \\ _ = if(true) {}
......@@ -117,7 +163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
117163 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
118164
119165 cases.add("implicit semicolon - if-else statement",
120 \\export fn entry() {
166 \\export fn entry() void {
121167 \\ if(true) {} else {}
122168 \\ var good = {};
123169 \\ if(true) ({}) else ({})
......@@ -126,7 +172,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
126172 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
127173
128174 cases.add("implicit semicolon - if-else expression",
129 \\export fn entry() {
175 \\export fn entry() void {
130176 \\ _ = if(true) {} else {};
131177 \\ var good = {};
132178 \\ _ = if(true) {} else {}
......@@ -135,7 +181,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
135181 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
136182
137183 cases.add("implicit semicolon - if-else-if statement",
138 \\export fn entry() {
184 \\export fn entry() void {
139185 \\ if(true) {} else if(true) {}
140186 \\ var good = {};
141187 \\ if(true) ({}) else if(true) ({})
......@@ -144,7 +190,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
144190 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
145191
146192 cases.add("implicit semicolon - if-else-if expression",
147 \\export fn entry() {
193 \\export fn entry() void {
148194 \\ _ = if(true) {} else if(true) {};
149195 \\ var good = {};
150196 \\ _ = if(true) {} else if(true) {}
......@@ -153,7 +199,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
153199 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
154200
155201 cases.add("implicit semicolon - if-else-if-else statement",
156 \\export fn entry() {
202 \\export fn entry() void {
157203 \\ if(true) {} else if(true) {} else {}
158204 \\ var good = {};
159205 \\ if(true) ({}) else if(true) ({}) else ({})
......@@ -162,7 +208,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
162208 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
163209
164210 cases.add("implicit semicolon - if-else-if-else expression",
165 \\export fn entry() {
211 \\export fn entry() void {
166212 \\ _ = if(true) {} else if(true) {} else {};
167213 \\ var good = {};
168214 \\ _ = if(true) {} else if(true) {} else {}
......@@ -171,7 +217,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
171217 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
172218
173219 cases.add("implicit semicolon - test statement",
174 \\export fn entry() {
220 \\export fn entry() void {
175221 \\ if (foo()) |_| {}
176222 \\ var good = {};
177223 \\ if (foo()) |_| ({})
......@@ -180,7 +226,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
180226 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
181227
182228 cases.add("implicit semicolon - test expression",
183 \\export fn entry() {
229 \\export fn entry() void {
184230 \\ _ = if (foo()) |_| {};
185231 \\ var good = {};
186232 \\ _ = if (foo()) |_| {}
......@@ -189,7 +235,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
189235 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
190236
191237 cases.add("implicit semicolon - while statement",
192 \\export fn entry() {
238 \\export fn entry() void {
193239 \\ while(true) {}
194240 \\ var good = {};
195241 \\ while(true) ({})
......@@ -198,7 +244,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
198244 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
199245
200246 cases.add("implicit semicolon - while expression",
201 \\export fn entry() {
247 \\export fn entry() void {
202248 \\ _ = while(true) {};
203249 \\ var good = {};
204250 \\ _ = while(true) {}
......@@ -207,7 +253,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
207253 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
208254
209255 cases.add("implicit semicolon - while-continue statement",
210 \\export fn entry() {
256 \\export fn entry() void {
211257 \\ while(true):({}) {}
212258 \\ var good = {};
213259 \\ while(true):({}) ({})
......@@ -216,7 +262,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
216262 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
217263
218264 cases.add("implicit semicolon - while-continue expression",
219 \\export fn entry() {
265 \\export fn entry() void {
220266 \\ _ = while(true):({}) {};
221267 \\ var good = {};
222268 \\ _ = while(true):({}) {}
......@@ -225,7 +271,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
225271 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
226272
227273 cases.add("implicit semicolon - for statement",
228 \\export fn entry() {
274 \\export fn entry() void {
229275 \\ for(foo()) {}
230276 \\ var good = {};
231277 \\ for(foo()) ({})
......@@ -234,7 +280,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
234280 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
235281
236282 cases.add("implicit semicolon - for expression",
237 \\export fn entry() {
283 \\export fn entry() void {
238284 \\ _ = for(foo()) {};
239285 \\ var good = {};
240286 \\ _ = for(foo()) {}
......@@ -243,60 +289,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
243289 , ".tmp_source.zig:5:5: error: expected token ';', found 'var'");
244290
245291 cases.add("multiple function definitions",
246 \\fn a() {}
247 \\fn a() {}
248 \\export fn entry() { a(); }
292 \\fn a() void {}
293 \\fn a() void {}
294 \\export fn entry() void { a(); }
249295 , ".tmp_source.zig:2:1: error: redefinition of 'a'");
250296
251297 cases.add("unreachable with return",
252 \\fn a() -> noreturn {return;}
253 \\export fn entry() { a(); }
254 , ".tmp_source.zig:1:21: error: expected type 'noreturn', found 'void'");
298 \\fn a() noreturn {return;}
299 \\export fn entry() void { a(); }
300 , ".tmp_source.zig:1:18: error: expected type 'noreturn', found 'void'");
255301
256302 cases.add("control reaches end of non-void function",
257 \\fn a() -> i32 {}
258 \\export fn entry() { _ = a(); }
259 , ".tmp_source.zig:1:15: error: expected type 'i32', found 'void'");
303 \\fn a() i32 {}
304 \\export fn entry() void { _ = a(); }
305 , ".tmp_source.zig:1:12: error: expected type 'i32', found 'void'");
260306
261307 cases.add("undefined function call",
262 \\export fn a() {
308 \\export fn a() void {
263309 \\ b();
264310 \\}
265311 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
266312
267313 cases.add("wrong number of arguments",
268 \\export fn a() {
314 \\export fn a() void {
269315 \\ b(1);
270316 \\}
271 \\fn b(a: i32, b: i32, c: i32) { }
317 \\fn b(a: i32, b: i32, c: i32) void { }
272318 , ".tmp_source.zig:2:6: error: expected 3 arguments, found 1");
273319
274320 cases.add("invalid type",
275 \\fn a() -> bogus {}
276 \\export fn entry() { _ = a(); }
277 , ".tmp_source.zig:1:11: error: use of undeclared identifier 'bogus'");
321 \\fn a() bogus {}
322 \\export fn entry() void { _ = a(); }
323 , ".tmp_source.zig:1:8: error: use of undeclared identifier 'bogus'");
278324
279325 cases.add("pointer to unreachable",
280 \\fn a() -> &noreturn {}
281 \\export fn entry() { _ = a(); }
282 , ".tmp_source.zig:1:12: error: pointer to unreachable not allowed");
326 \\fn a() &noreturn {}
327 \\export fn entry() void { _ = a(); }
328 , ".tmp_source.zig:1:9: error: pointer to unreachable not allowed");
283329
284330 cases.add("unreachable code",
285 \\export fn a() {
331 \\export fn a() void {
286332 \\ return;
287333 \\ b();
288334 \\}
289335 \\
290 \\fn b() {}
336 \\fn b() void {}
291337 , ".tmp_source.zig:3:5: error: unreachable code");
292338
293339 cases.add("bad import",
294340 \\const bogus = @import("bogus-does-not-exist.zig");
295 \\export fn entry() { bogus.bogo(); }
341 \\export fn entry() void { bogus.bogo(); }
296342 , ".tmp_source.zig:1:15: error: unable to find 'bogus-does-not-exist.zig'");
297343
298344 cases.add("undeclared identifier",
299 \\export fn a() {
345 \\export fn a() void {
300346 \\ return
301347 \\ b +
302348 \\ c;
......@@ -306,89 +352,89 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
306352 ".tmp_source.zig:4:5: error: use of undeclared identifier 'c'");
307353
308354 cases.add("parameter redeclaration",
309 \\fn f(a : i32, a : i32) {
355 \\fn f(a : i32, a : i32) void {
310356 \\}
311 \\export fn entry() { f(1, 2); }
357 \\export fn entry() void { f(1, 2); }
312358 , ".tmp_source.zig:1:15: error: redeclaration of variable 'a'");
313359
314360 cases.add("local variable redeclaration",
315 \\export fn f() {
361 \\export fn f() void {
316362 \\ const a : i32 = 0;
317363 \\ const a = 0;
318364 \\}
319365 , ".tmp_source.zig:3:5: error: redeclaration of variable 'a'");
320366
321367 cases.add("local variable redeclares parameter",
322 \\fn f(a : i32) {
368 \\fn f(a : i32) void {
323369 \\ const a = 0;
324370 \\}
325 \\export fn entry() { f(1); }
371 \\export fn entry() void { f(1); }
326372 , ".tmp_source.zig:2:5: error: redeclaration of variable 'a'");
327373
328374 cases.add("variable has wrong type",
329 \\export fn f() -> i32 {
375 \\export fn f() i32 {
330376 \\ const a = c"a";
331377 \\ return a;
332378 \\}
333379 , ".tmp_source.zig:3:12: error: expected type 'i32', found '&const u8'");
334380
335381 cases.add("if condition is bool, not int",
336 \\export fn f() {
382 \\export fn f() void {
337383 \\ if (0) {}
338384 \\}
339385 , ".tmp_source.zig:2:9: error: integer value 0 cannot be implicitly casted to type 'bool'");
340386
341387 cases.add("assign unreachable",
342 \\export fn f() {
388 \\export fn f() void {
343389 \\ const a = return;
344390 \\}
345391 , ".tmp_source.zig:2:5: error: unreachable code");
346392
347393 cases.add("unreachable variable",
348 \\export fn f() {
394 \\export fn f() void {
349395 \\ const a: noreturn = {};
350396 \\}
351397 , ".tmp_source.zig:2:14: error: variable of type 'noreturn' not allowed");
352398
353399 cases.add("unreachable parameter",
354 \\fn f(a: noreturn) {}
355 \\export fn entry() { f(); }
400 \\fn f(a: noreturn) void {}
401 \\export fn entry() void { f(); }
356402 , ".tmp_source.zig:1:9: error: parameter of type 'noreturn' not allowed");
357403
358404 cases.add("bad assignment target",
359 \\export fn f() {
405 \\export fn f() void {
360406 \\ 3 = 3;
361407 \\}
362408 , ".tmp_source.zig:2:7: error: cannot assign to constant");
363409
364410 cases.add("assign to constant variable",
365 \\export fn f() {
411 \\export fn f() void {
366412 \\ const a = 3;
367413 \\ a = 4;
368414 \\}
369415 , ".tmp_source.zig:3:7: error: cannot assign to constant");
370416
371417 cases.add("use of undeclared identifier",
372 \\export fn f() {
418 \\export fn f() void {
373419 \\ b = 3;
374420 \\}
375421 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'b'");
376422
377423 cases.add("const is a statement, not an expression",
378 \\export fn f() {
424 \\export fn f() void {
379425 \\ (const a = 0);
380426 \\}
381427 , ".tmp_source.zig:2:6: error: invalid token: 'const'");
382428
383429 cases.add("array access of undeclared identifier",
384 \\export fn f() {
430 \\export fn f() void {
385431 \\ i[i] = i[i];
386432 \\}
387433 , ".tmp_source.zig:2:5: error: use of undeclared identifier 'i'",
388434 ".tmp_source.zig:2:12: error: use of undeclared identifier 'i'");
389435
390436 cases.add("array access of non array",
391 \\export fn f() {
437 \\export fn f() void {
392438 \\ var bad : bool = undefined;
393439 \\ bad[bad] = bad[bad];
394440 \\}
......@@ -396,7 +442,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
396442 ".tmp_source.zig:3:19: error: array access of non-array type 'bool'");
397443
398444 cases.add("array access with non integer index",
399 \\export fn f() {
445 \\export fn f() void {
400446 \\ var array = "aoeu";
401447 \\ var bad = false;
402448 \\ array[bad] = array[bad];
......@@ -406,37 +452,37 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
406452
407453 cases.add("write to const global variable",
408454 \\const x : i32 = 99;
409 \\fn f() {
455 \\fn f() void {
410456 \\ x = 1;
411457 \\}
412 \\export fn entry() { f(); }
458 \\export fn entry() void { f(); }
413459 , ".tmp_source.zig:3:7: error: cannot assign to constant");
414460
415461
416462 cases.add("missing else clause",
417 \\fn f(b: bool) {
463 \\fn f(b: bool) void {
418464 \\ const x : i32 = if (b) h: { break :h 1; };
419465 \\ const y = if (b) h: { break :h i32(1); };
420466 \\}
421 \\export fn entry() { f(true); }
467 \\export fn entry() void { f(true); }
422468 , ".tmp_source.zig:2:42: error: integer value 1 cannot be implicitly casted to type 'void'",
423469 ".tmp_source.zig:3:15: error: incompatible types: 'i32' and 'void'");
424470
425471 cases.add("direct struct loop",
426472 \\const A = struct { a : A, };
427 \\export fn entry() -> usize { return @sizeOf(A); }
473 \\export fn entry() usize { return @sizeOf(A); }
428474 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
429475
430476 cases.add("indirect struct loop",
431477 \\const A = struct { b : B, };
432478 \\const B = struct { c : C, };
433479 \\const C = struct { a : A, };
434 \\export fn entry() -> usize { return @sizeOf(A); }
480 \\export fn entry() usize { return @sizeOf(A); }
435481 , ".tmp_source.zig:1:11: error: struct 'A' contains itself");
436482
437483 cases.add("invalid struct field",
438484 \\const A = struct { x : i32, };
439 \\export fn f() {
485 \\export fn f() void {
440486 \\ var a : A = undefined;
441487 \\ a.foo = 1;
442488 \\ const y = a.bar;
......@@ -468,7 +514,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
468514 \\ y : i32,
469515 \\ z : i32,
470516 \\};
471 \\export fn f() {
517 \\export fn f() void {
472518 \\ const a = A {
473519 \\ .z = 1,
474520 \\ .y = 2,
......@@ -484,7 +530,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
484530 \\ y : i32,
485531 \\ z : i32,
486532 \\};
487 \\export fn f() {
533 \\export fn f() void {
488534 \\ // we want the error on the '{' not the 'A' because
489535 \\ // the A could be a complicated expression
490536 \\ const a = A {
......@@ -500,7 +546,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
500546 \\ y : i32,
501547 \\ z : i32,
502548 \\};
503 \\export fn f() {
549 \\export fn f() void {
504550 \\ const a = A {
505551 \\ .z = 4,
506552 \\ .y = 2,
......@@ -510,57 +556,57 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
510556 , ".tmp_source.zig:10:9: error: no member named 'foo' in struct 'A'");
511557
512558 cases.add("invalid break expression",
513 \\export fn f() {
559 \\export fn f() void {
514560 \\ break;
515561 \\}
516562 , ".tmp_source.zig:2:5: error: break expression outside loop");
517563
518564 cases.add("invalid continue expression",
519 \\export fn f() {
565 \\export fn f() void {
520566 \\ continue;
521567 \\}
522568 , ".tmp_source.zig:2:5: error: continue expression outside loop");
523569
524570 cases.add("invalid maybe type",
525 \\export fn f() {
571 \\export fn f() void {
526572 \\ if (true) |x| { }
527573 \\}
528574 , ".tmp_source.zig:2:9: error: expected nullable type, found 'bool'");
529575
530576 cases.add("cast unreachable",
531 \\fn f() -> i32 {
577 \\fn f() i32 {
532578 \\ return i32(return 1);
533579 \\}
534 \\export fn entry() { _ = f(); }
580 \\export fn entry() void { _ = f(); }
535581 , ".tmp_source.zig:2:15: error: unreachable code");
536582
537583 cases.add("invalid builtin fn",
538 \\fn f() -> @bogus(foo) {
584 \\fn f() @bogus(foo) {
539585 \\}
540 \\export fn entry() { _ = f(); }
541 , ".tmp_source.zig:1:11: error: invalid builtin function: 'bogus'");
586 \\export fn entry() void { _ = f(); }
587 , ".tmp_source.zig:1:8: error: invalid builtin function: 'bogus'");
542588
543589 cases.add("top level decl dependency loop",
544590 \\const a : @typeOf(b) = 0;
545591 \\const b : @typeOf(a) = 0;
546 \\export fn entry() {
592 \\export fn entry() void {
547593 \\ const c = a + b;
548594 \\}
549595 , ".tmp_source.zig:1:1: error: 'a' depends on itself");
550596
551597 cases.add("noalias on non pointer param",
552 \\fn f(noalias x: i32) {}
553 \\export fn entry() { f(1234); }
598 \\fn f(noalias x: i32) void {}
599 \\export fn entry() void { f(1234); }
554600 , ".tmp_source.zig:1:6: error: noalias on non-pointer parameter");
555601
556602 cases.add("struct init syntax for array",
557603 \\const foo = []u16{.x = 1024,};
558 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
604 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
559605 , ".tmp_source.zig:1:18: error: type '[]u16' does not support struct initialization syntax");
560606
561607 cases.add("type variables must be constant",
562608 \\var foo = u8;
563 \\export fn entry() -> foo {
609 \\export fn entry() foo {
564610 \\ return 1;
565611 \\}
566612 , ".tmp_source.zig:1:1: error: variable of type 'type' must be constant");
......@@ -570,11 +616,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
570616 \\const Foo = struct {};
571617 \\const Bar = struct {};
572618 \\
573 \\fn f(Foo: i32) {
619 \\fn f(Foo: i32) void {
574620 \\ var Bar : i32 = undefined;
575621 \\}
576622 \\
577 \\export fn entry() {
623 \\export fn entry() void {
578624 \\ f(1234);
579625 \\}
580626 ,
......@@ -590,7 +636,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
590636 \\ Three,
591637 \\ Four,
592638 \\};
593 \\fn f(n: Number) -> i32 {
639 \\fn f(n: Number) i32 {
594640 \\ switch (n) {
595641 \\ Number.One => 1,
596642 \\ Number.Two => 2,
......@@ -598,7 +644,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
598644 \\ }
599645 \\}
600646 \\
601 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
647 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
602648 , ".tmp_source.zig:8:5: error: enumeration value 'Number.Four' not handled in switch");
603649
604650 cases.add("switch expression - duplicate enumeration prong",
......@@ -608,7 +654,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
608654 \\ Three,
609655 \\ Four,
610656 \\};
611 \\fn f(n: Number) -> i32 {
657 \\fn f(n: Number) i32 {
612658 \\ switch (n) {
613659 \\ Number.One => 1,
614660 \\ Number.Two => 2,
......@@ -618,7 +664,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
618664 \\ }
619665 \\}
620666 \\
621 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
667 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
622668 , ".tmp_source.zig:13:15: error: duplicate switch value",
623669 ".tmp_source.zig:10:15: note: other value is here");
624670
......@@ -629,7 +675,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
629675 \\ Three,
630676 \\ Four,
631677 \\};
632 \\fn f(n: Number) -> i32 {
678 \\fn f(n: Number) i32 {
633679 \\ switch (n) {
634680 \\ Number.One => 1,
635681 \\ Number.Two => 2,
......@@ -640,35 +686,35 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
640686 \\ }
641687 \\}
642688 \\
643 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
689 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
644690 , ".tmp_source.zig:13:15: error: duplicate switch value",
645691 ".tmp_source.zig:10:15: note: other value is here");
646692
647693 cases.add("switch expression - multiple else prongs",
648 \\fn f(x: u32) {
694 \\fn f(x: u32) void {
649695 \\ const value: bool = switch (x) {
650696 \\ 1234 => false,
651697 \\ else => true,
652698 \\ else => true,
653699 \\ };
654700 \\}
655 \\export fn entry() {
701 \\export fn entry() void {
656702 \\ f(1234);
657703 \\}
658704 , ".tmp_source.zig:5:9: error: multiple else prongs in switch expression");
659705
660706 cases.add("switch expression - non exhaustive integer prongs",
661 \\fn foo(x: u8) {
707 \\fn foo(x: u8) void {
662708 \\ switch (x) {
663709 \\ 0 => {},
664710 \\ }
665711 \\}
666 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
712 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
667713 ,
668714 ".tmp_source.zig:2:5: error: switch must handle all possibilities");
669715
670716 cases.add("switch expression - duplicate or overlapping integer value",
671 \\fn foo(x: u8) -> u8 {
717 \\fn foo(x: u8) u8 {
672718 \\ return switch (x) {
673719 \\ 0 ... 100 => u8(0),
674720 \\ 101 ... 200 => 1,
......@@ -676,26 +722,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
676722 \\ 206 ... 255 => 3,
677723 \\ };
678724 \\}
679 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
725 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
680726 ,
681727 ".tmp_source.zig:6:9: error: duplicate switch value",
682728 ".tmp_source.zig:5:14: note: previous value is here");
683729
684730 cases.add("switch expression - switch on pointer type with no else",
685 \\fn foo(x: &u8) {
731 \\fn foo(x: &u8) void {
686732 \\ switch (x) {
687733 \\ &y => {},
688734 \\ }
689735 \\}
690736 \\const y: u8 = 100;
691 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
737 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
692738 ,
693739 ".tmp_source.zig:2:5: error: else prong required when switching on type '&u8'");
694740
695741 cases.add("global variable initializer must be constant expression",
696 \\extern fn foo() -> i32;
742 \\extern fn foo() i32;
697743 \\const x = foo();
698 \\export fn entry() -> i32 { return x; }
744 \\export fn entry() i32 { return x; }
699745 , ".tmp_source.zig:2:11: error: unable to evaluate constant expression");
700746
701747 cases.add("array concatenation with wrong type",
......@@ -703,38 +749,38 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
703749 \\const derp = usize(1234);
704750 \\const a = derp ++ "foo";
705751 \\
706 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }
752 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
707753 , ".tmp_source.zig:3:11: error: expected array or C string literal, found 'usize'");
708754
709755 cases.add("non compile time array concatenation",
710 \\fn f() -> []u8 {
756 \\fn f() []u8 {
711757 \\ return s ++ "foo";
712758 \\}
713759 \\var s: [10]u8 = undefined;
714 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
760 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
715761 , ".tmp_source.zig:2:12: error: unable to evaluate constant expression");
716762
717763 cases.add("@cImport with bogus include",
718764 \\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)); }
720766 , ".tmp_source.zig:1:11: error: C import failed",
721767 ".h:1:10: note: 'bogus.h' file not found");
722768
723769 cases.add("address of number literal",
724770 \\const x = 3;
725771 \\const y = &x;
726 \\fn foo() -> &const i32 { return y; }
727 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
728 , ".tmp_source.zig:3:33: error: expected type '&const i32', found '&const (integer literal)'");
772 \\fn foo() &const i32 { return y; }
773 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
774 , ".tmp_source.zig:3:30: error: expected type '&const i32', found '&const (integer literal)'");
729775
730776 cases.add("integer overflow error",
731777 \\const x : u8 = 300;
732 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }
778 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
733779 , ".tmp_source.zig:1:16: error: integer value 300 cannot be implicitly casted to type 'u8'");
734780
735781 cases.add("incompatible number literals",
736782 \\const x = 2 == 2.0;
737 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }
783 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
738784 , ".tmp_source.zig:1:11: error: integer value 2 cannot be implicitly casted to type '(float literal)'");
739785
740786 cases.add("missing function call param",
......@@ -742,10 +788,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
742788 \\ a: i32,
743789 \\ b: i32,
744790 \\
745 \\ fn member_a(foo: &const Foo) -> i32 {
791 \\ fn member_a(foo: &const Foo) i32 {
746792 \\ return foo.a;
747793 \\ }
748 \\ fn member_b(foo: &const Foo) -> i32 {
794 \\ fn member_b(foo: &const Foo) i32 {
749795 \\ return foo.b;
750796 \\ }
751797 \\};
......@@ -756,59 +802,59 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
756802 \\ Foo.member_b,
757803 \\};
758804 \\
759 \\fn f(foo: &const Foo, index: usize) {
805 \\fn f(foo: &const Foo, index: usize) void {
760806 \\ const result = members[index]();
761807 \\}
762808 \\
763 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
809 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
764810 , ".tmp_source.zig:20:34: error: expected 1 arguments, found 0");
765811
766812 cases.add("missing function name and param name",
767 \\fn () {}
768 \\fn f(i32) {}
769 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
813 \\fn () void {}
814 \\fn f(i32) void {}
815 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
770816 ,
771817 ".tmp_source.zig:1:1: error: missing function name",
772818 ".tmp_source.zig:2:6: error: missing parameter name");
773819
774820 cases.add("wrong function type",
775 \\const fns = []fn(){ a, b, c };
776 \\fn a() -> i32 {return 0;}
777 \\fn b() -> i32 {return 1;}
778 \\fn c() -> i32 {return 2;}
779 \\export fn entry() -> usize { return @sizeOf(@typeOf(fns)); }
780 , ".tmp_source.zig:1:21: error: expected type 'fn()', found 'fn() -> i32'");
821 \\const fns = []fn() void { a, b, c };
822 \\fn a() i32 {return 0;}
823 \\fn b() i32 {return 1;}
824 \\fn c() i32 {return 2;}
825 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
826 , ".tmp_source.zig:1:27: error: expected type 'fn() void', found 'fn() i32'");
781827
782828 cases.add("extern function pointer mismatch",
783 \\const fns = [](fn(i32)->i32){ a, b, c };
784 \\pub fn a(x: i32) -> i32 {return x + 0;}
785 \\pub fn b(x: i32) -> i32 {return x + 1;}
786 \\export fn c(x: i32) -> i32 {return x + 2;}
829 \\const fns = [](fn(i32)i32) { a, b, c };
830 \\pub fn a(x: i32) i32 {return x + 0;}
831 \\pub fn b(x: i32) i32 {return x + 1;}
832 \\export fn c(x: i32) i32 {return x + 2;}
787833 \\
788 \\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'");
834 \\export fn entry() usize { return @sizeOf(@typeOf(fns)); }
835 , ".tmp_source.zig:1:36: error: expected type 'fn(i32) i32', found 'extern fn(i32) i32'");
790836
791837
792838 cases.add("implicit cast from f64 to f32",
793839 \\const x : f64 = 1.0;
794840 \\const y : f32 = x;
795841 \\
796 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
842 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
797843 , ".tmp_source.zig:2:17: error: expected type 'f32', found 'f64'");
798844
799845
800846 cases.add("colliding invalid top level functions",
801 \\fn func() -> bogus {}
802 \\fn func() -> bogus {}
803 \\export fn entry() -> usize { return @sizeOf(@typeOf(func)); }
847 \\fn func() bogus {}
848 \\fn func() bogus {}
849 \\export fn entry() usize { return @sizeOf(@typeOf(func)); }
804850 ,
805851 ".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
809855 cases.add("bogus compile var",
810856 \\const x = @import("builtin").bogus;
811 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }
857 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
812858 , ".tmp_source.zig:1:29: error: no member named 'bogus' in '");
813859
814860
......@@ -817,11 +863,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
817863 \\ y: [get()]u8,
818864 \\};
819865 \\var global_var: usize = 1;
820 \\fn get() -> usize { return global_var; }
866 \\fn get() usize { return global_var; }
821867 \\
822 \\export fn entry() -> usize { return @sizeOf(@typeOf(Foo)); }
868 \\export fn entry() usize { return @sizeOf(@typeOf(Foo)); }
823869 ,
824 ".tmp_source.zig:5:28: error: unable to evaluate constant expression",
870 ".tmp_source.zig:5:25: error: unable to evaluate constant expression",
825871 ".tmp_source.zig:2:12: note: called from here",
826872 ".tmp_source.zig:2:8: note: called from here");
827873
......@@ -832,7 +878,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
832878 \\};
833879 \\const x = Foo {.field = 1} + Foo {.field = 2};
834880 \\
835 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }
881 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
836882 , ".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) {
842888 \\const int_x = u32(1) / u32(0);
843889 \\const float_x = f32(1.0) / f32(0.0);
844890 \\
845 \\export fn entry1() -> usize { return @sizeOf(@typeOf(lit_int_x)); }
846 \\export fn entry2() -> usize { return @sizeOf(@typeOf(lit_float_x)); }
847 \\export fn entry3() -> usize { return @sizeOf(@typeOf(int_x)); }
848 \\export fn entry4() -> usize { return @sizeOf(@typeOf(float_x)); }
891 \\export fn entry1() usize { return @sizeOf(@typeOf(lit_int_x)); }
892 \\export fn entry2() usize { return @sizeOf(@typeOf(lit_float_x)); }
893 \\export fn entry3() usize { return @sizeOf(@typeOf(int_x)); }
894 \\export fn entry4() usize { return @sizeOf(@typeOf(float_x)); }
849895 ,
850 ".tmp_source.zig:1:21: error: division by zero is undefined",
851 ".tmp_source.zig:2:25: error: division by zero is undefined",
852 ".tmp_source.zig:3:22: error: division by zero is undefined",
853 ".tmp_source.zig:4:26: error: division by zero is undefined");
896 ".tmp_source.zig:1:21: error: division by zero",
897 ".tmp_source.zig:2:25: error: division by zero",
898 ".tmp_source.zig:3:22: error: division by zero",
899 ".tmp_source.zig:4:26: error: division by zero");
854900
855901
856902 cases.add("normal string with newline",
857903 \\const foo = "a
858904 \\b";
859905 \\
860 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
906 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
861907 , ".tmp_source.zig:1:13: error: newline not allowed in string literal");
862908
863909 cases.add("invalid comparison for function pointers",
864 \\fn foo() {}
910 \\fn foo() void {}
865911 \\const invalid = foo > foo;
866912 \\
867 \\export fn entry() -> usize { return @sizeOf(@typeOf(invalid)); }
868 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn()'");
913 \\export fn entry() usize { return @sizeOf(@typeOf(invalid)); }
914 , ".tmp_source.zig:2:21: error: operator not allowed for type 'fn() void'");
869915
870916 cases.add("generic function instance with non-constant expression",
871 \\fn foo(comptime x: i32, y: i32) -> i32 { return x + y; }
872 \\fn test1(a: i32, b: i32) -> i32 {
917 \\fn foo(comptime x: i32, y: i32) i32 { return x + y; }
918 \\fn test1(a: i32, b: i32) i32 {
873919 \\ return foo(a, b);
874920 \\}
875921 \\
876 \\export fn entry() -> usize { return @sizeOf(@typeOf(test1)); }
922 \\export fn entry() usize { return @sizeOf(@typeOf(test1)); }
877923 , ".tmp_source.zig:3:16: error: unable to evaluate constant expression");
878924
879925 cases.add("assign null to non-nullable pointer",
880926 \\const a: &u8 = null;
881927 \\
882 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }
928 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
883929 , ".tmp_source.zig:1:16: error: expected type '&u8', found '(null)'");
884930
885931 cases.add("indexing an array of size zero",
886932 \\const array = []u8{};
887 \\export fn foo() {
933 \\export fn foo() void {
888934 \\ const pointer = &array[0];
889935 \\}
890936 , ".tmp_source.zig:3:27: error: index 0 outside array of size 0");
891937
892938 cases.add("compile time division by zero",
893939 \\const y = foo(0);
894 \\fn foo(x: u32) -> u32 {
940 \\fn foo(x: u32) u32 {
895941 \\ return 1 / x;
896942 \\}
897943 \\
898 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
944 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
899945 ,
900 ".tmp_source.zig:3:14: error: division by zero is undefined",
946 ".tmp_source.zig:3:14: error: division by zero",
901947 ".tmp_source.zig:1:14: note: called from here");
902948
903949 cases.add("branch on undefined value",
904950 \\const x = if (undefined) true else false;
905951 \\
906 \\export fn entry() -> usize { return @sizeOf(@typeOf(x)); }
952 \\export fn entry() usize { return @sizeOf(@typeOf(x)); }
907953 , ".tmp_source.zig:1:15: error: use of undefined value");
908954
909955
910956 cases.add("endless loop in function evaluation",
911957 \\const seventh_fib_number = fibbonaci(7);
912 \\fn fibbonaci(x: i32) -> i32 {
958 \\fn fibbonaci(x: i32) i32 {
913959 \\ return fibbonaci(x - 1) + fibbonaci(x - 2);
914960 \\}
915961 \\
916 \\export fn entry() -> usize { return @sizeOf(@typeOf(seventh_fib_number)); }
962 \\export fn entry() usize { return @sizeOf(@typeOf(seventh_fib_number)); }
917963 ,
918964 ".tmp_source.zig:3:21: error: evaluation exceeded 1000 backwards branches",
919965 ".tmp_source.zig:3:21: note: called from here");
......@@ -921,7 +967,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
921967 cases.add("@embedFile with bogus file",
922968 \\const resource = @embedFile("bogus.txt");
923969 \\
924 \\export fn entry() -> usize { return @sizeOf(@typeOf(resource)); }
970 \\export fn entry() usize { return @sizeOf(@typeOf(resource)); }
925971 , ".tmp_source.zig:1:29: error: unable to find '", "bogus.txt'");
926972
927973 cases.add("non-const expression in struct literal outside function",
......@@ -929,9 +975,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
929975 \\ x: i32,
930976 \\};
931977 \\const a = Foo {.x = get_it()};
932 \\extern fn get_it() -> i32;
978 \\extern fn get_it() i32;
933979 \\
934 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }
980 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
935981 , ".tmp_source.zig:4:21: error: unable to evaluate constant expression");
936982
937983 cases.add("non-const expression function call with struct return value outside function",
......@@ -939,60 +985,60 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
939985 \\ x: i32,
940986 \\};
941987 \\const a = get_it();
942 \\fn get_it() -> Foo {
988 \\fn get_it() Foo {
943989 \\ global_side_effect = true;
944990 \\ return Foo {.x = 13};
945991 \\}
946992 \\var global_side_effect = false;
947993 \\
948 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }
994 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
949995 ,
950996 ".tmp_source.zig:6:24: error: unable to evaluate constant expression",
951997 ".tmp_source.zig:4:17: note: called from here");
952998
953999 cases.add("undeclared identifier error should mark fn as impure",
954 \\export fn foo() {
1000 \\export fn foo() void {
9551001 \\ test_a_thing();
9561002 \\}
957 \\fn test_a_thing() {
1003 \\fn test_a_thing() void {
9581004 \\ bad_fn_call();
9591005 \\}
9601006 , ".tmp_source.zig:5:5: error: use of undeclared identifier 'bad_fn_call'");
9611007
9621008 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 {
9641010 \\ return a == b;
9651011 \\}
9661012 \\const EnumWithData = union(enum) {
9671013 \\ One: void,
9681014 \\ Two: i32,
9691015 \\};
970 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) -> bool {
1016 \\fn bad_eql_2(a: &const EnumWithData, b: &const EnumWithData) bool {
9711017 \\ return *a == *b;
9721018 \\}
9731019 \\
974 \\export fn entry1() -> usize { return @sizeOf(@typeOf(bad_eql_1)); }
975 \\export fn entry2() -> usize { return @sizeOf(@typeOf(bad_eql_2)); }
1020 \\export fn entry1() usize { return @sizeOf(@typeOf(bad_eql_1)); }
1021 \\export fn entry2() usize { return @sizeOf(@typeOf(bad_eql_2)); }
9761022 ,
9771023 ".tmp_source.zig:2:14: error: operator not allowed for type '[]u8'",
9781024 ".tmp_source.zig:9:15: error: operator not allowed for type 'EnumWithData'");
9791025
9801026 cases.add("non-const switch number literal",
981 \\export fn foo() {
1027 \\export fn foo() void {
9821028 \\ const x = switch (bar()) {
9831029 \\ 1, 2 => 1,
9841030 \\ 3, 4 => 2,
9851031 \\ else => 3,
9861032 \\ };
9871033 \\}
988 \\fn bar() -> i32 {
1034 \\fn bar() i32 {
9891035 \\ return 2;
9901036 \\}
9911037 , ".tmp_source.zig:2:15: error: unable to infer expression type");
9921038
9931039 cases.add("atomic orderings of cmpxchg - failure stricter than success",
9941040 \\const AtomicOrder = @import("builtin").AtomicOrder;
995 \\export fn f() {
1041 \\export fn f() void {
9961042 \\ var x: i32 = 1234;
9971043 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Monotonic, AtomicOrder.SeqCst)) {}
9981044 \\}
......@@ -1000,7 +1046,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10001046
10011047 cases.add("atomic orderings of cmpxchg - success Monotonic or stricter",
10021048 \\const AtomicOrder = @import("builtin").AtomicOrder;
1003 \\export fn f() {
1049 \\export fn f() void {
10041050 \\ var x: i32 = 1234;
10051051 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.Unordered, AtomicOrder.Unordered)) {}
10061052 \\}
......@@ -1008,22 +1054,22 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10081054
10091055 cases.add("negation overflow in function evaluation",
10101056 \\const y = neg(-128);
1011 \\fn neg(x: i8) -> i8 {
1057 \\fn neg(x: i8) i8 {
10121058 \\ return -x;
10131059 \\}
10141060 \\
1015 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
1061 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
10161062 ,
10171063 ".tmp_source.zig:3:12: error: negation caused overflow",
10181064 ".tmp_source.zig:1:14: note: called from here");
10191065
10201066 cases.add("add overflow in function evaluation",
10211067 \\const y = add(65530, 10);
1022 \\fn add(a: u16, b: u16) -> u16 {
1068 \\fn add(a: u16, b: u16) u16 {
10231069 \\ return a + b;
10241070 \\}
10251071 \\
1026 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
1072 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
10271073 ,
10281074 ".tmp_source.zig:3:14: error: operation caused overflow",
10291075 ".tmp_source.zig:1:14: note: called from here");
......@@ -1031,47 +1077,47 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10311077
10321078 cases.add("sub overflow in function evaluation",
10331079 \\const y = sub(10, 20);
1034 \\fn sub(a: u16, b: u16) -> u16 {
1080 \\fn sub(a: u16, b: u16) u16 {
10351081 \\ return a - b;
10361082 \\}
10371083 \\
1038 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
1084 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
10391085 ,
10401086 ".tmp_source.zig:3:14: error: operation caused overflow",
10411087 ".tmp_source.zig:1:14: note: called from here");
10421088
10431089 cases.add("mul overflow in function evaluation",
10441090 \\const y = mul(300, 6000);
1045 \\fn mul(a: u16, b: u16) -> u16 {
1091 \\fn mul(a: u16, b: u16) u16 {
10461092 \\ return a * b;
10471093 \\}
10481094 \\
1049 \\export fn entry() -> usize { return @sizeOf(@typeOf(y)); }
1095 \\export fn entry() usize { return @sizeOf(@typeOf(y)); }
10501096 ,
10511097 ".tmp_source.zig:3:14: error: operation caused overflow",
10521098 ".tmp_source.zig:1:14: note: called from here");
10531099
10541100 cases.add("truncate sign mismatch",
1055 \\fn f() -> i8 {
1101 \\fn f() i8 {
10561102 \\ const x: u32 = 10;
10571103 \\ return @truncate(i8, x);
10581104 \\}
10591105 \\
1060 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
1106 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
10611107 , ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");
10621108
10631109 cases.add("try in function with non error return type",
1064 \\export fn f() {
1110 \\export fn f() void {
10651111 \\ try something();
10661112 \\}
1067 \\fn something() -> %void { }
1113 \\fn something() %void { }
10681114 ,
10691115 ".tmp_source.zig:2:5: error: expected type 'void', found 'error'");
10701116
10711117 cases.add("invalid pointer for var type",
1072 \\extern fn ext() -> usize;
1118 \\extern fn ext() usize;
10731119 \\var bytes: [ext()]u8 = undefined;
1074 \\export fn f() {
1120 \\export fn f() void {
10751121 \\ for (bytes) |*b, i| {
10761122 \\ *b = u8(i);
10771123 \\ }
......@@ -1079,21 +1125,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
10791125 , ".tmp_source.zig:2:13: error: unable to evaluate constant expression");
10801126
10811127 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{
10831129 \\ return x + y;
10841130 \\}
10851131 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10861132
10871133 cases.add("extern function with comptime parameter",
1088 \\extern fn foo(comptime x: i32, y: i32) -> i32;
1089 \\fn f() -> i32 {
1134 \\extern fn foo(comptime x: i32, y: i32) i32;
1135 \\fn f() i32 {
10901136 \\ return foo(1, 2);
10911137 \\}
1092 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
1138 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
10931139 , ".tmp_source.zig:1:15: error: comptime parameter not allowed in function with calling convention 'ccc'");
10941140
10951141 cases.add("convert fixed size array to slice with invalid size",
1096 \\export fn f() {
1142 \\export fn f() void {
10971143 \\ var array: [5]u8 = undefined;
10981144 \\ var foo = ([]const u32)(array)[0];
10991145 \\}
......@@ -1101,12 +1147,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11011147
11021148 cases.add("non-pure function returns type",
11031149 \\var a: u32 = 0;
1104 \\pub fn List(comptime T: type) -> type {
1150 \\pub fn List(comptime T: type) type {
11051151 \\ a += 1;
11061152 \\ return SmallList(T, 8);
11071153 \\}
11081154 \\
1109 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) -> type {
1155 \\pub fn SmallList(comptime T: type, comptime STATIC_SIZE: usize) type {
11101156 \\ return struct {
11111157 \\ items: []T,
11121158 \\ length: usize,
......@@ -1114,7 +1160,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11141160 \\ };
11151161 \\}
11161162 \\
1117 \\export fn function_with_return_type_type() {
1163 \\export fn function_with_return_type_type() void {
11181164 \\ var list: List(i32) = undefined;
11191165 \\ list.length = 10;
11201166 \\}
......@@ -1123,46 +1169,46 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11231169
11241170 cases.add("bogus method call on slice",
11251171 \\var self = "aoeu";
1126 \\fn f(m: []const u8) {
1172 \\fn f(m: []const u8) void {
11271173 \\ m.copy(u8, self[0..], m);
11281174 \\}
1129 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
1175 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
11301176 , ".tmp_source.zig:3:6: error: no member named 'copy' in '[]const u8'");
11311177
11321178 cases.add("wrong number of arguments for method fn call",
11331179 \\const Foo = struct {
1134 \\ fn method(self: &const Foo, a: i32) {}
1180 \\ fn method(self: &const Foo, a: i32) void {}
11351181 \\};
1136 \\fn f(foo: &const Foo) {
1182 \\fn f(foo: &const Foo) void {
11371183 \\
11381184 \\ foo.method(1, 2);
11391185 \\}
1140 \\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
1186 \\export fn entry() usize { return @sizeOf(@typeOf(f)); }
11411187 , ".tmp_source.zig:6:15: error: expected 2 arguments, found 3");
11421188
11431189 cases.add("assign through constant pointer",
1144 \\export fn f() {
1190 \\export fn f() void {
11451191 \\ var cstr = c"Hat";
11461192 \\ cstr[0] = 'W';
11471193 \\}
11481194 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11491195
11501196 cases.add("assign through constant slice",
1151 \\export fn f() {
1197 \\export fn f() void {
11521198 \\ var cstr: []const u8 = "Hat";
11531199 \\ cstr[0] = 'W';
11541200 \\}
11551201 , ".tmp_source.zig:3:11: error: cannot assign to constant");
11561202
11571203 cases.add("main function with bogus args type",
1158 \\pub fn main(args: [][]bogus) -> %void {}
1204 \\pub fn main(args: [][]bogus) %void {}
11591205 , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'");
11601206
11611207 cases.add("for loop missing element param",
1162 \\fn foo(blah: []u8) {
1208 \\fn foo(blah: []u8) void {
11631209 \\ for (blah) { }
11641210 \\}
1165 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1211 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
11661212 , ".tmp_source.zig:2:5: error: for loop expression missing element parameter");
11671213
11681214 cases.add("misspelled type with pointer only reference",
......@@ -1189,27 +1235,27 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
11891235 \\ jobject: ?JsonOA,
11901236 \\};
11911237 \\
1192 \\fn foo() {
1238 \\fn foo() void {
11931239 \\ var jll: JasonList = undefined;
11941240 \\ jll.init(1234);
11951241 \\ var jd = JsonNode {.kind = JsonType.JSONArray , .jobject = JsonOA.JSONArray {jll} };
11961242 \\}
11971243 \\
1198 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1244 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
11991245 , ".tmp_source.zig:5:16: error: use of undeclared identifier 'JsonList'");
12001246
12011247 cases.add("method call with first arg type primitive",
12021248 \\const Foo = struct {
12031249 \\ x: i32,
12041250 \\
1205 \\ fn init(x: i32) -> Foo {
1251 \\ fn init(x: i32) Foo {
12061252 \\ return Foo {
12071253 \\ .x = x,
12081254 \\ };
12091255 \\ }
12101256 \\};
12111257 \\
1212 \\export fn f() {
1258 \\export fn f() void {
12131259 \\ const derp = Foo.init(3);
12141260 \\
12151261 \\ derp.init();
......@@ -1221,7 +1267,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12211267 \\ len: usize,
12221268 \\ allocator: &Allocator,
12231269 \\
1224 \\ pub fn init(allocator: &Allocator) -> List {
1270 \\ pub fn init(allocator: &Allocator) List {
12251271 \\ return List {
12261272 \\ .len = 0,
12271273 \\ .allocator = allocator,
......@@ -1237,7 +1283,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12371283 \\ field: i32,
12381284 \\};
12391285 \\
1240 \\export fn foo() {
1286 \\export fn foo() void {
12411287 \\ var x = List.init(&global_allocator);
12421288 \\ x.init();
12431289 \\}
......@@ -1248,14 +1294,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12481294 \\const TINY_QUANTUM_SIZE = 1 << TINY_QUANTUM_SHIFT;
12491295 \\var block_aligned_stuff: usize = (4 + TINY_QUANTUM_SIZE) & ~(TINY_QUANTUM_SIZE - 1);
12501296 \\
1251 \\export fn entry() -> usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
1297 \\export fn entry() usize { return @sizeOf(@typeOf(block_aligned_stuff)); }
12521298 , ".tmp_source.zig:3:60: error: unable to perform binary not operation on type '(integer literal)'");
12531299
12541300 cases.addCase(x: {
12551301 const tc = cases.create("multiple files with private function error",
12561302 \\const foo = @import("foo.zig");
12571303 \\
1258 \\export fn callPrivFunction() {
1304 \\export fn callPrivFunction() void {
12591305 \\ foo.privateFunction();
12601306 \\}
12611307 ,
......@@ -1263,7 +1309,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12631309 "foo.zig:1:1: note: declared here");
12641310
12651311 tc.addSourceFile("foo.zig",
1266 \\fn privateFunction() { }
1312 \\fn privateFunction() void { }
12671313 );
12681314
12691315 break :x tc;
......@@ -1273,21 +1319,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12731319 \\const zero: i32 = 0;
12741320 \\const a = zero{1};
12751321 \\
1276 \\export fn entry() -> usize { return @sizeOf(@typeOf(a)); }
1322 \\export fn entry() usize { return @sizeOf(@typeOf(a)); }
12771323 , ".tmp_source.zig:2:11: error: expected type, found 'i32'");
12781324
12791325 cases.add("assign to constant field",
12801326 \\const Foo = struct {
12811327 \\ field: i32,
12821328 \\};
1283 \\export fn derp() {
1329 \\export fn derp() void {
12841330 \\ const f = Foo {.field = 1234,};
12851331 \\ f.field = 0;
12861332 \\}
12871333 , ".tmp_source.zig:6:13: error: cannot assign to constant");
12881334
12891335 cases.add("return from defer expression",
1290 \\pub fn testTrickyDefer() -> %void {
1336 \\pub fn testTrickyDefer() %void {
12911337 \\ defer canFail() catch {};
12921338 \\
12931339 \\ defer try canFail();
......@@ -1295,31 +1341,31 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
12951341 \\ const a = maybeInt() ?? return;
12961342 \\}
12971343 \\
1298 \\fn canFail() -> %void { }
1344 \\fn canFail() %void { }
12991345 \\
1300 \\pub fn maybeInt() -> ?i32 {
1346 \\pub fn maybeInt() ?i32 {
13011347 \\ return 0;
13021348 \\}
13031349 \\
1304 \\export fn entry() -> usize { return @sizeOf(@typeOf(testTrickyDefer)); }
1350 \\export fn entry() usize { return @sizeOf(@typeOf(testTrickyDefer)); }
13051351 , ".tmp_source.zig:4:11: error: cannot return from defer expression");
13061352
13071353 cases.add("attempt to access var args out of bounds",
1308 \\fn add(args: ...) -> i32 {
1354 \\fn add(args: ...) i32 {
13091355 \\ return args[0] + args[1];
13101356 \\}
13111357 \\
1312 \\fn foo() -> i32 {
1358 \\fn foo() i32 {
13131359 \\ return add(i32(1234));
13141360 \\}
13151361 \\
1316 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1362 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
13171363 ,
13181364 ".tmp_source.zig:2:26: error: index 1 outside argument list of size 1",
13191365 ".tmp_source.zig:6:15: note: called from here");
13201366
13211367 cases.add("pass integer literal to var args",
1322 \\fn add(args: ...) -> i32 {
1368 \\fn add(args: ...) i32 {
13231369 \\ var sum = i32(0);
13241370 \\ {comptime var i: usize = 0; inline while (i < args.len) : (i += 1) {
13251371 \\ sum += args[i];
......@@ -1327,34 +1373,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13271373 \\ return sum;
13281374 \\}
13291375 \\
1330 \\fn bar() -> i32 {
1376 \\fn bar() i32 {
13311377 \\ return add(1, 2, 3, 4);
13321378 \\}
13331379 \\
1334 \\export fn entry() -> usize { return @sizeOf(@typeOf(bar)); }
1380 \\export fn entry() usize { return @sizeOf(@typeOf(bar)); }
13351381 , ".tmp_source.zig:10:16: error: parameter of type '(integer literal)' requires comptime");
13361382
13371383 cases.add("assign too big number to u16",
1338 \\export fn foo() {
1384 \\export fn foo() void {
13391385 \\ var vga_mem: u16 = 0xB8000;
13401386 \\}
13411387 , ".tmp_source.zig:2:24: error: integer value 753664 cannot be implicitly casted to type 'u16'");
13421388
13431389 cases.add("global variable alignment non power of 2",
13441390 \\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)); }
13461392 , ".tmp_source.zig:1:32: error: alignment value 3 is not a power of 2");
13471393
13481394 cases.add("function alignment non power of 2",
1349 \\extern fn foo() align(3);
1350 \\export fn entry() { return foo(); }
1395 \\extern fn foo() align(3) void;
1396 \\export fn entry() void { return foo(); }
13511397 , ".tmp_source.zig:1:23: error: alignment value 3 is not a power of 2");
13521398
13531399 cases.add("compile log",
1354 \\export fn foo() {
1400 \\export fn foo() void {
13551401 \\ comptime bar(12, "hi");
13561402 \\}
1357 \\fn bar(a: i32, b: []const u8) {
1403 \\fn bar(a: i32, b: []const u8) void {
13581404 \\ @compileLog("begin");
13591405 \\ @compileLog("a", a, "b", b);
13601406 \\ @compileLog("end");
......@@ -1374,15 +1420,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13741420 \\ c: u2,
13751421 \\};
13761422 \\
1377 \\fn foo(bit_field: &const BitField) -> u3 {
1423 \\fn foo(bit_field: &const BitField) u3 {
13781424 \\ return bar(&bit_field.b);
13791425 \\}
13801426 \\
1381 \\fn bar(x: &const u3) -> u3 {
1427 \\fn bar(x: &const u3) u3 {
13821428 \\ return *x;
13831429 \\}
13841430 \\
1385 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1431 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
13861432 , ".tmp_source.zig:8:26: error: expected type '&const u3', found '&align(1:3:6) const u3'");
13871433
13881434 cases.add("referring to a struct that is invalid",
......@@ -1390,11 +1436,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
13901436 \\ Type: u8,
13911437 \\};
13921438 \\
1393 \\export fn foo() {
1439 \\export fn foo() void {
13941440 \\ comptime assert(@sizeOf(UsbDeviceRequest) == 0x8);
13951441 \\}
13961442 \\
1397 \\fn assert(ok: bool) {
1443 \\fn assert(ok: bool) void {
13981444 \\ if (!ok) unreachable;
13991445 \\}
14001446 ,
......@@ -1402,92 +1448,92 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
14021448 ".tmp_source.zig:6:20: note: called from here");
14031449
14041450 cases.add("control flow uses comptime var at runtime",
1405 \\export fn foo() {
1451 \\export fn foo() void {
14061452 \\ comptime var i = 0;
14071453 \\ while (i < 5) : (i += 1) {
14081454 \\ bar();
14091455 \\ }
14101456 \\}
14111457 \\
1412 \\fn bar() { }
1458 \\fn bar() void { }
14131459 ,
14141460 ".tmp_source.zig:3:5: error: control flow attempts to use compile-time variable at runtime",
14151461 ".tmp_source.zig:3:24: note: compile-time variable assigned here");
14161462
14171463 cases.add("ignored return value",
1418 \\export fn foo() {
1464 \\export fn foo() void {
14191465 \\ bar();
14201466 \\}
1421 \\fn bar() -> i32 { return 0; }
1467 \\fn bar() i32 { return 0; }
14221468 , ".tmp_source.zig:2:8: error: expression value is ignored");
14231469
14241470 cases.add("ignored assert-err-ok return value",
1425 \\export fn foo() {
1471 \\export fn foo() void {
14261472 \\ bar() catch unreachable;
14271473 \\}
1428 \\fn bar() -> %i32 { return 0; }
1474 \\fn bar() %i32 { return 0; }
14291475 , ".tmp_source.zig:2:11: error: expression value is ignored");
14301476
14311477 cases.add("ignored statement value",
1432 \\export fn foo() {
1478 \\export fn foo() void {
14331479 \\ 1;
14341480 \\}
14351481 , ".tmp_source.zig:2:5: error: expression value is ignored");
14361482
14371483 cases.add("ignored comptime statement value",
1438 \\export fn foo() {
1484 \\export fn foo() void {
14391485 \\ comptime {1;}
14401486 \\}
14411487 , ".tmp_source.zig:2:15: error: expression value is ignored");
14421488
14431489 cases.add("ignored comptime value",
1444 \\export fn foo() {
1490 \\export fn foo() void {
14451491 \\ comptime 1;
14461492 \\}
14471493 , ".tmp_source.zig:2:5: error: expression value is ignored");
14481494
14491495 cases.add("ignored defered statement value",
1450 \\export fn foo() {
1496 \\export fn foo() void {
14511497 \\ defer {1;}
14521498 \\}
14531499 , ".tmp_source.zig:2:12: error: expression value is ignored");
14541500
14551501 cases.add("ignored defered function call",
1456 \\export fn foo() {
1502 \\export fn foo() void {
14571503 \\ defer bar();
14581504 \\}
1459 \\fn bar() -> %i32 { return 0; }
1505 \\fn bar() %i32 { return 0; }
14601506 , ".tmp_source.zig:2:14: error: expression value is ignored");
14611507
14621508 cases.add("dereference an array",
14631509 \\var s_buffer: [10]u8 = undefined;
1464 \\pub fn pass(in: []u8) -> []u8 {
1510 \\pub fn pass(in: []u8) []u8 {
14651511 \\ var out = &s_buffer;
14661512 \\ *out[0] = in[0];
14671513 \\ return (*out)[0..1];
14681514 \\}
14691515 \\
1470 \\export fn entry() -> usize { return @sizeOf(@typeOf(pass)); }
1516 \\export fn entry() usize { return @sizeOf(@typeOf(pass)); }
14711517 , ".tmp_source.zig:4:5: error: attempt to dereference non pointer type '[10]u8'");
14721518
14731519 cases.add("pass const ptr to mutable ptr fn",
1474 \\fn foo() -> bool {
1520 \\fn foo() bool {
14751521 \\ const a = ([]const u8)("a");
14761522 \\ const b = &a;
14771523 \\ return ptrEql(b, b);
14781524 \\}
1479 \\fn ptrEql(a: &[]const u8, b: &[]const u8) -> bool {
1525 \\fn ptrEql(a: &[]const u8, b: &[]const u8) bool {
14801526 \\ return true;
14811527 \\}
14821528 \\
1483 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1529 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
14841530 , ".tmp_source.zig:4:19: error: expected type '&[]const u8', found '&const []const u8'");
14851531
14861532 cases.addCase(x: {
14871533 const tc = cases.create("export collision",
14881534 \\const foo = @import("foo.zig");
14891535 \\
1490 \\export fn bar() -> usize {
1536 \\export fn bar() usize {
14911537 \\ return foo.baz;
14921538 \\}
14931539 ,
......@@ -1495,7 +1541,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
14951541 ".tmp_source.zig:3:8: note: other symbol here");
14961542
14971543 tc.addSourceFile("foo.zig",
1498 \\export fn bar() {}
1544 \\export fn bar() void {}
14991545 \\pub const baz = 1234;
15001546 );
15011547
......@@ -1504,20 +1550,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15041550
15051551 cases.add("pass non-copyable type by value to function",
15061552 \\const Point = struct { x: i32, y: i32, };
1507 \\fn foo(p: Point) { }
1508 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1553 \\fn foo(p: Point) void { }
1554 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
15091555 , ".tmp_source.zig:2:11: error: type 'Point' is not copyable; cannot pass by value");
15101556
15111557 cases.add("implicit cast from array to mutable slice",
15121558 \\var global_array: [10]i32 = undefined;
1513 \\fn foo(param: []i32) {}
1514 \\export fn entry() {
1559 \\fn foo(param: []i32) void {}
1560 \\export fn entry() void {
15151561 \\ foo(global_array);
15161562 \\}
15171563 , ".tmp_source.zig:4:9: error: expected type '[]i32', found '[10]i32'");
15181564
15191565 cases.add("ptrcast to non-pointer",
1520 \\export fn entry(a: &i32) -> usize {
1566 \\export fn entry(a: &i32) usize {
15211567 \\ return @ptrCast(usize, a);
15221568 \\}
15231569 , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'");
......@@ -1525,10 +1571,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15251571 cases.add("too many error values to cast to small integer",
15261572 \\error A; error B; error C; error D; error E; error F; error G; error H;
15271573 \\const u2 = @IntType(false, 2);
1528 \\fn foo(e: error) -> u2 {
1574 \\fn foo(e: error) u2 {
15291575 \\ return u2(e);
15301576 \\}
1531 \\export fn entry() -> usize { return @sizeOf(@typeOf(foo)); }
1577 \\export fn entry() usize { return @sizeOf(@typeOf(foo)); }
15321578 , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'");
15331579
15341580 cases.add("asm at compile time",
......@@ -1536,7 +1582,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15361582 \\ doSomeAsm();
15371583 \\}
15381584 \\
1539 \\fn doSomeAsm() {
1585 \\fn doSomeAsm() void {
15401586 \\ asm volatile (
15411587 \\ \\.globl aoeu;
15421588 \\ \\.type aoeu, @function;
......@@ -1547,13 +1593,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15471593
15481594 cases.add("invalid member of builtin enum",
15491595 \\const builtin = @import("builtin");
1550 \\export fn entry() {
1596 \\export fn entry() void {
15511597 \\ const foo = builtin.Arch.x86;
15521598 \\}
15531599 , ".tmp_source.zig:3:29: error: container 'Arch' has no member called 'x86'");
15541600
15551601 cases.add("int to ptr of 0 bits",
1556 \\export fn foo() {
1602 \\export fn foo() void {
15571603 \\ var x: usize = 0x1000;
15581604 \\ var y: &void = @intToPtr(&void, x);
15591605 \\}
......@@ -1561,25 +1607,25 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
15611607
15621608 cases.add("@fieldParentPtr - non struct",
15631609 \\const Foo = i32;
1564 \\export fn foo(a: &i32) -> &Foo {
1610 \\export fn foo(a: &i32) &Foo {
15651611 \\ return @fieldParentPtr(Foo, "a", a);
15661612 \\}
15671613 , ".tmp_source.zig:3:28: error: expected struct type, found 'i32'");
15681614
15691615 cases.add("@fieldParentPtr - bad field name",
1570 \\const Foo = struct {
1616 \\const Foo = extern struct {
15711617 \\ derp: i32,
15721618 \\};
1573 \\export fn foo(a: &i32) -> &Foo {
1619 \\export fn foo(a: &i32) &Foo {
15741620 \\ return @fieldParentPtr(Foo, "a", a);
15751621 \\}
15761622 , ".tmp_source.zig:5:33: error: struct 'Foo' has no field 'a'");
15771623
15781624 cases.add("@fieldParentPtr - field pointer is not pointer",
1579 \\const Foo = struct {
1625 \\const Foo = extern struct {
15801626 \\ a: i32,
15811627 \\};
1582 \\export fn foo(a: i32) -> &Foo {
1628 \\export fn foo(a: i32) &Foo {
15831629 \\ return @fieldParentPtr(Foo, "a", a);
15841630 \\}
15851631 , ".tmp_source.zig:5:38: error: expected pointer, found 'i32'");
......@@ -1611,7 +1657,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16111657
16121658 cases.add("@offsetOf - non struct",
16131659 \\const Foo = i32;
1614 \\export fn foo() -> usize {
1660 \\export fn foo() usize {
16151661 \\ return @offsetOf(Foo, "a");
16161662 \\}
16171663 , ".tmp_source.zig:3:22: error: expected struct type, found 'i32'");
......@@ -1620,7 +1666,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16201666 \\const Foo = struct {
16211667 \\ derp: i32,
16221668 \\};
1623 \\export fn foo() -> usize {
1669 \\export fn foo() usize {
16241670 \\ return @offsetOf(Foo, "a");
16251671 \\}
16261672 , ".tmp_source.zig:5:27: error: struct 'Foo' has no field 'a'");
......@@ -1630,21 +1676,21 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16301676 , "error: no member named 'main' in '");
16311677
16321678 cases.addExe("private main fn",
1633 \\fn main() {}
1679 \\fn main() void {}
16341680 ,
16351681 "error: 'main' is private",
16361682 ".tmp_source.zig:1:1: note: declared here");
16371683
16381684 cases.add("setting a section on an extern variable",
16391685 \\extern var foo: i32 section(".text2");
1640 \\export fn entry() -> i32 {
1686 \\export fn entry() i32 {
16411687 \\ return foo;
16421688 \\}
16431689 ,
16441690 ".tmp_source.zig:1:29: error: cannot set section of external variable 'foo'");
16451691
16461692 cases.add("setting a section on a local variable",
1647 \\export fn entry() -> i32 {
1693 \\export fn entry() i32 {
16481694 \\ var foo: i32 section(".text2") = 1234;
16491695 \\ return foo;
16501696 \\}
......@@ -1652,15 +1698,15 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16521698 ".tmp_source.zig:2:26: error: cannot set section of local variable 'foo'");
16531699
16541700 cases.add("setting a section on an extern fn",
1655 \\extern fn foo() section(".text2");
1656 \\export fn entry() {
1701 \\extern fn foo() section(".text2") void;
1702 \\export fn entry() void {
16571703 \\ foo();
16581704 \\}
16591705 ,
16601706 ".tmp_source.zig:1:25: error: cannot set section of external function 'foo'");
16611707
16621708 cases.add("returning address of local variable - simple",
1663 \\export fn foo() -> &i32 {
1709 \\export fn foo() &i32 {
16641710 \\ var a: i32 = undefined;
16651711 \\ return &a;
16661712 \\}
......@@ -1668,7 +1714,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16681714 ".tmp_source.zig:3:13: error: function returns address of local variable");
16691715
16701716 cases.add("returning address of local variable - phi",
1671 \\export fn foo(c: bool) -> &i32 {
1717 \\export fn foo(c: bool) &i32 {
16721718 \\ var a: i32 = undefined;
16731719 \\ var b: i32 = undefined;
16741720 \\ return if (c) &a else &b;
......@@ -1677,13 +1723,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16771723 ".tmp_source.zig:4:12: error: function returns address of local variable");
16781724
16791725 cases.add("inner struct member shadowing outer struct member",
1680 \\fn A() -> type {
1726 \\fn A() type {
16811727 \\ return struct {
16821728 \\ b: B(),
16831729 \\
16841730 \\ const Self = this;
16851731 \\
1686 \\ fn B() -> type {
1732 \\ fn B() type {
16871733 \\ return struct {
16881734 \\ const Self = this;
16891735 \\ };
......@@ -1693,7 +1739,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
16931739 \\comptime {
16941740 \\ assert(A().B().Self != A().Self);
16951741 \\}
1696 \\fn assert(ok: bool) {
1742 \\fn assert(ok: bool) void {
16971743 \\ if (!ok) unreachable;
16981744 \\}
16991745 ,
......@@ -1701,87 +1747,87 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
17011747 ".tmp_source.zig:5:9: note: previous definition is here");
17021748
17031749 cases.add("while expected bool, got nullable",
1704 \\export fn foo() {
1750 \\export fn foo() void {
17051751 \\ while (bar()) {}
17061752 \\}
1707 \\fn bar() -> ?i32 { return 1; }
1753 \\fn bar() ?i32 { return 1; }
17081754 ,
17091755 ".tmp_source.zig:2:15: error: expected type 'bool', found '?i32'");
17101756
17111757 cases.add("while expected bool, got error union",
1712 \\export fn foo() {
1758 \\export fn foo() void {
17131759 \\ while (bar()) {}
17141760 \\}
1715 \\fn bar() -> %i32 { return 1; }
1761 \\fn bar() %i32 { return 1; }
17161762 ,
17171763 ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'");
17181764
17191765 cases.add("while expected nullable, got bool",
1720 \\export fn foo() {
1766 \\export fn foo() void {
17211767 \\ while (bar()) |x| {}
17221768 \\}
1723 \\fn bar() -> bool { return true; }
1769 \\fn bar() bool { return true; }
17241770 ,
17251771 ".tmp_source.zig:2:15: error: expected nullable type, found 'bool'");
17261772
17271773 cases.add("while expected nullable, got error union",
1728 \\export fn foo() {
1774 \\export fn foo() void {
17291775 \\ while (bar()) |x| {}
17301776 \\}
1731 \\fn bar() -> %i32 { return 1; }
1777 \\fn bar() %i32 { return 1; }
17321778 ,
17331779 ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'");
17341780
17351781 cases.add("while expected error union, got bool",
1736 \\export fn foo() {
1782 \\export fn foo() void {
17371783 \\ while (bar()) |x| {} else |err| {}
17381784 \\}
1739 \\fn bar() -> bool { return true; }
1785 \\fn bar() bool { return true; }
17401786 ,
17411787 ".tmp_source.zig:2:15: error: expected error union type, found 'bool'");
17421788
17431789 cases.add("while expected error union, got nullable",
1744 \\export fn foo() {
1790 \\export fn foo() void {
17451791 \\ while (bar()) |x| {} else |err| {}
17461792 \\}
1747 \\fn bar() -> ?i32 { return 1; }
1793 \\fn bar() ?i32 { return 1; }
17481794 ,
17491795 ".tmp_source.zig:2:15: error: expected error union type, found '?i32'");
17501796
17511797 cases.add("inline fn calls itself indirectly",
1752 \\export fn foo() {
1798 \\export fn foo() void {
17531799 \\ bar();
17541800 \\}
1755 \\inline fn bar() {
1801 \\inline fn bar() void {
17561802 \\ baz();
17571803 \\ quux();
17581804 \\}
1759 \\inline fn baz() {
1805 \\inline fn baz() void {
17601806 \\ bar();
17611807 \\ quux();
17621808 \\}
1763 \\extern fn quux();
1809 \\extern fn quux() void;
17641810 ,
17651811 ".tmp_source.zig:4:8: error: unable to inline function");
17661812
17671813 cases.add("save reference to inline function",
1768 \\export fn foo() {
1814 \\export fn foo() void {
17691815 \\ quux(@ptrToInt(bar));
17701816 \\}
1771 \\inline fn bar() { }
1772 \\extern fn quux(usize);
1817 \\inline fn bar() void { }
1818 \\extern fn quux(usize) void;
17731819 ,
17741820 ".tmp_source.zig:4:8: error: unable to inline function");
17751821
17761822 cases.add("signed integer division",
1777 \\export fn foo(a: i32, b: i32) -> i32 {
1823 \\export fn foo(a: i32, b: i32) i32 {
17781824 \\ return a / b;
17791825 \\}
17801826 ,
17811827 ".tmp_source.zig:2:14: error: division with 'i32' and 'i32': signed integers must use @divTrunc, @divFloor, or @divExact");
17821828
17831829 cases.add("signed integer remainder division",
1784 \\export fn foo(a: i32, b: i32) -> i32 {
1830 \\export fn foo(a: i32, b: i32) i32 {
17851831 \\ return a % b;
17861832 \\}
17871833 ,
......@@ -1802,7 +1848,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18021848 \\ const c = a / b;
18031849 \\}
18041850 ,
1805 ".tmp_source.zig:4:17: error: division by zero is undefined");
1851 ".tmp_source.zig:4:17: error: division by zero");
18061852
18071853 cases.add("compile-time remainder division by zero",
18081854 \\comptime {
......@@ -1811,7 +1857,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18111857 \\ const c = a % b;
18121858 \\}
18131859 ,
1814 ".tmp_source.zig:4:17: error: division by zero is undefined");
1860 ".tmp_source.zig:4:17: error: division by zero");
18151861
18161862 cases.add("compile-time integer cast truncates bits",
18171863 \\comptime {
......@@ -1821,17 +1867,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18211867 ,
18221868 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
18231869
1824 cases.add("@setDebugSafety twice for same scope",
1825 \\export fn foo() {
1826 \\ @setDebugSafety(this, false);
1827 \\ @setDebugSafety(this, false);
1870 cases.add("@setRuntimeSafety twice for same scope",
1871 \\export fn foo() void {
1872 \\ @setRuntimeSafety(false);
1873 \\ @setRuntimeSafety(false);
18281874 \\}
18291875 ,
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",
18311877 ".tmp_source.zig:2:5: note: first set here");
18321878
18331879 cases.add("@setFloatMode twice for same scope",
1834 \\export fn foo() {
1880 \\export fn foo() void {
18351881 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
18361882 \\ @setFloatMode(this, @import("builtin").FloatMode.Optimized);
18371883 \\}
......@@ -1840,14 +1886,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18401886 ".tmp_source.zig:2:5: note: first set here");
18411887
18421888 cases.add("array access of type",
1843 \\export fn foo() {
1889 \\export fn foo() void {
18441890 \\ var b: u8[40] = undefined;
18451891 \\}
18461892 ,
18471893 ".tmp_source.zig:2:14: error: array access of non-array type 'type'");
18481894
18491895 cases.add("cannot break out of defer expression",
1850 \\export fn foo() {
1896 \\export fn foo() void {
18511897 \\ while (true) {
18521898 \\ defer {
18531899 \\ break;
......@@ -1858,7 +1904,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18581904 ".tmp_source.zig:4:13: error: cannot break out of defer expression");
18591905
18601906 cases.add("cannot continue out of defer expression",
1861 \\export fn foo() {
1907 \\export fn foo() void {
18621908 \\ while (true) {
18631909 \\ defer {
18641910 \\ continue;
......@@ -1869,24 +1915,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18691915 ".tmp_source.zig:4:13: error: cannot continue out of defer expression");
18701916
18711917 cases.add("calling a var args function only known at runtime",
1872 \\var foos = []fn(...) { foo1, foo2 };
1918 \\var foos = []fn(...) void { foo1, foo2 };
18731919 \\
1874 \\fn foo1(args: ...) {}
1875 \\fn foo2(args: ...) {}
1920 \\fn foo1(args: ...) void {}
1921 \\fn foo2(args: ...) void {}
18761922 \\
1877 \\pub fn main() -> %void {
1923 \\pub fn main() %void {
18781924 \\ foos[0]();
18791925 \\}
18801926 ,
18811927 ".tmp_source.zig:7:9: error: calling a generic function requires compile-time known function value");
18821928
18831929 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 };
18851931 \\
1886 \\fn foo1(arg: var) {}
1887 \\fn foo2(arg: var) {}
1932 \\fn foo1(arg: var) void {}
1933 \\fn foo2(arg: var) void {}
18881934 \\
1889 \\pub fn main() -> %void {
1935 \\pub fn main() %void {
18901936 \\ foos[0](true);
18911937 \\}
18921938 ,
......@@ -1898,7 +1944,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18981944 \\const bar = baz + foo;
18991945 \\const baz = 1;
19001946 \\
1901 \\export fn entry() -> i32 {
1947 \\export fn entry() i32 {
19021948 \\ return bar;
19031949 \\}
19041950 ,
......@@ -1913,7 +1959,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19131959 \\
19141960 \\var foo: Foo = undefined;
19151961 \\
1916 \\export fn entry() -> usize {
1962 \\export fn entry() usize {
19171963 \\ return @sizeOf(@typeOf(foo.x));
19181964 \\}
19191965 ,
......@@ -1934,14 +1980,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19341980 ".tmp_source.zig:2:15: error: float literal out of range of any type");
19351981
19361982 cases.add("explicit cast float literal to integer when there is a fraction component",
1937 \\export fn entry() -> i32 {
1983 \\export fn entry() i32 {
19381984 \\ return i32(12.34);
19391985 \\}
19401986 ,
19411987 ".tmp_source.zig:2:16: error: fractional component prevents float value 12.340000 from being casted to type 'i32'");
19421988
19431989 cases.add("non pointer given to @ptrToInt",
1944 \\export fn entry(x: i32) -> usize {
1990 \\export fn entry(x: i32) usize {
19451991 \\ return @ptrToInt(x);
19461992 \\}
19471993 ,
......@@ -1962,14 +2008,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19622008 ".tmp_source.zig:2:15: error: exact shift shifted out 1 bits");
19632009
19642010 cases.add("shifting without int type or comptime known",
1965 \\export fn entry(x: u8) -> u8 {
2011 \\export fn entry(x: u8) u8 {
19662012 \\ return 0x11 << x;
19672013 \\}
19682014 ,
19692015 ".tmp_source.zig:2:17: error: LHS of shift must be an integer type, or RHS must be compile-time known");
19702016
19712017 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 {
19732019 \\ return x << y;
19742020 \\}
19752021 ,
......@@ -1977,7 +2023,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19772023
19782024 cases.add("globally shadowing a primitive type",
19792025 \\const u16 = @intType(false, 8);
1980 \\export fn entry() {
2026 \\export fn entry() void {
19812027 \\ const a: u16 = 300;
19822028 \\}
19832029 ,
......@@ -1989,12 +2035,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
19892035 \\ b: u32,
19902036 \\};
19912037 \\
1992 \\export fn entry() {
2038 \\export fn entry() void {
19932039 \\ var foo = Foo { .a = 1, .b = 10 };
19942040 \\ bar(&foo.b);
19952041 \\}
19962042 \\
1997 \\fn bar(x: &u32) {
2043 \\fn bar(x: &u32) void {
19982044 \\ *x += 1;
19992045 \\}
20002046 ,
......@@ -2006,20 +2052,20 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20062052 \\ b: u32,
20072053 \\};
20082054 \\
2009 \\export fn entry() {
2055 \\export fn entry() void {
20102056 \\ var foo = Foo { .a = 1, .b = 10 };
20112057 \\ foo.b += 1;
20122058 \\ bar((&foo.b)[0..1]);
20132059 \\}
20142060 \\
2015 \\fn bar(x: []u32) {
2061 \\fn bar(x: []u32) void {
20162062 \\ x[0] += 1;
20172063 \\}
20182064 ,
20192065 ".tmp_source.zig:9:17: error: expected type '[]u32', found '[]align(1) u32'");
20202066
20212067 cases.add("increase pointer alignment in @ptrCast",
2022 \\export fn entry() -> u32 {
2068 \\export fn entry() u32 {
20232069 \\ var bytes: [4]u8 = []u8{0x01, 0x02, 0x03, 0x04};
20242070 \\ const ptr = @ptrCast(&u32, &bytes[0]);
20252071 \\ return *ptr;
......@@ -2030,7 +2076,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20302076 ".tmp_source.zig:3:27: note: '&u32' has alignment 4");
20312077
20322078 cases.add("increase pointer alignment in slice resize",
2033 \\export fn entry() -> u32 {
2079 \\export fn entry() u32 {
20342080 \\ var bytes = []u8{0x01, 0x02, 0x03, 0x04};
20352081 \\ return ([]u32)(bytes[0..])[0];
20362082 \\}
......@@ -2040,26 +2086,26 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20402086 ".tmp_source.zig:3:19: note: '[]u32' has alignment 4");
20412087
20422088 cases.add("@alignCast expects pointer or slice",
2043 \\export fn entry() {
2089 \\export fn entry() void {
20442090 \\ @alignCast(4, u32(3));
20452091 \\}
20462092 ,
20472093 ".tmp_source.zig:2:22: error: expected pointer or slice, found 'u32'");
20482094
20492095 cases.add("passing an under-aligned function pointer",
2050 \\export fn entry() {
2096 \\export fn entry() void {
20512097 \\ testImplicitlyDecreaseFnAlign(alignedSmall, 1234);
20522098 \\}
2053 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) -> i32, answer: i32) {
2099 \\fn testImplicitlyDecreaseFnAlign(ptr: fn () align(8) i32, answer: i32) void {
20542100 \\ if (ptr() != answer) unreachable;
20552101 \\}
2056 \\fn alignedSmall() align(4) -> i32 { return 1234; }
2102 \\fn alignedSmall() align(4) i32 { return 1234; }
20572103 ,
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
20602106 cases.add("passing a not-aligned-enough pointer to cmpxchg",
20612107 \\const AtomicOrder = @import("builtin").AtomicOrder;
2062 \\export fn entry() -> bool {
2108 \\export fn entry() bool {
20632109 \\ var x: i32 align(1) = 1234;
20642110 \\ while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
20652111 \\ return x == 5678;
......@@ -2078,7 +2124,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20782124 \\comptime {
20792125 \\ foo();
20802126 \\}
2081 \\fn foo() {
2127 \\fn foo() void {
20822128 \\ @setEvalBranchQuota(1001);
20832129 \\}
20842130 ,
......@@ -2088,8 +2134,8 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20882134
20892135 cases.add("wrong pointer implicitly casted to pointer to @OpaqueType()",
20902136 \\const Derp = @OpaqueType();
2091 \\extern fn bar(d: &Derp);
2092 \\export fn foo() {
2137 \\extern fn bar(d: &Derp) void;
2138 \\export fn foo() void {
20932139 \\ const x = u8(1);
20942140 \\ bar(@ptrCast(&c_void, &x));
20952141 \\}
......@@ -2099,7 +2145,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20992145 cases.add("non-const variables of things that require const variables",
21002146 \\const Opaque = @OpaqueType();
21012147 \\
2102 \\export fn entry(opaque: &Opaque) {
2148 \\export fn entry(opaque: &Opaque) void {
21032149 \\ var m2 = &2;
21042150 \\ const y: u32 = *m2;
21052151 \\
......@@ -2117,7 +2163,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21172163 \\}
21182164 \\
21192165 \\const Foo = struct {
2120 \\ fn bar(self: &const Foo) {}
2166 \\ fn bar(self: &const Foo) void {}
21212167 \\};
21222168 ,
21232169 ".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) {
21292175 ".tmp_source.zig:12:4: error: variable of type 'Opaque' must be const or comptime",
21302176 ".tmp_source.zig:13:4: error: variable of type 'type' must be const or comptime",
21312177 ".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",
21332179 ".tmp_source.zig:17:4: error: unreachable code");
21342180
21352181 cases.add("wrong types given to atomic order args in cmpxchg",
2136 \\export fn entry() {
2182 \\export fn entry() void {
21372183 \\ var x: i32 = 1234;
21382184 \\ while (!@cmpxchg(&x, 1234, 5678, u32(1234), u32(1234))) {}
21392185 \\}
......@@ -2141,7 +2187,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21412187 ".tmp_source.zig:3:41: error: expected type 'AtomicOrder', found 'u32'");
21422188
21432189 cases.add("wrong types given to @export",
2144 \\extern fn entry() { }
2190 \\extern fn entry() void { }
21452191 \\comptime {
21462192 \\ @export("entry", entry, u32(1234));
21472193 \\}
......@@ -2166,7 +2212,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21662212 \\ },
21672213 \\};
21682214 \\
2169 \\export fn entry() {
2215 \\export fn entry() void {
21702216 \\ const a = MdNode.Header {
21712217 \\ .text = MdText.init(&std.debug.global_allocator),
21722218 \\ .weight = HeaderWeight.H1,
......@@ -2183,24 +2229,24 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
21832229 ".tmp_source.zig:2:5: error: @setAlignStack outside function");
21842230
21852231 cases.add("@setAlignStack in naked function",
2186 \\export nakedcc fn entry() {
2232 \\export nakedcc fn entry() void {
21872233 \\ @setAlignStack(16);
21882234 \\}
21892235 ,
21902236 ".tmp_source.zig:2:5: error: @setAlignStack in naked function");
21912237
21922238 cases.add("@setAlignStack in inline function",
2193 \\export fn entry() {
2239 \\export fn entry() void {
21942240 \\ foo();
21952241 \\}
2196 \\inline fn foo() {
2242 \\inline fn foo() void {
21972243 \\ @setAlignStack(16);
21982244 \\}
21992245 ,
22002246 ".tmp_source.zig:5:5: error: @setAlignStack in inline function");
22012247
22022248 cases.add("@setAlignStack set twice",
2203 \\export fn entry() {
2249 \\export fn entry() void {
22042250 \\ @setAlignStack(16);
22052251 \\ @setAlignStack(16);
22062252 \\}
......@@ -2209,7 +2255,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22092255 ".tmp_source.zig:2:5: note: first set here");
22102256
22112257 cases.add("@setAlignStack too big",
2212 \\export fn entry() {
2258 \\export fn entry() void {
22132259 \\ @setAlignStack(511 + 1);
22142260 \\}
22152261 ,
......@@ -2218,14 +2264,14 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22182264 cases.add("storing runtime value in compile time variable then using it",
22192265 \\const Mode = @import("builtin").Mode;
22202266 \\
2221 \\fn Free(comptime filename: []const u8) -> TestCase {
2267 \\fn Free(comptime filename: []const u8) TestCase {
22222268 \\ return TestCase {
22232269 \\ .filename = filename,
22242270 \\ .problem_type = ProblemType.Free,
22252271 \\ };
22262272 \\}
22272273 \\
2228 \\fn LibC(comptime filename: []const u8) -> TestCase {
2274 \\fn LibC(comptime filename: []const u8) TestCase {
22292275 \\ return TestCase {
22302276 \\ .filename = filename,
22312277 \\ .problem_type = ProblemType.LinkLibC,
......@@ -2242,7 +2288,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22422288 \\ LinkLibC,
22432289 \\};
22442290 \\
2245 \\export fn entry() {
2291 \\export fn entry() void {
22462292 \\ const tests = []TestCase {
22472293 \\ Free("001"),
22482294 \\ Free("002"),
......@@ -2263,34 +2309,34 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
22632309 cases.add("field access of opaque type",
22642310 \\const MyType = @OpaqueType();
22652311 \\
2266 \\export fn entry() -> bool {
2312 \\export fn entry() bool {
22672313 \\ var x: i32 = 1;
22682314 \\ return bar(@ptrCast(&MyType, &x));
22692315 \\}
22702316 \\
2271 \\fn bar(x: &MyType) -> bool {
2317 \\fn bar(x: &MyType) bool {
22722318 \\ return x.blah;
22732319 \\}
22742320 ,
22752321 ".tmp_source.zig:9:13: error: type '&MyType' does not support field access");
22762322
22772323 cases.add("carriage return special case",
2278 "fn test() -> bool {\r\n" ++
2324 "fn test() bool {\r\n" ++
22792325 " true\r\n" ++
22802326 "}\r\n"
22812327 ,
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
22842330 cases.add("non-printable invalid character",
22852331 "\xff\xfe" ++
2286 \\fn test() -> bool {\r
2332 \\fn test() bool {\r
22872333 \\ true\r
22882334 \\}
22892335 ,
22902336 ".tmp_source.zig:1:1: error: invalid character: '\\xff'");
22912337
22922338 cases.add("non-printable invalid character with escape alternative",
2293 "fn test() -> bool {\n" ++
2339 "fn test() bool {\n" ++
22942340 "\ttrue\n" ++
22952341 "}\n"
22962342 ,
......@@ -2307,9 +2353,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23072353 \\comptime {
23082354 \\ _ = @ArgType(@typeOf(add), 2);
23092355 \\}
2310 \\fn add(a: i32, b: i32) -> i32 { return a + b; }
2356 \\fn add(a: i32, b: i32) i32 { return a + b; }
23112357 ,
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
23142360 cases.add("@memberType on unsupported type",
23152361 \\comptime {
......@@ -2374,17 +2420,17 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23742420 ".tmp_source.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members");
23752421
23762422 cases.add("calling var args extern function, passing array instead of pointer",
2377 \\export fn entry() {
2423 \\export fn entry() void {
23782424 \\ foo("hello");
23792425 \\}
2380 \\pub extern fn foo(format: &const u8, ...);
2426 \\pub extern fn foo(format: &const u8, ...) void;
23812427 ,
23822428 ".tmp_source.zig:2:9: error: expected type '&const u8', found '[5]u8'");
23832429
23842430 cases.add("constant inside comptime function has compile error",
23852431 \\const ContextAllocator = MemoryPool(usize);
23862432 \\
2387 \\pub fn MemoryPool(comptime T: type) -> type {
2433 \\pub fn MemoryPool(comptime T: type) type {
23882434 \\ const free_list_t = @compileError("aoeu");
23892435 \\
23902436 \\ return struct {
......@@ -2392,7 +2438,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
23922438 \\ };
23932439 \\}
23942440 \\
2395 \\export fn entry() {
2441 \\export fn entry() void {
23962442 \\ var allocator: ContextAllocator = undefined;
23972443 \\}
23982444 ,
......@@ -2409,7 +2455,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24092455 \\ Five,
24102456 \\};
24112457 \\
2412 \\export fn entry() {
2458 \\export fn entry() void {
24132459 \\ var x = Small.One;
24142460 \\}
24152461 ,
......@@ -2422,7 +2468,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24222468 \\ Three,
24232469 \\};
24242470 \\
2425 \\export fn entry() {
2471 \\export fn entry() void {
24262472 \\ var x = Small.One;
24272473 \\}
24282474 ,
......@@ -2436,7 +2482,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24362482 \\ Four,
24372483 \\};
24382484 \\
2439 \\export fn entry() {
2485 \\export fn entry() void {
24402486 \\ var x: u2 = Small.Two;
24412487 \\}
24422488 ,
......@@ -2450,7 +2496,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24502496 \\ Four,
24512497 \\};
24522498 \\
2453 \\export fn entry() {
2499 \\export fn entry() void {
24542500 \\ var x = u3(Small.Two);
24552501 \\}
24562502 ,
......@@ -2464,7 +2510,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24642510 \\ Four,
24652511 \\};
24662512 \\
2467 \\export fn entry() {
2513 \\export fn entry() void {
24682514 \\ var y = u3(3);
24692515 \\ var x = Small(y);
24702516 \\}
......@@ -2479,7 +2525,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24792525 \\ Four,
24802526 \\};
24812527 \\
2482 \\export fn entry() {
2528 \\export fn entry() void {
24832529 \\ var y = Small.Two;
24842530 \\}
24852531 ,
......@@ -2489,7 +2535,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24892535 \\const MultipleChoice = struct {
24902536 \\ A: i32 = 20,
24912537 \\};
2492 \\export fn entry() {
2538 \\export fn entry() void {
24932539 \\ var x: MultipleChoice = undefined;
24942540 \\}
24952541 ,
......@@ -2499,7 +2545,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
24992545 \\const MultipleChoice = union {
25002546 \\ A: i32 = 20,
25012547 \\};
2502 \\export fn entry() {
2548 \\export fn entry() void {
25032549 \\ var x: MultipleChoice = undefined;
25042550 \\}
25052551 ,
......@@ -2508,7 +2554,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25082554
25092555 cases.add("enum with 0 fields",
25102556 \\const Foo = enum {};
2511 \\export fn entry() -> usize {
2557 \\export fn entry() usize {
25122558 \\ return @sizeOf(Foo);
25132559 \\}
25142560 ,
......@@ -2516,7 +2562,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25162562
25172563 cases.add("union with 0 fields",
25182564 \\const Foo = union {};
2519 \\export fn entry() -> usize {
2565 \\export fn entry() usize {
25202566 \\ return @sizeOf(Foo);
25212567 \\}
25222568 ,
......@@ -2530,7 +2576,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25302576 \\ D = 1000,
25312577 \\ E = 60,
25322578 \\};
2533 \\export fn entry() {
2579 \\export fn entry() void {
25342580 \\ var x = MultipleChoice.C;
25352581 \\}
25362582 ,
......@@ -2547,7 +2593,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25472593 \\ A: i32,
25482594 \\ B: f64,
25492595 \\};
2550 \\export fn entry() -> usize {
2596 \\export fn entry() usize {
25512597 \\ return @sizeOf(Payload);
25522598 \\}
25532599 ,
......@@ -2558,7 +2604,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25582604 \\const Foo = union {
25592605 \\ A: i32,
25602606 \\};
2561 \\export fn entry() {
2607 \\export fn entry() void {
25622608 \\ const x = @TagType(Foo);
25632609 \\}
25642610 ,
......@@ -2569,7 +2615,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25692615 \\const Foo = union(enum(f32)) {
25702616 \\ A: i32,
25712617 \\};
2572 \\export fn entry() {
2618 \\export fn entry() void {
25732619 \\ const x = @TagType(Foo);
25742620 \\}
25752621 ,
......@@ -2579,7 +2625,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25792625 \\const Foo = union(u32) {
25802626 \\ A: i32,
25812627 \\};
2582 \\export fn entry() {
2628 \\export fn entry() void {
25832629 \\ const x = @TagType(Foo);
25842630 \\}
25852631 ,
......@@ -2593,7 +2639,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
25932639 \\ D = 1000,
25942640 \\ E = 60,
25952641 \\};
2596 \\export fn entry() {
2642 \\export fn entry() void {
25972643 \\ var x = MultipleChoice { .C = {} };
25982644 \\}
25992645 ,
......@@ -2612,7 +2658,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26122658 \\ C: bool,
26132659 \\ D: bool,
26142660 \\};
2615 \\export fn entry() {
2661 \\export fn entry() void {
26162662 \\ var a = Payload {.A = 1234};
26172663 \\}
26182664 ,
......@@ -2625,7 +2671,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26252671 \\ B,
26262672 \\ C,
26272673 \\};
2628 \\export fn entry() {
2674 \\export fn entry() void {
26292675 \\ var b = Letter.B;
26302676 \\}
26312677 ,
......@@ -2636,7 +2682,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26362682 \\const Letter = struct {
26372683 \\ A,
26382684 \\};
2639 \\export fn entry() {
2685 \\export fn entry() void {
26402686 \\ var a = Letter { .A = {} };
26412687 \\}
26422688 ,
......@@ -2646,7 +2692,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26462692 \\const Letter = extern union {
26472693 \\ A,
26482694 \\};
2649 \\export fn entry() {
2695 \\export fn entry() void {
26502696 \\ var a = Letter { .A = {} };
26512697 \\}
26522698 ,
......@@ -2663,7 +2709,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26632709 \\ B: f64,
26642710 \\ C: bool,
26652711 \\};
2666 \\export fn entry() {
2712 \\export fn entry() void {
26672713 \\ var a = Payload { .A = 1234 };
26682714 \\}
26692715 ,
......@@ -2680,7 +2726,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26802726 \\ B: f64,
26812727 \\ C: bool,
26822728 \\};
2683 \\export fn entry() {
2729 \\export fn entry() void {
26842730 \\ var a = Payload { .A = 1234 };
26852731 \\}
26862732 ,
......@@ -2692,11 +2738,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
26922738 \\ B: f64,
26932739 \\ C: bool,
26942740 \\};
2695 \\export fn entry() {
2741 \\export fn entry() void {
26962742 \\ const a = Payload { .A = 1234 };
26972743 \\ foo(a);
26982744 \\}
2699 \\fn foo(a: &const Payload) {
2745 \\fn foo(a: &const Payload) void {
27002746 \\ switch (*a) {
27012747 \\ Payload.A => {},
27022748 \\ else => unreachable,
......@@ -2711,7 +2757,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
27112757 \\ A = 10,
27122758 \\ B = 11,
27132759 \\};
2714 \\export fn entry() {
2760 \\export fn entry() void {
27152761 \\ var x = Foo(0);
27162762 \\}
27172763 ,
......@@ -2725,7 +2771,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
27252771 \\ B,
27262772 \\ C,
27272773 \\};
2728 \\export fn entry() {
2774 \\export fn entry() void {
27292775 \\ var x: Value = Letter.A;
27302776 \\}
27312777 ,
......@@ -2739,10 +2785,10 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
27392785 \\ B,
27402786 \\ C,
27412787 \\};
2742 \\export fn entry() {
2788 \\export fn entry() void {
27432789 \\ foo(Letter.A);
27442790 \\}
2745 \\fn foo(l: Letter) {
2791 \\fn foo(l: Letter) void {
27462792 \\ var x: Value = l;
27472793 \\}
27482794 ,
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 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 const main = b.addTest("main.zig");
55 main.setBuildMode(b.standardReleaseOptions());
66
test/standalone/brace_expansion/main.zig+8-10
......@@ -19,7 +19,7 @@ const Token = union(enum) {
1919
2020var global_allocator: &mem.Allocator = undefined;
2121
22fn tokenize(input:[] const u8) -> %ArrayList(Token) {
22fn tokenize(input:[] const u8) %ArrayList(Token) {
2323 const State = enum {
2424 Start,
2525 Word,
......@@ -71,7 +71,7 @@ const Node = union(enum) {
7171 Combine: []Node,
7272};
7373
74fn parse(tokens: &const ArrayList(Token), token_index: &usize) -> %Node {
74fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
7575 const first_token = tokens.items[*token_index];
7676 *token_index += 1;
7777
......@@ -107,7 +107,7 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) -> %Node {
107107 }
108108}
109109
110fn expandString(input: []const u8, output: &Buffer) -> %void {
110fn expandString(input: []const u8, output: &Buffer) %void {
111111 const tokens = try tokenize(input);
112112 if (tokens.len == 1) {
113113 return output.resize(0);
......@@ -135,9 +135,7 @@ fn expandString(input: []const u8, output: &Buffer) -> %void {
135135 }
136136}
137137
138const ListOfBuffer0 = ArrayList(Buffer); // TODO this is working around a compiler bug, fix and delete this
139
140fn expandNode(node: &const Node, output: &ListOfBuffer0) -> %void {
138fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
141139 assert(output.len == 0);
142140 switch (*node) {
143141 Node.Scalar => |scalar| {
......@@ -174,7 +172,7 @@ fn expandNode(node: &const Node, output: &ListOfBuffer0) -> %void {
174172 }
175173}
176174
177pub fn main() -> %void {
175pub fn main() %void {
178176 var stdin_file = try io.getStdIn();
179177 var stdout_file = try io.getStdOut();
180178
......@@ -210,11 +208,11 @@ test "invalid inputs" {
210208 expectError("\n", error.InvalidInput);
211209}
212210
213fn expectError(test_input: []const u8, expected_err: error) {
211fn expectError(test_input: []const u8, expected_err: error) void {
214212 var output_buf = Buffer.initSize(global_allocator, 0) catch unreachable;
215213 defer output_buf.deinit();
216214
217 if (expandString("}ABC", &output_buf)) {
215 if (expandString(test_input, &output_buf)) {
218216 unreachable;
219217 } else |err| {
220218 assert(expected_err == err);
......@@ -244,7 +242,7 @@ test "valid inputs" {
244242 expectExpansion("a{b}", "ab");
245243}
246244
247fn expectExpansion(test_input: []const u8, expected_result: []const u8) {
245fn expectExpansion(test_input: []const u8, expected_result: []const u8) void {
248246 var result = Buffer.initSize(global_allocator, 0) catch unreachable;
249247 defer result.deinit();
250248
test/standalone/issue_339/build.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 const obj = b.addObject("test", "test.zig");
55
66 const test_step = b.step("test", "Test the program");
test/standalone/issue_339/test.zig+3-3
......@@ -1,8 +1,8 @@
11const 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 {
77 bar() catch unreachable;
88}
test/standalone/pkg_import/build.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 const exe = b.addExecutable("test", "test.zig");
55 exe.addPackagePath("my_pkg", "pkg.zig");
66
test/standalone/pkg_import/pkg.zig+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 @@
11const my_pkg = @import("my_pkg");
22const assert = @import("std").debug.assert;
33
4pub fn main() -> %void {
4pub fn main() %void {
55 assert(my_pkg.add(10, 20) == 30);
66}
test/standalone/use_alias/build.zig+1-1
......@@ -1,6 +1,6 @@
11const Builder = @import("std").build.Builder;
22
3pub fn build(b: &Builder) -> %void {
3pub fn build(b: &Builder) %void {
44 b.addCIncludePath(".");
55
66 const main = b.addTest("main.zig");
test/tests.zig+206-57
......@@ -17,8 +17,9 @@ const compare_output = @import("compare_output.zig");
1717const build_examples = @import("build_examples.zig");
1818const compile_errors = @import("compile_errors.zig");
1919const assemble_and_link = @import("assemble_and_link.zig");
20const debug_safety = @import("debug_safety.zig");
20const runtime_safety = @import("runtime_safety.zig");
2121const translate_c = @import("translate_c.zig");
22const gen_h = @import("gen_h.zig");
2223
2324const TestTarget = struct {
2425 os: builtin.Os,
......@@ -49,7 +50,7 @@ error CompilationIncorrectlySucceeded;
4950
5051const 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 {
5354 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
5455 *cases = CompareOutputContext {
5556 .b = b,
......@@ -63,21 +64,21 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) -> &bu
6364 return cases.step;
6465}
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 {
6768 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
6869 *cases = CompareOutputContext {
6970 .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"),
7172 .test_index = 0,
7273 .test_filter = test_filter,
7374 };
7475
75 debug_safety.addCases(cases);
76 runtime_safety.addCases(cases);
7677
7778 return cases.step;
7879}
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 {
8182 const cases = b.allocator.create(CompileErrorContext) catch unreachable;
8283 *cases = CompileErrorContext {
8384 .b = b,
......@@ -91,7 +92,7 @@ pub fn addCompileErrorTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui
9192 return cases.step;
9293}
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 {
9596 const cases = b.allocator.create(BuildExamplesContext) catch unreachable;
9697 *cases = BuildExamplesContext {
9798 .b = b,
......@@ -105,7 +106,7 @@ pub fn addBuildExampleTests(b: &build.Builder, test_filter: ?[]const u8) -> &bui
105106 return cases.step;
106107}
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 {
109110 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
110111 *cases = CompareOutputContext {
111112 .b = b,
......@@ -119,11 +120,11 @@ pub fn addAssembleAndLinkTests(b: &build.Builder, test_filter: ?[]const u8) -> &
119120 return cases.step;
120121}
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 {
123124 const cases = b.allocator.create(TranslateCContext) catch unreachable;
124125 *cases = TranslateCContext {
125126 .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"),
127128 .test_index = 0,
128129 .test_filter = test_filter,
129130 };
......@@ -133,8 +134,23 @@ pub fn addTranslateCTests(b: &build.Builder, test_filter: ?[]const u8) -> &build
133134 return cases.step;
134135}
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
136152pub fn addPkgTests(b: &build.Builder, test_filter: ?[]const u8, root_src: []const u8,
137 name:[] const u8, desc: []const u8, with_lldb: bool) -> &build.Step
153 name:[] const u8, desc: []const u8, with_lldb: bool) &build.Step
138154{
139155 const step = b.step(b.fmt("test-{}", name), desc);
140156 for (test_targets) |test_target| {
......@@ -176,7 +192,7 @@ pub const CompareOutputContext = struct {
176192 const Special = enum {
177193 None,
178194 Asm,
179 DebugSafety,
195 RuntimeSafety,
180196 };
181197
182198 const TestCase = struct {
......@@ -192,14 +208,14 @@ pub const CompareOutputContext = struct {
192208 source: []const u8,
193209 };
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 {
196212 self.sources.append(SourceFile {
197213 .filename = filename,
198214 .source = source,
199215 }) catch unreachable;
200216 }
201217
202 pub fn setCommandLineArgs(self: &TestCase, args: []const []const u8) {
218 pub fn setCommandLineArgs(self: &TestCase, args: []const []const u8) void {
203219 self.cli_args = args;
204220 }
205221 };
......@@ -215,7 +231,7 @@ pub const CompareOutputContext = struct {
215231
216232 pub fn create(context: &CompareOutputContext, exe_path: []const u8,
217233 name: []const u8, expected_output: []const u8,
218 cli_args: []const []const u8) -> &RunCompareOutputStep
234 cli_args: []const []const u8) &RunCompareOutputStep
219235 {
220236 const allocator = context.b.allocator;
221237 const ptr = allocator.create(RunCompareOutputStep) catch unreachable;
......@@ -232,7 +248,7 @@ pub const CompareOutputContext = struct {
232248 return ptr;
233249 }
234250
235 fn make(step: &build.Step) -> %void {
251 fn make(step: &build.Step) %void {
236252 const self = @fieldParentPtr(RunCompareOutputStep, "step", step);
237253 const b = self.context.b;
238254
......@@ -298,7 +314,7 @@ pub const CompareOutputContext = struct {
298314 }
299315 };
300316
301 const DebugSafetyRunStep = struct {
317 const RuntimeSafetyRunStep = struct {
302318 step: build.Step,
303319 context: &CompareOutputContext,
304320 exe_path: []const u8,
......@@ -306,23 +322,23 @@ pub const CompareOutputContext = struct {
306322 test_index: usize,
307323
308324 pub fn create(context: &CompareOutputContext, exe_path: []const u8,
309 name: []const u8) -> &DebugSafetyRunStep
325 name: []const u8) &RuntimeSafetyRunStep
310326 {
311327 const allocator = context.b.allocator;
312 const ptr = allocator.create(DebugSafetyRunStep) catch unreachable;
313 *ptr = DebugSafetyRunStep {
328 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
329 *ptr = RuntimeSafetyRunStep {
314330 .context = context,
315331 .exe_path = exe_path,
316332 .name = name,
317333 .test_index = context.test_index,
318 .step = build.Step.init("DebugSafetyRun", allocator, make),
334 .step = build.Step.init("RuntimeSafetyRun", allocator, make),
319335 };
320336 context.test_index += 1;
321337 return ptr;
322338 }
323339
324 fn make(step: &build.Step) -> %void {
325 const self = @fieldParentPtr(DebugSafetyRunStep, "step", step);
340 fn make(step: &build.Step) %void {
341 const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
326342 const b = self.context.b;
327343
328344 const full_exe_path = b.pathFromRoot(self.exe_path);
......@@ -367,7 +383,7 @@ pub const CompareOutputContext = struct {
367383 };
368384
369385 pub fn createExtra(self: &CompareOutputContext, name: []const u8, source: []const u8,
370 expected_output: []const u8, special: Special) -> TestCase
386 expected_output: []const u8, special: Special) TestCase
371387 {
372388 var tc = TestCase {
373389 .name = name,
......@@ -383,33 +399,33 @@ pub const CompareOutputContext = struct {
383399 }
384400
385401 pub fn create(self: &CompareOutputContext, name: []const u8, source: []const u8,
386 expected_output: []const u8) -> TestCase
402 expected_output: []const u8) TestCase
387403 {
388404 return createExtra(self, name, source, expected_output, Special.None);
389405 }
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 {
392408 var tc = self.create(name, source, expected_output);
393409 tc.link_libc = true;
394410 self.addCase(tc);
395411 }
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 {
398414 const tc = self.create(name, source, expected_output);
399415 self.addCase(tc);
400416 }
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 {
403419 const tc = self.createExtra(name, source, expected_output, Special.Asm);
404420 self.addCase(tc);
405421 }
406422
407 pub fn addDebugSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) {
408 const tc = self.createExtra(name, source, undefined, Special.DebugSafety);
423 pub fn addRuntimeSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) void {
424 const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
409425 self.addCase(tc);
410426 }
411427
412 pub fn addCase(self: &CompareOutputContext, case: &const TestCase) {
428 pub fn addCase(self: &CompareOutputContext, case: &const TestCase) void {
413429 const b = self.b;
414430
415431 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 {
465481 self.step.dependOn(&run_and_cmp_output.step);
466482 }
467483 },
468 Special.DebugSafety => {
484 Special.RuntimeSafety => {
469485 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
470486 if (self.test_filter) |filter| {
471487 if (mem.indexOf(u8, annotated_case_name, filter) == null)
......@@ -483,7 +499,7 @@ pub const CompareOutputContext = struct {
483499 exe.step.dependOn(&write_src.step);
484500 }
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);
487503 run_and_cmp_output.step.dependOn(&exe.step);
488504
489505 self.step.dependOn(&run_and_cmp_output.step);
......@@ -510,14 +526,14 @@ pub const CompileErrorContext = struct {
510526 source: []const u8,
511527 };
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 {
514530 self.sources.append(SourceFile {
515531 .filename = filename,
516532 .source = source,
517533 }) catch unreachable;
518534 }
519535
520 pub fn addExpectedError(self: &TestCase, text: []const u8) {
536 pub fn addExpectedError(self: &TestCase, text: []const u8) void {
521537 self.expected_errors.append(text) catch unreachable;
522538 }
523539 };
......@@ -531,7 +547,7 @@ pub const CompileErrorContext = struct {
531547 build_mode: Mode,
532548
533549 pub fn create(context: &CompileErrorContext, name: []const u8,
534 case: &const TestCase, build_mode: Mode) -> &CompileCmpOutputStep
550 case: &const TestCase, build_mode: Mode) &CompileCmpOutputStep
535551 {
536552 const allocator = context.b.allocator;
537553 const ptr = allocator.create(CompileCmpOutputStep) catch unreachable;
......@@ -547,7 +563,7 @@ pub const CompileErrorContext = struct {
547563 return ptr;
548564 }
549565
550 fn make(step: &build.Step) -> %void {
566 fn make(step: &build.Step) %void {
551567 const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
552568 const b = self.context.b;
553569
......@@ -645,7 +661,7 @@ pub const CompileErrorContext = struct {
645661 }
646662 };
647663
648 fn printInvocation(args: []const []const u8) {
664 fn printInvocation(args: []const []const u8) void {
649665 for (args) |arg| {
650666 warn("{} ", arg);
651667 }
......@@ -653,7 +669,7 @@ pub const CompileErrorContext = struct {
653669 }
654670
655671 pub fn create(self: &CompileErrorContext, name: []const u8, source: []const u8,
656 expected_lines: ...) -> &TestCase
672 expected_lines: ...) &TestCase
657673 {
658674 const tc = self.b.allocator.create(TestCase) catch unreachable;
659675 *tc = TestCase {
......@@ -671,24 +687,24 @@ pub const CompileErrorContext = struct {
671687 return tc;
672688 }
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 {
675691 var tc = self.create(name, source, expected_lines);
676692 tc.link_libc = true;
677693 self.addCase(tc);
678694 }
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 {
681697 var tc = self.create(name, source, expected_lines);
682698 tc.is_exe = true;
683699 self.addCase(tc);
684700 }
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 {
687703 const tc = self.create(name, source, expected_lines);
688704 self.addCase(tc);
689705 }
690706
691 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) {
707 pub fn addCase(self: &CompileErrorContext, case: &const TestCase) void {
692708 const b = self.b;
693709
694710 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
......@@ -717,15 +733,15 @@ pub const BuildExamplesContext = struct {
717733 test_index: usize,
718734 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 {
721737 self.addAllArgs(root_src, true);
722738 }
723739
724 pub fn add(self: &BuildExamplesContext, root_src: []const u8) {
740 pub fn add(self: &BuildExamplesContext, root_src: []const u8) void {
725741 self.addAllArgs(root_src, false);
726742 }
727743
728 pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) {
744 pub fn addBuildFile(self: &BuildExamplesContext, build_file: []const u8) void {
729745 const b = self.b;
730746
731747 const annotated_case_name = b.fmt("build {} (Debug)", build_file);
......@@ -756,7 +772,7 @@ pub const BuildExamplesContext = struct {
756772 self.step.dependOn(&log_step.step);
757773 }
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 {
760776 const b = self.b;
761777
762778 for ([]Mode{Mode.Debug, Mode.ReleaseSafe, Mode.ReleaseFast}) |mode| {
......@@ -798,14 +814,14 @@ pub const TranslateCContext = struct {
798814 source: []const u8,
799815 };
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 {
802818 self.sources.append(SourceFile {
803819 .filename = filename,
804820 .source = source,
805821 }) catch unreachable;
806822 }
807823
808 pub fn addExpectedLine(self: &TestCase, text: []const u8) {
824 pub fn addExpectedLine(self: &TestCase, text: []const u8) void {
809825 self.expected_lines.append(text) catch unreachable;
810826 }
811827 };
......@@ -817,7 +833,7 @@ pub const TranslateCContext = struct {
817833 test_index: usize,
818834 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 {
821837 const allocator = context.b.allocator;
822838 const ptr = allocator.create(TranslateCCmpOutputStep) catch unreachable;
823839 *ptr = TranslateCCmpOutputStep {
......@@ -831,7 +847,7 @@ pub const TranslateCContext = struct {
831847 return ptr;
832848 }
833849
834 fn make(step: &build.Step) -> %void {
850 fn make(step: &build.Step) %void {
835851 const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
836852 const b = self.context.b;
837853
......@@ -918,7 +934,7 @@ pub const TranslateCContext = struct {
918934 }
919935 };
920936
921 fn printInvocation(args: []const []const u8) {
937 fn printInvocation(args: []const []const u8) void {
922938 for (args) |arg| {
923939 warn("{} ", arg);
924940 }
......@@ -926,7 +942,7 @@ pub const TranslateCContext = struct {
926942 }
927943
928944 pub fn create(self: &TranslateCContext, allow_warnings: bool, filename: []const u8, name: []const u8,
929 source: []const u8, expected_lines: ...) -> &TestCase
945 source: []const u8, expected_lines: ...) &TestCase
930946 {
931947 const tc = self.b.allocator.create(TestCase) catch unreachable;
932948 *tc = TestCase {
......@@ -943,22 +959,22 @@ pub const TranslateCContext = struct {
943959 return tc;
944960 }
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 {
947963 const tc = self.create(false, "source.h", name, source, expected_lines);
948964 self.addCase(tc);
949965 }
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 {
952968 const tc = self.create(false, "source.c", name, source, expected_lines);
953969 self.addCase(tc);
954970 }
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 {
957973 const tc = self.create(true, "source.h", name, source, expected_lines);
958974 self.addCase(tc);
959975 }
960976
961 pub fn addCase(self: &TranslateCContext, case: &const TestCase) {
977 pub fn addCase(self: &TranslateCContext, case: &const TestCase) void {
962978 const b = self.b;
963979
964980 const annotated_case_name = fmt.allocPrint(self.b.allocator, "translate-c {}", case.name) catch unreachable;
......@@ -977,3 +993,136 @@ pub const TranslateCContext = struct {
977993 }
978994 }
979995};
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 @@
11const tests = @import("tests.zig");
22
3pub fn addCases(cases: &tests.TranslateCContext) {
3pub fn addCases(cases: &tests.TranslateCContext) void {
44 cases.addAllowWarnings("simple data types",
55 \\#include <stdint.h>
66 \\int foo(char a, unsigned char b, signed char c);
......@@ -8,17 +8,17 @@ pub fn addCases(cases: &tests.TranslateCContext) {
88 \\void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
99 \\void baz(int8_t a, int16_t b, int32_t c, int64_t d);
1010 ,
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;
1212 ,
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;
1414 ,
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;
1616 );
1717
1818 cases.add("noreturn attribute",
1919 \\void foo(void) __attribute__((noreturn));
2020 ,
21 \\pub extern fn foo() -> noreturn;
21 \\pub extern fn foo() noreturn;
2222 );
2323
2424 cases.addC("simple function",
......@@ -26,7 +26,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
2626 \\ return a < 0 ? -a : a;
2727 \\}
2828 ,
29 \\export fn abs(a: c_int) -> c_int {
29 \\export fn abs(a: c_int) c_int {
3030 \\ return if (a < 0) -a else a;
3131 \\}
3232 );
......@@ -56,7 +56,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
5656 cases.add("restrict -> noalias",
5757 \\void foo(void *restrict bar, void *restrict);
5858 ,
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;
6060 );
6161
6262 cases.add("simple struct",
......@@ -98,7 +98,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
9898 ,
9999 \\pub const BarB = enum_Bar.B;
100100 ,
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar));
101 \\pub extern fn func(a: ?&struct_Foo, b: ?&(?&enum_Bar)) void;
102102 ,
103103 \\pub const Foo = struct_Foo;
104104 ,
......@@ -108,7 +108,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
108108 cases.add("constant size array",
109109 \\void func(int array[20]);
110110 ,
111 \\pub extern fn func(array: ?&c_int);
111 \\pub extern fn func(array: ?&c_int) void;
112112 );
113113
114114 cases.add("self referential struct with function pointer",
......@@ -117,7 +117,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
117117 \\};
118118 ,
119119 \\pub const struct_Foo = extern struct {
120 \\ derp: ?extern fn(?&struct_Foo),
120 \\ derp: ?extern fn(?&struct_Foo) void,
121121 \\};
122122 ,
123123 \\pub const Foo = struct_Foo;
......@@ -129,7 +129,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
129129 ,
130130 \\pub const struct_Foo = @OpaqueType();
131131 ,
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;
133133 ,
134134 \\pub const Foo = struct_Foo;
135135 );
......@@ -190,7 +190,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
190190 ,
191191 \\pub const Foo = c_void;
192192 ,
193 \\pub extern fn fun(a: ?&Foo) -> Foo;
193 \\pub extern fn fun(a: ?&Foo) Foo;
194194 );
195195
196196 cases.add("generate inline func for #define global extern fn",
......@@ -200,15 +200,15 @@ pub fn addCases(cases: &tests.TranslateCContext) {
200200 \\extern char (*fn_ptr2)(int, float);
201201 \\#define bar fn_ptr2
202202 ,
203 \\pub extern var fn_ptr: ?extern fn();
203 \\pub extern var fn_ptr: ?extern fn() void;
204204 ,
205 \\pub inline fn foo() {
205 \\pub inline fn foo() void {
206206 \\ return (??fn_ptr)();
207207 \\}
208208 ,
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) -> u8;
209 \\pub extern var fn_ptr2: ?extern fn(c_int, f32) u8;
210210 ,
211 \\pub inline fn bar(arg0: c_int, arg1: f32) -> u8 {
211 \\pub inline fn bar(arg0: c_int, arg1: f32) u8 {
212212 \\ return (??fn_ptr2)(arg0, arg1);
213213 \\}
214214 );
......@@ -222,7 +222,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
222222 cases.add("__cdecl doesn't mess up function pointers",
223223 \\void foo(void (__cdecl *fn_ptr)(void));
224224 ,
225 \\pub extern fn foo(fn_ptr: ?extern fn());
225 \\pub extern fn foo(fn_ptr: ?extern fn() void) void;
226226 );
227227
228228 cases.add("comment after integer literal",
......@@ -325,12 +325,12 @@ pub fn addCases(cases: &tests.TranslateCContext) {
325325 \\ return a;
326326 \\}
327327 ,
328 \\pub export fn foo1(_arg_a: c_uint) -> c_uint {
328 \\pub export fn foo1(_arg_a: c_uint) c_uint {
329329 \\ var a = _arg_a;
330330 \\ a +%= 1;
331331 \\ return a;
332332 \\}
333 \\pub export fn foo2(_arg_a: c_int) -> c_int {
333 \\pub export fn foo2(_arg_a: c_int) c_int {
334334 \\ var a = _arg_a;
335335 \\ a += 1;
336336 \\ return a;
......@@ -346,7 +346,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
346346 \\ return i;
347347 \\}
348348 ,
349 \\pub export fn log2(_arg_a: c_uint) -> c_int {
349 \\pub export fn log2(_arg_a: c_uint) c_int {
350350 \\ var a = _arg_a;
351351 \\ var i: c_int = 0;
352352 \\ while (a > c_uint(0)) {
......@@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
367367 \\ return a;
368368 \\}
369369 ,
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 {
371371 \\ if (a < b) return b;
372372 \\ if (a < b) return b else return a;
373373 \\}
......@@ -382,7 +382,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
382382 \\ return a;
383383 \\}
384384 ,
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 {
386386 \\ if (a == b) return a;
387387 \\ if (a != b) return b;
388388 \\ return a;
......@@ -407,7 +407,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
407407 \\ c = a % b;
408408 \\}
409409 ,
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 {
411411 \\ var c: c_int = undefined;
412412 \\ c = (a + b);
413413 \\ c = (a - b);
......@@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
415415 \\ c = @divTrunc(a, b);
416416 \\ c = @rem(a, b);
417417 \\}
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 {
419419 \\ var c: c_uint = undefined;
420420 \\ c = (a +% b);
421421 \\ c = (a -% b);
......@@ -430,7 +430,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
430430 \\ return (a & b) ^ (a | b);
431431 \\}
432432 ,
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 {
434434 \\ return (a & b) ^ (a | b);
435435 \\}
436436 );
......@@ -444,7 +444,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
444444 \\ return a;
445445 \\}
446446 ,
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 {
448448 \\ if ((a < b) or (a == b)) return b;
449449 \\ if ((a >= b) and (a == b)) return a;
450450 \\ return a;
......@@ -458,7 +458,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
458458 \\ a = tmp;
459459 \\}
460460 ,
461 \\pub export fn max(_arg_a: c_int) -> c_int {
461 \\pub export fn max(_arg_a: c_int) c_int {
462462 \\ var a = _arg_a;
463463 \\ var tmp: c_int = undefined;
464464 \\ tmp = a;
......@@ -472,7 +472,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
472472 \\ c = b = a;
473473 \\}
474474 ,
475 \\pub export fn max(a: c_int) {
475 \\pub export fn max(a: c_int) void {
476476 \\ var b: c_int = undefined;
477477 \\ var c: c_int = undefined;
478478 \\ c = x: {
......@@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
493493 \\ return i;
494494 \\}
495495 ,
496 \\pub export fn log2(_arg_a: u32) -> c_int {
496 \\pub export fn log2(_arg_a: u32) c_int {
497497 \\ var a = _arg_a;
498498 \\ var i: c_int = 0;
499499 \\ while (a > c_uint(0)) {
......@@ -517,8 +517,8 @@ pub fn addCases(cases: &tests.TranslateCContext) {
517517 \\static void bar(void) { }
518518 \\void foo(void) { bar(); }
519519 ,
520 \\pub fn bar() {}
521 \\pub export fn foo() {
520 \\pub fn bar() void {}
521 \\pub export fn foo() void {
522522 \\ bar();
523523 \\}
524524 );
......@@ -534,7 +534,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
534534 \\pub const struct_Foo = extern struct {
535535 \\ field: c_int,
536536 \\};
537 \\pub export fn read_field(foo: ?&struct_Foo) -> c_int {
537 \\pub export fn read_field(foo: ?&struct_Foo) c_int {
538538 \\ return (??foo).field;
539539 \\}
540540 );
......@@ -544,7 +544,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
544544 \\ ;;;;;
545545 \\}
546546 ,
547 \\pub export fn foo() {}
547 \\pub export fn foo() void {}
548548 );
549549
550550 cases.add("undefined array global",
......@@ -560,7 +560,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
560560 \\}
561561 ,
562562 \\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 {
564564 \\ return array[index];
565565 \\}
566566 );
......@@ -571,7 +571,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
571571 \\ return (int)a;
572572 \\}
573573 ,
574 \\pub export fn float_to_int(a: f32) -> c_int {
574 \\pub export fn float_to_int(a: f32) c_int {
575575 \\ return c_int(a);
576576 \\}
577577 );
......@@ -581,7 +581,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
581581 \\ return x;
582582 \\}
583583 ,
584 \\pub export fn foo(x: ?&c_ushort) -> ?&c_void {
584 \\pub export fn foo(x: ?&c_ushort) ?&c_void {
585585 \\ return @ptrCast(?&c_void, x);
586586 \\}
587587 );
......@@ -592,7 +592,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
592592 \\ return sizeof(int);
593593 \\}
594594 ,
595 \\pub export fn size_of() -> usize {
595 \\pub export fn size_of() usize {
596596 \\ return @sizeOf(c_int);
597597 \\}
598598 );
......@@ -602,7 +602,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
602602 \\ return 0;
603603 \\}
604604 ,
605 \\pub export fn foo() -> ?&c_int {
605 \\pub export fn foo() ?&c_int {
606606 \\ return null;
607607 \\}
608608 );
......@@ -612,7 +612,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
612612 \\ return 1, 2;
613613 \\}
614614 ,
615 \\pub export fn foo() -> c_int {
615 \\pub export fn foo() c_int {
616616 \\ return x: {
617617 \\ _ = 1;
618618 \\ break :x 2;
......@@ -625,7 +625,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
625625 \\ return (1 << 2) >> 1;
626626 \\}
627627 ,
628 \\pub export fn foo() -> c_int {
628 \\pub export fn foo() c_int {
629629 \\ return (1 << @import("std").math.Log2Int(c_int)(2)) >> @import("std").math.Log2Int(c_int)(1);
630630 \\}
631631 );
......@@ -643,7 +643,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
643643 \\ a <<= (a <<= 1);
644644 \\}
645645 ,
646 \\pub export fn foo() {
646 \\pub export fn foo() void {
647647 \\ var a: c_int = 0;
648648 \\ a += x: {
649649 \\ const _ref = &a;
......@@ -701,7 +701,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
701701 \\ a <<= (a <<= 1);
702702 \\}
703703 ,
704 \\pub export fn foo() {
704 \\pub export fn foo() void {
705705 \\ var a: c_uint = c_uint(0);
706706 \\ a +%= x: {
707707 \\ const _ref = &a;
......@@ -771,7 +771,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
771771 \\ u = u--;
772772 \\}
773773 ,
774 \\pub export fn foo() {
774 \\pub export fn foo() void {
775775 \\ var i: c_int = 0;
776776 \\ var u: c_uint = c_uint(0);
777777 \\ i += 1;
......@@ -819,7 +819,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
819819 \\ u = --u;
820820 \\}
821821 ,
822 \\pub export fn foo() {
822 \\pub export fn foo() void {
823823 \\ var i: c_int = 0;
824824 \\ var u: c_uint = c_uint(0);
825825 \\ i += 1;
......@@ -862,7 +862,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
862862 \\ while (b != 0);
863863 \\}
864864 ,
865 \\pub export fn foo() {
865 \\pub export fn foo() void {
866866 \\ var a: c_int = 2;
867867 \\ while (true) {
868868 \\ a -= 1;
......@@ -886,10 +886,10 @@ pub fn addCases(cases: &tests.TranslateCContext) {
886886 \\ baz();
887887 \\}
888888 ,
889 \\pub export fn foo() {}
890 \\pub export fn baz() {}
891 \\pub export fn bar() {
892 \\ var f: ?extern fn() = foo;
889 \\pub export fn foo() void {}
890 \\pub export fn baz() void {}
891 \\pub export fn bar() void {
892 \\ var f: ?extern fn() void = foo;
893893 \\ (??f)();
894894 \\ (??f)();
895895 \\ baz();
......@@ -901,7 +901,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
901901 \\ *x = 1;
902902 \\}
903903 ,
904 \\pub export fn foo(x: ?&c_int) {
904 \\pub export fn foo(x: ?&c_int) void {
905905 \\ (*??x) = 1;
906906 \\}
907907 );
......@@ -927,7 +927,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
927927 \\ return *ptr;
928928 \\}
929929 ,
930 \\pub fn foo() -> c_int {
930 \\pub fn foo() c_int {
931931 \\ var x: c_int = 1234;
932932 \\ var ptr: ?&c_int = &x;
933933 \\ return *??ptr;
......@@ -939,7 +939,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
939939 \\ return "bar";
940940 \\}
941941 ,
942 \\pub fn foo() -> ?&const u8 {
942 \\pub fn foo() ?&const u8 {
943943 \\ return c"bar";
944944 \\}
945945 );
......@@ -949,7 +949,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
949949 \\ return;
950950 \\}
951951 ,
952 \\pub fn foo() {
952 \\pub fn foo() void {
953953 \\ return;
954954 \\}
955955 );
......@@ -959,7 +959,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
959959 \\ for (int i = 0; i < 10; i += 1) { }
960960 \\}
961961 ,
962 \\pub fn foo() {
962 \\pub fn foo() void {
963963 \\ {
964964 \\ var i: c_int = 0;
965965 \\ while (i < 10) : (i += 1) {};
......@@ -972,7 +972,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
972972 \\ for (;;) { }
973973 \\}
974974 ,
975 \\pub fn foo() {
975 \\pub fn foo() void {
976976 \\ while (true) {};
977977 \\}
978978 );
......@@ -984,7 +984,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
984984 \\ }
985985 \\}
986986 ,
987 \\pub fn foo() {
987 \\pub fn foo() void {
988988 \\ while (true) {
989989 \\ break;
990990 \\ };
......@@ -998,7 +998,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
998998 \\ }
999999 \\}
10001000 ,
1001 \\pub fn foo() {
1001 \\pub fn foo() void {
10021002 \\ while (true) {
10031003 \\ continue;
10041004 \\ };
......@@ -1021,9 +1021,9 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10211021 ,
10221022 \\pub const GLbitfield = c_uint;
10231023 ,
1024 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield);
1024 \\pub const PFNGLCLEARPROC = ?extern fn(GLbitfield) void;
10251025 ,
1026 \\pub const OpenGLProc = ?extern fn();
1026 \\pub const OpenGLProc = ?extern fn() void;
10271027 ,
10281028 \\pub const union_OpenGLProcs = extern union {
10291029 \\ ptr: [1]OpenGLProc,
......@@ -1036,7 +1036,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10361036 ,
10371037 \\pub const glClearPFN = PFNGLCLEARPROC;
10381038 ,
1039 \\pub inline fn glClearUnion(arg0: GLbitfield) {
1039 \\pub inline fn glClearUnion(arg0: GLbitfield) void {
10401040 \\ return (??glProcs.gl.Clear)(arg0);
10411041 \\}
10421042 ,
......@@ -1053,7 +1053,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10531053 \\ return x;
10541054 \\}
10551055 ,
1056 \\pub fn foo() -> c_int {
1056 \\pub fn foo() c_int {
10571057 \\ var x: c_int = 1;
10581058 \\ {
10591059 \\ var x_0: c_int = 2;
......@@ -1068,7 +1068,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10681068 \\ return (float *)a;
10691069 \\}
10701070 ,
1071 \\fn ptrcast(a: ?&c_int) -> ?&f32 {
1071 \\fn ptrcast(a: ?&c_int) ?&f32 {
10721072 \\ return @ptrCast(?&f32, a);
10731073 \\}
10741074 );
......@@ -1078,7 +1078,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10781078 \\ return ~x;
10791079 \\}
10801080 ,
1081 \\pub fn foo(x: c_int) -> c_int {
1081 \\pub fn foo(x: c_int) c_int {
10821082 \\ return ~x;
10831083 \\}
10841084 );
......@@ -1088,7 +1088,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
10881088 \\ return u32;
10891089 \\}
10901090 ,
1091 \\pub fn foo(u32_0: c_int) -> c_int {
1091 \\pub fn foo(u32_0: c_int) c_int {
10921092 \\ return u32_0;
10931093 \\}
10941094 );
......@@ -1104,7 +1104,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
11041104 \\ static const char v2[] = "2.2.2";
11051105 \\}
11061106 ,
1107 \\pub fn foo() {
1107 \\pub fn foo() void {
11081108 \\ const v2: &const u8 = c"2.2.2";
11091109 \\}
11101110 );
......@@ -1124,7 +1124,7 @@ pub fn addCases(cases: &tests.TranslateCContext) {
11241124 \\ }
11251125 \\}
11261126 ,
1127 \\pub fn if_int(i: c_int) -> c_int {
1127 \\pub fn if_int(i: c_int) c_int {
11281128 \\ {
11291129 \\ const _tmp = i;
11301130 \\ if (@bitCast(@IntType(false, @sizeOf(@typeOf(_tmp)) * 8), _tmp) != 0) {