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