| author | |
| committer | |
| log | 0d5ff6f4622a492dddbb1fc2b19b3157237500b1 |
| tree | 4a707f626dc12adeeed3438b5966876c6b401ea0 |
| parent | 68238d5678a4c055bb6f1206254dcac2e0c634f0 |
28 files changed, 333 insertions(+), 121 deletions(-)
TODO+11| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find . -name "*.zig") |
| 2 | 2 | |
| 3 | ||
| 3 | 4 | the literal translation of `%T` to this new code is `error!T`. |
| 4 | 5 | however this would not take advantage of error sets. It's |
| 5 | 6 | recommended to generally have all your functions which return possible |
| ... | ... | @@ -11,6 +12,11 @@ fn foo() !void { |
| 11 | 12 | |
| 12 | 13 | then you can return void, or any error, and the error set is inferred. |
| 13 | 14 | |
| 15 | ||
| 16 | you can get the compiler to tell you the possible errors for an inferred error set like this: | |
| 17 | ||
| 18 | foo() catch |err| switch (err) {}; | |
| 19 | ||
| 14 | 20 | // TODO this is an explicit cast and should actually coerce the type |
| 15 | 21 | erorr set casting |
| 16 | 22 | |
| ... | ... | @@ -27,3 +33,8 @@ comptime test for err |
| 27 | 33 | undefined in infer error |
| 28 | 34 | |
| 29 | 35 | syntax - ?a!b should be ?(a!b) but it's (?a)!b |
| 36 | ||
| 37 | syntax - (error{}!void) as the return type | |
| 38 | ||
| 39 | ||
| 40 | passing a fn()error{}!T to a fn()error!T should be a compile error, they're not compatible |
doc/docgen.zig+2-11| ... | ... | @@ -42,7 +42,7 @@ pub fn main() !void { |
| 42 | 42 | const input_file_bytes = try file_in_stream.stream.readAllAlloc(allocator, max_doc_file_size); |
| 43 | 43 | |
| 44 | 44 | var file_out_stream = io.FileOutStream.init(&out_file); |
| 45 | var buffered_out_stream = io.BufferedOutStream.init(&file_out_stream.stream); | |
| 45 | var buffered_out_stream = io.BufferedOutStream(io.FileOutStream.Error).init(&file_out_stream.stream); | |
| 46 | 46 | |
| 47 | 47 | var tokenizer = Tokenizer.init(in_file_name, input_file_bytes); |
| 48 | 48 | var toc = try genToc(allocator, &tokenizer); |
| ... | ... | @@ -218,8 +218,6 @@ const Tokenizer = struct { |
| 218 | 218 | } |
| 219 | 219 | }; |
| 220 | 220 | |
| 221 | error ParseError; | |
| 222 | ||
| 223 | 221 | fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const u8, args: ...) error { |
| 224 | 222 | const loc = tokenizer.getTokenLocation(token); |
| 225 | 223 | warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args); |
| ... | ... | @@ -596,8 +594,6 @@ const TermState = enum { |
| 596 | 594 | ExpectEnd, |
| 597 | 595 | }; |
| 598 | 596 | |
| 599 | error UnsupportedEscape; | |
| 600 | ||
| 601 | 597 | test "term color" { |
| 602 | 598 | const input_bytes = "A\x1b[32;1mgreen\x1b[0mB"; |
| 603 | 599 | const result = try termColor(std.debug.global_allocator, input_bytes); |
| ... | ... | @@ -684,9 +680,7 @@ fn termColor(allocator: &mem.Allocator, input: []const u8) ![]u8 { |
| 684 | 680 | return buf.toOwnedSlice(); |
| 685 | 681 | } |
| 686 | 682 | |
| 687 | error ExampleFailedToCompile; | |
| 688 | ||
| 689 | fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) !void { | |
| 683 | fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: var, zig_exe: []const u8) !void { | |
| 690 | 684 | var code_progress_index: usize = 0; |
| 691 | 685 | for (toc.nodes) |node| { |
| 692 | 686 | switch (node) { |
| ... | ... | @@ -974,9 +968,6 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io |
| 974 | 968 | |
| 975 | 969 | } |
| 976 | 970 | |
| 977 | error ChildCrashed; | |
| 978 | error ChildExitError; | |
| 979 | ||
| 980 | 971 | fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult { |
| 981 | 972 | const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size); |
| 982 | 973 | switch (result.term) { |
example/cat/main.zig+1-1| ... | ... | @@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) !void { |
| 61 | 61 | } |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | fn unwrapArg(arg: %[]u8) ![]u8 { | |
| 64 | fn unwrapArg(arg: error![]u8) ![]u8 { | |
| 65 | 65 | return arg catch |err| { |
| 66 | 66 | warn("Unable to parse command line: {}\n", err); |
| 67 | 67 | return err; |
example/mix_o_files/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | const obj = b.addObject("base64", "base64.zig"); |
| 5 | 5 | |
| 6 | 6 | const exe = b.addCExecutable("test"); |
example/shared_library/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); |
| 5 | 5 | |
| 6 | 6 | const exe = b.addCExecutable("test"); |
src-self-hosted/main.zig+1-5| ... | ... | @@ -14,10 +14,6 @@ const builtin = @import("builtin"); |
| 14 | 14 | const ArrayList = std.ArrayList; |
| 15 | 15 | const c = @import("c.zig"); |
| 16 | 16 | |
| 17 | error InvalidCommandLineArguments; | |
| 18 | error ZigLibDirNotFound; | |
| 19 | error ZigInstallationNotFound; | |
| 20 | ||
| 21 | 17 | const default_zig_cache_name = "zig-cache"; |
| 22 | 18 | |
| 23 | 19 | pub fn main() !void { |
| ... | ... | @@ -472,7 +468,7 @@ pub fn main2() !void { |
| 472 | 468 | } |
| 473 | 469 | } |
| 474 | 470 | |
| 475 | fn printUsage(stream: &io.OutStream) !void { | |
| 471 | fn printUsage(stream: var) !void { | |
| 476 | 472 | try stream.write( |
| 477 | 473 | \\Usage: zig [command] [options] |
| 478 | 474 | \\ |
src-self-hosted/module.zig+2-1| ... | ... | @@ -110,7 +110,7 @@ pub const Module = struct { |
| 110 | 110 | }; |
| 111 | 111 | |
| 112 | 112 | pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target, |
| 113 | kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) %&Module | |
| 113 | kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) !&Module | |
| 114 | 114 | { |
| 115 | 115 | var name_buffer = try Buffer.init(allocator, name); |
| 116 | 116 | errdefer name_buffer.deinit(); |
| ... | ... | @@ -265,6 +265,7 @@ pub const Module = struct { |
| 265 | 265 | |
| 266 | 266 | pub fn link(self: &Module, out_file: ?[]const u8) !void { |
| 267 | 267 | warn("TODO link"); |
| 268 | return error.Todo; | |
| 268 | 269 | } |
| 269 | 270 | |
| 270 | 271 | pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) !&LinkLib { |
src-self-hosted/parser.zig+6-12| ... | ... | @@ -12,8 +12,6 @@ const io = std.io; |
| 12 | 12 | // get rid of this |
| 13 | 13 | const warn = std.debug.warn; |
| 14 | 14 | |
| 15 | error ParseError; | |
| 16 | ||
| 17 | 15 | pub const Parser = struct { |
| 18 | 16 | allocator: &mem.Allocator, |
| 19 | 17 | tokenizer: &Tokenizer, |
| ... | ... | @@ -555,7 +553,7 @@ pub const Parser = struct { |
| 555 | 553 | } |
| 556 | 554 | |
| 557 | 555 | fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token, |
| 558 | extern_token: &const ?Token) %&ast.NodeVarDecl | |
| 556 | extern_token: &const ?Token) !&ast.NodeVarDecl | |
| 559 | 557 | { |
| 560 | 558 | const node = try self.allocator.create(ast.NodeVarDecl); |
| 561 | 559 | |
| ... | ... | @@ -577,7 +575,7 @@ pub const Parser = struct { |
| 577 | 575 | } |
| 578 | 576 | |
| 579 | 577 | fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token, |
| 580 | cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) %&ast.NodeFnProto | |
| 578 | cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) !&ast.NodeFnProto | |
| 581 | 579 | { |
| 582 | 580 | const node = try self.allocator.create(ast.NodeFnProto); |
| 583 | 581 | |
| ... | ... | @@ -694,7 +692,7 @@ pub const Parser = struct { |
| 694 | 692 | |
| 695 | 693 | fn createAttachFnProto(self: &Parser, list: &ArrayList(&ast.Node), fn_token: &const Token, |
| 696 | 694 | extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token, |
| 697 | inline_token: &const ?Token) %&ast.NodeFnProto | |
| 695 | inline_token: &const ?Token) !&ast.NodeFnProto | |
| 698 | 696 | { |
| 699 | 697 | const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token); |
| 700 | 698 | try list.append(&node.base); |
| ... | ... | @@ -702,7 +700,7 @@ pub const Parser = struct { |
| 702 | 700 | } |
| 703 | 701 | |
| 704 | 702 | fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token, |
| 705 | mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) %&ast.NodeVarDecl | |
| 703 | mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) !&ast.NodeVarDecl | |
| 706 | 704 | { |
| 707 | 705 | const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token); |
| 708 | 706 | try list.append(&node.base); |
| ... | ... | @@ -763,7 +761,7 @@ pub const Parser = struct { |
| 763 | 761 | indent: usize, |
| 764 | 762 | }; |
| 765 | 763 | |
| 766 | pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void { | |
| 764 | pub fn renderAst(self: &Parser, stream: var, root_node: &ast.NodeRoot) !void { | |
| 767 | 765 | var stack = self.initUtilityArrayList(RenderAstFrame); |
| 768 | 766 | defer self.deinitUtilityArrayList(stack); |
| 769 | 767 | |
| ... | ... | @@ -802,7 +800,7 @@ pub const Parser = struct { |
| 802 | 800 | Indent: usize, |
| 803 | 801 | }; |
| 804 | 802 | |
| 805 | pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void { | |
| 803 | pub fn renderSource(self: &Parser, stream: var, root_node: &ast.NodeRoot) !void { | |
| 806 | 804 | var stack = self.initUtilityArrayList(RenderState); |
| 807 | 805 | defer self.deinitUtilityArrayList(stack); |
| 808 | 806 | |
| ... | ... | @@ -1058,10 +1056,6 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 { |
| 1058 | 1056 | return buffer.toOwnedSlice(); |
| 1059 | 1057 | } |
| 1060 | 1058 | |
| 1061 | error TestFailed; | |
| 1062 | error NondeterministicMemoryUsage; | |
| 1063 | error MemoryLeakDetected; | |
| 1064 | ||
| 1065 | 1059 | // TODO test for memory leaks |
| 1066 | 1060 | // TODO test for valid frees |
| 1067 | 1061 | fn testCanonical(source: []const u8) !void { |
src/ir.cpp+72-4| ... | ... | @@ -5442,6 +5442,10 @@ static TypeTableEntry *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, |
| 5442 | 5442 | buf_resize(&err_set_type->name, 0); |
| 5443 | 5443 | buf_appendf(&err_set_type->name, "error{"); |
| 5444 | 5444 | |
| 5445 | for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { | |
| 5446 | assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); | |
| 5447 | } | |
| 5448 | ||
| 5445 | 5449 | uint32_t count = set1->data.error_set.err_count; |
| 5446 | 5450 | for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { |
| 5447 | 5451 | ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; |
| ... | ... | @@ -5523,6 +5527,8 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A |
| 5523 | 5527 | err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); |
| 5524 | 5528 | } |
| 5525 | 5529 | |
| 5530 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); | |
| 5531 | ||
| 5526 | 5532 | for (uint32_t i = 0; i < err_count; i += 1) { |
| 5527 | 5533 | AstNode *symbol_node = node->data.err_set_decl.decls.at(i); |
| 5528 | 5534 | assert(symbol_node->type == NodeTypeSymbol); |
| ... | ... | @@ -5543,7 +5549,16 @@ static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, A |
| 5543 | 5549 | buf_ptr(err_name), error_value_count)); |
| 5544 | 5550 | } |
| 5545 | 5551 | err_set_type->data.error_set.errors[i] = err; |
| 5552 | ||
| 5553 | ErrorTableEntry *prev_err = errors[err->value]; | |
| 5554 | if (prev_err != nullptr) { | |
| 5555 | ErrorMsg *msg = add_node_error(irb->codegen, err->decl_node, buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); | |
| 5556 | add_error_note(irb->codegen, msg, prev_err->decl_node, buf_sprintf("other error here")); | |
| 5557 | return irb->codegen->invalid_instruction; | |
| 5558 | } | |
| 5559 | errors[err->value] = err; | |
| 5546 | 5560 | } |
| 5561 | free(errors); | |
| 5547 | 5562 | return ir_build_const_type(irb, parent_scope, node, err_set_type); |
| 5548 | 5563 | } |
| 5549 | 5564 | |
| ... | ... | @@ -6512,6 +6527,7 @@ static TypeTableEntry *get_error_set_intersection(IrAnalyze *ira, TypeTableEntry |
| 6512 | 6527 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| 6513 | 6528 | for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { |
| 6514 | 6529 | ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; |
| 6530 | assert(errors[error_entry->value] == nullptr); | |
| 6515 | 6531 | errors[error_entry->value] = error_entry; |
| 6516 | 6532 | } |
| 6517 | 6533 | ZigList<ErrorTableEntry *> intersection_list = {}; |
| ... | ... | @@ -6653,6 +6669,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, TypeTableEntry |
| 6653 | 6669 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); |
| 6654 | 6670 | for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { |
| 6655 | 6671 | ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; |
| 6672 | assert(errors[error_entry->value] == nullptr); | |
| 6656 | 6673 | errors[error_entry->value] = error_entry; |
| 6657 | 6674 | } |
| 6658 | 6675 | for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { |
| ... | ... | @@ -6767,6 +6784,12 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 6767 | 6784 | buf_sprintf("unable to cast global error set into smaller set")); |
| 6768 | 6785 | return ImplicitCastMatchResultReportedError; |
| 6769 | 6786 | } |
| 6787 | } else if (const_cast_result.id == ConstCastResultIdErrSetGlobal) { | |
| 6788 | ErrorMsg *msg = ir_add_error(ira, value, | |
| 6789 | buf_sprintf("expected '%s', found '%s'", buf_ptr(&expected_type->name), buf_ptr(&actual_type->name))); | |
| 6790 | add_error_note(ira->codegen, msg, value->source_node, | |
| 6791 | buf_sprintf("unable to cast global error set into smaller set")); | |
| 6792 | return ImplicitCastMatchResultReportedError; | |
| 6770 | 6793 | } |
| 6771 | 6794 | if (missing_errors != nullptr) { |
| 6772 | 6795 | ErrorMsg *msg = ir_add_error(ira, value, |
| ... | ... | @@ -6995,6 +7018,12 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 6995 | 7018 | return ImplicitCastMatchResultNo; |
| 6996 | 7019 | } |
| 6997 | 7020 | |
| 7021 | static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { | |
| 7022 | size_t old_errors_count = *errors_count; | |
| 7023 | *errors_count = g->errors_by_index.length; | |
| 7024 | *errors = reallocate(*errors, old_errors_count, *errors_count); | |
| 7025 | } | |
| 7026 | ||
| 6998 | 7027 | static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, IrInstruction **instructions, size_t instruction_count) { |
| 6999 | 7028 | assert(instruction_count >= 1); |
| 7000 | 7029 | IrInstruction *prev_inst = instructions[0]; |
| ... | ... | @@ -7002,6 +7031,7 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7002 | 7031 | return ira->codegen->builtin_types.entry_invalid; |
| 7003 | 7032 | } |
| 7004 | 7033 | ErrorTableEntry **errors = nullptr; |
| 7034 | size_t errors_count = 0; | |
| 7005 | 7035 | TypeTableEntry *err_set_type = nullptr; |
| 7006 | 7036 | if (prev_inst->value.type->id == TypeTableEntryIdErrorSet) { |
| 7007 | 7037 | if (type_is_global_error_set(prev_inst->value.type)) { |
| ... | ... | @@ -7011,9 +7041,11 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7011 | 7041 | if (!resolve_inferred_error_set(ira, err_set_type, prev_inst->source_node)) { |
| 7012 | 7042 | return ira->codegen->builtin_types.entry_invalid; |
| 7013 | 7043 | } |
| 7014 | errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); | |
| 7044 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7045 | ||
| 7015 | 7046 | for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { |
| 7016 | 7047 | ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; |
| 7048 | assert(errors[error_entry->value] == nullptr); | |
| 7017 | 7049 | errors[error_entry->value] = error_entry; |
| 7018 | 7050 | } |
| 7019 | 7051 | } |
| ... | ... | @@ -7064,6 +7096,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7064 | 7096 | continue; |
| 7065 | 7097 | } |
| 7066 | 7098 | |
| 7099 | // number of declared errors might have increased now | |
| 7100 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7101 | ||
| 7067 | 7102 | // if err_set_type is a superset of cur_type, keep err_set_type. |
| 7068 | 7103 | // if cur_type is a superset of err_set_type, switch err_set_type to cur_type |
| 7069 | 7104 | bool prev_is_superset = true; |
| ... | ... | @@ -7084,8 +7119,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7084 | 7119 | ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; |
| 7085 | 7120 | errors[error_entry->value] = nullptr; |
| 7086 | 7121 | } |
| 7122 | for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { | |
| 7123 | assert(errors[i] == nullptr); | |
| 7124 | } | |
| 7087 | 7125 | for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { |
| 7088 | 7126 | ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; |
| 7127 | assert(errors[error_entry->value] == nullptr); | |
| 7089 | 7128 | errors[error_entry->value] = error_entry; |
| 7090 | 7129 | } |
| 7091 | 7130 | bool cur_is_superset = true; |
| ... | ... | @@ -7122,14 +7161,21 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7122 | 7161 | prev_inst = cur_inst; |
| 7123 | 7162 | continue; |
| 7124 | 7163 | } |
| 7164 | ||
| 7165 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7166 | ||
| 7125 | 7167 | // test if err_set_type is a subset of cur_type's error set |
| 7126 | 7168 | // unset everything in errors |
| 7127 | 7169 | for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { |
| 7128 | 7170 | ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; |
| 7129 | 7171 | errors[error_entry->value] = nullptr; |
| 7130 | 7172 | } |
| 7173 | for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { | |
| 7174 | assert(errors[i] == nullptr); | |
| 7175 | } | |
| 7131 | 7176 | for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { |
| 7132 | 7177 | ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; |
| 7178 | assert(errors[error_entry->value] == nullptr); | |
| 7133 | 7179 | errors[error_entry->value] = error_entry; |
| 7134 | 7180 | } |
| 7135 | 7181 | bool cur_is_superset = true; |
| ... | ... | @@ -7173,15 +7219,18 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7173 | 7219 | if (!resolve_inferred_error_set(ira, cur_type, cur_inst->source_node)) { |
| 7174 | 7220 | return ira->codegen->builtin_types.entry_invalid; |
| 7175 | 7221 | } |
| 7222 | ||
| 7223 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7224 | ||
| 7176 | 7225 | if (err_set_type == nullptr) { |
| 7177 | 7226 | if (prev_type->id == TypeTableEntryIdErrorUnion) { |
| 7178 | 7227 | err_set_type = prev_type->data.error_union.err_set_type; |
| 7179 | 7228 | } else { |
| 7180 | 7229 | err_set_type = cur_type; |
| 7181 | 7230 | } |
| 7182 | errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); | |
| 7183 | 7231 | for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { |
| 7184 | 7232 | ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; |
| 7233 | assert(errors[error_entry->value] == nullptr); | |
| 7185 | 7234 | errors[error_entry->value] = error_entry; |
| 7186 | 7235 | } |
| 7187 | 7236 | if (err_set_type == cur_type) { |
| ... | ... | @@ -7237,11 +7286,13 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7237 | 7286 | continue; |
| 7238 | 7287 | } |
| 7239 | 7288 | |
| 7289 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7290 | ||
| 7240 | 7291 | if (err_set_type == nullptr) { |
| 7241 | 7292 | err_set_type = prev_err_set_type; |
| 7242 | errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); | |
| 7243 | 7293 | for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { |
| 7244 | 7294 | ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; |
| 7295 | assert(errors[error_entry->value] == nullptr); | |
| 7245 | 7296 | errors[error_entry->value] = error_entry; |
| 7246 | 7297 | } |
| 7247 | 7298 | } |
| ... | ... | @@ -7262,8 +7313,12 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7262 | 7313 | ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; |
| 7263 | 7314 | errors[error_entry->value] = nullptr; |
| 7264 | 7315 | } |
| 7316 | for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { | |
| 7317 | assert(errors[i] == nullptr); | |
| 7318 | } | |
| 7265 | 7319 | for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { |
| 7266 | 7320 | ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; |
| 7321 | assert(errors[error_entry->value] == nullptr); | |
| 7267 | 7322 | errors[error_entry->value] = error_entry; |
| 7268 | 7323 | } |
| 7269 | 7324 | bool cur_is_superset = true; |
| ... | ... | @@ -7331,6 +7386,8 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod |
| 7331 | 7386 | continue; |
| 7332 | 7387 | } |
| 7333 | 7388 | |
| 7389 | update_errors_helper(ira->codegen, &errors, &errors_count); | |
| 7390 | ||
| 7334 | 7391 | err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); |
| 7335 | 7392 | } |
| 7336 | 7393 | prev_inst = cur_inst; |
| ... | ... | @@ -8000,6 +8057,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 8000 | 8057 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| 8001 | 8058 | for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { |
| 8002 | 8059 | ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; |
| 8060 | assert(errors[error_entry->value] == nullptr); | |
| 8003 | 8061 | errors[error_entry->value] = error_entry; |
| 8004 | 8062 | } |
| 8005 | 8063 | ErrorMsg *err_msg = nullptr; |
| ... | ... | @@ -10212,8 +10270,9 @@ static TypeTableEntry *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstruction |
| 10212 | 10270 | } |
| 10213 | 10271 | |
| 10214 | 10272 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); |
| 10215 | for (uint32_t i = 0; i < op1_type->data.error_set.err_count; i += 1) { | |
| 10273 | for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { | |
| 10216 | 10274 | ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; |
| 10275 | assert(errors[error_entry->value] == nullptr); | |
| 10217 | 10276 | errors[error_entry->value] = error_entry; |
| 10218 | 10277 | } |
| 10219 | 10278 | TypeTableEntry *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); |
| ... | ... | @@ -14987,6 +15046,15 @@ static TypeTableEntry *ir_analyze_instruction_member_count(IrAnalyze *ira, IrIns |
| 14987 | 15046 | result = container_type->data.structure.src_field_count; |
| 14988 | 15047 | } else if (container_type->id == TypeTableEntryIdUnion) { |
| 14989 | 15048 | result = container_type->data.unionation.src_field_count; |
| 15049 | } else if (container_type->id == TypeTableEntryIdErrorSet) { | |
| 15050 | if (!resolve_inferred_error_set(ira, container_type, instruction->base.source_node)) { | |
| 15051 | return ira->codegen->builtin_types.entry_invalid; | |
| 15052 | } | |
| 15053 | if (type_is_global_error_set(container_type)) { | |
| 15054 | ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); | |
| 15055 | return ira->codegen->builtin_types.entry_invalid; | |
| 15056 | } | |
| 15057 | result = container_type->data.error_set.err_count; | |
| 14990 | 15058 | } else { |
| 14991 | 15059 | ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); |
| 14992 | 15060 | return ira->codegen->builtin_types.entry_invalid; |
src/util.hpp+11-8| ... | ... | @@ -92,19 +92,22 @@ static inline void safe_memcpy(T *dest, const T *src, size_t count) { |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | template<typename T> |
| 95 | static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) { | |
| 96 | #ifdef NDEBUG | |
| 95 | static inline T *reallocate(T *old, size_t old_count, size_t new_count) { | |
| 97 | 96 | T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T))); |
| 98 | 97 | if (!ptr) |
| 99 | 98 | zig_panic("allocation failed"); |
| 99 | if (new_count > old_count) { | |
| 100 | memset(&ptr[old_count], 0, (new_count - old_count) * sizeof(T)); | |
| 101 | } | |
| 100 | 102 | return ptr; |
| 101 | #else | |
| 102 | // manually assign every element to trigger compile error for non-copyable structs | |
| 103 | T *ptr = allocate_nonzero<T>(new_count); | |
| 104 | safe_memcpy(ptr, old, old_count); | |
| 105 | free(old); | |
| 103 | } | |
| 104 | ||
| 105 | template<typename T> | |
| 106 | static inline T *reallocate_nonzero(T *old, size_t old_count, size_t new_count) { | |
| 107 | T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T))); | |
| 108 | if (!ptr) | |
| 109 | zig_panic("allocation failed"); | |
| 106 | 110 | return ptr; |
| 107 | #endif | |
| 108 | 111 | } |
| 109 | 112 | |
| 110 | 113 | template <typename T, size_t n> |
std/build.zig+4-4| ... | ... | @@ -271,7 +271,7 @@ pub const Builder = struct { |
| 271 | 271 | return &self.uninstall_tls.step; |
| 272 | 272 | } |
| 273 | 273 | |
| 274 | fn makeUninstall(uninstall_step: &Step) !void { | |
| 274 | fn makeUninstall(uninstall_step: &Step) error!void { | |
| 275 | 275 | const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step); |
| 276 | 276 | const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls); |
| 277 | 277 | |
| ... | ... | @@ -285,7 +285,7 @@ pub const Builder = struct { |
| 285 | 285 | // TODO remove empty directories |
| 286 | 286 | } |
| 287 | 287 | |
| 288 | fn makeOneStep(self: &Builder, s: &Step) !void { | |
| 288 | fn makeOneStep(self: &Builder, s: &Step) error!void { | |
| 289 | 289 | if (s.loop_flag) { |
| 290 | 290 | warn("Dependency loop detected:\n {}\n", s.name); |
| 291 | 291 | return error.DependencyLoopDetected; |
| ... | ... | @@ -1910,7 +1910,7 @@ pub const LogStep = struct { |
| 1910 | 1910 | }; |
| 1911 | 1911 | } |
| 1912 | 1912 | |
| 1913 | fn make(step: &Step) !void { | |
| 1913 | fn make(step: &Step) error!void { | |
| 1914 | 1914 | const self = @fieldParentPtr(LogStep, "step", step); |
| 1915 | 1915 | warn("{}", self.data); |
| 1916 | 1916 | } |
| ... | ... | @@ -1972,7 +1972,7 @@ pub const Step = struct { |
| 1972 | 1972 | self.dependencies.append(other) catch unreachable; |
| 1973 | 1973 | } |
| 1974 | 1974 | |
| 1975 | fn makeNoOp(self: &Step) (error{}!void) {} | |
| 1975 | fn makeNoOp(self: &Step) error!void {} | |
| 1976 | 1976 | }; |
| 1977 | 1977 | |
| 1978 | 1978 | fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_major_only: []const u8, |
std/fmt/index.zig+1-1| ... | ... | @@ -510,7 +510,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ... |
| 510 | 510 | return bufPrint(buf, fmt, args); |
| 511 | 511 | } |
| 512 | 512 | |
| 513 | fn countSize(size: &usize, bytes: []const u8) !void { | |
| 513 | fn countSize(size: &usize, bytes: []const u8) (error{}!void) { | |
| 514 | 514 | *size += bytes.len; |
| 515 | 515 | } |
| 516 | 516 |
std/io.zig+2-2| ... | ... | @@ -694,13 +694,13 @@ pub const BufferOutStream = struct { |
| 694 | 694 | pub fn init(buffer: &Buffer) BufferOutStream { |
| 695 | 695 | return BufferOutStream { |
| 696 | 696 | .buffer = buffer, |
| 697 | .stream = OutStream { | |
| 697 | .stream = Stream { | |
| 698 | 698 | .writeFn = writeFn, |
| 699 | 699 | }, |
| 700 | 700 | }; |
| 701 | 701 | } |
| 702 | 702 | |
| 703 | fn writeFn(out_stream: &OutStream, bytes: []const u8) !void { | |
| 703 | fn writeFn(out_stream: &Stream, bytes: []const u8) !void { | |
| 704 | 704 | const self = @fieldParentPtr(BufferOutStream, "stream", out_stream); |
| 705 | 705 | return self.buffer.append(bytes); |
| 706 | 706 | } |
std/os/child_process.zig+18-3| ... | ... | @@ -55,7 +55,22 @@ pub const ChildProcess = struct { |
| 55 | 55 | llnode: if (is_windows) void else LinkedList(&ChildProcess).Node, |
| 56 | 56 | |
| 57 | 57 | pub const SpawnError = error { |
| 58 | ||
| 58 | ProcessFdQuotaExceeded, | |
| 59 | Unexpected, | |
| 60 | NotDir, | |
| 61 | SystemResources, | |
| 62 | FileNotFound, | |
| 63 | NameTooLong, | |
| 64 | SymLinkLoop, | |
| 65 | FileSystem, | |
| 66 | OutOfMemory, | |
| 67 | AccessDenied, | |
| 68 | PermissionDenied, | |
| 69 | InvalidUserId, | |
| 70 | ResourceLimitReached, | |
| 71 | InvalidExe, | |
| 72 | IsDir, | |
| 73 | FileBusy, | |
| 59 | 74 | }; |
| 60 | 75 | |
| 61 | 76 | pub const Term = union(enum) { |
| ... | ... | @@ -313,7 +328,7 @@ pub const ChildProcess = struct { |
| 313 | 328 | // Here we potentially return the fork child's error |
| 314 | 329 | // from the parent pid. |
| 315 | 330 | if (err_int != @maxValue(ErrInt)) { |
| 316 | return error(err_int); | |
| 331 | return SpawnError(err_int); | |
| 317 | 332 | } |
| 318 | 333 | |
| 319 | 334 | return statusToTerm(status); |
| ... | ... | @@ -757,7 +772,7 @@ fn destroyPipe(pipe: &const [2]i32) void { |
| 757 | 772 | |
| 758 | 773 | // Child of fork calls this to report an error to the fork parent. |
| 759 | 774 | // Then the child exits. |
| 760 | fn forkChildErrReport(fd: i32, err: error) noreturn { | |
| 775 | fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn { | |
| 761 | 776 | _ = writeIntFd(fd, ErrInt(err)); |
| 762 | 777 | posix.exit(1); |
| 763 | 778 | } |
std/os/index.zig+80-19| ... | ... | @@ -243,7 +243,6 @@ pub const PosixOpenError = error { |
| 243 | 243 | SystemResources, |
| 244 | 244 | NoSpaceLeft, |
| 245 | 245 | NotDir, |
| 246 | AccessDenied, | |
| 247 | 246 | PathAlreadyExists, |
| 248 | 247 | Unexpected, |
| 249 | 248 | }; |
| ... | ... | @@ -411,7 +410,19 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap, |
| 411 | 410 | return posixExecveErrnoToErr(err); |
| 412 | 411 | } |
| 413 | 412 | |
| 414 | fn posixExecveErrnoToErr(err: usize) error { | |
| 413 | pub const PosixExecveError = error { | |
| 414 | SystemResources, | |
| 415 | AccessDenied, | |
| 416 | InvalidExe, | |
| 417 | FileSystem, | |
| 418 | IsDir, | |
| 419 | FileNotFound, | |
| 420 | NotDir, | |
| 421 | FileBusy, | |
| 422 | Unexpected, | |
| 423 | }; | |
| 424 | ||
| 425 | fn posixExecveErrnoToErr(err: usize) PosixExecveError { | |
| 415 | 426 | assert(err > 0); |
| 416 | 427 | return switch (err) { |
| 417 | 428 | posix.EFAULT => unreachable, |
| ... | ... | @@ -904,24 +915,68 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) !void { |
| 904 | 915 | /// removes it. If it cannot be removed because it is a non-empty directory, |
| 905 | 916 | /// this function recursively removes its entries and then tries again. |
| 906 | 917 | // TODO non-recursive implementation |
| 907 | pub fn deleteTree(allocator: &Allocator, full_path: []const u8) !void { | |
| 918 | const DeleteTreeError = error { | |
| 919 | OutOfMemory, | |
| 920 | AccessDenied, | |
| 921 | FileTooBig, | |
| 922 | IsDir, | |
| 923 | SymLinkLoop, | |
| 924 | ProcessFdQuotaExceeded, | |
| 925 | NameTooLong, | |
| 926 | SystemFdQuotaExceeded, | |
| 927 | NoDevice, | |
| 928 | PathNotFound, | |
| 929 | SystemResources, | |
| 930 | NoSpaceLeft, | |
| 931 | PathAlreadyExists, | |
| 932 | ReadOnlyFileSystem, | |
| 933 | NotDir, | |
| 934 | FileNotFound, | |
| 935 | FileSystem, | |
| 936 | FileBusy, | |
| 937 | DirNotEmpty, | |
| 938 | Unexpected, | |
| 939 | }; | |
| 940 | pub fn deleteTree(allocator: &Allocator, full_path: []const u8) DeleteTreeError!void { | |
| 908 | 941 | start_over: while (true) { |
| 909 | 942 | // First, try deleting the item as a file. This way we don't follow sym links. |
| 910 | 943 | if (deleteFile(allocator, full_path)) { |
| 911 | 944 | return; |
| 912 | } else |err| { | |
| 913 | if (err == error.FileNotFound) | |
| 914 | return; | |
| 915 | if (err != error.IsDir) | |
| 916 | return err; | |
| 945 | } else |err| switch (err) { | |
| 946 | error.FileNotFound => return, | |
| 947 | error.IsDir => {}, | |
| 948 | ||
| 949 | error.OutOfMemory, | |
| 950 | error.AccessDenied, | |
| 951 | error.SymLinkLoop, | |
| 952 | error.NameTooLong, | |
| 953 | error.SystemResources, | |
| 954 | error.ReadOnlyFileSystem, | |
| 955 | error.NotDir, | |
| 956 | error.FileSystem, | |
| 957 | error.FileBusy, | |
| 958 | error.Unexpected | |
| 959 | => return err, | |
| 917 | 960 | } |
| 918 | 961 | { |
| 919 | var dir = Dir.open(allocator, full_path) catch |err| { | |
| 920 | if (err == error.FileNotFound) | |
| 921 | return; | |
| 922 | if (err == error.NotDir) | |
| 923 | continue :start_over; | |
| 924 | return err; | |
| 962 | var dir = Dir.open(allocator, full_path) catch |err| switch (err) { | |
| 963 | error.NotDir => continue :start_over, | |
| 964 | ||
| 965 | error.OutOfMemory, | |
| 966 | error.AccessDenied, | |
| 967 | error.FileTooBig, | |
| 968 | error.IsDir, | |
| 969 | error.SymLinkLoop, | |
| 970 | error.ProcessFdQuotaExceeded, | |
| 971 | error.NameTooLong, | |
| 972 | error.SystemFdQuotaExceeded, | |
| 973 | error.NoDevice, | |
| 974 | error.PathNotFound, | |
| 975 | error.SystemResources, | |
| 976 | error.NoSpaceLeft, | |
| 977 | error.PathAlreadyExists, | |
| 978 | error.Unexpected | |
| 979 | => return err, | |
| 925 | 980 | }; |
| 926 | 981 | defer dir.close(); |
| 927 | 982 | |
| ... | ... | @@ -1252,6 +1307,8 @@ pub const ArgIteratorWindows = struct { |
| 1252 | 1307 | quote_count: usize, |
| 1253 | 1308 | seen_quote_count: usize, |
| 1254 | 1309 | |
| 1310 | pub const NextError = error{OutOfMemory}; | |
| 1311 | ||
| 1255 | 1312 | pub fn init() ArgIteratorWindows { |
| 1256 | 1313 | return initWithCmdLine(windows.GetCommandLineA()); |
| 1257 | 1314 | } |
| ... | ... | @@ -1267,7 +1324,7 @@ pub const ArgIteratorWindows = struct { |
| 1267 | 1324 | } |
| 1268 | 1325 | |
| 1269 | 1326 | /// You must free the returned memory when done. |
| 1270 | pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?(@typeOf(internalNext).ReturnType.ErrorSet![]u8) { | |
| 1327 | pub fn next(self: &ArgIteratorWindows, allocator: &Allocator) ?(NextError![]u8) { | |
| 1271 | 1328 | // march forward over whitespace |
| 1272 | 1329 | while (true) : (self.index += 1) { |
| 1273 | 1330 | const byte = self.cmd_line[self.index]; |
| ... | ... | @@ -1320,7 +1377,7 @@ pub const ArgIteratorWindows = struct { |
| 1320 | 1377 | } |
| 1321 | 1378 | } |
| 1322 | 1379 | |
| 1323 | fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) ![]u8 { | |
| 1380 | fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) NextError![]u8 { | |
| 1324 | 1381 | var buf = try Buffer.initSize(allocator, 0); |
| 1325 | 1382 | defer buf.deinit(); |
| 1326 | 1383 | |
| ... | ... | @@ -1394,16 +1451,20 @@ pub const ArgIteratorWindows = struct { |
| 1394 | 1451 | }; |
| 1395 | 1452 | |
| 1396 | 1453 | pub const ArgIterator = struct { |
| 1397 | inner: if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix, | |
| 1454 | const InnerType = if (builtin.os == Os.windows) ArgIteratorWindows else ArgIteratorPosix; | |
| 1455 | ||
| 1456 | inner: InnerType, | |
| 1398 | 1457 | |
| 1399 | 1458 | pub fn init() ArgIterator { |
| 1400 | 1459 | return ArgIterator { |
| 1401 | .inner = if (builtin.os == Os.windows) ArgIteratorWindows.init() else ArgIteratorPosix.init(), | |
| 1460 | .inner = InnerType.init(), | |
| 1402 | 1461 | }; |
| 1403 | 1462 | } |
| 1463 | ||
| 1464 | pub const NextError = ArgIteratorWindows.NextError; | |
| 1404 | 1465 | |
| 1405 | 1466 | /// You must free the returned memory when done. |
| 1406 | pub fn next(self: &ArgIterator, allocator: &Allocator) ?![]u8 { | |
| 1467 | pub fn next(self: &ArgIterator, allocator: &Allocator) ?(NextError![]u8) { | |
| 1407 | 1468 | if (builtin.os == Os.windows) { |
| 1408 | 1469 | return self.inner.next(allocator); |
| 1409 | 1470 | } else { |
std/os/windows/util.zig+2-1| ... | ... | @@ -30,7 +30,6 @@ pub fn windowsClose(handle: windows.HANDLE) void { |
| 30 | 30 | pub const WriteError = error { |
| 31 | 31 | SystemResources, |
| 32 | 32 | OperationAborted, |
| 33 | SystemResources, | |
| 34 | 33 | IoPending, |
| 35 | 34 | BrokenPipe, |
| 36 | 35 | Unexpected, |
| ... | ... | @@ -83,6 +82,8 @@ pub const OpenError = error { |
| 83 | 82 | AccessDenied, |
| 84 | 83 | PipeBusy, |
| 85 | 84 | Unexpected, |
| 85 | OutOfMemory, | |
| 86 | NameTooLong, | |
| 86 | 87 | }; |
| 87 | 88 | |
| 88 | 89 | /// `file_path` may need to be copied in memory to add a null terminating byte. In this case |
std/special/bootstrap.zig+2-2| ... | ... | @@ -77,7 +77,7 @@ fn callMain() u8 { |
| 77 | 77 | }, |
| 78 | 78 | builtin.TypeId.Int => { |
| 79 | 79 | if (@typeOf(root.main).ReturnType.bit_count != 8) { |
| 80 | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 80 | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); | |
| 81 | 81 | } |
| 82 | 82 | return root.main(); |
| 83 | 83 | }, |
| ... | ... | @@ -91,6 +91,6 @@ fn callMain() u8 { |
| 91 | 91 | }; |
| 92 | 92 | return 0; |
| 93 | 93 | }, |
| 94 | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"), | |
| 94 | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"), | |
| 95 | 95 | } |
| 96 | 96 | } |
std/special/build_runner.zig+18-7| ... | ... | @@ -1,5 +1,6 @@ |
| 1 | 1 | const root = @import("@build"); |
| 2 | 2 | const std = @import("std"); |
| 3 | const builtin = @import("builtin"); | |
| 3 | 4 | const io = std.io; |
| 4 | 5 | const fmt = std.fmt; |
| 5 | 6 | const os = std.os; |
| ... | ... | @@ -43,14 +44,14 @@ pub fn main() !void { |
| 43 | 44 | |
| 44 | 45 | var stderr_file = io.getStdErr(); |
| 45 | 46 | var stderr_file_stream: io.FileOutStream = undefined; |
| 46 | var stderr_stream: %&io.OutStream = if (stderr_file) |*f| x: { | |
| 47 | var stderr_stream = if (stderr_file) |*f| x: { | |
| 47 | 48 | stderr_file_stream = io.FileOutStream.init(f); |
| 48 | 49 | break :x &stderr_file_stream.stream; |
| 49 | 50 | } else |err| err; |
| 50 | 51 | |
| 51 | 52 | var stdout_file = io.getStdOut(); |
| 52 | 53 | var stdout_file_stream: io.FileOutStream = undefined; |
| 53 | var stdout_stream: %&io.OutStream = if (stdout_file) |*f| x: { | |
| 54 | var stdout_stream = if (stdout_file) |*f| x: { | |
| 54 | 55 | stdout_file_stream = io.FileOutStream.init(f); |
| 55 | 56 | break :x &stdout_file_stream.stream; |
| 56 | 57 | } else |err| err; |
| ... | ... | @@ -110,7 +111,7 @@ pub fn main() !void { |
| 110 | 111 | } |
| 111 | 112 | |
| 112 | 113 | builder.setInstallPrefix(prefix); |
| 113 | try root.build(&builder); | |
| 114 | try runBuild(&builder); | |
| 114 | 115 | |
| 115 | 116 | if (builder.validateUserInputDidItFail()) |
| 116 | 117 | return usageAndErr(&builder, true, try stderr_stream); |
| ... | ... | @@ -123,11 +124,19 @@ pub fn main() !void { |
| 123 | 124 | }; |
| 124 | 125 | } |
| 125 | 126 | |
| 126 | fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) !void { | |
| 127 | fn runBuild(builder: &Builder) error!void { | |
| 128 | switch (@typeId(@typeOf(root.build).ReturnType)) { | |
| 129 | builtin.TypeId.Void => root.build(builder), | |
| 130 | builtin.TypeId.ErrorUnion => try root.build(builder), | |
| 131 | else => @compileError("expected return type of build to be 'void' or '!void'"), | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | fn usage(builder: &Builder, already_ran_build: bool, out_stream: var) !void { | |
| 127 | 136 | // run the build script to collect the options |
| 128 | 137 | if (!already_ran_build) { |
| 129 | 138 | builder.setInstallPrefix(null); |
| 130 | try root.build(builder); | |
| 139 | try runBuild(builder); | |
| 131 | 140 | } |
| 132 | 141 | |
| 133 | 142 | // This usage text has to be synchronized with src/main.cpp |
| ... | ... | @@ -181,12 +190,14 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 181 | 190 | ); |
| 182 | 191 | } |
| 183 | 192 | |
| 184 | fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) error { | |
| 193 | fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: var) error { | |
| 185 | 194 | usage(builder, already_ran_build, out_stream) catch {}; |
| 186 | 195 | return error.InvalidArgs; |
| 187 | 196 | } |
| 188 | 197 | |
| 189 | fn unwrapArg(arg: %[]u8) ![]u8 { | |
| 198 | const UnwrapArgError = error {OutOfMemory}; | |
| 199 | ||
| 200 | fn unwrapArg(arg: UnwrapArgError![]u8) UnwrapArgError![]u8 { | |
| 190 | 201 | return arg catch |err| { |
| 191 | 202 | warn("Unable to parse command line: {}\n", err); |
| 192 | 203 | return err; |
test/cases/error.zig+36-2| ... | ... | @@ -1,5 +1,7 @@ |
| 1 | const assert = @import("std").debug.assert; | |
| 2 | const mem = @import("std").mem; | |
| 1 | const std = @import("std"); | |
| 2 | const assert = std.debug.assert; | |
| 3 | const mem = std.mem; | |
| 4 | const builtin = @import("builtin"); | |
| 3 | 5 | |
| 4 | 6 | pub fn foo() error!i32 { |
| 5 | 7 | const x = try bar(); |
| ... | ... | @@ -74,3 +76,35 @@ fn doErrReturnInAssignment() error!void { |
| 74 | 76 | fn makeANonErr() error!i32 { |
| 75 | 77 | return 1; |
| 76 | 78 | } |
| 79 | ||
| 80 | test "error union type " { | |
| 81 | testErrorUnionType(); | |
| 82 | comptime testErrorUnionType(); | |
| 83 | } | |
| 84 | ||
| 85 | fn testErrorUnionType() void { | |
| 86 | const x: error!i32 = 1234; | |
| 87 | if (x) |value| assert(value == 1234) else |_| unreachable; | |
| 88 | assert(@typeId(@typeOf(x)) == builtin.TypeId.ErrorUnion); | |
| 89 | assert(@typeId(@typeOf(x).ErrorSet) == builtin.TypeId.ErrorSet); | |
| 90 | assert(@typeOf(x).ErrorSet == error); | |
| 91 | } | |
| 92 | ||
| 93 | test "error set type " { | |
| 94 | testErrorSetType(); | |
| 95 | comptime testErrorSetType(); | |
| 96 | } | |
| 97 | ||
| 98 | const MyErrSet = error {OutOfMemory, FileNotFound}; | |
| 99 | ||
| 100 | fn testErrorSetType() void { | |
| 101 | assert(@memberCount(MyErrSet) == 2); | |
| 102 | ||
| 103 | const a: MyErrSet!i32 = 5678; | |
| 104 | const b: MyErrSet!i32 = MyErrSet.OutOfMemory; | |
| 105 | ||
| 106 | if (a) |value| assert(value == 5678) else |err| switch (err) { | |
| 107 | error.OutOfMemory => unreachable, | |
| 108 | error.FileNotFound => unreachable, | |
| 109 | } | |
| 110 | } |
test/compare_output.zig+12-13| ... | ... | @@ -15,7 +15,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 15 | 15 | \\use @import("std").io; |
| 16 | 16 | \\use @import("foo.zig"); |
| 17 | 17 | \\ |
| 18 | \\pub fn main() !void { | |
| 18 | \\pub fn main() void { | |
| 19 | 19 | \\ privateFunction(); |
| 20 | 20 | \\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream); |
| 21 | 21 | \\ stdout.print("OK 2\n") catch unreachable; |
| ... | ... | @@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 49 | 49 | \\use @import("foo.zig"); |
| 50 | 50 | \\use @import("bar.zig"); |
| 51 | 51 | \\ |
| 52 | \\pub fn main() !void { | |
| 52 | \\pub fn main() void { | |
| 53 | 53 | \\ foo_function(); |
| 54 | 54 | \\ bar_function(); |
| 55 | 55 | \\} |
| ... | ... | @@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 89 | 89 | var tc = cases.create("two files use import each other", |
| 90 | 90 | \\use @import("a.zig"); |
| 91 | 91 | \\ |
| 92 | \\pub fn main() !void { | |
| 92 | \\pub fn main() void { | |
| 93 | 93 | \\ ok(); |
| 94 | 94 | \\} |
| 95 | 95 | , "OK\n"); |
| ... | ... | @@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 118 | 118 | cases.add("hello world without libc", |
| 119 | 119 | \\const io = @import("std").io; |
| 120 | 120 | \\ |
| 121 | \\pub fn main() !void { | |
| 121 | \\pub fn main() void { | |
| 122 | 122 | \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); |
| 123 | 123 | \\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable; |
| 124 | 124 | \\} |
| ... | ... | @@ -268,7 +268,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 268 | 268 | \\const z = io.stdin_fileno; |
| 269 | 269 | \\const x : @typeOf(y) = 1234; |
| 270 | 270 | \\const y : u16 = 5678; |
| 271 | \\pub fn main() !void { | |
| 271 | \\pub fn main() void { | |
| 272 | 272 | \\ var x_local : i32 = print_ok(x); |
| 273 | 273 | \\} |
| 274 | 274 | \\fn print_ok(val: @typeOf(x)) @typeOf(foo) { |
| ... | ... | @@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 351 | 351 | \\ fn method(b: &const Bar) bool { return true; } |
| 352 | 352 | \\}; |
| 353 | 353 | \\ |
| 354 | \\pub fn main() !void { | |
| 354 | \\pub fn main() void { | |
| 355 | 355 | \\ const bar = Bar {.field2 = 13,}; |
| 356 | 356 | \\ const foo = Foo {.field1 = bar,}; |
| 357 | 357 | \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); |
| ... | ... | @@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 367 | 367 | |
| 368 | 368 | cases.add("defer with only fallthrough", |
| 369 | 369 | \\const io = @import("std").io; |
| 370 | \\pub fn main() !void { | |
| 370 | \\pub fn main() void { | |
| 371 | 371 | \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); |
| 372 | 372 | \\ stdout.print("before\n") catch unreachable; |
| 373 | 373 | \\ defer stdout.print("defer1\n") catch unreachable; |
| ... | ... | @@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 380 | 380 | cases.add("defer with return", |
| 381 | 381 | \\const io = @import("std").io; |
| 382 | 382 | \\const os = @import("std").os; |
| 383 | \\pub fn main() !void { | |
| 383 | \\pub fn main() void { | |
| 384 | 384 | \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); |
| 385 | 385 | \\ stdout.print("before\n") catch unreachable; |
| 386 | 386 | \\ defer stdout.print("defer1\n") catch unreachable; |
| ... | ... | @@ -394,7 +394,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 394 | 394 | |
| 395 | 395 | cases.add("errdefer and it fails", |
| 396 | 396 | \\const io = @import("std").io; |
| 397 | \\pub fn main() !void { | |
| 397 | \\pub fn main() void { | |
| 398 | 398 | \\ do_test() catch return; |
| 399 | 399 | \\} |
| 400 | 400 | \\fn do_test() !void { |
| ... | ... | @@ -406,7 +406,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 406 | 406 | \\ defer stdout.print("defer3\n") catch unreachable; |
| 407 | 407 | \\ stdout.print("after\n") catch unreachable; |
| 408 | 408 | \\} |
| 409 | \\error IToldYouItWouldFail; | |
| 410 | 409 | \\fn its_gonna_fail() !void { |
| 411 | 410 | \\ return error.IToldYouItWouldFail; |
| 412 | 411 | \\} |
| ... | ... | @@ -414,7 +413,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 414 | 413 | |
| 415 | 414 | cases.add("errdefer and it passes", |
| 416 | 415 | \\const io = @import("std").io; |
| 417 | \\pub fn main() !void { | |
| 416 | \\pub fn main() void { | |
| 418 | 417 | \\ do_test() catch return; |
| 419 | 418 | \\} |
| 420 | 419 | \\fn do_test() !void { |
| ... | ... | @@ -426,7 +425,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 426 | 425 | \\ defer stdout.print("defer3\n") catch unreachable; |
| 427 | 426 | \\ stdout.print("after\n") catch unreachable; |
| 428 | 427 | \\} |
| 429 | \\fn its_gonna_pass() %void { } | |
| 428 | \\fn its_gonna_pass() error!void { } | |
| 430 | 429 | , "before\nafter\ndefer3\ndefer1\n"); |
| 431 | 430 | |
| 432 | 431 | cases.addCase(x: { |
| ... | ... | @@ -434,7 +433,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void { |
| 434 | 433 | \\const foo_txt = @embedFile("foo.txt"); |
| 435 | 434 | \\const io = @import("std").io; |
| 436 | 435 | \\ |
| 437 | \\pub fn main() !void { | |
| 436 | \\pub fn main() void { | |
| 438 | 437 | \\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream); |
| 439 | 438 | \\ stdout.print(foo_txt) catch unreachable; |
| 440 | 439 | \\} |
test/compile_errors.zig+33-15| ... | ... | @@ -1,6 +1,25 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 4 | cases.add("@memberCount of error", | |
| 5 | \\comptime { | |
| 6 | \\ _ = @memberCount(error); | |
| 7 | \\} | |
| 8 | , | |
| 9 | ".tmp_source.zig:2:9: error: global error set member count not available at comptime"); | |
| 10 | ||
| 11 | cases.add("duplicate error value in error set", | |
| 12 | \\const Foo = error { | |
| 13 | \\ Bar, | |
| 14 | \\ Bar, | |
| 15 | \\}; | |
| 16 | \\export fn entry() void { | |
| 17 | \\ const a: Foo = undefined; | |
| 18 | \\} | |
| 19 | , | |
| 20 | ".tmp_source.zig:3:5: error: duplicate error: 'Bar'", | |
| 21 | ".tmp_source.zig:2:5: note: other error here"); | |
| 22 | ||
| 4 | 23 | cases.add("duplicate struct field", |
| 5 | 24 | \\const Foo = struct { |
| 6 | 25 | \\ Bar: i32, |
| ... | ... | @@ -99,12 +118,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 99 | 118 | |
| 100 | 119 | cases.add("wrong return type for main", |
| 101 | 120 | \\pub fn main() f32 { } |
| 102 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 121 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); | |
| 103 | 122 | |
| 104 | 123 | cases.add("double ?? on main return value", |
| 105 | 124 | \\pub fn main() ??void { |
| 106 | 125 | \\} |
| 107 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 126 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '!void'"); | |
| 108 | 127 | |
| 109 | 128 | cases.add("bad identifier in function with struct defined inside function which references local const", |
| 110 | 129 | \\export fn entry() void { |
| ... | ... | @@ -1160,7 +1179,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1160 | 1179 | \\export fn f() void { |
| 1161 | 1180 | \\ try something(); |
| 1162 | 1181 | \\} |
| 1163 | \\fn something() %void { } | |
| 1182 | \\fn something() error!void { } | |
| 1164 | 1183 | , |
| 1165 | 1184 | ".tmp_source.zig:2:5: error: expected type 'void', found 'error'"); |
| 1166 | 1185 | |
| ... | ... | @@ -1251,7 +1270,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1251 | 1270 | , ".tmp_source.zig:3:11: error: cannot assign to constant"); |
| 1252 | 1271 | |
| 1253 | 1272 | cases.add("main function with bogus args type", |
| 1254 | \\pub fn main(args: [][]bogus) %void {} | |
| 1273 | \\pub fn main(args: [][]bogus) !void {} | |
| 1255 | 1274 | , ".tmp_source.zig:1:23: error: use of undeclared identifier 'bogus'"); |
| 1256 | 1275 | |
| 1257 | 1276 | cases.add("for loop missing element param", |
| ... | ... | @@ -1391,7 +1410,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1391 | 1410 | \\ const a = maybeInt() ?? return; |
| 1392 | 1411 | \\} |
| 1393 | 1412 | \\ |
| 1394 | \\fn canFail() %void { } | |
| 1413 | \\fn canFail() error!void { } | |
| 1395 | 1414 | \\ |
| 1396 | 1415 | \\pub fn maybeInt() ?i32 { |
| 1397 | 1416 | \\ return 0; |
| ... | ... | @@ -1521,7 +1540,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1521 | 1540 | \\export fn foo() void { |
| 1522 | 1541 | \\ bar() catch unreachable; |
| 1523 | 1542 | \\} |
| 1524 | \\fn bar() %i32 { return 0; } | |
| 1543 | \\fn bar() error!i32 { return 0; } | |
| 1525 | 1544 | , ".tmp_source.zig:2:11: error: expression value is ignored"); |
| 1526 | 1545 | |
| 1527 | 1546 | cases.add("ignored statement value", |
| ... | ... | @@ -1552,7 +1571,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1552 | 1571 | \\export fn foo() void { |
| 1553 | 1572 | \\ defer bar(); |
| 1554 | 1573 | \\} |
| 1555 | \\fn bar() %i32 { return 0; } | |
| 1574 | \\fn bar() error!i32 { return 0; } | |
| 1556 | 1575 | , ".tmp_source.zig:2:14: error: expression value is ignored"); |
| 1557 | 1576 | |
| 1558 | 1577 | cases.add("dereference an array", |
| ... | ... | @@ -1619,13 +1638,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1619 | 1638 | , ".tmp_source.zig:2:21: error: expected pointer, found 'usize'"); |
| 1620 | 1639 | |
| 1621 | 1640 | cases.add("too many error values to cast to small integer", |
| 1622 | \\error A; error B; error C; error D; error E; error F; error G; error H; | |
| 1623 | \\const u2 = @IntType(false, 2); | |
| 1624 | \\fn foo(e: error) u2 { | |
| 1641 | \\const Error = error { A, B, C, D, E, F, G, H }; | |
| 1642 | \\fn foo(e: Error) u2 { | |
| 1625 | 1643 | \\ return u2(e); |
| 1626 | 1644 | \\} |
| 1627 | 1645 | \\export fn entry() usize { return @sizeOf(@typeOf(foo)); } |
| 1628 | , ".tmp_source.zig:4:14: error: too many error values to fit in 'u2'"); | |
| 1646 | , ".tmp_source.zig:3:14: error: too many error values to fit in 'u2'"); | |
| 1629 | 1647 | |
| 1630 | 1648 | cases.add("asm at compile time", |
| 1631 | 1649 | \\comptime { |
| ... | ... | @@ -1808,9 +1826,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1808 | 1826 | \\export fn foo() void { |
| 1809 | 1827 | \\ while (bar()) {} |
| 1810 | 1828 | \\} |
| 1811 | \\fn bar() %i32 { return 1; } | |
| 1829 | \\fn bar() error!i32 { return 1; } | |
| 1812 | 1830 | , |
| 1813 | ".tmp_source.zig:2:15: error: expected type 'bool', found '%i32'"); | |
| 1831 | ".tmp_source.zig:2:15: error: expected type 'bool', found 'error!i32'"); | |
| 1814 | 1832 | |
| 1815 | 1833 | cases.add("while expected nullable, got bool", |
| 1816 | 1834 | \\export fn foo() void { |
| ... | ... | @@ -1824,9 +1842,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) void { |
| 1824 | 1842 | \\export fn foo() void { |
| 1825 | 1843 | \\ while (bar()) |x| {} |
| 1826 | 1844 | \\} |
| 1827 | \\fn bar() %i32 { return 1; } | |
| 1845 | \\fn bar() error!i32 { return 1; } | |
| 1828 | 1846 | , |
| 1829 | ".tmp_source.zig:2:15: error: expected nullable type, found '%i32'"); | |
| 1847 | ".tmp_source.zig:2:15: error: expected nullable type, found 'error!i32'"); | |
| 1830 | 1848 | |
| 1831 | 1849 | cases.add("while expected error union, got bool", |
| 1832 | 1850 | \\export fn foo() void { |
test/standalone/brace_expansion/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | const main = b.addTest("main.zig"); |
| 5 | 5 | main.setBuildMode(b.standardReleaseOptions()); |
| 6 | 6 |
test/standalone/brace_expansion/main.zig+11-2| ... | ... | @@ -68,7 +68,12 @@ const Node = union(enum) { |
| 68 | 68 | Combine: []Node, |
| 69 | 69 | }; |
| 70 | 70 | |
| 71 | fn parse(tokens: &const ArrayList(Token), token_index: &usize) !Node { | |
| 71 | const ParseError = error { | |
| 72 | InvalidInput, | |
| 73 | OutOfMemory, | |
| 74 | }; | |
| 75 | ||
| 76 | fn parse(tokens: &const ArrayList(Token), token_index: &usize) ParseError!Node { | |
| 72 | 77 | const first_token = tokens.items[*token_index]; |
| 73 | 78 | *token_index += 1; |
| 74 | 79 | |
| ... | ... | @@ -132,7 +137,11 @@ fn expandString(input: []const u8, output: &Buffer) !void { |
| 132 | 137 | } |
| 133 | 138 | } |
| 134 | 139 | |
| 135 | fn expandNode(node: &const Node, output: &ArrayList(Buffer)) !void { | |
| 140 | const ExpandNodeError = error { | |
| 141 | OutOfMemory, | |
| 142 | }; | |
| 143 | ||
| 144 | fn expandNode(node: &const Node, output: &ArrayList(Buffer)) ExpandNodeError!void { | |
| 136 | 145 | assert(output.len == 0); |
| 137 | 146 | switch (*node) { |
| 138 | 147 | Node.Scalar => |scalar| { |
test/standalone/issue_339/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | const obj = b.addObject("test", "test.zig"); |
| 5 | 5 | |
| 6 | 6 | const test_step = b.step("test", "Test the program"); |
test/standalone/issue_339/test.zig+1-1| ... | ... | @@ -1,7 +1,7 @@ |
| 1 | 1 | const StackTrace = @import("builtin").StackTrace; |
| 2 | 2 | pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) noreturn { @breakpoint(); while (true) {} } |
| 3 | 3 | |
| 4 | fn bar() %void {} | |
| 4 | fn bar() error!void {} | |
| 5 | 5 | |
| 6 | 6 | export fn foo() void { |
| 7 | 7 | bar() catch unreachable; |
test/standalone/pkg_import/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | const exe = b.addExecutable("test", "test.zig"); |
| 5 | 5 | exe.addPackagePath("my_pkg", "pkg.zig"); |
| 6 | 6 |
test/standalone/pkg_import/test.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const my_pkg = @import("my_pkg"); |
| 2 | 2 | const assert = @import("std").debug.assert; |
| 3 | 3 | |
| 4 | pub fn main() !void { | |
| 4 | pub fn main() void { | |
| 5 | 5 | assert(my_pkg.add(10, 20) == 30); |
| 6 | 6 | } |
test/standalone/use_alias/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) !void { | |
| 3 | pub fn build(b: &Builder) void { | |
| 4 | 4 | b.addCIncludePath("."); |
| 5 | 5 | |
| 6 | 6 | const main = b.addTest("main.zig"); |