replace a %% b with a catch b

See #632

better fits the convention of using keywords for control flow
This commit is contained in:
Andrew Kelley 2018-01-07 17:28:20 -05:00
parent 66717db735
commit 632d143bff
32 changed files with 173 additions and 170 deletions

View File

@ -45,7 +45,7 @@ const State = enum {
fn gen(in: &io.InStream, out: &io.OutStream) {
var state = State.Start;
while (true) {
const byte = in.readByte() %% |err| {
const byte = in.readByte() catch |err| {
if (err == error.EndOfStream) {
return;
}

View File

@ -142,7 +142,7 @@ pub fn addOverflow(comptime T: type, a: T, b: T) -> %T {
}
fn getNumberWithDefault(s: []u8) -> u32 {
parseUnsigned(u32, s, 10) %% 42
parseUnsigned(u32, s, 10) catch 42
}
fn getNumberOrCrash(s: []u8) -> u32 {
@ -150,8 +150,8 @@ fn getNumberOrCrash(s: []u8) -> u32 {
}
fn addTwoTogetherOrReturnErr(a_str: []u8, b_str: []u8) -> %u32 {
const a = parseUnsigned(u32, a_str, 10) %% |err| return err;
const b = parseUnsigned(u32, b_str, 10) %% |err| return err;
const a = parseUnsigned(u32, a_str, 10) catch |err| return err;
const b = parseUnsigned(u32, b_str, 10) catch |err| return err;
return a + b;
}</code></pre>
<h3 id="hashmap">HashMap with Custom Allocator</h3>
@ -424,7 +424,7 @@ pub fn main() -&gt; %void {
} else if (arg[0] == '-') {
return usage(exe);
} else {
var is = io.InStream.open(arg, null) %% |err| {
var is = io.InStream.open(arg, null) catch |err| {
%%io.stderr.printf("Unable to open file: {}\n", @errorName(err));
return err;
};
@ -449,7 +449,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void {
var buf: [1024 * 4]u8 = undefined;
while (true) {
const bytes_read = is.read(buf[0..]) %% |err| {
const bytes_read = is.read(buf[0..]) catch |err| {
%%io.stderr.printf("Unable to read from stream: {}\n", @errorName(err));
return err;
};
@ -458,7 +458,7 @@ fn cat_stream(is: &amp;io.InStream) -&gt; %void {
break;
}
io.stdout.write(buf[0..bytes_read]) %% |err| {
io.stdout.write(buf[0..bytes_read]) catch |err| {
%%io.stderr.printf("Unable to write to stdout: {}\n", @errorName(err));
return err;
};

View File

@ -1211,8 +1211,8 @@ unwrapped == 1234</code></pre>
</td>
</tr>
<tr>
<td><pre><code class="zig">a %% b
a %% |err| b</code></pre></td>
<td><pre><code class="zig">a catch b
a catch |err| b</code></pre></td>
<td>
<ul>
<li><a href="#errors">Error Unions</a></li>
@ -1226,7 +1226,7 @@ a %% |err| b</code></pre></td>
</td>
<td>
<pre><code class="zig">const value: %u32 = null;
const unwrapped = value %% 1234;
const unwrapped = value catch 1234;
unwrapped == 1234</code></pre>
</td>
</tr>
@ -1238,7 +1238,7 @@ unwrapped == 1234</code></pre>
</ul>
</td>
<td>Equivalent to:
<pre><code class="zig">a %% unreachable</code></pre>
<pre><code class="zig">a catch unreachable</code></pre>
</td>
<td>
<pre><code class="zig">const value: %u32 = 5678;
@ -1482,7 +1482,7 @@ x{}
== != &lt; &gt; &lt;= &gt;=
and
or
?? %%
?? catch
= *= /= %= += -= &lt;&lt;= &gt;&gt;= &amp;= ^= |=</code></pre>
<h2 id="arrays">Arrays</h2>
<pre><code class="zig">const assert = @import("std").debug.assert;
@ -1829,7 +1829,7 @@ Test 1/1 pointer alignment safety...incorrect alignment
return root.main();
^
/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000216050 in ??? (test)
callMain(argc, argv, envp) %% std.os.posix.exit(1);
callMain(argc, argv, envp) catch std.os.posix.exit(1);
^
/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000215fa0 in ??? (test)
posixCallMainAndExit()
@ -1885,7 +1885,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x00000000002149e7 in ??? (test)
return root.main();
^
lib/zig/std/special/bootstrap.zig:47:13: 0x00000000002148a0 in ??? (test)
callMain(argc, argv, envp) %% std.os.posix.exit(1);
callMain(argc, argv, envp) catch std.os.posix.exit(1);
^
lib/zig/std/special/bootstrap.zig:34:25: 0x00000000002147f0 in ??? (test)
posixCallMainAndExit()
@ -2965,7 +2965,7 @@ lib/zig/std/special/bootstrap.zig:60:21: 0x0000000000214947 in ??? (test)
return root.main();
^
lib/zig/std/special/bootstrap.zig:47:13: 0x0000000000214800 in ??? (test)
callMain(argc, argv, envp) %% std.os.posix.exit(1);
callMain(argc, argv, envp) catch std.os.posix.exit(1);
^
lib/zig/std/special/bootstrap.zig:34:25: 0x0000000000214750 in ??? (test)
posixCallMainAndExit()
@ -3019,7 +3019,7 @@ extern fn bar(value: u32);</code></pre>
<pre><code class="zig">pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) -&gt; noreturn;
fn foo() {
const value = bar() %% ExitProcess(1);
const value = bar() catch ExitProcess(1);
assert(value == 1234);
}
@ -3209,7 +3209,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
</ul>
<p>If you want to provide a default value, you can use the <code>%%</code> binary operator:</p>
<pre><code class="zig">fn doAThing(str: []u8) {
const number = parseU64(str, 10) %% 13;
const number = parseU64(str, 10) catch 13;
// ...
}</code></pre>
<p>
@ -3220,7 +3220,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
<p>Let's say you wanted to return the error if you got one, otherwise continue with the
function logic:</p>
<pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {
const number = parseU64(str, 10) %% |err| return err;
const number = parseU64(str, 10) catch |err| return err;
// ...
}</code></pre>
<p>
@ -3239,7 +3239,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
Maybe you know with complete certainty that an expression will never be an error.
In this case you can do this:
</p>
<pre><code class="zig">const number = parseU64("1234", 10) %% unreachable;</code></pre>
<pre><code class="zig">const number = parseU64("1234", 10) catch unreachable;</code></pre>
<p>
Here we know for sure that "1234" will parse successfully. So we put the
<code>unreachable</code> value on the right hand side. <code>unreachable</code> generates
@ -3250,7 +3250,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
<p>Again there is a syntactic shortcut for this:</p>
<pre><code class="zig">const number = %%parseU64("1234", 10);</code></pre>
<p>
The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression %% unreachable</code>. It unwraps an error union type,
The <code>%%</code> <em>prefix</em> operator is equivalent to <code class="zig">expression catch unreachable</code>. It unwraps an error union type,
and panics in debug mode if the value was an error.
</p>
<p>
@ -4984,7 +4984,7 @@ Test 1/1 safety check...reached unreachable code
return root.main();
^
/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:37:13: 0x00000000002148d0 in ??? (test)
callMain(argc, argv, envp) %% exit(1);
callMain(argc, argv, envp) catch exit(1);
^
/home/andy/dev/zig/build/lib/zig/std/special/bootstrap.zig:30:20: 0x0000000000214820 in ??? (test)
callMainAndExit()
@ -5909,7 +5909,7 @@ UnwrapExpression = BoolOrExpression (UnwrapNullable | UnwrapError) | BoolOrExpre
UnwrapNullable = "??" Expression
UnwrapError = "%%" option("|" Symbol "|") Expression
UnwrapError = "catch" option("|" Symbol "|") Expression
AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | UnwrapExpression

View File

@ -20,7 +20,7 @@ pub fn main() -> %void {
} else if (arg[0] == '-') {
return usage(exe);
} else {
var file = io.File.openRead(arg, null) %% |err| {
var file = io.File.openRead(arg, null) catch |err| {
warn("Unable to open file: {}\n", @errorName(err));
return err;
};
@ -45,7 +45,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
var buf: [1024 * 4]u8 = undefined;
while (true) {
const bytes_read = file.read(buf[0..]) %% |err| {
const bytes_read = file.read(buf[0..]) catch |err| {
warn("Unable to read from stream: {}\n", @errorName(err));
return err;
};
@ -54,7 +54,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
break;
}
stdout.write(buf[0..bytes_read]) %% |err| {
stdout.write(buf[0..bytes_read]) catch |err| {
warn("Unable to write to stdout: {}\n", @errorName(err));
return err;
};
@ -62,7 +62,7 @@ fn cat_file(stdout: &io.File, file: &io.File) -> %void {
}
fn unwrapArg(arg: %[]u8) -> %[]u8 {
return arg %% |err| {
return arg catch |err| {
warn("Unable to parse command line: {}\n", err);
return err;
};

View File

@ -25,12 +25,12 @@ pub fn main() -> %void {
try stdout.print("\nGuess a number between 1 and 100: ");
var line_buf : [20]u8 = undefined;
const line_len = stdin_file.read(line_buf[0..]) %% |err| {
const line_len = stdin_file.read(line_buf[0..]) catch |err| {
try stdout.print("Unable to read from stdin: {}\n", @errorName(err));
return err;
};
const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) %% {
const guess = fmt.parseUnsigned(u8, line_buf[0..line_len - 1], 10) catch {
try stdout.print("Invalid number.\n");
continue;
};

View File

@ -21,7 +21,7 @@ error ZigInstallationNotFound;
const default_zig_cache_name = "zig-cache";
pub fn main() -> %void {
main2() %% |err| {
main2() catch |err| {
if (err != error.InvalidCommandLineArguments) {
warn("{}\n", @errorName(err));
}
@ -571,12 +571,12 @@ fn printZen() -> %void {
/// Caller must free result
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) -> %[]u8 {
if (zig_install_prefix_arg) |zig_install_prefix| {
return testZigInstallPrefix(allocator, zig_install_prefix) %% |err| {
return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));
return error.ZigInstallationNotFound;
};
} else {
return findZigLibDir(allocator) %% |err| {
return findZigLibDir(allocator) catch |err| {
warn("Unable to find zig lib directory: {}.\nReinstall Zig or use --zig-install-prefix.\n",
@errorName(err));
return error.ZigLibDirNotFound;
@ -611,7 +611,7 @@ fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 {
break;
}
return testZigInstallPrefix(allocator, test_dir) %% |err| {
return testZigInstallPrefix(allocator, test_dir) catch |err| {
cur_path = test_dir;
continue;
};

View File

@ -207,13 +207,13 @@ pub const Module = struct {
}
const root_src_path = self.root_src_path ?? @panic("TODO handle null root src path");
const root_src_real_path = os.path.real(self.allocator, root_src_path) %% |err| {
const root_src_real_path = os.path.real(self.allocator, root_src_path) catch |err| {
try printError("unable to get real path '{}': {}", root_src_path, err);
return err;
};
%defer self.allocator.free(root_src_real_path);
const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) %% |err| {
const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) catch |err| {
try printError("unable to open '{}': {}", root_src_real_path, err);
return err;
};

View File

@ -96,12 +96,12 @@ pub const Parser = struct {
var stack = self.initUtilityArrayList(&ast.Node);
defer self.deinitUtilityArrayList(stack);
stack.append(&root_node.base) %% unreachable;
stack.append(&root_node.base) catch unreachable;
while (stack.popOrNull()) |node| {
var i: usize = 0;
while (node.iterate(i)) |child| : (i += 1) {
if (child.iterate(0) != null) {
stack.append(child) %% unreachable;
stack.append(child) catch unreachable;
} else {
child.destroy(self.allocator);
}
@ -111,7 +111,7 @@ pub const Parser = struct {
}
pub fn parse(self: &Parser) -> %&ast.NodeRoot {
const result = self.parseInner() %% |err| x: {
const result = self.parseInner() catch |err| x: {
if (self.cleanup_root_node) |root_node| {
self.freeAst(root_node);
}
@ -156,14 +156,14 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_pub, Token.Id.Keyword_export => {
stack.append(State { .TopLevelExtern = token }) %% unreachable;
stack.append(State { .TopLevelExtern = token }) catch unreachable;
continue;
},
Token.Id.Eof => return root_node,
else => {
self.putBackToken(token);
// TODO shouldn't need this cast
stack.append(State { .TopLevelExtern = null }) %% unreachable;
stack.append(State { .TopLevelExtern = null }) catch unreachable;
continue;
},
}
@ -176,7 +176,7 @@ pub const Parser = struct {
.visib_token = visib_token,
.extern_token = token,
},
}) %% unreachable;
}) catch unreachable;
continue;
}
self.putBackToken(token);
@ -185,14 +185,14 @@ pub const Parser = struct {
.visib_token = visib_token,
.extern_token = null,
},
}) %% unreachable;
}) catch unreachable;
continue;
},
State.TopLevelDecl => |ctx| {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_var, Token.Id.Keyword_const => {
stack.append(State.TopLevel) %% unreachable;
stack.append(State.TopLevel) catch unreachable;
// TODO shouldn't need these casts
const var_decl_node = try self.createAttachVarDecl(&root_node.decls, ctx.visib_token,
token, (?Token)(null), ctx.extern_token);
@ -200,7 +200,7 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_fn => {
stack.append(State.TopLevel) %% unreachable;
stack.append(State.TopLevel) catch unreachable;
// TODO shouldn't need these casts
const fn_proto = try self.createAttachFnProto(&root_node.decls, token,
ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null));
@ -212,7 +212,7 @@ pub const Parser = struct {
@panic("TODO extern with string literal");
},
Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
stack.append(State.TopLevel) %% unreachable;
stack.append(State.TopLevel) catch unreachable;
const fn_token = try self.eatToken(Token.Id.Keyword_fn);
// TODO shouldn't need this cast
const fn_proto = try self.createAttachFnProto(&root_node.decls, fn_token,
@ -226,7 +226,7 @@ pub const Parser = struct {
},
State.VarDecl => |var_decl| {
var_decl.name_token = try self.eatToken(Token.Id.Identifier);
stack.append(State { .VarDeclAlign = var_decl }) %% unreachable;
stack.append(State { .VarDeclAlign = var_decl }) catch unreachable;
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Colon) {
@ -238,7 +238,7 @@ pub const Parser = struct {
continue;
},
State.VarDeclAlign => |var_decl| {
stack.append(State { .VarDeclEq = var_decl }) %% unreachable;
stack.append(State { .VarDeclEq = var_decl }) catch unreachable;
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Keyword_align) {
@ -255,7 +255,7 @@ pub const Parser = struct {
const token = self.getNextToken();
if (token.id == Token.Id.Equal) {
var_decl.eq_token = token;
stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
try stack.append(State {
.Expression = DestPtr {.NullableField = &var_decl.init_node},
});
@ -273,7 +273,7 @@ pub const Parser = struct {
State.Expression => |dest_ptr| {
// save the dest_ptr for later
stack.append(state) %% unreachable;
stack.append(state) catch unreachable;
try stack.append(State.ExpectOperand);
continue;
},
@ -383,7 +383,7 @@ pub const Parser = struct {
var token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_align => {
stack.append(state) %% unreachable;
stack.append(state) catch unreachable;
if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers");
_ = try self.eatToken(Token.Id.LParen);
try stack.append(State { .ExpectToken = Token.Id.RParen });
@ -391,13 +391,13 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_const => {
stack.append(state) %% unreachable;
stack.append(state) catch unreachable;
if (addr_of_info.const_token != null) return self.parseError(token, "duplicate qualifier: const");
addr_of_info.const_token = token;
continue;
},
Token.Id.Keyword_volatile => {
stack.append(state) %% unreachable;
stack.append(state) catch unreachable;
if (addr_of_info.volatile_token != null) return self.parseError(token, "duplicate qualifier: volatile");
addr_of_info.volatile_token = token;
continue;
@ -416,12 +416,12 @@ pub const Parser = struct {
}
self.putBackToken(token);
stack.append(State { .Expression = dest_ptr }) %% unreachable;
stack.append(State { .Expression = dest_ptr }) catch unreachable;
continue;
},
State.FnProto => |fn_proto| {
stack.append(State { .FnProtoAlign = fn_proto }) %% unreachable;
stack.append(State { .FnProtoAlign = fn_proto }) catch unreachable;
try stack.append(State { .ParamDecl = fn_proto });
try stack.append(State { .ExpectToken = Token.Id.LParen });
@ -442,7 +442,7 @@ pub const Parser = struct {
if (token.id == Token.Id.Arrow) {
stack.append(State {
.TypeExpr = DestPtr {.NullableField = &fn_proto.return_type},
}) %% unreachable;
}) catch unreachable;
continue;
} else {
self.putBackToken(token);
@ -474,13 +474,13 @@ pub const Parser = struct {
}
if (token.id == Token.Id.Ellipsis3) {
param_decl.var_args_token = token;
stack.append(State { .ExpectToken = Token.Id.RParen }) %% unreachable;
stack.append(State { .ExpectToken = Token.Id.RParen }) catch unreachable;
continue;
} else {
self.putBackToken(token);
}
stack.append(State { .ParamDecl = fn_proto }) %% unreachable;
stack.append(State { .ParamDecl = fn_proto }) catch unreachable;
try stack.append(State.ParamDeclComma);
try stack.append(State {
.TypeExpr = DestPtr {.Field = &param_decl.type_node}
@ -506,7 +506,7 @@ pub const Parser = struct {
Token.Id.LBrace => {
const block = try self.createBlock(token);
fn_proto.body_node = &block.base;
stack.append(State { .Block = block }) %% unreachable;
stack.append(State { .Block = block }) catch unreachable;
continue;
},
Token.Id.Semicolon => continue,
@ -523,7 +523,7 @@ pub const Parser = struct {
},
else => {
self.putBackToken(token);
stack.append(State { .Block = block }) %% unreachable;
stack.append(State { .Block = block }) catch unreachable;
try stack.append(State { .Statement = block });
continue;
},
@ -560,7 +560,7 @@ pub const Parser = struct {
self.putBackToken(mut_token);
}
stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
stack.append(State { .ExpectToken = Token.Id.Semicolon }) catch unreachable;
try stack.append(State { .Expression = DestPtr{.List = &block.statements} });
continue;
},
@ -1112,7 +1112,7 @@ fn testCanonical(source: []const u8) {
// Try it once with unlimited memory, make sure it works
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);
var failing_allocator = std.debug.FailingAllocator.init(&fixed_allocator.allocator, @maxValue(usize));
const result_source = testParse(source, &failing_allocator.allocator) %% @panic("test failed");
const result_source = testParse(source, &failing_allocator.allocator) catch @panic("test failed");
if (!mem.eql(u8, result_source, source)) {
warn("\n====== expected this output: =========\n");
warn("{}", source);

View File

@ -557,22 +557,22 @@ pub const Tokenizer = struct {
return 0;
} else {
// check utf8-encoded character.
const length = std.unicode.utf8ByteSequenceLength(c0) %% return 1;
const length = std.unicode.utf8ByteSequenceLength(c0) catch return 1;
// the last 3 bytes in the buffer are guaranteed to be '\n',
// which means we don't need to do any bounds checking here.
const bytes = self.buffer[self.index..self.index + length];
switch (length) {
2 => {
const value = std.unicode.utf8Decode2(bytes) %% return length;
const value = std.unicode.utf8Decode2(bytes) catch return length;
if (value == 0x85) return length; // U+0085 (NEL)
},
3 => {
const value = std.unicode.utf8Decode3(bytes) %% return length;
const value = std.unicode.utf8Decode3(bytes) catch return length;
if (value == 0x2028) return length; // U+2028 (LS)
if (value == 0x2029) return length; // U+2029 (PS)
},
4 => {
_ = std.unicode.utf8Decode4(bytes) %% return length;
_ = std.unicode.utf8Decode4(bytes) catch return length;
},
else => unreachable,
}

View File

@ -389,7 +389,7 @@ enum NodeType {
NodeTypeArrayType,
NodeTypeErrorType,
NodeTypeVarLiteral,
NodeTypeTryExpr,
NodeTypeIfErrorExpr,
NodeTypeTestExpr,
};
@ -546,7 +546,7 @@ struct AstNodeBinOpExpr {
AstNode *op2;
};
struct AstNodeUnwrapErrorExpr {
struct AstNodeCatchExpr {
AstNode *op1;
AstNode *symbol; // can be null
AstNode *op2;
@ -860,7 +860,7 @@ struct AstNode {
AstNodeErrorValueDecl error_value_decl;
AstNodeTestDecl test_decl;
AstNodeBinOpExpr bin_op_expr;
AstNodeUnwrapErrorExpr unwrap_err_expr;
AstNodeCatchExpr unwrap_err_expr;
AstNodePrefixOpExpr prefix_op_expr;
AstNodeAddrOfExpr addr_of_expr;
AstNodeFnCallExpr fn_call_expr;
@ -868,7 +868,7 @@ struct AstNode {
AstNodeSliceExpr slice_expr;
AstNodeUse use;
AstNodeIfBoolExpr if_bool_expr;
AstNodeTryExpr try_expr;
AstNodeTryExpr if_err_expr;
AstNodeTestExpr test_expr;
AstNodeWhileExpr while_expr;
AstNodeForExpr for_expr;

View File

@ -2933,7 +2933,7 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) {
case NodeTypeArrayType:
case NodeTypeErrorType:
case NodeTypeVarLiteral:
case NodeTypeTryExpr:
case NodeTypeIfErrorExpr:
case NodeTypeTestExpr:
zig_unreachable();
}

View File

@ -68,7 +68,7 @@ static const char *prefix_op_str(PrefixOp prefix_op) {
case PrefixOpDereference: return "*";
case PrefixOpMaybe: return "?";
case PrefixOpError: return "%";
case PrefixOpUnwrapError: return "%%";
case PrefixOpUnwrapError: return "catch";
case PrefixOpUnwrapMaybe: return "??";
}
zig_unreachable();
@ -241,8 +241,8 @@ static const char *node_type_str(NodeType node_type) {
return "ErrorType";
case NodeTypeVarLiteral:
return "VarLiteral";
case NodeTypeTryExpr:
return "TryExpr";
case NodeTypeIfErrorExpr:
return "IfErrorExpr";
case NodeTypeTestExpr:
return "TestExpr";
}
@ -872,23 +872,23 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
fprintf(ar->f, "null");
break;
}
case NodeTypeTryExpr:
case NodeTypeIfErrorExpr:
{
fprintf(ar->f, "if (");
render_node_grouped(ar, node->data.try_expr.target_node);
render_node_grouped(ar, node->data.if_err_expr.target_node);
fprintf(ar->f, ") ");
if (node->data.try_expr.var_symbol) {
const char *ptr_str = node->data.try_expr.var_is_ptr ? "*" : "";
const char *var_name = buf_ptr(node->data.try_expr.var_symbol);
if (node->data.if_err_expr.var_symbol) {
const char *ptr_str = node->data.if_err_expr.var_is_ptr ? "*" : "";
const char *var_name = buf_ptr(node->data.if_err_expr.var_symbol);
fprintf(ar->f, "|%s%s| ", ptr_str, var_name);
}
render_node_grouped(ar, node->data.try_expr.then_node);
if (node->data.try_expr.else_node) {
render_node_grouped(ar, node->data.if_err_expr.then_node);
if (node->data.if_err_expr.else_node) {
fprintf(ar->f, " else ");
if (node->data.try_expr.err_symbol) {
fprintf(ar->f, "|%s| ", buf_ptr(node->data.try_expr.err_symbol));
if (node->data.if_err_expr.err_symbol) {
fprintf(ar->f, "|%s| ", buf_ptr(node->data.if_err_expr.err_symbol));
}
render_node_grouped(ar, node->data.try_expr.else_node);
render_node_grouped(ar, node->data.if_err_expr.else_node);
}
break;
}

View File

@ -4665,16 +4665,16 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
}
static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeTryExpr);
static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
assert(node->type == NodeTypeIfErrorExpr);
AstNode *target_node = node->data.try_expr.target_node;
AstNode *then_node = node->data.try_expr.then_node;
AstNode *else_node = node->data.try_expr.else_node;
bool var_is_ptr = node->data.try_expr.var_is_ptr;
AstNode *target_node = node->data.if_err_expr.target_node;
AstNode *then_node = node->data.if_err_expr.then_node;
AstNode *else_node = node->data.if_err_expr.else_node;
bool var_is_ptr = node->data.if_err_expr.var_is_ptr;
bool var_is_const = true;
Buf *var_symbol = node->data.try_expr.var_symbol;
Buf *err_symbol = node->data.try_expr.err_symbol;
Buf *var_symbol = node->data.if_err_expr.var_symbol;
Buf *err_symbol = node->data.if_err_expr.err_symbol;
IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LVAL_PTR);
if (err_val_ptr == irb->codegen->invalid_instruction)
@ -5411,8 +5411,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval);
case NodeTypeVarLiteral:
return ir_lval_wrap(irb, scope, ir_gen_var_literal(irb, scope, node), lval);
case NodeTypeTryExpr:
return ir_lval_wrap(irb, scope, ir_gen_try_expr(irb, scope, node), lval);
case NodeTypeIfErrorExpr:
return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval);
case NodeTypeTestExpr:
return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval);
case NodeTypeSwitchExpr:

View File

@ -1407,15 +1407,15 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index
}
if (err_name_tok != nullptr) {
AstNode *node = ast_create_node(pc, NodeTypeTryExpr, if_token);
node->data.try_expr.target_node = condition;
node->data.try_expr.var_is_ptr = var_is_ptr;
AstNode *node = ast_create_node(pc, NodeTypeIfErrorExpr, if_token);
node->data.if_err_expr.target_node = condition;
node->data.if_err_expr.var_is_ptr = var_is_ptr;
if (var_name_tok != nullptr) {
node->data.try_expr.var_symbol = token_buf(var_name_tok);
node->data.if_err_expr.var_symbol = token_buf(var_name_tok);
}
node->data.try_expr.then_node = body_node;
node->data.try_expr.err_symbol = token_buf(err_name_tok);
node->data.try_expr.else_node = else_node;
node->data.if_err_expr.then_node = body_node;
node->data.if_err_expr.err_symbol = token_buf(err_name_tok);
node->data.if_err_expr.else_node = else_node;
return node;
} else if (var_name_tok != nullptr) {
AstNode *node = ast_create_node(pc, NodeTypeTestExpr, if_token);
@ -2041,7 +2041,7 @@ static BinOpType ast_parse_ass_op(ParseContext *pc, size_t *token_index, bool ma
/*
UnwrapExpression : BoolOrExpression (UnwrapMaybe | UnwrapError) | BoolOrExpression
UnwrapMaybe : "??" BoolOrExpression
UnwrapError : "%%" option("|" "Symbol" "|") BoolOrExpression
UnwrapError = "catch" option("|" Symbol "|") Expression
*/
static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
AstNode *lhs = ast_parse_bool_or_expr(pc, token_index, mandatory);
@ -2061,7 +2061,7 @@ static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, boo
node->data.bin_op_expr.op2 = rhs;
return node;
} else if (token->id == TokenIdPercentPercent) {
} else if (token->id == TokenIdKeywordCatch) {
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeUnwrapErrorExpr, token);
@ -2157,10 +2157,10 @@ static bool statement_terminates_without_semicolon(AstNode *node) {
if (node->data.if_bool_expr.else_node)
return statement_terminates_without_semicolon(node->data.if_bool_expr.else_node);
return node->data.if_bool_expr.then_block->type == NodeTypeBlock;
case NodeTypeTryExpr:
if (node->data.try_expr.else_node)
return statement_terminates_without_semicolon(node->data.try_expr.else_node);
return node->data.try_expr.then_node->type == NodeTypeBlock;
case NodeTypeIfErrorExpr:
if (node->data.if_err_expr.else_node)
return statement_terminates_without_semicolon(node->data.if_err_expr.else_node);
return node->data.if_err_expr.then_node->type == NodeTypeBlock;
case NodeTypeTestExpr:
if (node->data.test_expr.else_node)
return statement_terminates_without_semicolon(node->data.test_expr.else_node);
@ -2833,10 +2833,10 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
visit_field(&node->data.if_bool_expr.then_block, visit, context);
visit_field(&node->data.if_bool_expr.else_node, visit, context);
break;
case NodeTypeTryExpr:
visit_field(&node->data.try_expr.target_node, visit, context);
visit_field(&node->data.try_expr.then_node, visit, context);
visit_field(&node->data.try_expr.else_node, visit, context);
case NodeTypeIfErrorExpr:
visit_field(&node->data.if_err_expr.target_node, visit, context);
visit_field(&node->data.if_err_expr.then_node, visit, context);
visit_field(&node->data.if_err_expr.else_node, visit, context);
break;
case NodeTypeTestExpr:
visit_field(&node->data.test_expr.target_node, visit, context);

View File

@ -111,6 +111,7 @@ static const struct ZigKeyword zig_keywords[] = {
{"and", TokenIdKeywordAnd},
{"asm", TokenIdKeywordAsm},
{"break", TokenIdKeywordBreak},
{"catch", TokenIdKeywordCatch},
{"coldcc", TokenIdKeywordColdCC},
{"comptime", TokenIdKeywordCompTime},
{"const", TokenIdKeywordConst},
@ -1512,6 +1513,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordAnd: return "and";
case TokenIdKeywordAsm: return "asm";
case TokenIdKeywordBreak: return "break";
case TokenIdKeywordCatch: return "catch";
case TokenIdKeywordColdCC: return "coldcc";
case TokenIdKeywordCompTime: return "comptime";
case TokenIdKeywordConst: return "const";

View File

@ -47,10 +47,10 @@ enum TokenId {
TokenIdFloatLiteral,
TokenIdIntLiteral,
TokenIdKeywordAlign,
TokenIdKeywordSection,
TokenIdKeywordAnd,
TokenIdKeywordAsm,
TokenIdKeywordBreak,
TokenIdKeywordCatch,
TokenIdKeywordColdCC,
TokenIdKeywordCompTime,
TokenIdKeywordConst,
@ -74,6 +74,7 @@ enum TokenId {
TokenIdKeywordPacked,
TokenIdKeywordPub,
TokenIdKeywordReturn,
TokenIdKeywordSection,
TokenIdKeywordStdcallCC,
TokenIdKeywordStruct,
TokenIdKeywordSwitch,

View File

@ -300,7 +300,7 @@ pub const Builder = struct {
s.loop_flag = true;
for (s.dependencies.toSlice()) |dep| {
self.makeOneStep(dep) %% |err| {
self.makeOneStep(dep) catch |err| {
if (err == error.DependencyLoopDetected) {
warn(" {}\n", s.name);
}
@ -573,7 +573,7 @@ pub const Builder = struct {
child.cwd = cwd;
child.env_map = env_map;
const term = child.spawnAndWait() %% |err| {
const term = child.spawnAndWait() catch |err| {
warn("Unable to spawn {}: {}\n", argv[0], @errorName(err));
return err;
};
@ -596,7 +596,7 @@ pub const Builder = struct {
}
pub fn makePath(self: &Builder, path: []const u8) -> %void {
os.makePath(self.allocator, self.pathFromRoot(path)) %% |err| {
os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
warn("Unable to create path {}: {}\n", path, @errorName(err));
return err;
};
@ -641,11 +641,11 @@ pub const Builder = struct {
const dirname = os.path.dirname(dest_path);
const abs_source_path = self.pathFromRoot(source_path);
os.makePath(self.allocator, dirname) %% |err| {
os.makePath(self.allocator, dirname) catch |err| {
warn("Unable to create path {}: {}\n", dirname, @errorName(err));
return err;
};
os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) %% |err| {
os.copyFileMode(self.allocator, abs_source_path, dest_path, mode) catch |err| {
warn("Unable to copy {} to {}: {}\n", abs_source_path, dest_path, @errorName(err));
return err;
};
@ -663,7 +663,7 @@ pub const Builder = struct {
if (builtin.environ == builtin.Environ.msvc) {
return "cl.exe";
} else {
return os.getEnvVarOwned(self.allocator, "CC") %% |err|
return os.getEnvVarOwned(self.allocator, "CC") catch |err|
if (err == error.EnvironmentVariableNotFound)
([]const u8)("cc")
else
@ -723,7 +723,7 @@ pub const Builder = struct {
pub fn exec(self: &Builder, argv: []const []const u8) -> []u8 {
const max_output_size = 100 * 1024;
const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) %% |err| {
const result = os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size) catch |err| {
std.debug.panic("Unable to spawn {}: {}", argv[0], @errorName(err));
};
switch (result.term) {
@ -1895,11 +1895,11 @@ pub const WriteFileStep = struct {
const self = @fieldParentPtr(WriteFileStep, "step", step);
const full_path = self.builder.pathFromRoot(self.file_path);
const full_path_dir = os.path.dirname(full_path);
os.makePath(self.builder.allocator, full_path_dir) %% |err| {
os.makePath(self.builder.allocator, full_path_dir) catch |err| {
warn("unable to make path {}: {}\n", full_path_dir, @errorName(err));
return err;
};
io.writeFile(full_path, self.data, self.builder.allocator) %% |err| {
io.writeFile(full_path, self.data, self.builder.allocator) catch |err| {
warn("unable to write {}: {}\n", full_path, @errorName(err));
return err;
};
@ -1942,7 +1942,7 @@ pub const RemoveDirStep = struct {
const self = @fieldParentPtr(RemoveDirStep, "step", step);
const full_path = self.builder.pathFromRoot(self.dir_path);
os.deleteTree(self.builder.allocator, full_path) %% |err| {
os.deleteTree(self.builder.allocator, full_path) catch |err| {
warn("Unable to remove {}: {}\n", full_path, @errorName(err));
return err;
};
@ -1991,13 +1991,13 @@ fn doAtomicSymLinks(allocator: &Allocator, output_path: []const u8, filename_maj
const out_basename = os.path.basename(output_path);
// sym link for libfoo.so.1 to libfoo.so.1.2.3
const major_only_path = %%os.path.join(allocator, out_dir, filename_major_only);
os.atomicSymLink(allocator, out_basename, major_only_path) %% |err| {
os.atomicSymLink(allocator, out_basename, major_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", major_only_path, out_basename);
return err;
};
// sym link for libfoo.so to libfoo.so.1
const name_only_path = %%os.path.join(allocator, out_dir, filename_name_only);
os.atomicSymLink(allocator, filename_major_only, name_only_path) %% |err| {
os.atomicSymLink(allocator, filename_major_only, name_only_path) catch |err| {
warn("Unable to symlink {} -> {}\n", name_only_path, filename_major_only);
return err;
};

View File

@ -22,8 +22,8 @@ var stderr_file: io.File = undefined;
var stderr_file_out_stream: io.FileOutStream = undefined;
var stderr_stream: ?&io.OutStream = null;
pub fn warn(comptime fmt: []const u8, args: ...) {
const stderr = getStderrStream() %% return;
stderr.print(fmt, args) %% return;
const stderr = getStderrStream() catch return;
stderr.print(fmt, args) catch return;
}
fn getStderrStream() -> %&io.OutStream {
if (stderr_stream) |st| {
@ -39,8 +39,8 @@ fn getStderrStream() -> %&io.OutStream {
/// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned.
pub fn dumpStackTrace() {
const stderr = getStderrStream() %% return;
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% return;
const stderr = getStderrStream() catch return;
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch return;
}
/// This function invokes undefined behavior when `ok` is `false`.
@ -86,9 +86,9 @@ pub fn panic(comptime format: []const u8, args: ...) -> noreturn {
panicking = true;
}
const stderr = getStderrStream() %% os.abort();
stderr.print(format ++ "\n", args) %% os.abort();
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) %% os.abort();
const stderr = getStderrStream() catch os.abort();
stderr.print(format ++ "\n", args) catch os.abort();
writeStackTrace(stderr, global_allocator, stderr_file.isTty(), 1) catch os.abort();
os.abort();
}
@ -146,7 +146,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
// at compile time. I'll call it issue #313
const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}";
const compile_unit = findCompileUnit(st, return_address) %% {
const compile_unit = findCompileUnit(st, return_address) catch {
try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",
return_address);
continue;
@ -757,7 +757,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
});
},
else => {
const fwd_amt = math.cast(isize, op_size - 1) %% return error.InvalidDebugInfo;
const fwd_amt = math.cast(isize, op_size - 1) catch return error.InvalidDebugInfo;
try in_file.seekForward(fwd_amt);
},
}

View File

@ -533,7 +533,7 @@ fn bufPrintIntToSlice(buf: []u8, value: var, base: u8, uppercase: bool, width: u
}
test "parse u64 digit too big" {
_ = parseUnsigned(u64, "123a", 10) %% |err| {
_ = parseUnsigned(u64, "123a", 10) catch |err| {
if (err == error.InvalidChar) return;
unreachable;
};

View File

@ -137,9 +137,9 @@ pub const IncrementingAllocator = struct {
test "c_allocator" {
if (builtin.link_libc) {
var slice = c_allocator.alloc(u8, 50) %% return;
var slice = c_allocator.alloc(u8, 50) catch return;
defer c_allocator.free(slice);
slice = c_allocator.realloc(u8, slice, 100) %% return;
slice = c_allocator.realloc(u8, slice, 100) catch return;
}
}

View File

@ -383,27 +383,27 @@ pub const ChildProcess = struct {
// we are the child
restore_SIGCHLD();
setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) %%
setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch
|err| forkChildErrReport(err_pipe[1], err);
setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) %%
setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch
|err| forkChildErrReport(err_pipe[1], err);
setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) %%
setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch
|err| forkChildErrReport(err_pipe[1], err);
if (self.cwd) |cwd| {
os.changeCurDir(self.allocator, cwd) %%
os.changeCurDir(self.allocator, cwd) catch
|err| forkChildErrReport(err_pipe[1], err);
}
if (self.gid) |gid| {
os.posix_setregid(gid, gid) %% |err| forkChildErrReport(err_pipe[1], err);
os.posix_setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
}
if (self.uid) |uid| {
os.posix_setreuid(uid, uid) %% |err| forkChildErrReport(err_pipe[1], err);
os.posix_setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
}
os.posixExecve(self.argv, env_map, self.allocator) %%
os.posixExecve(self.argv, env_map, self.allocator) catch
|err| forkChildErrReport(err_pipe[1], err);
}
@ -573,7 +573,7 @@ pub const ChildProcess = struct {
defer self.allocator.free(app_name);
windowsCreateProcess(app_name.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,
&siStartInfo, &piProcInfo) %% |no_path_err|
&siStartInfo, &piProcInfo) catch |no_path_err|
{
if (no_path_err != error.FileNotFound)
return no_path_err;
@ -767,12 +767,12 @@ const ErrInt = @IntType(false, @sizeOf(error) * 8);
fn writeIntFd(fd: i32, value: ErrInt) -> %void {
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
mem.writeInt(bytes[0..], value, builtin.endian);
os.posixWrite(fd, bytes[0..]) %% return error.SystemResources;
os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;
}
fn readIntFd(fd: i32) -> %ErrInt {
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
os.posixRead(fd, bytes[0..]) %% return error.SystemResources;
os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
return mem.readInt(bytes[0..], ErrInt, builtin.endian);
}

View File

@ -842,7 +842,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {
var end_index: usize = resolved_path.len;
while (true) {
makeDir(allocator, resolved_path[0..end_index]) %% |err| {
makeDir(allocator, resolved_path[0..end_index]) catch |err| {
if (err == error.PathAlreadyExists) {
// TODO stat the file and return an error if it's not a directory
// this is important because otherwise a dangling symlink
@ -915,7 +915,7 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void {
return err;
}
{
var dir = Dir.open(allocator, full_path) %% |err| {
var dir = Dir.open(allocator, full_path) catch |err| {
if (err == error.FileNotFound)
return;
if (err == error.NotDir)

View File

@ -1102,7 +1102,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
var buf = try allocator.alloc(u8, 256);
%defer allocator.free(buf);
while (true) {
const buf_len = math.cast(windows.DWORD, buf.len) %% return error.NameTooLong;
const buf_len = math.cast(windows.DWORD, buf.len) catch return error.NameTooLong;
const result = windows.GetFinalPathNameByHandleA(h_file, buf.ptr, buf_len, windows.VOLUME_NAME_DOS);
if (result == 0) {

View File

@ -166,7 +166,7 @@ pub fn windowsUnloadDll(hModule: windows.HMODULE) {
test "InvalidDll" {
const DllName = "asdf.dll";
const allocator = std.debug.global_allocator;
const handle = os.windowsLoadDll(allocator, DllName) %% |err| {
const handle = os.windowsLoadDll(allocator, DllName) catch |err| {
assert(err == error.DllNotFound);
return;
};

View File

@ -22,7 +22,7 @@ comptime {
extern fn zenMain() -> noreturn {
// TODO: call exit.
root.main() %% {};
root.main() catch {};
while (true) {}
}
@ -44,7 +44,7 @@ nakedcc fn _start() -> noreturn {
extern fn WinMainCRTStartup() -> noreturn {
@setAlignStack(16);
root.main() %% std.os.windows.ExitProcess(1);
root.main() catch std.os.windows.ExitProcess(1);
std.os.windows.ExitProcess(0);
}
@ -52,7 +52,7 @@ fn posixCallMainAndExit() -> noreturn {
const argc = *argc_ptr;
const argv = @ptrCast(&&u8, &argc_ptr[1]);
const envp = @ptrCast(&?&u8, &argv[argc + 1]);
callMain(argc, argv, envp) %% std.os.posix.exit(1);
callMain(argc, argv, envp) catch std.os.posix.exit(1);
std.os.posix.exit(0);
}
@ -67,6 +67,6 @@ fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void {
}
extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 {
callMain(usize(c_argc), c_argv, c_envp) %% return 1;
callMain(usize(c_argc), c_argv, c_envp) catch return 1;
return 0;
}

View File

@ -117,7 +117,7 @@ pub fn main() -> %void {
if (builder.validateUserInputDidItFail())
return usageAndErr(&builder, true, try stderr_stream);
builder.make(targets.toSliceConst()) %% |err| {
builder.make(targets.toSliceConst()) catch |err| {
if (err == error.InvalidStepName) {
return usageAndErr(&builder, true, try stderr_stream);
}
@ -184,12 +184,12 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
}
fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) -> error {
usage(builder, already_ran_build, out_stream) %% {};
usage(builder, already_ran_build, out_stream) catch {};
return error.InvalidArgs;
}
fn unwrapArg(arg: %[]u8) -> %[]u8 {
return arg %% |err| {
return arg catch |err| {
warn("Unable to parse command line: {}\n", err);
return err;
};

View File

@ -18,7 +18,7 @@ test "mixing normal and error defers" {
assert(result[0] == 'c');
assert(result[1] == 'a');
const ok = runSomeErrorDefers(false) %% |err| x: {
const ok = runSomeErrorDefers(false) catch |err| x: {
assert(err == error.FalseNotAllowed);
break :x true;
};

View File

@ -11,7 +11,7 @@ pub fn bar() -> %i32 {
}
pub fn baz() -> %i32 {
const y = foo() %% 1234;
const y = foo() catch 1234;
return y + 1;
}
@ -53,8 +53,8 @@ fn shouldBeNotEqual(a: error, b: error) {
test "error binary operator" {
const a = errBinaryOperatorG(true) %% 3;
const b = errBinaryOperatorG(false) %% 3;
const a = errBinaryOperatorG(true) catch 3;
const b = errBinaryOperatorG(false) catch 3;
assert(a == 3);
assert(b == 10);
}

View File

@ -230,7 +230,7 @@ fn return_a_number() -> %i32 {
}
test "capture value of switch with all unreachable prongs" {
const x = return_a_number() %% |err| switch (err) {
const x = return_a_number() catch |err| switch (err) {
else => unreachable,
};
assert(x == 1);

View File

@ -395,7 +395,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
cases.add("%defer and it fails",
\\const io = @import("std").io;
\\pub fn main() -> %void {
\\ do_test() %% return;
\\ do_test() catch return;
\\}
\\fn do_test() -> %void {
\\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream);
@ -415,7 +415,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
cases.add("%defer and it passes",
\\const io = @import("std").io;
\\pub fn main() -> %void {
\\ do_test() %% return;
\\ do_test() catch return;
\\}
\\fn do_test() -> %void {
\\ const stdout = &(io.FileOutStream.init(&%%io.getStdOut()).stream);

View File

@ -1288,7 +1288,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
cases.add("return from defer expression",
\\pub fn testTrickyDefer() -> %void {
\\ defer canFail() %% {};
\\ defer canFail() catch {};
\\
\\ defer try canFail();
\\

View File

@ -259,7 +259,7 @@ pub const CompareOutputContext = struct {
child.stderr_behavior = StdIo.Pipe;
child.env_map = &b.env_map;
child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
var stdout = Buffer.initNull(b.allocator);
var stderr = Buffer.initNull(b.allocator);
@ -270,7 +270,7 @@ pub const CompareOutputContext = struct {
%%stdout_file_in_stream.stream.readAllBuffer(&stdout, max_stdout_size);
%%stderr_file_in_stream.stream.readAllBuffer(&stderr, max_stdout_size);
const term = child.wait() %% |err| {
const term = child.wait() catch |err| {
debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
};
switch (term) {
@ -341,7 +341,7 @@ pub const CompareOutputContext = struct {
child.stdout_behavior = StdIo.Ignore;
child.stderr_behavior = StdIo.Ignore;
const term = child.spawnAndWait() %% |err| {
const term = child.spawnAndWait() catch |err| {
debug.panic("Unable to spawn {}: {}\n", full_exe_path, @errorName(err));
};
@ -590,7 +590,7 @@ pub const CompileErrorContext = struct {
child.stdout_behavior = StdIo.Pipe;
child.stderr_behavior = StdIo.Pipe;
child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err));
child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err));
var stdout_buf = Buffer.initNull(b.allocator);
var stderr_buf = Buffer.initNull(b.allocator);
@ -601,7 +601,7 @@ pub const CompileErrorContext = struct {
%%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size);
%%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size);
const term = child.wait() %% |err| {
const term = child.wait() catch |err| {
debug.panic("Unable to spawn {}: {}\n", zig_args.items[0], @errorName(err));
};
switch (term) {
@ -862,7 +862,7 @@ pub const TranslateCContext = struct {
child.stdout_behavior = StdIo.Pipe;
child.stderr_behavior = StdIo.Pipe;
child.spawn() %% |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err));
child.spawn() catch |err| debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err));
var stdout_buf = Buffer.initNull(b.allocator);
var stderr_buf = Buffer.initNull(b.allocator);
@ -873,7 +873,7 @@ pub const TranslateCContext = struct {
%%stdout_file_in_stream.stream.readAllBuffer(&stdout_buf, max_stdout_size);
%%stderr_file_in_stream.stream.readAllBuffer(&stderr_buf, max_stdout_size);
const term = child.wait() %% |err| {
const term = child.wait() catch |err| {
debug.panic("Unable to spawn {}: {}\n", zig_args.toSliceConst()[0], @errorName(err));
};
switch (term) {