replace `%return` with `try`

See #632

better fits the convention of using keywords for control flow
master
Andrew Kelley 2018-01-07 16:51:46 -05:00
parent de1f57926f
commit 66717db735
41 changed files with 810 additions and 801 deletions

View File

@ -75,10 +75,10 @@
pub fn main() -> %void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = %return std.io.getStdOut();
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
%return stdout_file.write("Hello, world!\n");
try stdout_file.write("Hello, world!\n");
}</code></pre>
<p>Build this with:</p>
<pre>zig build-exe hello.zig</pre>
@ -105,9 +105,9 @@ export fn main(argc: c_int, argv: &amp;&amp;u8) -&gt; c_int {
var x: T = 0;
for (buf) |c| {
const digit = %return charToDigit(c, radix);
x = %return mulOverflow(T, x, radix);
x = %return addOverflow(T, x, digit);
const digit = try charToDigit(c, radix);
x = try mulOverflow(T, x, radix);
x = try addOverflow(T, x, digit);
}
return x;
@ -234,14 +234,14 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt
pub fn put(hm: &amp;Self, key: K, value: V) -&gt; %void {
if (hm.entries.len == 0) {
%return hm.initCapacity(16);
try hm.initCapacity(16);
}
hm.incrementModificationCount();
// if we get too full (60%), double the capacity
if (hm.size * 5 &gt;= hm.entries.len * 3) {
const old_entries = hm.entries;
%return hm.initCapacity(hm.entries.len * 2);
try hm.initCapacity(hm.entries.len * 2);
// dump all of the old elements into the new table
for (old_entries) |*old_entry| {
if (old_entry.used) {
@ -296,7 +296,7 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn(key: K)-&gt
}
fn initCapacity(hm: &amp;Self, capacity: usize) -&gt; %void {
hm.entries = %return hm.allocator.alloc(Entry, capacity);
hm.entries = try hm.allocator.alloc(Entry, capacity);
hm.size = 0;
hm.max_distance_from_start_index = 0;
for (hm.entries) |*entry| {
@ -420,7 +420,7 @@ pub fn main() -&gt; %void {
const arg = os.args.at(arg_i);
if (mem.eql(u8, arg, "-")) {
catted_anything = true;
%return cat_stream(&amp;io.stdin);
try cat_stream(&amp;io.stdin);
} else if (arg[0] == '-') {
return usage(exe);
} else {
@ -431,13 +431,13 @@ pub fn main() -&gt; %void {
defer is.close();
catted_anything = true;
%return cat_stream(&amp;is);
try cat_stream(&amp;is);
}
}
if (!catted_anything) {
%return cat_stream(&amp;io.stdin);
try cat_stream(&amp;io.stdin);
}
%return io.stdout.flush();
try io.stdout.flush();
}
fn usage(exe: []const u8) -&gt; %void {

View File

@ -268,10 +268,10 @@
pub fn main() -&gt; %void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = %return std.io.getStdOut();
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
%return stdout_file.write("Hello, world!\n");
try stdout_file.write("Hello, world!\n");
}</code></pre>
<pre><code class="sh">$ zig build-exe hello.zig
$ ./hello
@ -3224,14 +3224,14 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
// ...
}</code></pre>
<p>
There is a shortcut for this. The <code>%return</code> expression:
There is a shortcut for this. The <code>try</code> expression:
</p>
<pre><code class="zig">fn doAThing(str: []u8) -&gt; %void {
const number = %return parseU64(str, 10);
const number = try parseU64(str, 10);
// ...
}</code></pre>
<p>
<code>%return</code> evaluates an error union expression. If it is an error, it returns
<code>try</code> evaluates an error union expression. If it is an error, it returns
from the current function with the same error. Otherwise, the expression results in
the unwrapped value.
</p>
@ -3278,7 +3278,7 @@ pub fn parseU64(buf: []const u8, radix: u8) -&gt; %u64 {
Example:
</p>
<pre><code class="zig">fn createFoo(param: i32) -&gt; %Foo {
const foo = %return tryToAllocateFoo();
const foo = try tryToAllocateFoo();
// now we have allocated foo. we need to free it if the function fails.
// but we want to return it if the function succeeds.
%defer deallocateFoo(foo);
@ -3928,11 +3928,11 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
switch (state) {
State.Start =&gt; switch (c) {
'{' =&gt; {
if (start_index &lt; i) %return self.write(format[start_index...i]);
if (start_index &lt; i) try self.write(format[start_index...i]);
state = State.OpenBrace;
},
'}' =&gt; {
if (start_index &lt; i) %return self.write(format[start_index...i]);
if (start_index &lt; i) try self.write(format[start_index...i]);
state = State.CloseBrace;
},
else =&gt; {},
@ -3943,7 +3943,7 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
start_index = i;
},
'}' =&gt; {
%return self.printValue(args[next_arg]);
try self.printValue(args[next_arg]);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -3968,9 +3968,9 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
}
}
if (start_index &lt; format.len) {
%return self.write(format[start_index...format.len]);
try self.write(format[start_index...format.len]);
}
%return self.flush();
try self.flush();
}</code></pre>
<p>
This is a proof of concept implementation; the actual function in the standard library has more
@ -3984,12 +3984,12 @@ pub fn printf(self: &amp;OutStream, comptime format: []const u8, args: ...) -&gt
and emits a function that actually looks like this:
</p>
<pre><code class="zig">pub fn printf(self: &amp;OutStream, arg0: i32, arg1: []const u8) -&gt; %void {
%return self.write("here is a string: '");
%return self.printValue(arg0);
%return self.write("' here is a number: ");
%return self.printValue(arg1);
%return self.write("\n");
%return self.flush();
try self.write("here is a string: '");
try self.printValue(arg0);
try self.write("' here is a number: ");
try self.printValue(arg1);
try self.write("\n");
try self.flush();
}</code></pre>
<p>
<code>printValue</code> is a function that takes a parameter of any type, and does different things depending
@ -5891,7 +5891,7 @@ TypeExpr = PrefixOpExpression | "var"
BlockOrExpression = Block | Expression
Expression = ReturnExpression | BreakExpression | AssignmentExpression
Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression
AsmExpression = "asm" option("volatile") "(" String option(AsmOutput) ")"
@ -5915,7 +5915,7 @@ AssignmentExpression = UnwrapExpression AssignmentOperator UnwrapExpression | Un
AssignmentOperator = "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "&lt;&lt;=" | "&gt;&gt;=" | "&amp;=" | "^=" | "|=" | "*%=" | "+%=" | "-%="
BlockExpression(body) = Block | IfExpression(body) | TryExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
BlockExpression(body) = Block | IfExpression(body) | IfErrorExpression(body) | TestExpression(body) | WhileExpression(body) | ForExpression(body) | SwitchExpression | CompTimeExpression(body)
CompTimeExpression(body) = "comptime" body
@ -5929,7 +5929,9 @@ ForExpression(body) = option(Symbol ":") option("inline") "for" "(" Expression "
BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression
ReturnExpression = option("%") "return" option(Expression)
ReturnExpression = "return" option(Expression)
TryExpression = "try" Expression
BreakExpression = "break" option(":" Symbol) option(Expression)
@ -5937,7 +5939,7 @@ Defer(body) = option("%") "defer" body
IfExpression(body) = "if" "(" Expression ")" body option("else" BlockExpression(body))
TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)
IfErrorExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body "else" "|" Symbol "|" BlockExpression(body)
TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body))
@ -5987,7 +5989,7 @@ ContainerInitBody = list(StructLiteralField, ",") | list(Expression, ",")
StructLiteralField = "." Symbol "=" Expression
PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try"
PrimaryExpression = Integer | Float | String | CharLiteral | KeywordLiteral | GroupedExpression | BlockExpression(BlockOrExpression) | Symbol | ("@" Symbol FnCallExpression) | ArrayType | FnProto | AsmExpression | ("error" "." Symbol) | ContainerDecl | ("continue" option(":" Symbol))

View File

@ -7,16 +7,16 @@ const allocator = std.debug.global_allocator;
pub fn main() -> %void {
var args_it = os.args();
const exe = %return unwrapArg(??args_it.next(allocator));
const exe = try unwrapArg(??args_it.next(allocator));
var catted_anything = false;
var stdout_file = %return io.getStdOut();
var stdout_file = try io.getStdOut();
while (args_it.next(allocator)) |arg_or_err| {
const arg = %return unwrapArg(arg_or_err);
const arg = try unwrapArg(arg_or_err);
if (mem.eql(u8, arg, "-")) {
catted_anything = true;
var stdin_file = %return io.getStdIn();
%return cat_file(&stdout_file, &stdin_file);
var stdin_file = try io.getStdIn();
try cat_file(&stdout_file, &stdin_file);
} else if (arg[0] == '-') {
return usage(exe);
} else {
@ -27,12 +27,12 @@ pub fn main() -> %void {
defer file.close();
catted_anything = true;
%return cat_file(&stdout_file, &file);
try cat_file(&stdout_file, &file);
}
}
if (!catted_anything) {
var stdin_file = %return io.getStdIn();
%return cat_file(&stdout_file, &stdin_file);
var stdin_file = try io.getStdIn();
try cat_file(&stdout_file, &stdin_file);
}
}

View File

@ -6,13 +6,13 @@ const Rand = std.rand.Rand;
const os = std.os;
pub fn main() -> %void {
var stdout_file = %return io.getStdOut();
var stdout_file = try io.getStdOut();
var stdout_file_stream = io.FileOutStream.init(&stdout_file);
const stdout = &stdout_file_stream.stream;
var stdin_file = %return io.getStdIn();
var stdin_file = try io.getStdIn();
%return stdout.print("Welcome to the Guess Number Game in Zig.\n");
try stdout.print("Welcome to the Guess Number Game in Zig.\n");
var seed_bytes: [@sizeOf(usize)]u8 = undefined;
%%os.getRandomBytes(seed_bytes[0..]);
@ -22,24 +22,24 @@ pub fn main() -> %void {
const answer = rand.range(u8, 0, 100) + 1;
while (true) {
%return stdout.print("\nGuess a number between 1 and 100: ");
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| {
%return stdout.print("Unable to read from stdin: {}\n", @errorName(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) %% {
%return stdout.print("Invalid number.\n");
try stdout.print("Invalid number.\n");
continue;
};
if (guess > answer) {
%return stdout.print("Guess lower.\n");
try stdout.print("Guess lower.\n");
} else if (guess < answer) {
%return stdout.print("Guess higher.\n");
try stdout.print("Guess higher.\n");
} else {
%return stdout.print("You win!\n");
try stdout.print("You win!\n");
return;
}
}

View File

@ -2,8 +2,8 @@ const std = @import("std");
pub fn main() -> %void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = %return std.io.getStdOut();
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit
// with an error.
%return stdout_file.write("Hello, world!\n");
try stdout_file.write("Hello, world!\n");
}

View File

@ -40,18 +40,18 @@ const Cmd = enum {
};
fn badArgs(comptime format: []const u8, args: ...) -> error {
var stderr = %return io.getStdErr();
var stderr = try io.getStdErr();
var stderr_stream_adapter = io.FileOutStream.init(&stderr);
const stderr_stream = &stderr_stream_adapter.stream;
%return stderr_stream.print(format ++ "\n\n", args);
%return printUsage(&stderr_stream_adapter.stream);
try stderr_stream.print(format ++ "\n\n", args);
try printUsage(&stderr_stream_adapter.stream);
return error.InvalidCommandLineArguments;
}
pub fn main2() -> %void {
const allocator = std.heap.c_allocator;
const args = %return os.argsAlloc(allocator);
const args = try os.argsAlloc(allocator);
defer os.argsFree(allocator, args);
var cmd = Cmd.None;
@ -167,7 +167,7 @@ pub fn main2() -> %void {
@panic("TODO --test-cmd-bin");
} else if (arg[1] == 'L' and arg.len > 2) {
// alias for --library-path
%return lib_dirs.append(arg[1..]);
try lib_dirs.append(arg[1..]);
} else if (mem.eql(u8, arg, "--pkg-begin")) {
@panic("TODO --pkg-begin");
} else if (mem.eql(u8, arg, "--pkg-end")) {
@ -217,24 +217,24 @@ pub fn main2() -> %void {
} else if (mem.eql(u8, arg, "--dynamic-linker")) {
dynamic_linker_arg = args[arg_i];
} else if (mem.eql(u8, arg, "-isystem")) {
%return clang_argv.append("-isystem");
%return clang_argv.append(args[arg_i]);
try clang_argv.append("-isystem");
try clang_argv.append(args[arg_i]);
} else if (mem.eql(u8, arg, "-dirafter")) {
%return clang_argv.append("-dirafter");
%return clang_argv.append(args[arg_i]);
try clang_argv.append("-dirafter");
try clang_argv.append(args[arg_i]);
} else if (mem.eql(u8, arg, "-mllvm")) {
%return clang_argv.append("-mllvm");
%return clang_argv.append(args[arg_i]);
try clang_argv.append("-mllvm");
try clang_argv.append(args[arg_i]);
%return llvm_argv.append(args[arg_i]);
try llvm_argv.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--library-path") or mem.eql(u8, arg, "-L")) {
%return lib_dirs.append(args[arg_i]);
try lib_dirs.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--library")) {
%return link_libs.append(args[arg_i]);
try link_libs.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--object")) {
%return objects.append(args[arg_i]);
try objects.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--assembly")) {
%return asm_files.append(args[arg_i]);
try asm_files.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--cache-dir")) {
cache_dir_arg = args[arg_i];
} else if (mem.eql(u8, arg, "--target-arch")) {
@ -248,21 +248,21 @@ pub fn main2() -> %void {
} else if (mem.eql(u8, arg, "-mios-version-min")) {
mios_version_min = args[arg_i];
} else if (mem.eql(u8, arg, "-framework")) {
%return frameworks.append(args[arg_i]);
try frameworks.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--linker-script")) {
linker_script_arg = args[arg_i];
} else if (mem.eql(u8, arg, "-rpath")) {
%return rpath_list.append(args[arg_i]);
try rpath_list.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--test-filter")) {
%return test_filters.append(args[arg_i]);
try test_filters.append(args[arg_i]);
} else if (mem.eql(u8, arg, "--test-name-prefix")) {
test_name_prefix_arg = args[arg_i];
} else if (mem.eql(u8, arg, "--ver-major")) {
ver_major = %return std.fmt.parseUnsigned(u32, args[arg_i], 10);
ver_major = try std.fmt.parseUnsigned(u32, args[arg_i], 10);
} else if (mem.eql(u8, arg, "--ver-minor")) {
ver_minor = %return std.fmt.parseUnsigned(u32, args[arg_i], 10);
ver_minor = try std.fmt.parseUnsigned(u32, args[arg_i], 10);
} else if (mem.eql(u8, arg, "--ver-patch")) {
ver_patch = %return std.fmt.parseUnsigned(u32, args[arg_i], 10);
ver_patch = try std.fmt.parseUnsigned(u32, args[arg_i], 10);
} else if (mem.eql(u8, arg, "--test-cmd")) {
@panic("TODO --test-cmd");
} else {
@ -367,13 +367,13 @@ pub fn main2() -> %void {
const zig_root_source_file = if (cmd == Cmd.TranslateC) null else in_file_arg;
const chosen_cache_dir = cache_dir_arg ?? default_zig_cache_name;
const full_cache_dir = %return os.path.resolve(allocator, ".", chosen_cache_dir);
const full_cache_dir = try os.path.resolve(allocator, ".", chosen_cache_dir);
defer allocator.free(full_cache_dir);
const zig_lib_dir = %return resolveZigLibDir(allocator, zig_install_prefix);
const zig_lib_dir = try resolveZigLibDir(allocator, zig_install_prefix);
%defer allocator.free(zig_lib_dir);
const module = %return Module.create(allocator, root_name, zig_root_source_file,
const module = try Module.create(allocator, root_name, zig_root_source_file,
Target.Native, build_kind, build_mode, zig_lib_dir, full_cache_dir);
defer module.destroy();
@ -424,7 +424,7 @@ pub fn main2() -> %void {
module.rpath_list = rpath_list.toSliceConst();
for (link_libs.toSliceConst()) |name| {
_ = %return module.addLinkLib(name, true);
_ = try module.addLinkLib(name, true);
}
module.windows_subsystem_windows = mwindows;
@ -455,8 +455,8 @@ pub fn main2() -> %void {
module.link_objects = objects.toSliceConst();
module.assembly_files = asm_files.toSliceConst();
%return module.build();
%return module.link(out_file);
try module.build();
try module.link(out_file);
},
Cmd.TranslateC => @panic("TODO translate-c"),
Cmd.Test => @panic("TODO test cmd"),
@ -464,16 +464,16 @@ pub fn main2() -> %void {
}
},
Cmd.Version => {
var stdout_file = %return io.getStdErr();
%return stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
%return stdout_file.write("\n");
var stdout_file = try io.getStdErr();
try stdout_file.write(std.cstr.toSliceConst(c.ZIG_VERSION_STRING));
try stdout_file.write("\n");
},
Cmd.Targets => @panic("TODO zig targets"),
}
}
fn printUsage(stream: &io.OutStream) -> %void {
%return stream.write(
try stream.write(
\\Usage: zig [command] [options]
\\
\\Commands:
@ -549,8 +549,8 @@ fn printUsage(stream: &io.OutStream) -> %void {
}
fn printZen() -> %void {
var stdout_file = %return io.getStdErr();
%return stdout_file.write(
var stdout_file = try io.getStdErr();
try stdout_file.write(
\\
\\ * Communicate intent precisely.
\\ * Edge cases matter.
@ -586,13 +586,13 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const
/// Caller must free result
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]u8 {
const test_zig_dir = %return os.path.join(allocator, test_path, "lib", "zig");
const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");
%defer allocator.free(test_zig_dir);
const test_index_file = %return os.path.join(allocator, test_zig_dir, "std", "index.zig");
const test_index_file = try os.path.join(allocator, test_zig_dir, "std", "index.zig");
defer allocator.free(test_index_file);
var file = %return io.File.openRead(test_index_file, allocator);
var file = try io.File.openRead(test_index_file, allocator);
file.close();
return test_zig_dir;
@ -600,7 +600,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) -> %[]
/// Caller must free result
fn findZigLibDir(allocator: &mem.Allocator) -> %[]u8 {
const self_exe_path = %return os.selfExeDirPath(allocator);
const self_exe_path = try os.selfExeDirPath(allocator);
defer allocator.free(self_exe_path);
var cur_path: []const u8 = self_exe_path;

View File

@ -112,7 +112,7 @@ pub const Module = struct {
pub fn create(allocator: &mem.Allocator, name: []const u8, root_src_path: ?[]const u8, target: &const Target,
kind: Kind, build_mode: builtin.Mode, zig_lib_dir: []const u8, cache_dir: []const u8) -> %&Module
{
var name_buffer = %return Buffer.init(allocator, name);
var name_buffer = try Buffer.init(allocator, name);
%defer name_buffer.deinit();
const context = c.LLVMContextCreate() ?? return error.OutOfMemory;
@ -124,7 +124,7 @@ pub const Module = struct {
const builder = c.LLVMCreateBuilderInContext(context) ?? return error.OutOfMemory;
%defer c.LLVMDisposeBuilder(builder);
const module_ptr = %return allocator.create(Module);
const module_ptr = try allocator.create(Module);
%defer allocator.destroy(module_ptr);
*module_ptr = Module {
@ -200,7 +200,7 @@ pub const Module = struct {
pub fn build(self: &Module) -> %void {
if (self.llvm_argv.len != 0) {
var c_compatible_args = %return std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
defer c_compatible_args.deinit();
c.ZigLLVMParseCommandLineOptions(self.llvm_argv.len + 1, c_compatible_args.ptr);
@ -208,13 +208,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| {
%return printError("unable to get real path '{}': {}", root_src_path, 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| {
%return printError("unable to open '{}': {}", root_src_real_path, err);
try printError("unable to open '{}': {}", root_src_real_path, err);
return err;
};
%defer self.allocator.free(source_code);
@ -244,16 +244,16 @@ pub const Module = struct {
var parser = Parser.init(&tokenizer, self.allocator, root_src_real_path);
defer parser.deinit();
const root_node = %return parser.parse();
const root_node = try parser.parse();
defer parser.freeAst(root_node);
var stderr_file = %return std.io.getStdErr();
var stderr_file = try std.io.getStdErr();
var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
const out_stream = &stderr_file_out_stream.stream;
%return parser.renderAst(out_stream, root_node);
try parser.renderAst(out_stream, root_node);
warn("====fmt:====\n");
%return parser.renderSource(out_stream, root_node);
try parser.renderSource(out_stream, root_node);
warn("====ir:====\n");
warn("TODO\n\n");
@ -282,14 +282,14 @@ pub const Module = struct {
}
}
const link_lib = %return self.allocator.create(LinkLib);
const link_lib = try self.allocator.create(LinkLib);
*link_lib = LinkLib {
.name = name,
.path = null,
.provided_explicitly = provided_explicitly,
.symbols = ArrayList([]u8).init(self.allocator),
};
%return self.link_libs_list.append(link_lib);
try self.link_libs_list.append(link_lib);
if (is_libc) {
self.libc_link_lib = link_lib;
}
@ -298,8 +298,8 @@ pub const Module = struct {
};
fn printError(comptime format: []const u8, args: ...) -> %void {
var stderr_file = %return std.io.getStdErr();
var stderr_file = try std.io.getStdErr();
var stderr_file_out_stream = std.io.FileOutStream.init(&stderr_file);
const out_stream = &stderr_file_out_stream.stream;
%return out_stream.print(format, args);
try out_stream.print(format, args);
}

View File

@ -58,7 +58,7 @@ pub const Parser = struct {
switch (*self) {
DestPtr.Field => |ptr| *ptr = value,
DestPtr.NullableField => |ptr| *ptr = value,
DestPtr.List => |list| %return list.append(value),
DestPtr.List => |list| try list.append(value),
}
}
};
@ -126,10 +126,10 @@ pub const Parser = struct {
defer self.deinitUtilityArrayList(stack);
const root_node = x: {
const root_node = %return self.createRoot();
const root_node = try self.createRoot();
%defer self.allocator.destroy(root_node);
// This stack append has to succeed for freeAst to work
%return stack.append(State.TopLevel);
try stack.append(State.TopLevel);
break :x root_node;
};
assert(self.cleanup_root_node == null);
@ -194,18 +194,18 @@ pub const Parser = struct {
Token.Id.Keyword_var, Token.Id.Keyword_const => {
stack.append(State.TopLevel) %% unreachable;
// TODO shouldn't need these casts
const var_decl_node = %return self.createAttachVarDecl(&root_node.decls, ctx.visib_token,
const var_decl_node = try self.createAttachVarDecl(&root_node.decls, ctx.visib_token,
token, (?Token)(null), ctx.extern_token);
%return stack.append(State { .VarDecl = var_decl_node });
try stack.append(State { .VarDecl = var_decl_node });
continue;
},
Token.Id.Keyword_fn => {
stack.append(State.TopLevel) %% unreachable;
// TODO shouldn't need these casts
const fn_proto = %return self.createAttachFnProto(&root_node.decls, token,
const fn_proto = try self.createAttachFnProto(&root_node.decls, token,
ctx.extern_token, (?Token)(null), (?Token)(null), (?Token)(null));
%return stack.append(State { .FnDef = fn_proto });
%return stack.append(State { .FnProto = fn_proto });
try stack.append(State { .FnDef = fn_proto });
try stack.append(State { .FnProto = fn_proto });
continue;
},
Token.Id.StringLiteral => {
@ -213,24 +213,24 @@ pub const Parser = struct {
},
Token.Id.Keyword_coldcc, Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
stack.append(State.TopLevel) %% unreachable;
const fn_token = %return self.eatToken(Token.Id.Keyword_fn);
const fn_token = try self.eatToken(Token.Id.Keyword_fn);
// TODO shouldn't need this cast
const fn_proto = %return self.createAttachFnProto(&root_node.decls, fn_token,
const fn_proto = try self.createAttachFnProto(&root_node.decls, fn_token,
ctx.extern_token, (?Token)(token), (?Token)(null), (?Token)(null));
%return stack.append(State { .FnDef = fn_proto });
%return stack.append(State { .FnProto = fn_proto });
try stack.append(State { .FnDef = fn_proto });
try stack.append(State { .FnProto = fn_proto });
continue;
},
else => return self.parseError(token, "expected variable declaration or function, found {}", @tagName(token.id)),
}
},
State.VarDecl => |var_decl| {
var_decl.name_token = %return self.eatToken(Token.Id.Identifier);
var_decl.name_token = try self.eatToken(Token.Id.Identifier);
stack.append(State { .VarDeclAlign = var_decl }) %% unreachable;
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Colon) {
%return stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} });
try stack.append(State { .TypeExpr = DestPtr {.NullableField = &var_decl.type_node} });
continue;
}
@ -242,9 +242,9 @@ pub const Parser = struct {
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Keyword_align) {
_ = %return self.eatToken(Token.Id.LParen);
%return stack.append(State { .ExpectToken = Token.Id.RParen });
%return stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} });
_ = try self.eatToken(Token.Id.LParen);
try stack.append(State { .ExpectToken = Token.Id.RParen });
try stack.append(State { .Expression = DestPtr{.NullableField = &var_decl.align_node} });
continue;
}
@ -256,7 +256,7 @@ pub const Parser = struct {
if (token.id == Token.Id.Equal) {
var_decl.eq_token = token;
stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
%return stack.append(State {
try stack.append(State {
.Expression = DestPtr {.NullableField = &var_decl.init_node},
});
continue;
@ -267,14 +267,14 @@ pub const Parser = struct {
return self.parseError(token, "expected '=' or ';', found {}", @tagName(token.id));
},
State.ExpectToken => |token_id| {
_ = %return self.eatToken(token_id);
_ = try self.eatToken(token_id);
continue;
},
State.Expression => |dest_ptr| {
// save the dest_ptr for later
stack.append(state) %% unreachable;
%return stack.append(State.ExpectOperand);
try stack.append(State.ExpectOperand);
continue;
},
State.ExpectOperand => {
@ -283,13 +283,13 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_return => {
%return stack.append(State { .PrefixOp = %return self.createPrefixOp(token,
try stack.append(State { .PrefixOp = try self.createPrefixOp(token,
ast.NodePrefixOp.PrefixOp.Return) });
%return stack.append(State.ExpectOperand);
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.Ampersand => {
const prefix_op = %return self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{
const prefix_op = try self.createPrefixOp(token, ast.NodePrefixOp.PrefixOp{
.AddrOf = ast.NodePrefixOp.AddrOfInfo {
.align_expr = null,
.bit_offset_start_token = null,
@ -298,30 +298,30 @@ pub const Parser = struct {
.volatile_token = null,
}
});
%return stack.append(State { .PrefixOp = prefix_op });
%return stack.append(State.ExpectOperand);
%return stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf });
try stack.append(State { .PrefixOp = prefix_op });
try stack.append(State.ExpectOperand);
try stack.append(State { .AddrOfModifiers = &prefix_op.op.AddrOf });
continue;
},
Token.Id.Identifier => {
%return stack.append(State {
.Operand = &(%return self.createIdentifier(token)).base
try stack.append(State {
.Operand = &(try self.createIdentifier(token)).base
});
%return stack.append(State.AfterOperand);
try stack.append(State.AfterOperand);
continue;
},
Token.Id.IntegerLiteral => {
%return stack.append(State {
.Operand = &(%return self.createIntegerLiteral(token)).base
try stack.append(State {
.Operand = &(try self.createIntegerLiteral(token)).base
});
%return stack.append(State.AfterOperand);
try stack.append(State.AfterOperand);
continue;
},
Token.Id.FloatLiteral => {
%return stack.append(State {
.Operand = &(%return self.createFloatLiteral(token)).base
try stack.append(State {
.Operand = &(try self.createFloatLiteral(token)).base
});
%return stack.append(State.AfterOperand);
try stack.append(State.AfterOperand);
continue;
},
else => return self.parseError(token, "expected primary expression, found {}", @tagName(token.id)),
@ -335,17 +335,17 @@ pub const Parser = struct {
var token = self.getNextToken();
switch (token.id) {
Token.Id.EqualEqual => {
%return stack.append(State {
.InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual)
try stack.append(State {
.InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.EqualEqual)
});
%return stack.append(State.ExpectOperand);
try stack.append(State.ExpectOperand);
continue;
},
Token.Id.BangEqual => {
%return stack.append(State {
.InfixOp = %return self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual)
try stack.append(State {
.InfixOp = try self.createInfixOp(token, ast.NodeInfixOp.InfixOp.BangEqual)
});
%return stack.append(State.ExpectOperand);
try stack.append(State.ExpectOperand);
continue;
},
else => {
@ -357,7 +357,7 @@ pub const Parser = struct {
switch (stack.pop()) {
State.Expression => |dest_ptr| {
// we're done
%return dest_ptr.store(expression);
try dest_ptr.store(expression);
break;
},
State.InfixOp => |infix_op| {
@ -385,9 +385,9 @@ pub const Parser = struct {
Token.Id.Keyword_align => {
stack.append(state) %% unreachable;
if (addr_of_info.align_expr != null) return self.parseError(token, "multiple align qualifiers");
_ = %return self.eatToken(Token.Id.LParen);
%return stack.append(State { .ExpectToken = Token.Id.RParen });
%return stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} });
_ = try self.eatToken(Token.Id.LParen);
try stack.append(State { .ExpectToken = Token.Id.RParen });
try stack.append(State { .Expression = DestPtr{.NullableField = &addr_of_info.align_expr} });
continue;
},
Token.Id.Keyword_const => {
@ -422,8 +422,8 @@ pub const Parser = struct {
State.FnProto => |fn_proto| {
stack.append(State { .FnProtoAlign = fn_proto }) %% unreachable;
%return stack.append(State { .ParamDecl = fn_proto });
%return stack.append(State { .ExpectToken = Token.Id.LParen });
try stack.append(State { .ParamDecl = fn_proto });
try stack.append(State { .ExpectToken = Token.Id.LParen });
const next_token = self.getNextToken();
if (next_token.id == Token.Id.Identifier) {
@ -455,7 +455,7 @@ pub const Parser = struct {
if (token.id == Token.Id.RParen) {
continue;
}
const param_decl = %return self.createAttachParamDecl(&fn_proto.params);
const param_decl = try self.createAttachParamDecl(&fn_proto.params);
if (token.id == Token.Id.Keyword_comptime) {
param_decl.comptime_token = token;
token = self.getNextToken();
@ -481,8 +481,8 @@ pub const Parser = struct {
}
stack.append(State { .ParamDecl = fn_proto }) %% unreachable;
%return stack.append(State.ParamDeclComma);
%return stack.append(State {
try stack.append(State.ParamDeclComma);
try stack.append(State {
.TypeExpr = DestPtr {.Field = &param_decl.type_node}
});
continue;
@ -504,7 +504,7 @@ pub const Parser = struct {
const token = self.getNextToken();
switch(token.id) {
Token.Id.LBrace => {
const block = %return self.createBlock(token);
const block = try self.createBlock(token);
fn_proto.body_node = &block.base;
stack.append(State { .Block = block }) %% unreachable;
continue;
@ -524,7 +524,7 @@ pub const Parser = struct {
else => {
self.putBackToken(token);
stack.append(State { .Block = block }) %% unreachable;
%return stack.append(State { .Statement = block });
try stack.append(State { .Statement = block });
continue;
},
}
@ -538,9 +538,9 @@ pub const Parser = struct {
const mut_token = self.getNextToken();
if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
// TODO shouldn't need these casts
const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null),
const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null),
mut_token, (?Token)(comptime_token), (?Token)(null));
%return stack.append(State { .VarDecl = var_decl });
try stack.append(State { .VarDecl = var_decl });
continue;
}
self.putBackToken(mut_token);
@ -552,16 +552,16 @@ pub const Parser = struct {
const mut_token = self.getNextToken();
if (mut_token.id == Token.Id.Keyword_var or mut_token.id == Token.Id.Keyword_const) {
// TODO shouldn't need these casts
const var_decl = %return self.createAttachVarDecl(&block.statements, (?Token)(null),
const var_decl = try self.createAttachVarDecl(&block.statements, (?Token)(null),
mut_token, (?Token)(null), (?Token)(null));
%return stack.append(State { .VarDecl = var_decl });
try stack.append(State { .VarDecl = var_decl });
continue;
}
self.putBackToken(mut_token);
}
stack.append(State { .ExpectToken = Token.Id.Semicolon }) %% unreachable;
%return stack.append(State { .Expression = DestPtr{.List = &block.statements} });
try stack.append(State { .Expression = DestPtr{.List = &block.statements} });
continue;
},
@ -576,7 +576,7 @@ pub const Parser = struct {
}
fn createRoot(self: &Parser) -> %&ast.NodeRoot {
const node = %return self.allocator.create(ast.NodeRoot);
const node = try self.allocator.create(ast.NodeRoot);
%defer self.allocator.destroy(node);
*node = ast.NodeRoot {
@ -589,7 +589,7 @@ pub const Parser = struct {
fn createVarDecl(self: &Parser, visib_token: &const ?Token, mut_token: &const Token, comptime_token: &const ?Token,
extern_token: &const ?Token) -> %&ast.NodeVarDecl
{
const node = %return self.allocator.create(ast.NodeVarDecl);
const node = try self.allocator.create(ast.NodeVarDecl);
%defer self.allocator.destroy(node);
*node = ast.NodeVarDecl {
@ -612,7 +612,7 @@ pub const Parser = struct {
fn createFnProto(self: &Parser, fn_token: &const Token, extern_token: &const ?Token,
cc_token: &const ?Token, visib_token: &const ?Token, inline_token: &const ?Token) -> %&ast.NodeFnProto
{
const node = %return self.allocator.create(ast.NodeFnProto);
const node = try self.allocator.create(ast.NodeFnProto);
%defer self.allocator.destroy(node);
*node = ast.NodeFnProto {
@ -634,7 +634,7 @@ pub const Parser = struct {
}
fn createParamDecl(self: &Parser) -> %&ast.NodeParamDecl {
const node = %return self.allocator.create(ast.NodeParamDecl);
const node = try self.allocator.create(ast.NodeParamDecl);
%defer self.allocator.destroy(node);
*node = ast.NodeParamDecl {
@ -649,7 +649,7 @@ pub const Parser = struct {
}
fn createBlock(self: &Parser, begin_token: &const Token) -> %&ast.NodeBlock {
const node = %return self.allocator.create(ast.NodeBlock);
const node = try self.allocator.create(ast.NodeBlock);
%defer self.allocator.destroy(node);
*node = ast.NodeBlock {
@ -662,7 +662,7 @@ pub const Parser = struct {
}
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) -> %&ast.NodeInfixOp {
const node = %return self.allocator.create(ast.NodeInfixOp);
const node = try self.allocator.create(ast.NodeInfixOp);
%defer self.allocator.destroy(node);
*node = ast.NodeInfixOp {
@ -676,7 +676,7 @@ pub const Parser = struct {
}
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) -> %&ast.NodePrefixOp {
const node = %return self.allocator.create(ast.NodePrefixOp);
const node = try self.allocator.create(ast.NodePrefixOp);
%defer self.allocator.destroy(node);
*node = ast.NodePrefixOp {
@ -689,7 +689,7 @@ pub const Parser = struct {
}
fn createIdentifier(self: &Parser, name_token: &const Token) -> %&ast.NodeIdentifier {
const node = %return self.allocator.create(ast.NodeIdentifier);
const node = try self.allocator.create(ast.NodeIdentifier);
%defer self.allocator.destroy(node);
*node = ast.NodeIdentifier {
@ -700,7 +700,7 @@ pub const Parser = struct {
}
fn createIntegerLiteral(self: &Parser, token: &const Token) -> %&ast.NodeIntegerLiteral {
const node = %return self.allocator.create(ast.NodeIntegerLiteral);
const node = try self.allocator.create(ast.NodeIntegerLiteral);
%defer self.allocator.destroy(node);
*node = ast.NodeIntegerLiteral {
@ -711,7 +711,7 @@ pub const Parser = struct {
}
fn createFloatLiteral(self: &Parser, token: &const Token) -> %&ast.NodeFloatLiteral {
const node = %return self.allocator.create(ast.NodeFloatLiteral);
const node = try self.allocator.create(ast.NodeFloatLiteral);
%defer self.allocator.destroy(node);
*node = ast.NodeFloatLiteral {
@ -722,16 +722,16 @@ pub const Parser = struct {
}
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) -> %&ast.NodeIdentifier {
const node = %return self.createIdentifier(name_token);
const node = try self.createIdentifier(name_token);
%defer self.allocator.destroy(node);
%return dest_ptr.store(&node.base);
try dest_ptr.store(&node.base);
return node;
}
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) -> %&ast.NodeParamDecl {
const node = %return self.createParamDecl();
const node = try self.createParamDecl();
%defer self.allocator.destroy(node);
%return list.append(&node.base);
try list.append(&node.base);
return node;
}
@ -739,18 +739,18 @@ pub const Parser = struct {
extern_token: &const ?Token, cc_token: &const ?Token, visib_token: &const ?Token,
inline_token: &const ?Token) -> %&ast.NodeFnProto
{
const node = %return self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
const node = try self.createFnProto(fn_token, extern_token, cc_token, visib_token, inline_token);
%defer self.allocator.destroy(node);
%return list.append(&node.base);
try list.append(&node.base);
return node;
}
fn createAttachVarDecl(self: &Parser, list: &ArrayList(&ast.Node), visib_token: &const ?Token,
mut_token: &const Token, comptime_token: &const ?Token, extern_token: &const ?Token) -> %&ast.NodeVarDecl
{
const node = %return self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
const node = try self.createVarDecl(visib_token, mut_token, comptime_token, extern_token);
%defer self.allocator.destroy(node);
%return list.append(&node.base);
try list.append(&node.base);
return node;
}
@ -783,7 +783,7 @@ pub const Parser = struct {
fn eatToken(self: &Parser, id: @TagType(Token.Id)) -> %Token {
const token = self.getNextToken();
%return self.expectToken(token, id);
try self.expectToken(token, id);
return token;
}
@ -812,7 +812,7 @@ pub const Parser = struct {
var stack = self.initUtilityArrayList(RenderAstFrame);
defer self.deinitUtilityArrayList(stack);
%return stack.append(RenderAstFrame {
try stack.append(RenderAstFrame {
.node = &root_node.base,
.indent = 0,
});
@ -821,13 +821,13 @@ pub const Parser = struct {
{
var i: usize = 0;
while (i < frame.indent) : (i += 1) {
%return stream.print(" ");
try stream.print(" ");
}
}
%return stream.print("{}\n", @tagName(frame.node.id));
try stream.print("{}\n", @tagName(frame.node.id));
var child_i: usize = 0;
while (frame.node.iterate(child_i)) |child| : (child_i += 1) {
%return stack.append(RenderAstFrame {
try stack.append(RenderAstFrame {
.node = child,
.indent = frame.indent + 2,
});
@ -856,7 +856,7 @@ pub const Parser = struct {
while (i != 0) {
i -= 1;
const decl = root_node.decls.items[i];
%return stack.append(RenderState {.TopLevelDecl = decl});
try stack.append(RenderState {.TopLevelDecl = decl});
}
}
@ -870,42 +870,42 @@ pub const Parser = struct {
const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl);
if (fn_proto.visib_token) |visib_token| {
switch (visib_token.id) {
Token.Id.Keyword_pub => %return stream.print("pub "),
Token.Id.Keyword_export => %return stream.print("export "),
Token.Id.Keyword_pub => try stream.print("pub "),
Token.Id.Keyword_export => try stream.print("export "),
else => unreachable,
}
}
if (fn_proto.extern_token) |extern_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
}
%return stream.print("fn");
try stream.print("fn");
if (fn_proto.name_token) |name_token| {
%return stream.print(" {}", self.tokenizer.getTokenSlice(name_token));
try stream.print(" {}", self.tokenizer.getTokenSlice(name_token));
}
%return stream.print("(");
try stream.print("(");
%return stack.append(RenderState { .Text = "\n" });
try stack.append(RenderState { .Text = "\n" });
if (fn_proto.body_node == null) {
%return stack.append(RenderState { .Text = ";" });
try stack.append(RenderState { .Text = ";" });
}
%return stack.append(RenderState { .FnProtoRParen = fn_proto});
try stack.append(RenderState { .FnProtoRParen = fn_proto});
var i = fn_proto.params.len;
while (i != 0) {
i -= 1;
const param_decl_node = fn_proto.params.items[i];
%return stack.append(RenderState { .ParamDecl = param_decl_node});
try stack.append(RenderState { .ParamDecl = param_decl_node});
if (i != 0) {
%return stack.append(RenderState { .Text = ", " });
try stack.append(RenderState { .Text = ", " });
}
}
},
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
%return stack.append(RenderState { .Text = "\n"});
%return stack.append(RenderState { .VarDecl = var_decl});
try stack.append(RenderState { .Text = "\n"});
try stack.append(RenderState { .VarDecl = var_decl});
},
else => unreachable,
@ -914,111 +914,111 @@ pub const Parser = struct {
RenderState.VarDecl => |var_decl| {
if (var_decl.visib_token) |visib_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
}
if (var_decl.extern_token) |extern_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(extern_token));
if (var_decl.lib_name != null) {
@panic("TODO");
}
}
if (var_decl.comptime_token) |comptime_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
}
%return stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
%return stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(var_decl.mut_token));
try stream.print("{}", self.tokenizer.getTokenSlice(var_decl.name_token));
%return stack.append(RenderState { .Text = ";" });
try stack.append(RenderState { .Text = ";" });
if (var_decl.init_node) |init_node| {
%return stack.append(RenderState { .Expression = init_node });
%return stack.append(RenderState { .Text = " = " });
try stack.append(RenderState { .Expression = init_node });
try stack.append(RenderState { .Text = " = " });
}
if (var_decl.align_node) |align_node| {
%return stack.append(RenderState { .Text = ")" });
%return stack.append(RenderState { .Expression = align_node });
%return stack.append(RenderState { .Text = " align(" });
try stack.append(RenderState { .Text = ")" });
try stack.append(RenderState { .Expression = align_node });
try stack.append(RenderState { .Text = " align(" });
}
if (var_decl.type_node) |type_node| {
%return stream.print(": ");
%return stack.append(RenderState { .Expression = type_node });
try stream.print(": ");
try stack.append(RenderState { .Expression = type_node });
}
},
RenderState.ParamDecl => |base| {
const param_decl = @fieldParentPtr(ast.NodeParamDecl, "base", base);
if (param_decl.comptime_token) |comptime_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
}
if (param_decl.noalias_token) |noalias_token| {
%return stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token));
try stream.print("{} ", self.tokenizer.getTokenSlice(noalias_token));
}
if (param_decl.name_token) |name_token| {
%return stream.print("{}: ", self.tokenizer.getTokenSlice(name_token));
try stream.print("{}: ", self.tokenizer.getTokenSlice(name_token));
}
if (param_decl.var_args_token) |var_args_token| {
%return stream.print("{}", self.tokenizer.getTokenSlice(var_args_token));
try stream.print("{}", self.tokenizer.getTokenSlice(var_args_token));
} else {
%return stack.append(RenderState { .Expression = param_decl.type_node});
try stack.append(RenderState { .Expression = param_decl.type_node});
}
},
RenderState.Text => |bytes| {
%return stream.write(bytes);
try stream.write(bytes);
},
RenderState.Expression => |base| switch (base.id) {
ast.Node.Id.Identifier => {
const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base);
%return stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token));
try stream.print("{}", self.tokenizer.getTokenSlice(identifier.name_token));
},
ast.Node.Id.Block => {
const block = @fieldParentPtr(ast.NodeBlock, "base", base);
%return stream.write("{");
%return stack.append(RenderState { .Text = "}"});
%return stack.append(RenderState.PrintIndent);
%return stack.append(RenderState { .Indent = indent});
%return stack.append(RenderState { .Text = "\n"});
try stream.write("{");
try stack.append(RenderState { .Text = "}"});
try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { .Indent = indent});
try stack.append(RenderState { .Text = "\n"});
var i = block.statements.len;
while (i != 0) {
i -= 1;
const statement_node = block.statements.items[i];
%return stack.append(RenderState { .Statement = statement_node});
%return stack.append(RenderState.PrintIndent);
%return stack.append(RenderState { .Indent = indent + indent_delta});
%return stack.append(RenderState { .Text = "\n" });
try stack.append(RenderState { .Statement = statement_node});
try stack.append(RenderState.PrintIndent);
try stack.append(RenderState { .Indent = indent + indent_delta});
try stack.append(RenderState { .Text = "\n" });
}
},
ast.Node.Id.InfixOp => {
const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);
%return stack.append(RenderState { .Expression = prefix_op_node.rhs });
try stack.append(RenderState { .Expression = prefix_op_node.rhs });
switch (prefix_op_node.op) {
ast.NodeInfixOp.InfixOp.EqualEqual => {
%return stack.append(RenderState { .Text = " == "});
try stack.append(RenderState { .Text = " == "});
},
ast.NodeInfixOp.InfixOp.BangEqual => {
%return stack.append(RenderState { .Text = " != "});
try stack.append(RenderState { .Text = " != "});
},
else => unreachable,
}
%return stack.append(RenderState { .Expression = prefix_op_node.lhs });
try stack.append(RenderState { .Expression = prefix_op_node.lhs });
},
ast.Node.Id.PrefixOp => {
const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base);
%return stack.append(RenderState { .Expression = prefix_op_node.rhs });
try stack.append(RenderState { .Expression = prefix_op_node.rhs });
switch (prefix_op_node.op) {
ast.NodePrefixOp.PrefixOp.Return => {
%return stream.write("return ");
try stream.write("return ");
},
ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| {
%return stream.write("&");
try stream.write("&");
if (addr_of_info.volatile_token != null) {
%return stack.append(RenderState { .Text = "volatile "});
try stack.append(RenderState { .Text = "volatile "});
}
if (addr_of_info.const_token != null) {
%return stack.append(RenderState { .Text = "const "});
try stack.append(RenderState { .Text = "const "});
}
if (addr_of_info.align_expr) |align_expr| {
%return stream.print("align(");
%return stack.append(RenderState { .Text = ") "});
%return stack.append(RenderState { .Expression = align_expr});
try stream.print("align(");
try stack.append(RenderState { .Text = ") "});
try stack.append(RenderState { .Expression = align_expr});
}
},
else => unreachable,
@ -1026,42 +1026,42 @@ pub const Parser = struct {
},
ast.Node.Id.IntegerLiteral => {
const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base);
%return stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));
try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));
},
ast.Node.Id.FloatLiteral => {
const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base);
%return stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token));
try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token));
},
else => unreachable,
},
RenderState.FnProtoRParen => |fn_proto| {
%return stream.print(")");
try stream.print(")");
if (fn_proto.align_expr != null) {
@panic("TODO");
}
if (fn_proto.return_type) |return_type| {
%return stream.print(" -> ");
try stream.print(" -> ");
if (fn_proto.body_node) |body_node| {
%return stack.append(RenderState { .Expression = body_node});
%return stack.append(RenderState { .Text = " "});
try stack.append(RenderState { .Expression = body_node});
try stack.append(RenderState { .Text = " "});
}
%return stack.append(RenderState { .Expression = return_type});
try stack.append(RenderState { .Expression = return_type});
}
},
RenderState.Statement => |base| {
switch (base.id) {
ast.Node.Id.VarDecl => {
const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base);
%return stack.append(RenderState { .VarDecl = var_decl});
try stack.append(RenderState { .VarDecl = var_decl});
},
else => {
%return stack.append(RenderState { .Text = ";"});
%return stack.append(RenderState { .Expression = base});
try stack.append(RenderState { .Text = ";"});
try stack.append(RenderState { .Expression = base});
},
}
},
RenderState.Indent => |new_indent| indent = new_indent,
RenderState.PrintIndent => %return stream.writeByteNTimes(' ', indent),
RenderState.PrintIndent => try stream.writeByteNTimes(' ', indent),
}
}
}
@ -1096,12 +1096,12 @@ fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
defer parser.deinit();
const root_node = %return parser.parse();
const root_node = try parser.parse();
defer parser.freeAst(root_node);
var buffer = %return std.Buffer.initSize(allocator, 0);
var buffer = try std.Buffer.initSize(allocator, 0);
var buffer_out_stream = io.BufferOutStream.init(&buffer);
%return parser.renderSource(&buffer_out_stream.stream, root_node);
try parser.renderSource(&buffer_out_stream.stream, root_node);
return buffer.toOwnedSlice();
}

View File

@ -85,7 +85,7 @@ static const char *visib_mod_string(VisibMod mod) {
static const char *return_string(ReturnKind kind) {
switch (kind) {
case ReturnKindUnconditional: return "return";
case ReturnKindError: return "%return";
case ReturnKindError: return "try";
}
zig_unreachable();
}

View File

@ -225,6 +225,7 @@ static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index);
static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bool mandatory);
static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index);
static void ast_expect_token(ParseContext *pc, Token *token, TokenId token_id) {
if (token->id == token_id) {
@ -1003,25 +1004,21 @@ static AstNode *ast_parse_addr_of(ParseContext *pc, size_t *token_index) {
/*
PrefixOpExpression : PrefixOp PrefixOpExpression | SuffixOpExpression
PrefixOp = "!" | "-" | "~" | "*" | ("&" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%"
PrefixOp = "!" | "-" | "~" | "*" | ("&amp;" option("align" "(" Expression option(":" Integer ":" Integer) ")" ) option("const") option("volatile")) | "?" | "%" | "%%" | "??" | "-%" | "try"
*/
static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
if (token->id == TokenIdAmpersand) {
return ast_parse_addr_of(pc, token_index);
}
if (token->id == TokenIdKeywordTry) {
return ast_parse_try_expr(pc, token_index);
}
PrefixOp prefix_op = tok_to_prefix_op(token);
if (prefix_op == PrefixOpInvalid) {
return ast_parse_suffix_op_expr(pc, token_index, mandatory);
}
if (prefix_op == PrefixOpError || prefix_op == PrefixOpMaybe) {
Token *maybe_return = &pc->tokens->at(*token_index + 1);
if (maybe_return->id == TokenIdKeywordReturn) {
return ast_parse_return_expr(pc, token_index);
}
}
*token_index += 1;
@ -1438,38 +1435,41 @@ static AstNode *ast_parse_if_try_test_expr(ParseContext *pc, size_t *token_index
}
/*
ReturnExpression : option("%") "return" option(Expression)
ReturnExpression : "return" option(Expression)
*/
static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index) {
Token *token = &pc->tokens->at(*token_index);
NodeType node_type;
ReturnKind kind;
if (token->id == TokenIdPercent) {
Token *next_token = &pc->tokens->at(*token_index + 1);
if (next_token->id == TokenIdKeywordReturn) {
kind = ReturnKindError;
node_type = NodeTypeReturnExpr;
*token_index += 2;
} else {
return nullptr;
}
} else if (token->id == TokenIdKeywordReturn) {
kind = ReturnKindUnconditional;
node_type = NodeTypeReturnExpr;
*token_index += 1;
} else {
if (token->id != TokenIdKeywordReturn) {
return nullptr;
}
*token_index += 1;
AstNode *node = ast_create_node(pc, node_type, token);
node->data.return_expr.kind = kind;
AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);
node->data.return_expr.kind = ReturnKindUnconditional;
node->data.return_expr.expr = ast_parse_expression(pc, token_index, false);
return node;
}
/*
TryExpression : "try" Expression
*/
static AstNode *ast_parse_try_expr(ParseContext *pc, size_t *token_index) {
Token *token = &pc->tokens->at(*token_index);
if (token->id != TokenIdKeywordTry) {
return nullptr;
}
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeReturnExpr, token);
node->data.return_expr.kind = ReturnKindError;
node->data.return_expr.expr = ast_parse_expression(pc, token_index, true);
return node;
}
/*
BreakExpression = "break" option(":" Symbol) option(Expression)
*/
@ -2124,7 +2124,7 @@ static AstNode *ast_parse_block_or_expression(ParseContext *pc, size_t *token_in
}
/*
Expression = ReturnExpression | BreakExpression | AssignmentExpression
Expression = TryExpression | ReturnExpression | BreakExpression | AssignmentExpression
*/
static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@ -2133,6 +2133,10 @@ static AstNode *ast_parse_expression(ParseContext *pc, size_t *token_index, bool
if (return_expr)
return return_expr;
AstNode *try_expr = ast_parse_try_expr(pc, token_index);
if (try_expr)
return try_expr;
AstNode *break_expr = ast_parse_break_expr(pc, token_index);
if (break_expr)
return break_expr;

View File

@ -141,6 +141,7 @@ static const struct ZigKeyword zig_keywords[] = {
{"test", TokenIdKeywordTest},
{"this", TokenIdKeywordThis},
{"true", TokenIdKeywordTrue},
{"try", TokenIdKeywordTry},
{"undefined", TokenIdKeywordUndefined},
{"union", TokenIdKeywordUnion},
{"unreachable", TokenIdKeywordUnreachable},
@ -1541,6 +1542,7 @@ const char * token_name(TokenId id) {
case TokenIdKeywordTest: return "test";
case TokenIdKeywordThis: return "this";
case TokenIdKeywordTrue: return "true";
case TokenIdKeywordTry: return "try";
case TokenIdKeywordUndefined: return "undefined";
case TokenIdKeywordUnion: return "union";
case TokenIdKeywordUnreachable: return "unreachable";

View File

@ -80,6 +80,7 @@ enum TokenId {
TokenIdKeywordTest,
TokenIdKeywordThis,
TokenIdKeywordTrue,
TokenIdKeywordTry,
TokenIdKeywordUndefined,
TokenIdKeywordUnion,
TokenIdKeywordUnreachable,

View File

@ -60,18 +60,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
}
pub fn append(l: &Self, item: &const T) -> %void {
const new_item_ptr = %return l.addOne();
const new_item_ptr = try l.addOne();
*new_item_ptr = *item;
}
pub fn appendSlice(l: &Self, items: []align(A) const T) -> %void {
%return l.ensureCapacity(l.len + items.len);
try l.ensureCapacity(l.len + items.len);
mem.copy(T, l.items[l.len..], items);
l.len += items.len;
}
pub fn resize(l: &Self, new_len: usize) -> %void {
%return l.ensureCapacity(new_len);
try l.ensureCapacity(new_len);
l.len = new_len;
}
@ -87,12 +87,12 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) -> type{
better_capacity += better_capacity / 2 + 8;
if (better_capacity >= new_capacity) break;
}
l.items = %return l.allocator.alignedRealloc(T, A, l.items, better_capacity);
l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
}
pub fn addOne(l: &Self) -> %&T {
const new_length = l.len + 1;
%return l.ensureCapacity(new_length);
try l.ensureCapacity(new_length);
const result = &l.items[l.len];
l.len = new_length;
return result;

View File

@ -379,37 +379,37 @@ test "base64" {
}
fn testBase64() -> %void {
%return testAllApis("", "");
%return testAllApis("f", "Zg==");
%return testAllApis("fo", "Zm8=");
%return testAllApis("foo", "Zm9v");
%return testAllApis("foob", "Zm9vYg==");
%return testAllApis("fooba", "Zm9vYmE=");
%return testAllApis("foobar", "Zm9vYmFy");
try testAllApis("", "");
try testAllApis("f", "Zg==");
try testAllApis("fo", "Zm8=");
try testAllApis("foo", "Zm9v");
try testAllApis("foob", "Zm9vYg==");
try testAllApis("fooba", "Zm9vYmE=");
try testAllApis("foobar", "Zm9vYmFy");
%return testDecodeIgnoreSpace("", " ");
%return testDecodeIgnoreSpace("f", "Z g= =");
%return testDecodeIgnoreSpace("fo", " Zm8=");
%return testDecodeIgnoreSpace("foo", "Zm9v ");
%return testDecodeIgnoreSpace("foob", "Zm9vYg = = ");
%return testDecodeIgnoreSpace("fooba", "Zm9v YmE=");
%return testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y ");
try testDecodeIgnoreSpace("", " ");
try testDecodeIgnoreSpace("f", "Z g= =");
try testDecodeIgnoreSpace("fo", " Zm8=");
try testDecodeIgnoreSpace("foo", "Zm9v ");
try testDecodeIgnoreSpace("foob", "Zm9vYg = = ");
try testDecodeIgnoreSpace("fooba", "Zm9v YmE=");
try testDecodeIgnoreSpace("foobar", " Z m 9 v Y m F y ");
// test getting some api errors
%return testError("A", error.InvalidPadding);
%return testError("AA", error.InvalidPadding);
%return testError("AAA", error.InvalidPadding);
%return testError("A..A", error.InvalidCharacter);
%return testError("AA=A", error.InvalidCharacter);
%return testError("AA/=", error.InvalidPadding);
%return testError("A/==", error.InvalidPadding);
%return testError("A===", error.InvalidCharacter);
%return testError("====", error.InvalidCharacter);
try testError("A", error.InvalidPadding);
try testError("AA", error.InvalidPadding);
try testError("AAA", error.InvalidPadding);
try testError("A..A", error.InvalidCharacter);
try testError("AA=A", error.InvalidCharacter);
try testError("AA/=", error.InvalidPadding);
try testError("A/==", error.InvalidPadding);
try testError("A===", error.InvalidCharacter);
try testError("====", error.InvalidCharacter);
%return testOutputTooSmallError("AA==");
%return testOutputTooSmallError("AAA=");
%return testOutputTooSmallError("AAAA");
%return testOutputTooSmallError("AAAAAA==");
try testOutputTooSmallError("AA==");
try testOutputTooSmallError("AAA=");
try testOutputTooSmallError("AAAA");
try testOutputTooSmallError("AAAAAA==");
}
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %void {
@ -424,8 +424,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v
// Base64Decoder
{
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..%return standard_decoder.calcSize(expected_encoded)];
%return standard_decoder.decode(decoded, expected_encoded);
var decoded = buffer[0..try standard_decoder.calcSize(expected_encoded)];
try standard_decoder.decode(decoded, expected_encoded);
assert(mem.eql(u8, decoded, expected_decoded));
}
@ -434,8 +434,8 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) -> %v
const standard_decoder_ignore_nothing = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, "");
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];
var written = %return standard_decoder_ignore_nothing.decode(decoded, expected_encoded);
var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(expected_encoded.len)];
var written = try standard_decoder_ignore_nothing.decode(decoded, expected_encoded);
assert(written <= decoded.len);
assert(mem.eql(u8, decoded[0..written], expected_decoded));
}
@ -453,8 +453,8 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) -> %
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
var decoded = buffer[0..%return Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];
var written = %return standard_decoder_ignore_space.decode(decoded, encoded);
var decoded = buffer[0..try Base64DecoderWithIgnore.calcSizeUpperBound(encoded.len)];
var written = try standard_decoder_ignore_space.decode(decoded, encoded);
assert(mem.eql(u8, decoded[0..written], expected_decoded));
}

View File

@ -29,16 +29,16 @@ pub const BufMap = struct {
pub fn set(self: &BufMap, key: []const u8, value: []const u8) -> %void {
if (self.hash_map.get(key)) |entry| {
const value_copy = %return self.copy(value);
const value_copy = try self.copy(value);
%defer self.free(value_copy);
_ = %return self.hash_map.put(key, value_copy);
_ = try self.hash_map.put(key, value_copy);
self.free(entry.value);
} else {
const key_copy = %return self.copy(key);
const key_copy = try self.copy(key);
%defer self.free(key_copy);
const value_copy = %return self.copy(value);
const value_copy = try self.copy(value);
%defer self.free(value_copy);
_ = %return self.hash_map.put(key_copy, value_copy);
_ = try self.hash_map.put(key_copy, value_copy);
}
}
@ -68,7 +68,7 @@ pub const BufMap = struct {
}
fn copy(self: &BufMap, value: []const u8) -> %[]const u8 {
const result = %return self.hash_map.allocator.alloc(u8, value.len);
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;
}

View File

@ -26,9 +26,9 @@ pub const BufSet = struct {
pub fn put(self: &BufSet, key: []const u8) -> %void {
if (self.hash_map.get(key) == null) {
const key_copy = %return self.copy(key);
const key_copy = try self.copy(key);
%defer self.free(key_copy);
_ = %return self.hash_map.put(key_copy, {});
_ = try self.hash_map.put(key_copy, {});
}
}
@ -56,7 +56,7 @@ pub const BufSet = struct {
}
fn copy(self: &BufSet, value: []const u8) -> %[]const u8 {
const result = %return self.hash_map.allocator.alloc(u8, value.len);
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;
}

View File

@ -13,7 +13,7 @@ pub const Buffer = struct {
/// Must deinitialize with deinit.
pub fn init(allocator: &Allocator, m: []const u8) -> %Buffer {
var self = %return initSize(allocator, m.len);
var self = try initSize(allocator, m.len);
mem.copy(u8, self.list.items, m);
return self;
}
@ -21,7 +21,7 @@ pub const Buffer = struct {
/// Must deinitialize with deinit.
pub fn initSize(allocator: &Allocator, size: usize) -> %Buffer {
var self = initNull(allocator);
%return self.resize(size);
try self.resize(size);
return self;
}
@ -81,7 +81,7 @@ pub const Buffer = struct {
}
pub fn resize(self: &Buffer, new_len: usize) -> %void {
%return self.list.resize(new_len + 1);
try self.list.resize(new_len + 1);
self.list.items[self.len()] = 0;
}
@ -95,7 +95,7 @@ pub const Buffer = struct {
pub fn append(self: &Buffer, m: []const u8) -> %void {
const old_len = self.len();
%return self.resize(old_len + m.len);
try self.resize(old_len + m.len);
mem.copy(u8, self.list.toSlice()[old_len..], m);
}
@ -113,7 +113,7 @@ pub const Buffer = struct {
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) -> %void {
var prev_size: usize = self.len();
const new_size = prev_size + count;
%return self.resize(new_size);
try self.resize(new_size);
var i: usize = prev_size;
while (i < new_size) : (i += 1) {
@ -138,7 +138,7 @@ pub const Buffer = struct {
}
pub fn replaceContents(self: &const Buffer, m: []const u8) -> %void {
%return self.resize(m.len);
try self.resize(m.len);
mem.copy(u8, self.list.toSlice(), m);
}

View File

@ -250,13 +250,13 @@ pub const Builder = struct {
%%wanted_steps.append(&self.default_step);
} else {
for (step_names) |step_name| {
const s = %return self.getTopLevelStepByName(step_name);
const s = try self.getTopLevelStepByName(step_name);
%%wanted_steps.append(s);
}
}
for (wanted_steps.toSliceConst()) |s| {
%return self.makeOneStep(s);
try self.makeOneStep(s);
}
}
@ -310,7 +310,7 @@ pub const Builder = struct {
s.loop_flag = false;
%return s.make();
try s.make();
}
fn getTopLevelStepByName(self: &Builder, name: []const u8) -> %&Step {
@ -680,7 +680,7 @@ pub const Builder = struct {
if (os.path.isAbsolute(name)) {
return name;
}
const full_path = %return os.path.join(self.allocator, search_prefix, "bin",
const full_path = try os.path.join(self.allocator, search_prefix, "bin",
self.fmt("{}{}", name, exe_extension));
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
@ -696,7 +696,7 @@ pub const Builder = struct {
}
var it = mem.split(PATH, []u8{os.path.delimiter});
while (it.next()) |path| {
const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension));
const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension));
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
@ -710,7 +710,7 @@ pub const Builder = struct {
return name;
}
for (paths) |path| {
const full_path = %return os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension));
const full_path = try os.path.join(self.allocator, path, self.fmt("{}{}", name, exe_extension));
if (os.path.real(self.allocator, full_path)) |real_path| {
return real_path;
} else |_| {
@ -1345,10 +1345,10 @@ pub const LibExeObjStep = struct {
}
}
%return builder.spawnChild(zig_args.toSliceConst());
try builder.spawnChild(zig_args.toSliceConst());
if (self.kind == Kind.Lib and !self.static and self.target.wantSharedLibSymLinks()) {
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
self.name_only_filename);
}
}
@ -1423,7 +1423,7 @@ pub const LibExeObjStep = struct {
self.appendCompileFlags(&cc_args);
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
},
Kind.Lib => {
for (self.source_files.toSliceConst()) |source_file| {
@ -1440,14 +1440,14 @@ pub const LibExeObjStep = struct {
const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file);
const cache_o_dir = os.path.dirname(cache_o_src);
%return builder.makePath(cache_o_dir);
try builder.makePath(cache_o_dir);
const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt());
%%cc_args.append("-o");
%%cc_args.append(builder.pathFromRoot(cache_o_file));
self.appendCompileFlags(&cc_args);
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
%%self.object_files.append(cache_o_file);
}
@ -1466,14 +1466,14 @@ pub const LibExeObjStep = struct {
%%cc_args.append(builder.pathFromRoot(object_file));
}
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
// ranlib
%%cc_args.resize(0);
%%cc_args.append("ranlib");
%%cc_args.append(output_path);
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
} else {
%%cc_args.resize(0);
%%cc_args.append(cc);
@ -1537,10 +1537,10 @@ pub const LibExeObjStep = struct {
}
}
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
if (self.target.wantSharedLibSymLinks()) {
%return doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
try doAtomicSymLinks(builder.allocator, output_path, self.major_only_filename,
self.name_only_filename);
}
}
@ -1556,7 +1556,7 @@ pub const LibExeObjStep = struct {
const cache_o_src = %%os.path.join(builder.allocator, builder.cache_root, source_file);
const cache_o_dir = os.path.dirname(cache_o_src);
%return builder.makePath(cache_o_dir);
try builder.makePath(cache_o_dir);
const cache_o_file = builder.fmt("{}{}", cache_o_src, self.target.oFileExt());
%%cc_args.append("-o");
%%cc_args.append(builder.pathFromRoot(cache_o_file));
@ -1570,7 +1570,7 @@ pub const LibExeObjStep = struct {
%%cc_args.append(builder.pathFromRoot(dir));
}
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
%%self.object_files.append(cache_o_file);
}
@ -1619,7 +1619,7 @@ pub const LibExeObjStep = struct {
}
}
%return builder.spawnChild(cc_args.toSliceConst());
try builder.spawnChild(cc_args.toSliceConst());
},
}
}
@ -1770,7 +1770,7 @@ pub const TestStep = struct {
%%zig_args.append(lib_path);
}
%return builder.spawnChild(zig_args.toSliceConst());
try builder.spawnChild(zig_args.toSliceConst());
}
};
@ -1847,9 +1847,9 @@ const InstallArtifactStep = struct {
LibExeObjStep.Kind.Exe => usize(0o755),
LibExeObjStep.Kind.Lib => if (self.artifact.static) usize(0o666) else usize(0o755),
};
%return builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);
try builder.copyFileMode(self.artifact.getOutputPath(), self.dest_file, mode);
if (self.artifact.kind == LibExeObjStep.Kind.Lib and !self.artifact.static) {
%return doAtomicSymLinks(builder.allocator, self.dest_file,
try doAtomicSymLinks(builder.allocator, self.dest_file,
self.artifact.major_only_filename, self.artifact.name_only_filename);
}
}
@ -1872,7 +1872,7 @@ pub const InstallFileStep = struct {
fn make(step: &Step) -> %void {
const self = @fieldParentPtr(InstallFileStep, "step", step);
%return self.builder.copyFile(self.src_path, self.dest_path);
try self.builder.copyFile(self.src_path, self.dest_path);
}
};
@ -1973,7 +1973,7 @@ pub const Step = struct {
if (self.done_flag)
return;
%return self.makeFn(self);
try self.makeFn(self);
self.done_flag = true;
}

View File

@ -43,7 +43,7 @@ fn testCStrFnsImpl() {
/// have a null byte after it.
/// Caller owns the returned memory.
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) -> %[]u8 {
const result = %return allocator.alloc(u8, slice.len + 1);
const result = try allocator.alloc(u8, slice.len + 1);
mem.copy(u8, result, slice);
result[slice.len] = 0;
return result;
@ -70,7 +70,7 @@ pub const NullTerminated2DArray = struct {
const index_size = @sizeOf(usize) * new_len; // size of the ptrs
byte_count += index_size;
const buf = %return allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
const buf = try allocator.alignedAlloc(u8, @alignOf(?&u8), byte_count);
%defer allocator.free(buf);
var write_index = index_size;

View File

@ -33,7 +33,7 @@ pub const FailingAllocator = struct {
if (self.index == self.fail_index) {
return error.OutOfMemory;
}
const result = %return self.internal_allocator.allocFn(self.internal_allocator, n, alignment);
const result = try self.internal_allocator.allocFn(self.internal_allocator, n, alignment);
self.allocated_bytes += result.len;
self.index += 1;
return result;
@ -48,7 +48,7 @@ pub const FailingAllocator = struct {
if (self.index == self.fail_index) {
return error.OutOfMemory;
}
const result = %return self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
const result = try self.internal_allocator.reallocFn(self.internal_allocator, old_mem, new_size, alignment);
self.allocated_bytes += new_size - old_mem.len;
self.deallocations += 1;
self.index += 1;

View File

@ -29,7 +29,7 @@ fn getStderrStream() -> %&io.OutStream {
if (stderr_stream) |st| {
return st;
} else {
stderr_file = %return io.getStdErr();
stderr_file = try io.getStdErr();
stderr_file_out_stream = io.FileOutStream.init(&stderr_file);
const st = &stderr_file_out_stream.stream;
stderr_stream = st;
@ -118,18 +118,18 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
.compile_unit_list = ArrayList(CompileUnit).init(allocator),
};
const st = &stack_trace;
st.self_exe_file = %return os.openSelfExe();
st.self_exe_file = try os.openSelfExe();
defer st.self_exe_file.close();
%return st.elf.openFile(allocator, &st.self_exe_file);
try st.elf.openFile(allocator, &st.self_exe_file);
defer st.elf.close();
st.debug_info = (%return st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
st.debug_abbrev = (%return st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
st.debug_str = (%return st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo;
st.debug_line = (%return st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo;
st.debug_ranges = (%return st.elf.findSection(".debug_ranges"));
%return scanAllCompileUnits(st);
st.debug_info = (try st.elf.findSection(".debug_info")) ?? return error.MissingDebugInfo;
st.debug_abbrev = (try st.elf.findSection(".debug_abbrev")) ?? return error.MissingDebugInfo;
st.debug_str = (try st.elf.findSection(".debug_str")) ?? return error.MissingDebugInfo;
st.debug_line = (try st.elf.findSection(".debug_line")) ?? return error.MissingDebugInfo;
st.debug_ranges = (try st.elf.findSection(".debug_ranges"));
try scanAllCompileUnits(st);
var ignored_count: usize = 0;
@ -147,25 +147,25 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}";
const compile_unit = findCompileUnit(st, return_address) %% {
%return out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",
try out_stream.print("???:?:?: " ++ DIM ++ ptr_hex ++ " in ??? (???)" ++ RESET ++ "\n ???\n\n",
return_address);
continue;
};
const compile_unit_name = %return compile_unit.die.getAttrString(st, DW.AT_name);
const compile_unit_name = try compile_unit.die.getAttrString(st, DW.AT_name);
if (getLineNumberInfo(st, compile_unit, usize(return_address) - 1)) |line_info| {
defer line_info.deinit();
%return out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++
try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++
DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n",
line_info.file_name, line_info.line, line_info.column,
return_address, compile_unit_name);
if (printLineFromFile(st.allocator(), out_stream, line_info)) {
if (line_info.column == 0) {
%return out_stream.write("\n");
try out_stream.write("\n");
} else {
{var col_i: usize = 1; while (col_i < line_info.column) : (col_i += 1) {
%return out_stream.writeByte(' ');
try out_stream.writeByte(' ');
}}
%return out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
try out_stream.write(GREEN ++ "^" ++ RESET ++ "\n");
}
} else |err| switch (err) {
error.EndOfFile, error.PathNotFound => {},
@ -173,7 +173,7 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
}
} else |err| switch (err) {
error.MissingDebugInfo, error.InvalidDebugInfo => {
%return out_stream.print(ptr_hex ++ " in ??? ({})\n",
try out_stream.print(ptr_hex ++ " in ??? ({})\n",
return_address, compile_unit_name);
},
else => return err,
@ -181,22 +181,22 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
}
},
builtin.ObjectFormat.coff => {
%return out_stream.write("(stack trace unavailable for COFF object format)\n");
try out_stream.write("(stack trace unavailable for COFF object format)\n");
},
builtin.ObjectFormat.macho => {
%return out_stream.write("(stack trace unavailable for Mach-O object format)\n");
try out_stream.write("(stack trace unavailable for Mach-O object format)\n");
},
builtin.ObjectFormat.wasm => {
%return out_stream.write("(stack trace unavailable for WASM object format)\n");
try out_stream.write("(stack trace unavailable for WASM object format)\n");
},
builtin.ObjectFormat.unknown => {
%return out_stream.write("(stack trace unavailable for unknown object format)\n");
try out_stream.write("(stack trace unavailable for unknown object format)\n");
},
}
}
fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_info: &const LineInfo) -> %void {
var f = %return io.File.openRead(line_info.file_name, allocator);
var f = try io.File.openRead(line_info.file_name, allocator);
defer f.close();
// TODO fstat and make sure that the file has the correct size
@ -205,12 +205,12 @@ fn printLineFromFile(allocator: &mem.Allocator, out_stream: &io.OutStream, line_
var column: usize = 1;
var abs_index: usize = 0;
while (true) {
const amt_read = %return f.read(buf[0..]);
const amt_read = try f.read(buf[0..]);
const slice = buf[0..amt_read];
for (slice) |byte| {
if (line == line_info.line) {
%return out_stream.writeByte(byte);
try out_stream.writeByte(byte);
if (byte == '\n') {
return;
}
@ -437,7 +437,7 @@ const LineNumberProgram = struct {
const dir_name = if (file_entry.dir_index >= self.include_dirs.len) {
return error.InvalidDebugInfo;
} else self.include_dirs[file_entry.dir_index];
const file_name = %return os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
const file_name = try os.path.join(self.file_entries.allocator, dir_name, file_entry.file_name);
%defer self.file_entries.allocator.free(file_name);
return LineInfo {
.line = if (self.prev_line >= 0) usize(self.prev_line) else 0,
@ -461,73 +461,73 @@ const LineNumberProgram = struct {
fn readStringRaw(allocator: &mem.Allocator, in_stream: &io.InStream) -> %[]u8 {
var buf = ArrayList(u8).init(allocator);
while (true) {
const byte = %return in_stream.readByte();
const byte = try in_stream.readByte();
if (byte == 0)
break;
%return buf.append(byte);
try buf.append(byte);
}
return buf.toSlice();
}
fn getString(st: &ElfStackTrace, offset: u64) -> %[]u8 {
const pos = st.debug_str.offset + offset;
%return st.self_exe_file.seekTo(pos);
try st.self_exe_file.seekTo(pos);
return st.readString();
}
fn readAllocBytes(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %[]u8 {
const buf = %return global_allocator.alloc(u8, size);
const buf = try global_allocator.alloc(u8, size);
%defer global_allocator.free(buf);
if ((%return in_stream.read(buf)) < size) return error.EndOfFile;
if ((try in_stream.read(buf)) < size) return error.EndOfFile;
return buf;
}
fn parseFormValueBlockLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
const buf = %return readAllocBytes(allocator, in_stream, size);
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue { .Block = buf };
}
fn parseFormValueBlock(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
const block_len = %return in_stream.readVarInt(builtin.Endian.Little, usize, size);
const block_len = try in_stream.readVarInt(builtin.Endian.Little, usize, size);
return parseFormValueBlockLen(allocator, in_stream, block_len);
}
fn parseFormValueConstant(allocator: &mem.Allocator, in_stream: &io.InStream, signed: bool, size: usize) -> %FormValue {
return FormValue { .Const = Constant {
.signed = signed,
.payload = %return readAllocBytes(allocator, in_stream, size),
.payload = try readAllocBytes(allocator, in_stream, size),
}};
}
fn parseFormValueDwarfOffsetSize(in_stream: &io.InStream, is_64: bool) -> %u64 {
return if (is_64) %return in_stream.readIntLe(u64)
else u64(%return in_stream.readIntLe(u32)) ;
return if (is_64) try in_stream.readIntLe(u64)
else u64(try in_stream.readIntLe(u32)) ;
}
fn parseFormValueTargetAddrSize(in_stream: &io.InStream) -> %u64 {
return if (@sizeOf(usize) == 4) u64(%return in_stream.readIntLe(u32))
else if (@sizeOf(usize) == 8) %return in_stream.readIntLe(u64)
return if (@sizeOf(usize) == 4) u64(try in_stream.readIntLe(u32))
else if (@sizeOf(usize) == 8) try in_stream.readIntLe(u64)
else unreachable;
}
fn parseFormValueRefLen(allocator: &mem.Allocator, in_stream: &io.InStream, size: usize) -> %FormValue {
const buf = %return readAllocBytes(allocator, in_stream, size);
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue { .Ref = buf };
}
fn parseFormValueRef(allocator: &mem.Allocator, in_stream: &io.InStream, comptime T: type) -> %FormValue {
const block_len = %return in_stream.readIntLe(T);
const block_len = try in_stream.readIntLe(T);
return parseFormValueRefLen(allocator, in_stream, block_len);
}
fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u64, is_64: bool) -> %FormValue {
return switch (form_id) {
DW.FORM_addr => FormValue { .Address = %return parseFormValueTargetAddrSize(in_stream) },
DW.FORM_addr => FormValue { .Address = try parseFormValueTargetAddrSize(in_stream) },
DW.FORM_block1 => parseFormValueBlock(allocator, in_stream, 1),
DW.FORM_block2 => parseFormValueBlock(allocator, in_stream, 2),
DW.FORM_block4 => parseFormValueBlock(allocator, in_stream, 4),
DW.FORM_block => x: {
const block_len = %return readULeb128(in_stream);
const block_len = try readULeb128(in_stream);
return parseFormValueBlockLen(allocator, in_stream, block_len);
},
DW.FORM_data1 => parseFormValueConstant(allocator, in_stream, false, 1),
@ -535,35 +535,35 @@ fn parseFormValue(allocator: &mem.Allocator, in_stream: &io.InStream, form_id: u
DW.FORM_data4 => parseFormValueConstant(allocator, in_stream, false, 4),
DW.FORM_data8 => parseFormValueConstant(allocator, in_stream, false, 8),
DW.FORM_udata, DW.FORM_sdata => {
const block_len = %return readULeb128(in_stream);
const block_len = try readULeb128(in_stream);
const signed = form_id == DW.FORM_sdata;
return parseFormValueConstant(allocator, in_stream, signed, block_len);
},
DW.FORM_exprloc => {
const size = %return readULeb128(in_stream);
const buf = %return readAllocBytes(allocator, in_stream, size);
const size = try readULeb128(in_stream);
const buf = try readAllocBytes(allocator, in_stream, size);
return FormValue { .ExprLoc = buf };
},
DW.FORM_flag => FormValue { .Flag = (%return in_stream.readByte()) != 0 },
DW.FORM_flag => FormValue { .Flag = (try in_stream.readByte()) != 0 },
DW.FORM_flag_present => FormValue { .Flag = true },
DW.FORM_sec_offset => FormValue { .SecOffset = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_sec_offset => FormValue { .SecOffset = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_ref1 => parseFormValueRef(allocator, in_stream, u8),
DW.FORM_ref2 => parseFormValueRef(allocator, in_stream, u16),
DW.FORM_ref4 => parseFormValueRef(allocator, in_stream, u32),
DW.FORM_ref8 => parseFormValueRef(allocator, in_stream, u64),
DW.FORM_ref_udata => {
const ref_len = %return readULeb128(in_stream);
const ref_len = try readULeb128(in_stream);
return parseFormValueRefLen(allocator, in_stream, ref_len);
},
DW.FORM_ref_addr => FormValue { .RefAddr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_ref_sig8 => FormValue { .RefSig8 = %return in_stream.readIntLe(u64) },
DW.FORM_ref_addr => FormValue { .RefAddr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_ref_sig8 => FormValue { .RefSig8 = try in_stream.readIntLe(u64) },
DW.FORM_string => FormValue { .String = %return readStringRaw(allocator, in_stream) },
DW.FORM_strp => FormValue { .StrPtr = %return parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_string => FormValue { .String = try readStringRaw(allocator, in_stream) },
DW.FORM_strp => FormValue { .StrPtr = try parseFormValueDwarfOffsetSize(in_stream, is_64) },
DW.FORM_indirect => {
const child_form_id = %return readULeb128(in_stream);
const child_form_id = try readULeb128(in_stream);
return parseFormValue(allocator, in_stream, child_form_id, is_64);
},
else => error.InvalidDebugInfo,
@ -576,23 +576,23 @@ fn parseAbbrevTable(st: &ElfStackTrace) -> %AbbrevTable {
const in_stream = &in_file_stream.stream;
var result = AbbrevTable.init(st.allocator());
while (true) {
const abbrev_code = %return readULeb128(in_stream);
const abbrev_code = try readULeb128(in_stream);
if (abbrev_code == 0)
return result;
%return result.append(AbbrevTableEntry {
try result.append(AbbrevTableEntry {
.abbrev_code = abbrev_code,
.tag_id = %return readULeb128(in_stream),
.has_children = (%return in_stream.readByte()) == DW.CHILDREN_yes,
.tag_id = try readULeb128(in_stream),
.has_children = (try in_stream.readByte()) == DW.CHILDREN_yes,
.attrs = ArrayList(AbbrevAttr).init(st.allocator()),
});
const attrs = &result.items[result.len - 1].attrs;
while (true) {
const attr_id = %return readULeb128(in_stream);
const form_id = %return readULeb128(in_stream);
const attr_id = try readULeb128(in_stream);
const form_id = try readULeb128(in_stream);
if (attr_id == 0 and form_id == 0)
break;
%return attrs.append(AbbrevAttr {
try attrs.append(AbbrevAttr {
.attr_id = attr_id,
.form_id = form_id,
});
@ -608,10 +608,10 @@ fn getAbbrevTable(st: &ElfStackTrace, abbrev_offset: u64) -> %&const AbbrevTable
return &header.table;
}
}
%return st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);
%return st.abbrev_table_list.append(AbbrevTableHeader {
try st.self_exe_file.seekTo(st.debug_abbrev.offset + abbrev_offset);
try st.abbrev_table_list.append(AbbrevTableHeader {
.offset = abbrev_offset,
.table = %return parseAbbrevTable(st),
.table = try parseAbbrevTable(st),
});
return &st.abbrev_table_list.items[st.abbrev_table_list.len - 1].table;
}
@ -628,7 +628,7 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -
const in_file = &st.self_exe_file;
var in_file_stream = io.FileInStream.init(in_file);
const in_stream = &in_file_stream.stream;
const abbrev_code = %return readULeb128(in_stream);
const abbrev_code = try readULeb128(in_stream);
const table_entry = getAbbrevTableEntry(abbrev_table, abbrev_code) ?? return error.InvalidDebugInfo;
var result = Die {
@ -636,18 +636,18 @@ fn parseDie(st: &ElfStackTrace, abbrev_table: &const AbbrevTable, is_64: bool) -
.has_children = table_entry.has_children,
.attrs = ArrayList(Die.Attr).init(st.allocator()),
};
%return result.attrs.resize(table_entry.attrs.len);
try result.attrs.resize(table_entry.attrs.len);
for (table_entry.attrs.toSliceConst()) |attr, i| {
result.attrs.items[i] = Die.Attr {
.id = attr.attr_id,
.value = %return parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),
.value = try parseFormValue(st.allocator(), in_stream, attr.form_id, is_64),
};
}
return result;
}
fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, target_address: usize) -> %LineInfo {
const compile_unit_cwd = %return compile_unit.die.getAttrString(st, DW.AT_comp_dir);
const compile_unit_cwd = try compile_unit.die.getAttrString(st, DW.AT_comp_dir);
const in_file = &st.self_exe_file;
const debug_line_end = st.debug_line.offset + st.debug_line.size;
@ -658,10 +658,10 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
const in_stream = &in_file_stream.stream;
while (this_offset < debug_line_end) : (this_index += 1) {
%return in_file.seekTo(this_offset);
try in_file.seekTo(this_offset);
var is_64: bool = undefined;
const unit_length = %return readInitialLength(in_stream, &is_64);
const unit_length = try readInitialLength(in_stream, &is_64);
if (unit_length == 0)
return error.MissingDebugInfo;
const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
@ -671,37 +671,37 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
continue;
}
const version = %return in_stream.readInt(st.elf.endian, u16);
const version = try in_stream.readInt(st.elf.endian, u16);
if (version != 2) return error.InvalidDebugInfo;
const prologue_length = %return in_stream.readInt(st.elf.endian, u32);
const prog_start_offset = (%return in_file.getPos()) + prologue_length;
const prologue_length = try in_stream.readInt(st.elf.endian, u32);
const prog_start_offset = (try in_file.getPos()) + prologue_length;
const minimum_instruction_length = %return in_stream.readByte();
const minimum_instruction_length = try in_stream.readByte();
if (minimum_instruction_length == 0) return error.InvalidDebugInfo;
const default_is_stmt = (%return in_stream.readByte()) != 0;
const line_base = %return in_stream.readByteSigned();
const default_is_stmt = (try in_stream.readByte()) != 0;
const line_base = try in_stream.readByteSigned();
const line_range = %return in_stream.readByte();
const line_range = try in_stream.readByte();
if (line_range == 0)
return error.InvalidDebugInfo;
const opcode_base = %return in_stream.readByte();
const opcode_base = try in_stream.readByte();
const standard_opcode_lengths = %return st.allocator().alloc(u8, opcode_base - 1);
const standard_opcode_lengths = try st.allocator().alloc(u8, opcode_base - 1);
{var i: usize = 0; while (i < opcode_base - 1) : (i += 1) {
standard_opcode_lengths[i] = %return in_stream.readByte();
standard_opcode_lengths[i] = try in_stream.readByte();
}}
var include_directories = ArrayList([]u8).init(st.allocator());
%return include_directories.append(compile_unit_cwd);
try include_directories.append(compile_unit_cwd);
while (true) {
const dir = %return st.readString();
const dir = try st.readString();
if (dir.len == 0)
break;
%return include_directories.append(dir);
try include_directories.append(dir);
}
var file_entries = ArrayList(FileEntry).init(st.allocator());
@ -709,13 +709,13 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
&file_entries, target_address);
while (true) {
const file_name = %return st.readString();
const file_name = try st.readString();
if (file_name.len == 0)
break;
const dir_index = %return readULeb128(in_stream);
const mtime = %return readULeb128(in_stream);
const len_bytes = %return readULeb128(in_stream);
%return file_entries.append(FileEntry {
const dir_index = try readULeb128(in_stream);
const mtime = try readULeb128(in_stream);
const len_bytes = try readULeb128(in_stream);
try file_entries.append(FileEntry {
.file_name = file_name,
.dir_index = dir_index,
.mtime = mtime,
@ -723,33 +723,33 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
});
}
%return in_file.seekTo(prog_start_offset);
try in_file.seekTo(prog_start_offset);
while (true) {
const opcode = %return in_stream.readByte();
const opcode = try in_stream.readByte();
var sub_op: u8 = undefined; // TODO move this to the correct scope and fix the compiler crash
if (opcode == DW.LNS_extended_op) {
const op_size = %return readULeb128(in_stream);
const op_size = try readULeb128(in_stream);
if (op_size < 1)
return error.InvalidDebugInfo;
sub_op = %return in_stream.readByte();
sub_op = try in_stream.readByte();
switch (sub_op) {
DW.LNE_end_sequence => {
prog.end_sequence = true;
if (%return prog.checkLineMatch()) |info| return info;
if (try prog.checkLineMatch()) |info| return info;
return error.MissingDebugInfo;
},
DW.LNE_set_address => {
const addr = %return in_stream.readInt(st.elf.endian, usize);
const addr = try in_stream.readInt(st.elf.endian, usize);
prog.address = addr;
},
DW.LNE_define_file => {
const file_name = %return st.readString();
const dir_index = %return readULeb128(in_stream);
const mtime = %return readULeb128(in_stream);
const len_bytes = %return readULeb128(in_stream);
%return file_entries.append(FileEntry {
const file_name = try st.readString();
const dir_index = try readULeb128(in_stream);
const mtime = try readULeb128(in_stream);
const len_bytes = try readULeb128(in_stream);
try file_entries.append(FileEntry {
.file_name = file_name,
.dir_index = dir_index,
.mtime = mtime,
@ -758,7 +758,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
},
else => {
const fwd_amt = math.cast(isize, op_size - 1) %% return error.InvalidDebugInfo;
%return in_file.seekForward(fwd_amt);
try in_file.seekForward(fwd_amt);
},
}
} else if (opcode >= opcode_base) {
@ -768,28 +768,28 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
const inc_line = i32(line_base) + i32(adjusted_opcode % line_range);
prog.line += inc_line;
prog.address += inc_addr;
if (%return prog.checkLineMatch()) |info| return info;
if (try prog.checkLineMatch()) |info| return info;
prog.basic_block = false;
} else {
switch (opcode) {
DW.LNS_copy => {
if (%return prog.checkLineMatch()) |info| return info;
if (try prog.checkLineMatch()) |info| return info;
prog.basic_block = false;
},
DW.LNS_advance_pc => {
const arg = %return readULeb128(in_stream);
const arg = try readULeb128(in_stream);
prog.address += arg * minimum_instruction_length;
},
DW.LNS_advance_line => {
const arg = %return readILeb128(in_stream);
const arg = try readILeb128(in_stream);
prog.line += arg;
},
DW.LNS_set_file => {
const arg = %return readULeb128(in_stream);
const arg = try readULeb128(in_stream);
prog.file = arg;
},
DW.LNS_set_column => {
const arg = %return readULeb128(in_stream);
const arg = try readULeb128(in_stream);
prog.column = arg;
},
DW.LNS_negate_stmt => {
@ -803,7 +803,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
prog.address += inc_addr;
},
DW.LNS_fixed_advance_pc => {
const arg = %return in_stream.readInt(st.elf.endian, u16);
const arg = try in_stream.readInt(st.elf.endian, u16);
prog.address += arg;
},
DW.LNS_set_prologue_end => {
@ -812,7 +812,7 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
if (opcode - 1 >= standard_opcode_lengths.len)
return error.InvalidDebugInfo;
const len_bytes = standard_opcode_lengths[opcode - 1];
%return in_file.seekForward(len_bytes);
try in_file.seekForward(len_bytes);
},
}
}
@ -833,31 +833,31 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
const in_stream = &in_file_stream.stream;
while (this_unit_offset < debug_info_end) {
%return st.self_exe_file.seekTo(this_unit_offset);
try st.self_exe_file.seekTo(this_unit_offset);
var is_64: bool = undefined;
const unit_length = %return readInitialLength(in_stream, &is_64);
const unit_length = try readInitialLength(in_stream, &is_64);
if (unit_length == 0)
return;
const next_offset = unit_length + (if (is_64) usize(12) else usize(4));
const version = %return in_stream.readInt(st.elf.endian, u16);
const version = try in_stream.readInt(st.elf.endian, u16);
if (version < 2 or version > 5) return error.InvalidDebugInfo;
const debug_abbrev_offset =
if (is_64) %return in_stream.readInt(st.elf.endian, u64)
else %return in_stream.readInt(st.elf.endian, u32);
if (is_64) try in_stream.readInt(st.elf.endian, u64)
else try in_stream.readInt(st.elf.endian, u32);
const address_size = %return in_stream.readByte();
const address_size = try in_stream.readByte();
if (address_size != @sizeOf(usize)) return error.InvalidDebugInfo;
const compile_unit_pos = %return st.self_exe_file.getPos();
const abbrev_table = %return getAbbrevTable(st, debug_abbrev_offset);
const compile_unit_pos = try st.self_exe_file.getPos();
const abbrev_table = try getAbbrevTable(st, debug_abbrev_offset);
%return st.self_exe_file.seekTo(compile_unit_pos);
try st.self_exe_file.seekTo(compile_unit_pos);
const compile_unit_die = %return st.allocator().create(Die);
*compile_unit_die = %return parseDie(st, abbrev_table, is_64);
const compile_unit_die = try st.allocator().create(Die);
*compile_unit_die = try parseDie(st, abbrev_table, is_64);
if (compile_unit_die.tag_id != DW.TAG_compile_unit)
return error.InvalidDebugInfo;
@ -868,7 +868,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
const pc_end = switch (*high_pc_value) {
FormValue.Address => |value| value,
FormValue.Const => |value| b: {
const offset = %return value.asUnsignedLe();
const offset = try value.asUnsignedLe();
break :b (low_pc + offset);
},
else => return error.InvalidDebugInfo,
@ -887,7 +887,7 @@ fn scanAllCompileUnits(st: &ElfStackTrace) -> %void {
}
};
%return st.compile_unit_list.append(CompileUnit {
try st.compile_unit_list.append(CompileUnit {
.version = version,
.is_64 = is_64,
.pc_range = pc_range,
@ -911,10 +911,10 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
if (compile_unit.die.getAttrSecOffset(DW.AT_ranges)) |ranges_offset| {
var base_address: usize = 0;
if (st.debug_ranges) |debug_ranges| {
%return st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset);
try st.self_exe_file.seekTo(debug_ranges.offset + ranges_offset);
while (true) {
const begin_addr = %return in_stream.readIntLe(usize);
const end_addr = %return in_stream.readIntLe(usize);
const begin_addr = try in_stream.readIntLe(usize);
const end_addr = try in_stream.readIntLe(usize);
if (begin_addr == 0 and end_addr == 0) {
break;
}
@ -937,7 +937,7 @@ fn findCompileUnit(st: &ElfStackTrace, target_address: u64) -> %&const CompileUn
}
fn readInitialLength(in_stream: &io.InStream, is_64: &bool) -> %u64 {
const first_32_bits = %return in_stream.readIntLe(u32);
const first_32_bits = try in_stream.readIntLe(u32);
*is_64 = (first_32_bits == 0xffffffff);
if (*is_64) {
return in_stream.readIntLe(u64);
@ -952,7 +952,7 @@ fn readULeb128(in_stream: &io.InStream) -> %u64 {
var shift: usize = 0;
while (true) {
const byte = %return in_stream.readByte();
const byte = try in_stream.readByte();
var operand: u64 = undefined;
@ -973,7 +973,7 @@ fn readILeb128(in_stream: &io.InStream) -> %i64 {
var shift: usize = 0;
while (true) {
const byte = %return in_stream.readByte();
const byte = try in_stream.readByte();
var operand: i64 = undefined;

View File

@ -82,8 +82,8 @@ pub const Elf = struct {
/// Call close when done.
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) -> %void {
%return elf.prealloc_file.open(path);
%return elf.openFile(allocator, &elf.prealloc_file);
try elf.prealloc_file.open(path);
try elf.openFile(allocator, &elf.prealloc_file);
elf.auto_close_stream = true;
}
@ -97,28 +97,28 @@ pub const Elf = struct {
const in = &file_stream.stream;
var magic: [4]u8 = undefined;
%return in.readNoEof(magic[0..]);
try in.readNoEof(magic[0..]);
if (!mem.eql(u8, magic, "\x7fELF")) return error.InvalidFormat;
elf.is_64 = switch (%return in.readByte()) {
elf.is_64 = switch (try in.readByte()) {
1 => false,
2 => true,
else => return error.InvalidFormat,
};
elf.endian = switch (%return in.readByte()) {
elf.endian = switch (try in.readByte()) {
1 => builtin.Endian.Little,
2 => builtin.Endian.Big,
else => return error.InvalidFormat,
};
const version_byte = %return in.readByte();
const version_byte = try in.readByte();
if (version_byte != 1) return error.InvalidFormat;
// skip over padding
%return elf.in_file.seekForward(9);
try elf.in_file.seekForward(9);
elf.file_type = switch (%return in.readInt(elf.endian, u16)) {
elf.file_type = switch (try in.readInt(elf.endian, u16)) {
1 => FileType.Relocatable,
2 => FileType.Executable,
3 => FileType.Shared,
@ -126,7 +126,7 @@ pub const Elf = struct {
else => return error.InvalidFormat,
};
elf.arch = switch (%return in.readInt(elf.endian, u16)) {
elf.arch = switch (try in.readInt(elf.endian, u16)) {
0x02 => Arch.Sparc,
0x03 => Arch.x86,
0x08 => Arch.Mips,
@ -139,88 +139,88 @@ pub const Elf = struct {
else => return error.InvalidFormat,
};
const elf_version = %return in.readInt(elf.endian, u32);
const elf_version = try in.readInt(elf.endian, u32);
if (elf_version != 1) return error.InvalidFormat;
if (elf.is_64) {
elf.entry_addr = %return in.readInt(elf.endian, u64);
elf.program_header_offset = %return in.readInt(elf.endian, u64);
elf.section_header_offset = %return in.readInt(elf.endian, u64);
elf.entry_addr = try in.readInt(elf.endian, u64);
elf.program_header_offset = try in.readInt(elf.endian, u64);
elf.section_header_offset = try in.readInt(elf.endian, u64);
} else {
elf.entry_addr = u64(%return in.readInt(elf.endian, u32));
elf.program_header_offset = u64(%return in.readInt(elf.endian, u32));
elf.section_header_offset = u64(%return in.readInt(elf.endian, u32));
elf.entry_addr = u64(try in.readInt(elf.endian, u32));
elf.program_header_offset = u64(try in.readInt(elf.endian, u32));
elf.section_header_offset = u64(try in.readInt(elf.endian, u32));
}
// skip over flags
%return elf.in_file.seekForward(4);
try elf.in_file.seekForward(4);
const header_size = %return in.readInt(elf.endian, u16);
const header_size = try in.readInt(elf.endian, u16);
if ((elf.is_64 and header_size != 64) or
(!elf.is_64 and header_size != 52))
{
return error.InvalidFormat;
}
const ph_entry_size = %return in.readInt(elf.endian, u16);
const ph_entry_count = %return in.readInt(elf.endian, u16);
const sh_entry_size = %return in.readInt(elf.endian, u16);
const sh_entry_count = %return in.readInt(elf.endian, u16);
elf.string_section_index = u64(%return in.readInt(elf.endian, u16));
const ph_entry_size = try in.readInt(elf.endian, u16);
const ph_entry_count = try in.readInt(elf.endian, u16);
const sh_entry_size = try in.readInt(elf.endian, u16);
const sh_entry_count = try in.readInt(elf.endian, u16);
elf.string_section_index = u64(try in.readInt(elf.endian, u16));
if (elf.string_section_index >= sh_entry_count) return error.InvalidFormat;
const sh_byte_count = u64(sh_entry_size) * u64(sh_entry_count);
const end_sh = %return math.add(u64, elf.section_header_offset, sh_byte_count);
const end_sh = try math.add(u64, elf.section_header_offset, sh_byte_count);
const ph_byte_count = u64(ph_entry_size) * u64(ph_entry_count);
const end_ph = %return math.add(u64, elf.program_header_offset, ph_byte_count);
const end_ph = try math.add(u64, elf.program_header_offset, ph_byte_count);
const stream_end = %return elf.in_file.getEndPos();
const stream_end = try elf.in_file.getEndPos();
if (stream_end < end_sh or stream_end < end_ph) {
return error.InvalidFormat;
}
%return elf.in_file.seekTo(elf.section_header_offset);
try elf.in_file.seekTo(elf.section_header_offset);
elf.section_headers = %return elf.allocator.alloc(SectionHeader, sh_entry_count);
elf.section_headers = try elf.allocator.alloc(SectionHeader, sh_entry_count);
%defer elf.allocator.free(elf.section_headers);
if (elf.is_64) {
if (sh_entry_size != 64) return error.InvalidFormat;
for (elf.section_headers) |*elf_section| {
elf_section.name = %return in.readInt(elf.endian, u32);
elf_section.sh_type = %return in.readInt(elf.endian, u32);
elf_section.flags = %return in.readInt(elf.endian, u64);
elf_section.addr = %return in.readInt(elf.endian, u64);
elf_section.offset = %return in.readInt(elf.endian, u64);
elf_section.size = %return in.readInt(elf.endian, u64);
elf_section.link = %return in.readInt(elf.endian, u32);
elf_section.info = %return in.readInt(elf.endian, u32);
elf_section.addr_align = %return in.readInt(elf.endian, u64);
elf_section.ent_size = %return in.readInt(elf.endian, u64);
elf_section.name = try in.readInt(elf.endian, u32);
elf_section.sh_type = try in.readInt(elf.endian, u32);
elf_section.flags = try in.readInt(elf.endian, u64);
elf_section.addr = try in.readInt(elf.endian, u64);
elf_section.offset = try in.readInt(elf.endian, u64);
elf_section.size = try in.readInt(elf.endian, u64);
elf_section.link = try in.readInt(elf.endian, u32);
elf_section.info = try in.readInt(elf.endian, u32);
elf_section.addr_align = try in.readInt(elf.endian, u64);
elf_section.ent_size = try in.readInt(elf.endian, u64);
}
} else {
if (sh_entry_size != 40) return error.InvalidFormat;
for (elf.section_headers) |*elf_section| {
// TODO (multiple occurences) allow implicit cast from %u32 -> %u64 ?
elf_section.name = %return in.readInt(elf.endian, u32);
elf_section.sh_type = %return in.readInt(elf.endian, u32);
elf_section.flags = u64(%return in.readInt(elf.endian, u32));
elf_section.addr = u64(%return in.readInt(elf.endian, u32));
elf_section.offset = u64(%return in.readInt(elf.endian, u32));
elf_section.size = u64(%return in.readInt(elf.endian, u32));
elf_section.link = %return in.readInt(elf.endian, u32);
elf_section.info = %return in.readInt(elf.endian, u32);
elf_section.addr_align = u64(%return in.readInt(elf.endian, u32));
elf_section.ent_size = u64(%return in.readInt(elf.endian, u32));
elf_section.name = try in.readInt(elf.endian, u32);
elf_section.sh_type = try in.readInt(elf.endian, u32);
elf_section.flags = u64(try in.readInt(elf.endian, u32));
elf_section.addr = u64(try in.readInt(elf.endian, u32));
elf_section.offset = u64(try in.readInt(elf.endian, u32));
elf_section.size = u64(try in.readInt(elf.endian, u32));
elf_section.link = try in.readInt(elf.endian, u32);
elf_section.info = try in.readInt(elf.endian, u32);
elf_section.addr_align = u64(try in.readInt(elf.endian, u32));
elf_section.ent_size = u64(try in.readInt(elf.endian, u32));
}
}
for (elf.section_headers) |*elf_section| {
if (elf_section.sh_type != SHT_NOBITS) {
const file_end_offset = %return math.add(u64, elf_section.offset, elf_section.size);
const file_end_offset = try math.add(u64, elf_section.offset, elf_section.size);
if (stream_end < file_end_offset) return error.InvalidFormat;
}
}
@ -247,15 +247,15 @@ pub const Elf = struct {
if (elf_section.sh_type == SHT_NULL) continue;
const name_offset = elf.string_section.offset + elf_section.name;
%return elf.in_file.seekTo(name_offset);
try elf.in_file.seekTo(name_offset);
for (name) |expected_c| {
const target_c = %return in.readByte();
const target_c = try in.readByte();
if (target_c == 0 or expected_c != target_c) continue :section_loop;
}
{
const null_byte = %return in.readByte();
const null_byte = try in.readByte();
if (null_byte == 0) return elf_section;
}
}
@ -264,6 +264,6 @@ pub const Elf = struct {
}
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) -> %void {
%return elf.in_file.seekTo(elf_section.offset);
try elf.in_file.seekTo(elf_section.offset);
}
};

View File

@ -40,13 +40,13 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
State.Start => switch (c) {
'{' => {
if (start_index < i) {
%return output(context, fmt[start_index..i]);
try output(context, fmt[start_index..i]);
}
state = State.OpenBrace;
},
'}' => {
if (start_index < i) {
%return output(context, fmt[start_index..i]);
try output(context, fmt[start_index..i]);
}
state = State.CloseBrace;
},
@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
start_index = i;
},
'}' => {
%return formatValue(args[next_arg], context, output);
try formatValue(args[next_arg], context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -110,7 +110,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
},
State.Integer => switch (c) {
'}' => {
%return formatInt(args[next_arg], radix, uppercase, width, context, output);
try formatInt(args[next_arg], radix, uppercase, width, context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -124,7 +124,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
State.IntegerWidth => switch (c) {
'}' => {
width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
%return formatInt(args[next_arg], radix, uppercase, width, context, output);
try formatInt(args[next_arg], radix, uppercase, width, context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -134,7 +134,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
},
State.Float => switch (c) {
'}' => {
%return formatFloatDecimal(args[next_arg], 0, context, output);
try formatFloatDecimal(args[next_arg], 0, context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -148,7 +148,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
State.FloatWidth => switch (c) {
'}' => {
width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
%return formatFloatDecimal(args[next_arg], width, context, output);
try formatFloatDecimal(args[next_arg], width, context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -159,7 +159,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
State.BufWidth => switch (c) {
'}' => {
width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
%return formatBuf(args[next_arg], width, context, output);
try formatBuf(args[next_arg], width, context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -169,7 +169,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
},
State.Character => switch (c) {
'}' => {
%return formatAsciiChar(args[next_arg], context, output);
try formatAsciiChar(args[next_arg], context, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -187,7 +187,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
}
}
if (start_index < fmt.len) {
%return output(context, fmt[start_index..]);
try output(context, fmt[start_index..]);
}
}
@ -221,7 +221,7 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
}
},
builtin.TypeId.Error => {
%return output(context, "error.");
try output(context, "error.");
return output(context, @errorName(value));
},
builtin.TypeId.Pointer => {
@ -247,12 +247,12 @@ pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const
pub fn formatBuf(buf: []const u8, width: usize,
context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
{
%return output(context, buf);
try output(context, buf);
var leftover_padding = if (width > buf.len) (width - buf.len) else return;
const pad_byte: u8 = ' ';
while (leftover_padding > 0) : (leftover_padding -= 1) {
%return output(context, (&pad_byte)[0..1]);
try output(context, (&pad_byte)[0..1]);
}
}
@ -264,7 +264,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
return output(context, "NaN");
}
if (math.signbit(x)) {
%return output(context, "-");
try output(context, "-");
x = -x;
}
if (math.isPositiveInf(x)) {
@ -276,21 +276,21 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
var buffer: [32]u8 = undefined;
const float_decimal = errol3(x, buffer[0..]);
%return output(context, float_decimal.digits[0..1]);
%return output(context, ".");
try output(context, float_decimal.digits[0..1]);
try output(context, ".");
if (float_decimal.digits.len > 1) {
const num_digits = if (@typeOf(value) == f32)
math.min(usize(9), float_decimal.digits.len)
else
float_decimal.digits.len;
%return output(context, float_decimal.digits[1 .. num_digits]);
try output(context, float_decimal.digits[1 .. num_digits]);
} else {
%return output(context, "0");
try output(context, "0");
}
if (float_decimal.exp != 1) {
%return output(context, "e");
%return formatInt(float_decimal.exp - 1, 10, false, 0, context, output);
try output(context, "e");
try formatInt(float_decimal.exp - 1, 10, false, 0, context, output);
}
}
@ -302,7 +302,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
return output(context, "NaN");
}
if (math.signbit(x)) {
%return output(context, "-");
try output(context, "-");
x = -x;
}
if (math.isPositiveInf(x)) {
@ -317,8 +317,8 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
const num_left_digits = if (float_decimal.exp > 0) usize(float_decimal.exp) else 1;
%return output(context, float_decimal.digits[0 .. num_left_digits]);
%return output(context, ".");
try output(context, float_decimal.digits[0 .. num_left_digits]);
try output(context, ".");
if (float_decimal.digits.len > 1) {
const num_valid_digtis = if (@typeOf(value) == f32) math.min(usize(7), float_decimal.digits.len)
else
@ -328,9 +328,9 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
math.min(precision, (num_valid_digtis-num_left_digits))
else
num_valid_digtis - num_left_digits;
%return output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]);
try output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]);
} else {
%return output(context, "0");
try output(context, "0");
}
}
@ -351,7 +351,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
const uint = @IntType(false, @typeOf(value).bit_count);
if (value < 0) {
const minus_sign: u8 = '-';
%return output(context, (&minus_sign)[0..1]);
try output(context, (&minus_sign)[0..1]);
const new_value = uint(-(value + 1)) + 1;
const new_width = if (width == 0) 0 else (width - 1);
return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
@ -359,7 +359,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
return formatIntUnsigned(uint(value), base, uppercase, width, context, output);
} else {
const plus_sign: u8 = '+';
%return output(context, (&plus_sign)[0..1]);
try output(context, (&plus_sign)[0..1]);
const new_value = uint(value);
const new_width = if (width == 0) 0 else (width - 1);
return formatIntUnsigned(new_value, base, uppercase, new_width, context, output);
@ -391,7 +391,7 @@ fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
const zero_byte: u8 = '0';
var leftover_padding = padding - index;
while (true) {
%return output(context, (&zero_byte)[0..1]);
try output(context, (&zero_byte)[0..1]);
leftover_padding -= 1;
if (leftover_padding == 0)
break;
@ -428,7 +428,7 @@ pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) -> %T {
if (buf.len == 0)
return T(0);
if (buf[0] == '-') {
return math.negate(%return parseUnsigned(T, buf[1..], radix));
return math.negate(try parseUnsigned(T, buf[1..], radix));
} else if (buf[0] == '+') {
return parseUnsigned(T, buf[1..], radix);
} else {
@ -450,9 +450,9 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) -> %T {
var x: T = 0;
for (buf) |c| {
const digit = %return charToDigit(c, radix);
x = %return math.mul(T, x, radix);
x = %return math.add(T, x, digit);
const digit = try charToDigit(c, radix);
x = try math.mul(T, x, radix);
x = try math.add(T, x, digit);
}
return x;
@ -494,7 +494,7 @@ fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) -> %void {
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) -> %[]u8 {
var context = BufPrintContext { .remaining = buf, };
%return format(&context, bufPrintWrite, fmt, args);
try format(&context, bufPrintWrite, fmt, args);
return buf[0..buf.len - context.remaining.len];
}
@ -502,7 +502,7 @@ pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...
var size: usize = 0;
// Cannot fail because `countSize` cannot fail.
%%format(&size, countSize, fmt, args);
const buf = %return allocator.alloc(u8, size);
const buf = try allocator.alloc(u8, size);
return bufPrint(buf, fmt, args);
}

View File

@ -83,14 +83,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
/// Returns the value that was already there.
pub fn put(hm: &Self, key: K, value: &const V) -> %?V {
if (hm.entries.len == 0) {
%return hm.initCapacity(16);
try hm.initCapacity(16);
}
hm.incrementModificationCount();
// if we get too full (60%), double the capacity
if (hm.size * 5 >= hm.entries.len * 3) {
const old_entries = hm.entries;
%return hm.initCapacity(hm.entries.len * 2);
try hm.initCapacity(hm.entries.len * 2);
// dump all of the old elements into the new table
for (old_entries) |*old_entry| {
if (old_entry.used) {
@ -149,7 +149,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
}
fn initCapacity(hm: &Self, capacity: usize) -> %void {
hm.entries = %return hm.allocator.alloc(Entry, capacity);
hm.entries = try hm.allocator.alloc(Entry, capacity);
hm.size = 0;
hm.max_distance_from_start_index = 0;
for (hm.entries) |*entry| {

View File

@ -124,7 +124,7 @@ pub const IncrementingAllocator = struct {
if (new_size <= old_mem.len) {
return old_mem[0..new_size];
} else {
const result = %return alloc(allocator, new_size, alignment);
const result = try alloc(allocator, new_size, alignment);
mem.copy(u8, result, old_mem);
return result;
}

View File

@ -51,7 +51,7 @@ error EndOfFile;
pub fn getStdErr() -> %File {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
else if (is_posix)
system.STDERR_FILENO
else
@ -61,7 +61,7 @@ pub fn getStdErr() -> %File {
pub fn getStdOut() -> %File {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
else if (is_posix)
system.STDOUT_FILENO
else
@ -71,7 +71,7 @@ pub fn getStdOut() -> %File {
pub fn getStdIn() -> %File {
const handle = if (is_windows)
%return os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
else if (is_posix)
system.STDIN_FILENO
else
@ -131,10 +131,10 @@ pub const File = struct {
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) -> %File {
if (is_posix) {
const flags = system.O_LARGEFILE|system.O_RDONLY;
const fd = %return os.posixOpen(path, flags, 0, allocator);
const fd = try os.posixOpen(path, flags, 0, allocator);
return openHandle(fd);
} else if (is_windows) {
const handle = %return os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ,
const handle = try os.windowsOpen(path, system.GENERIC_READ, system.FILE_SHARE_READ,
system.OPEN_EXISTING, system.FILE_ATTRIBUTE_NORMAL, allocator);
return openHandle(handle);
} else {
@ -156,10 +156,10 @@ pub const File = struct {
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) -> %File {
if (is_posix) {
const flags = system.O_LARGEFILE|system.O_WRONLY|system.O_CREAT|system.O_CLOEXEC|system.O_TRUNC;
const fd = %return os.posixOpen(path, flags, mode, allocator);
const fd = try os.posixOpen(path, flags, mode, allocator);
return openHandle(fd);
} else if (is_windows) {
const handle = %return os.windowsOpen(path, system.GENERIC_WRITE,
const handle = try os.windowsOpen(path, system.GENERIC_WRITE,
system.FILE_SHARE_WRITE|system.FILE_SHARE_READ|system.FILE_SHARE_DELETE,
system.CREATE_ALWAYS, system.FILE_ATTRIBUTE_NORMAL, allocator);
return openHandle(handle);
@ -322,9 +322,9 @@ pub const File = struct {
fn write(self: &File, bytes: []const u8) -> %void {
if (is_posix) {
%return os.posixWrite(self.handle, bytes);
try os.posixWrite(self.handle, bytes);
} else if (is_windows) {
%return os.windowsWrite(self.handle, bytes);
try os.windowsWrite(self.handle, bytes);
} else {
@compileError("Unsupported OS");
}
@ -344,12 +344,12 @@ pub const InStream = struct {
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and
/// the contents read from the stream are lost.
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) -> %void {
%return buffer.resize(0);
try buffer.resize(0);
var actual_buf_len: usize = 0;
while (true) {
const dest_slice = buffer.toSlice()[actual_buf_len..];
const bytes_read = %return self.readFn(self, dest_slice);
const bytes_read = try self.readFn(self, dest_slice);
actual_buf_len += bytes_read;
if (bytes_read != dest_slice.len) {
@ -360,7 +360,7 @@ pub const InStream = struct {
const new_buf_size = math.min(max_size, actual_buf_len + os.page_size);
if (new_buf_size == actual_buf_len)
return error.StreamTooLong;
%return buffer.resize(new_buf_size);
try buffer.resize(new_buf_size);
}
}
@ -372,7 +372,7 @@ pub const InStream = struct {
var buf = Buffer.initNull(allocator);
defer buf.deinit();
%return self.readAllBuffer(&buf, max_size);
try self.readAllBuffer(&buf, max_size);
return buf.toOwnedSlice();
}
@ -381,10 +381,10 @@ pub const InStream = struct {
/// If `buffer.len()` would exceed `max_size`, `error.StreamTooLong` is returned and the contents
/// read from the stream so far are lost.
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) -> %void {
%return buf.resize(0);
try buf.resize(0);
while (true) {
var byte: u8 = %return self.readByte();
var byte: u8 = try self.readByte();
if (byte == delimiter) {
return;
@ -394,7 +394,7 @@ pub const InStream = struct {
return error.StreamTooLong;
}
%return buf.appendByte(byte);
try buf.appendByte(byte);
}
}
@ -408,7 +408,7 @@ pub const InStream = struct {
var buf = Buffer.initNull(allocator);
defer buf.deinit();
%return self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size);
try self.readUntilDelimiterBuffer(self, &buf, delimiter, max_size);
return buf.toOwnedSlice();
}
@ -421,20 +421,20 @@ pub const InStream = struct {
/// Same as `read` but end of stream returns `error.EndOfStream`.
pub fn readNoEof(self: &InStream, buf: []u8) -> %void {
const amt_read = %return self.read(buf);
const amt_read = try self.read(buf);
if (amt_read < buf.len) return error.EndOfStream;
}
/// Reads 1 byte from the stream or returns `error.EndOfStream`.
pub fn readByte(self: &InStream) -> %u8 {
var result: [1]u8 = undefined;
%return self.readNoEof(result[0..]);
try self.readNoEof(result[0..]);
return result[0];
}
/// Same as `readByte` except the returned byte is signed.
pub fn readByteSigned(self: &InStream) -> %i8 {
return @bitCast(i8, %return self.readByte());
return @bitCast(i8, try self.readByte());
}
pub fn readIntLe(self: &InStream, comptime T: type) -> %T {
@ -447,7 +447,7 @@ pub const InStream = struct {
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) -> %T {
var bytes: [@sizeOf(T)]u8 = undefined;
%return self.readNoEof(bytes[0..]);
try self.readNoEof(bytes[0..]);
return mem.readInt(bytes, T, endian);
}
@ -456,7 +456,7 @@ pub const InStream = struct {
assert(size <= 8);
var input_buf: [8]u8 = undefined;
const input_slice = input_buf[0..size];
%return self.readNoEof(input_slice);
try self.readNoEof(input_slice);
return mem.readInt(input_slice, T, endian);
}
@ -483,7 +483,7 @@ pub const OutStream = struct {
const slice = (&byte)[0..1];
var i: usize = 0;
while (i < n) : (i += 1) {
%return self.writeFn(self, slice);
try self.writeFn(self, slice);
}
}
};
@ -493,9 +493,9 @@ pub const OutStream = struct {
/// size buffer is too small, and the provided allocator is null, `error.NameTooLong` is returned.
/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) -> %void {
var file = %return File.openWrite(path, allocator);
var file = try File.openWrite(path, allocator);
defer file.close();
%return file.write(data);
try file.write(data);
}
/// On success, caller owns returned buffer.
@ -505,15 +505,15 @@ pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 {
/// On success, caller owns returned buffer.
/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 {
var file = %return File.openRead(path, allocator);
var file = try File.openRead(path, allocator);
defer file.close();
const size = %return file.getEndPos();
const buf = %return allocator.alloc(u8, size + extra_len);
const size = try file.getEndPos();
const buf = try allocator.alloc(u8, size + extra_len);
%defer allocator.free(buf);
var adapter = FileInStream.init(&file);
%return adapter.stream.readNoEof(buf[0..size]);
try adapter.stream.readNoEof(buf[0..size]);
return buf;
}
@ -565,11 +565,11 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) -> type {
// we can read more data from the unbuffered stream
if (dest_space < buffer_size) {
self.start_index = 0;
self.end_index = %return self.unbuffered_in_stream.read(self.buffer[0..]);
self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]);
} else {
// asking for so much data that buffering is actually less efficient.
// forward the request directly to the unbuffered stream
const amt_read = %return self.unbuffered_in_stream.read(dest[dest_index..]);
const amt_read = try self.unbuffered_in_stream.read(dest[dest_index..]);
return dest_index + amt_read;
}
} else {
@ -616,7 +616,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
if (self.index == 0)
return;
%return self.unbuffered_out_stream.write(self.buffer[0..self.index]);
try self.unbuffered_out_stream.write(self.buffer[0..self.index]);
self.index = 0;
}
@ -624,7 +624,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
const self = @fieldParentPtr(Self, "stream", out_stream);
if (bytes.len >= self.buffer.len) {
%return self.flush();
try self.flush();
return self.unbuffered_out_stream.write(bytes);
}
var src_index: usize = 0;
@ -636,7 +636,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) -> type {
self.index += copy_amt;
assert(self.index <= self.buffer.len);
if (self.index == self.buffer.len) {
%return self.flush();
try self.flush();
}
src_index += copy_amt;
}

View File

@ -188,7 +188,7 @@ pub fn LinkedList(comptime T: type) -> type {
/// Returns:
/// A pointer to the new node.
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) -> %&Node {
var node = %return list.allocateNode(allocator);
var node = try list.allocateNode(allocator);
*node = Node.init(data);
return node;
}

View File

@ -27,7 +27,7 @@ pub const Allocator = struct {
freeFn: fn (self: &Allocator, old_mem: []u8),
fn create(self: &Allocator, comptime T: type) -> %&T {
const slice = %return self.alloc(T, 1);
const slice = try self.alloc(T, 1);
return &slice[0];
}
@ -42,8 +42,8 @@ pub const Allocator = struct {
fn alignedAlloc(self: &Allocator, comptime T: type, comptime alignment: u29,
n: usize) -> %[]align(alignment) T
{
const byte_count = %return math.mul(usize, @sizeOf(T), n);
const byte_slice = %return self.allocFn(self, byte_count, alignment);
const byte_count = try math.mul(usize, @sizeOf(T), n);
const byte_slice = try self.allocFn(self, byte_count, alignment);
// This loop should get optimized out in ReleaseFast mode
for (byte_slice) |*byte| {
*byte = undefined;
@ -63,8 +63,8 @@ pub const Allocator = struct {
}
const old_byte_slice = ([]u8)(old_mem);
const byte_count = %return math.mul(usize, @sizeOf(T), n);
const byte_slice = %return self.reallocFn(self, old_byte_slice, byte_count, alignment);
const byte_count = try math.mul(usize, @sizeOf(T), n);
const byte_slice = try self.reallocFn(self, old_byte_slice, byte_count, alignment);
// This loop should get optimized out in ReleaseFast mode
for (byte_slice[old_byte_slice.len..]) |*byte| {
*byte = undefined;
@ -142,7 +142,7 @@ pub const FixedBufferAllocator = struct {
if (new_size <= old_mem.len) {
return old_mem[0..new_size];
} else {
const result = %return alloc(allocator, new_size, alignment);
const result = try alloc(allocator, new_size, alignment);
copy(u8, result, old_mem);
return result;
}
@ -198,7 +198,7 @@ pub fn eql(comptime T: type, a: []const T, b: []const T) -> bool {
/// Copies ::m to newly allocated memory. Caller is responsible to free it.
pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) -> %[]T {
const new_buf = %return allocator.alloc(T, m.len);
const new_buf = try allocator.alloc(T, m.len);
copy(T, new_buf, m);
return new_buf;
}
@ -425,7 +425,7 @@ pub fn join(allocator: &Allocator, sep: u8, strings: ...) -> %[]u8 {
}
}
const buf = %return allocator.alloc(u8, total_strings_len);
const buf = try allocator.alloc(u8, total_strings_len);
%defer allocator.free(buf);
var buf_index: usize = 0;

View File

@ -133,7 +133,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
pub fn connect(hostname: []const u8, port: u16) -> %Connection {
var addrs_buf: [1]Address = undefined;
const addrs_slice = %return lookup(hostname, addrs_buf[0..]);
const addrs_slice = try lookup(hostname, addrs_buf[0..]);
const main_addr = &addrs_slice[0];
return connectAddr(main_addr, port);

View File

@ -75,7 +75,7 @@ pub const ChildProcess = struct {
/// First argument in argv is the executable.
/// On success must call deinit.
pub fn init(argv: []const []const u8, allocator: &mem.Allocator) -> %&ChildProcess {
const child = %return allocator.create(ChildProcess);
const child = try allocator.create(ChildProcess);
%defer allocator.destroy(child);
*child = ChildProcess {
@ -104,7 +104,7 @@ pub const ChildProcess = struct {
}
pub fn setUserName(self: &ChildProcess, name: []const u8) -> %void {
const user_info = %return os.getUserInfo(name);
const user_info = try os.getUserInfo(name);
self.uid = user_info.uid;
self.gid = user_info.gid;
}
@ -120,7 +120,7 @@ pub const ChildProcess = struct {
}
pub fn spawnAndWait(self: &ChildProcess) -> %Term {
%return self.spawn();
try self.spawn();
return self.wait();
}
@ -200,7 +200,7 @@ pub const ChildProcess = struct {
child.cwd = cwd;
child.env_map = env_map;
%return child.spawn();
try child.spawn();
var stdout = Buffer.initNull(allocator);
var stderr = Buffer.initNull(allocator);
@ -210,11 +210,11 @@ pub const ChildProcess = struct {
var stdout_file_in_stream = io.FileInStream.init(&??child.stdout);
var stderr_file_in_stream = io.FileInStream.init(&??child.stderr);
%return stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
%return stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);
try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);
try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);
return ExecResult {
.term = %return child.wait(),
.term = try child.wait(),
.stdout = stdout.toOwnedSlice(),
.stderr = stderr.toOwnedSlice(),
};
@ -226,7 +226,7 @@ pub const ChildProcess = struct {
return term;
}
%return self.waitUnwrappedWindows();
try self.waitUnwrappedWindows();
return ??self.term;
}
@ -308,8 +308,8 @@ pub const ChildProcess = struct {
// pid potentially wrote an error. This way we can do a blocking
// read on the error pipe and either get @maxValue(ErrInt) (no error) or
// an error code.
%return writeIntFd(self.err_pipe[1], @maxValue(ErrInt));
const err_int = %return readIntFd(self.err_pipe[0]);
try writeIntFd(self.err_pipe[1], @maxValue(ErrInt));
const err_int = try readIntFd(self.err_pipe[0]);
// Here we potentially return the fork child's error
// from the parent pid.
if (err_int != @maxValue(ErrInt)) {
@ -335,18 +335,18 @@ pub const ChildProcess = struct {
// TODO atomically set a flag saying that we already did this
install_SIGCHLD_handler();
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) %return makePipe() else undefined;
const stdin_pipe = if (self.stdin_behavior == StdIo.Pipe) try makePipe() else undefined;
%defer if (self.stdin_behavior == StdIo.Pipe) { destroyPipe(stdin_pipe); };
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) %return makePipe() else undefined;
const stdout_pipe = if (self.stdout_behavior == StdIo.Pipe) try makePipe() else undefined;
%defer if (self.stdout_behavior == StdIo.Pipe) { destroyPipe(stdout_pipe); };
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) %return makePipe() else undefined;
const stderr_pipe = if (self.stderr_behavior == StdIo.Pipe) try makePipe() else undefined;
%defer if (self.stderr_behavior == StdIo.Pipe) { destroyPipe(stderr_pipe); };
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
const dev_null_fd = if (any_ignore)
%return os.posixOpen("/dev/null", posix.O_RDWR, 0, null)
try os.posixOpen("/dev/null", posix.O_RDWR, 0, null)
else
undefined
;
@ -359,14 +359,14 @@ pub const ChildProcess = struct {
break :x env_map;
} else x: {
we_own_env_map = true;
env_map_owned = %return os.getEnvMap(self.allocator);
env_map_owned = try os.getEnvMap(self.allocator);
break :x &env_map_owned;
};
defer { if (we_own_env_map) env_map_owned.deinit(); }
// This pipe is used to communicate errors between the time of fork
// and execve from the child process to the parent process.
const err_pipe = %return makePipe();
const err_pipe = try makePipe();
%defer destroyPipe(err_pipe);
block_SIGCHLD();
@ -452,14 +452,14 @@ pub const ChildProcess = struct {
self.stderr_behavior == StdIo.Ignore);
const nul_handle = if (any_ignore)
%return os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,
try os.windowsOpen("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ,
windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null)
else
undefined
;
defer { if (any_ignore) os.close(nul_handle); }
if (any_ignore) {
%return windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);
try windowsSetHandleInfo(nul_handle, windows.HANDLE_FLAG_INHERIT, 0);
}
@ -467,7 +467,7 @@ pub const ChildProcess = struct {
var g_hChildStd_IN_Wr: ?windows.HANDLE = null;
switch (self.stdin_behavior) {
StdIo.Pipe => {
%return windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr);
try windowsMakePipeIn(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, saAttr);
},
StdIo.Ignore => {
g_hChildStd_IN_Rd = nul_handle;
@ -485,7 +485,7 @@ pub const ChildProcess = struct {
var g_hChildStd_OUT_Wr: ?windows.HANDLE = null;
switch (self.stdout_behavior) {
StdIo.Pipe => {
%return windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr);
try windowsMakePipeOut(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, saAttr);
},
StdIo.Ignore => {
g_hChildStd_OUT_Wr = nul_handle;
@ -503,7 +503,7 @@ pub const ChildProcess = struct {
var g_hChildStd_ERR_Wr: ?windows.HANDLE = null;
switch (self.stderr_behavior) {
StdIo.Pipe => {
%return windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr);
try windowsMakePipeOut(&g_hChildStd_ERR_Rd, &g_hChildStd_ERR_Wr, saAttr);
},
StdIo.Ignore => {
g_hChildStd_ERR_Wr = nul_handle;
@ -517,7 +517,7 @@ pub const ChildProcess = struct {
}
%defer if (self.stdin_behavior == StdIo.Pipe) { windowsDestroyPipe(g_hChildStd_ERR_Rd, g_hChildStd_ERR_Wr); };
const cmd_line = %return windowsCreateCommandLine(self.allocator, self.argv);
const cmd_line = try windowsCreateCommandLine(self.allocator, self.argv);
defer self.allocator.free(cmd_line);
var siStartInfo = windows.STARTUPINFOA {
@ -544,7 +544,7 @@ pub const ChildProcess = struct {
var piProcInfo: windows.PROCESS_INFORMATION = undefined;
const cwd_slice = if (self.cwd) |cwd|
%return cstr.addNullByte(self.allocator, cwd)
try cstr.addNullByte(self.allocator, cwd)
else
null
;
@ -552,7 +552,7 @@ pub const ChildProcess = struct {
const cwd_ptr = if (cwd_slice) |cwd| cwd.ptr else null;
const maybe_envp_buf = if (self.env_map) |env_map|
%return os.createWindowsEnvBlock(self.allocator, env_map)
try os.createWindowsEnvBlock(self.allocator, env_map)
else
null
;
@ -563,11 +563,11 @@ pub const ChildProcess = struct {
// to match posix semantics
const app_name = x: {
if (self.cwd) |cwd| {
const resolved = %return os.path.resolve(self.allocator, cwd, self.argv[0]);
const resolved = try os.path.resolve(self.allocator, cwd, self.argv[0]);
defer self.allocator.free(resolved);
break :x %return cstr.addNullByte(self.allocator, resolved);
break :x try cstr.addNullByte(self.allocator, resolved);
} else {
break :x %return cstr.addNullByte(self.allocator, self.argv[0]);
break :x try cstr.addNullByte(self.allocator, self.argv[0]);
}
};
defer self.allocator.free(app_name);
@ -578,12 +578,12 @@ pub const ChildProcess = struct {
if (no_path_err != error.FileNotFound)
return no_path_err;
const PATH = %return os.getEnvVarOwned(self.allocator, "PATH");
const PATH = try os.getEnvVarOwned(self.allocator, "PATH");
defer self.allocator.free(PATH);
var it = mem.split(PATH, ";");
while (it.next()) |search_path| {
const joined_path = %return os.path.join(self.allocator, search_path, app_name);
const joined_path = try os.path.join(self.allocator, search_path, app_name);
defer self.allocator.free(joined_path);
if (windowsCreateProcess(joined_path.ptr, cmd_line.ptr, envp_ptr, cwd_ptr,
@ -625,10 +625,10 @@ pub const ChildProcess = struct {
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) -> %void {
switch (stdio) {
StdIo.Pipe => %return os.posixDup2(pipe_fd, std_fileno),
StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
StdIo.Close => os.close(std_fileno),
StdIo.Inherit => {},
StdIo.Ignore => %return os.posixDup2(dev_null_fd, std_fileno),
StdIo.Ignore => try os.posixDup2(dev_null_fd, std_fileno),
}
}
@ -656,35 +656,35 @@ fn windowsCreateProcess(app_name: &u8, cmd_line: &u8, envp_ptr: ?&u8, cwd_ptr: ?
/// Caller must dealloc.
/// Guarantees a null byte at result[result.len].
fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) -> %[]u8 {
var buf = %return Buffer.initSize(allocator, 0);
var buf = try Buffer.initSize(allocator, 0);
defer buf.deinit();
for (argv) |arg, arg_i| {
if (arg_i != 0)
%return buf.appendByte(' ');
try buf.appendByte(' ');
if (mem.indexOfAny(u8, arg, " \t\n\"") == null) {
%return buf.append(arg);
try buf.append(arg);
continue;
}
%return buf.appendByte('"');
try buf.appendByte('"');
var backslash_count: usize = 0;
for (arg) |byte| {
switch (byte) {
'\\' => backslash_count += 1,
'"' => {
%return buf.appendByteNTimes('\\', backslash_count * 2 + 1);
%return buf.appendByte('"');
try buf.appendByteNTimes('\\', backslash_count * 2 + 1);
try buf.appendByte('"');
backslash_count = 0;
},
else => {
%return buf.appendByteNTimes('\\', backslash_count);
%return buf.appendByte(byte);
try buf.appendByteNTimes('\\', backslash_count);
try buf.appendByte(byte);
backslash_count = 0;
},
}
}
%return buf.appendByteNTimes('\\', backslash_count * 2);
%return buf.appendByte('"');
try buf.appendByteNTimes('\\', backslash_count * 2);
try buf.appendByte('"');
}
return buf.toOwnedSlice();
@ -721,9 +721,9 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {
var rd_h: windows.HANDLE = undefined;
var wr_h: windows.HANDLE = undefined;
%return windowsMakePipe(&rd_h, &wr_h, sattr);
try windowsMakePipe(&rd_h, &wr_h, sattr);
%defer windowsDestroyPipe(rd_h, wr_h);
%return windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
try windowsSetHandleInfo(wr_h, windows.HANDLE_FLAG_INHERIT, 0);
*rd = rd_h;
*wr = wr_h;
}
@ -731,9 +731,9 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S
fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) -> %void {
var rd_h: windows.HANDLE = undefined;
var wr_h: windows.HANDLE = undefined;
%return windowsMakePipe(&rd_h, &wr_h, sattr);
try windowsMakePipe(&rd_h, &wr_h, sattr);
%defer windowsDestroyPipe(rd_h, wr_h);
%return windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
try windowsSetHandleInfo(rd_h, windows.HANDLE_FLAG_INHERIT, 0);
*rd = rd_h;
*wr = wr_h;
}

View File

@ -31,7 +31,7 @@ error CorruptPasswordFile;
// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`.
pub fn posixGetUserInfo(name: []const u8) -> %UserInfo {
var in_stream = %return io.InStream.open("/etc/passwd", null);
var in_stream = try io.InStream.open("/etc/passwd", null);
defer in_stream.close();
var buf: [os.page_size]u8 = undefined;
@ -41,7 +41,7 @@ pub fn posixGetUserInfo(name: []const u8) -> %UserInfo {
var gid: u32 = 0;
while (true) {
const amt_read = %return in_stream.read(buf[0..]);
const amt_read = try in_stream.read(buf[0..]);
for (buf[0..amt_read]) |byte| {
switch (state) {
State.Start => switch (byte) {

View File

@ -92,11 +92,11 @@ pub fn getRandomBytes(buf: []u8) -> %void {
return;
},
Os.macosx, Os.ios => {
const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC,
const fd = try posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC,
0, null);
defer close(fd);
%return posixRead(fd, buf);
try posixRead(fd, buf);
},
Os.windows => {
var hCryptProv: windows.HCRYPTPROV = undefined;
@ -256,7 +256,7 @@ pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Al
if (file_path.len < stack_buf.len) {
path0 = stack_buf[0..file_path.len + 1];
} else if (allocator) |a| {
path0 = %return a.alloc(u8, file_path.len + 1);
path0 = try a.alloc(u8, file_path.len + 1);
need_free = true;
} else {
return error.NameTooLong;
@ -314,14 +314,14 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
pub fn createNullDelimitedEnvMap(allocator: &Allocator, env_map: &const BufMap) -> %[]?&u8 {
const envp_count = env_map.count();
const envp_buf = %return allocator.alloc(?&u8, envp_count + 1);
const envp_buf = try allocator.alloc(?&u8, envp_count + 1);
mem.set(?&u8, envp_buf, null);
%defer freeNullDelimitedEnvMap(allocator, envp_buf);
{
var it = env_map.iterator();
var i: usize = 0;
while (it.next()) |pair| : (i += 1) {
const env_buf = %return allocator.alloc(u8, pair.key.len + pair.value.len + 2);
const env_buf = try allocator.alloc(u8, pair.key.len + pair.value.len + 2);
@memcpy(&env_buf[0], pair.key.ptr, pair.key.len);
env_buf[pair.key.len] = '=';
@memcpy(&env_buf[pair.key.len + 1], pair.value.ptr, pair.value.len);
@ -351,7 +351,7 @@ pub fn freeNullDelimitedEnvMap(allocator: &Allocator, envp_buf: []?&u8) {
pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
allocator: &Allocator) -> %void
{
const argv_buf = %return allocator.alloc(?&u8, argv.len + 1);
const argv_buf = try allocator.alloc(?&u8, argv.len + 1);
mem.set(?&u8, argv_buf, null);
defer {
for (argv_buf) |arg| {
@ -361,7 +361,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
allocator.free(argv_buf);
}
for (argv) |arg, i| {
const arg_buf = %return allocator.alloc(u8, arg.len + 1);
const arg_buf = try allocator.alloc(u8, arg.len + 1);
@memcpy(&arg_buf[0], arg.ptr, arg.len);
arg_buf[arg.len] = 0;
@ -369,7 +369,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
}
argv_buf[argv.len] = null;
const envp_buf = %return createNullDelimitedEnvMap(allocator, env_map);
const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);
defer freeNullDelimitedEnvMap(allocator, envp_buf);
const exe_path = argv[0];
@ -381,7 +381,7 @@ pub fn posixExecve(argv: []const []const u8, env_map: &const BufMap,
// PATH.len because it is >= the largest search_path
// +1 for the / to join the search path and exe_path
// +1 for the null terminating byte
const path_buf = %return allocator.alloc(u8, PATH.len + exe_path.len + 2);
const path_buf = try allocator.alloc(u8, PATH.len + exe_path.len + 2);
defer allocator.free(path_buf);
var it = mem.split(PATH, ":");
var seen_eacces = false;
@ -450,7 +450,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap {
i += 1; // skip over null byte
%return result.set(key, value);
try result.set(key, value);
}
} else {
for (posix_environ_raw) |ptr| {
@ -462,7 +462,7 @@ pub fn getEnvMap(allocator: &Allocator) -> %BufMap {
while (ptr[end_i] != 0) : (end_i += 1) {}
const value = ptr[line_i + 1..end_i];
%return result.set(key, value);
try result.set(key, value);
}
return result;
}
@ -490,14 +490,14 @@ error EnvironmentVariableNotFound;
/// Caller must free returned memory.
pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {
if (is_windows) {
const key_with_null = %return cstr.addNullByte(allocator, key);
const key_with_null = try cstr.addNullByte(allocator, key);
defer allocator.free(key_with_null);
var buf = %return allocator.alloc(u8, 256);
var buf = try allocator.alloc(u8, 256);
%defer allocator.free(buf);
while (true) {
const windows_buf_len = %return math.cast(windows.DWORD, buf.len);
const windows_buf_len = try math.cast(windows.DWORD, buf.len);
const result = windows.GetEnvironmentVariableA(key_with_null.ptr, buf.ptr, windows_buf_len);
if (result == 0) {
@ -509,7 +509,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {
}
if (result > buf.len) {
buf = %return allocator.realloc(u8, buf, result);
buf = try allocator.realloc(u8, buf, result);
continue;
}
@ -525,7 +525,7 @@ pub fn getEnvVarOwned(allocator: &mem.Allocator, key: []const u8) -> %[]u8 {
pub fn getCwd(allocator: &Allocator) -> %[]u8 {
switch (builtin.os) {
Os.windows => {
var buf = %return allocator.alloc(u8, 256);
var buf = try allocator.alloc(u8, 256);
%defer allocator.free(buf);
while (true) {
@ -539,7 +539,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
}
if (result > buf.len) {
buf = %return allocator.realloc(u8, buf, result);
buf = try allocator.realloc(u8, buf, result);
continue;
}
@ -547,12 +547,12 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
}
},
else => {
var buf = %return allocator.alloc(u8, 1024);
var buf = try allocator.alloc(u8, 1024);
%defer allocator.free(buf);
while (true) {
const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
if (err == posix.ERANGE) {
buf = %return allocator.realloc(u8, buf, buf.len * 2);
buf = try allocator.realloc(u8, buf, buf.len * 2);
continue;
} else if (err > 0) {
return unexpectedErrorPosix(err);
@ -578,9 +578,9 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
}
pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
const existing_with_null = %return cstr.addNullByte(allocator, existing_path);
const existing_with_null = try cstr.addNullByte(allocator, existing_path);
defer allocator.free(existing_with_null);
const new_with_null = %return cstr.addNullByte(allocator, new_path);
const new_with_null = try cstr.addNullByte(allocator, new_path);
defer allocator.free(new_with_null);
if (windows.CreateSymbolicLinkA(existing_with_null.ptr, new_with_null.ptr, 0) == 0) {
@ -592,7 +592,7 @@ pub fn symLinkWindows(allocator: &Allocator, existing_path: []const u8, new_path
}
pub fn symLinkPosix(allocator: &Allocator, existing_path: []const u8, new_path: []const u8) -> %void {
const full_buf = %return allocator.alloc(u8, existing_path.len + new_path.len + 2);
const full_buf = try allocator.alloc(u8, existing_path.len + new_path.len + 2);
defer allocator.free(full_buf);
const existing_buf = full_buf;
@ -638,11 +638,11 @@ pub fn atomicSymLink(allocator: &Allocator, existing_path: []const u8, new_path:
}
var rand_buf: [12]u8 = undefined;
const tmp_path = %return allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
const tmp_path = try allocator.alloc(u8, new_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
defer allocator.free(tmp_path);
mem.copy(u8, tmp_path[0..], new_path);
while (true) {
%return getRandomBytes(rand_buf[0..]);
try getRandomBytes(rand_buf[0..]);
b64_fs_encoder.encode(tmp_path[new_path.len..], rand_buf);
if (symLink(allocator, existing_path, tmp_path)) {
return rename(allocator, tmp_path, new_path);
@ -669,7 +669,7 @@ error FileNotFound;
error AccessDenied;
pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void {
const buf = %return allocator.alloc(u8, file_path.len + 1);
const buf = try allocator.alloc(u8, file_path.len + 1);
defer allocator.free(buf);
mem.copy(u8, buf, file_path);
@ -687,7 +687,7 @@ pub fn deleteFileWindows(allocator: &Allocator, file_path: []const u8) -> %void
}
pub fn deleteFilePosix(allocator: &Allocator, file_path: []const u8) -> %void {
const buf = %return allocator.alloc(u8, file_path.len + 1);
const buf = try allocator.alloc(u8, file_path.len + 1);
defer allocator.free(buf);
mem.copy(u8, buf, file_path);
@ -721,30 +721,30 @@ pub fn copyFile(allocator: &Allocator, source_path: []const u8, dest_path: []con
/// Guaranteed to be atomic.
pub fn copyFileMode(allocator: &Allocator, source_path: []const u8, dest_path: []const u8, mode: usize) -> %void {
var rand_buf: [12]u8 = undefined;
const tmp_path = %return allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
const tmp_path = try allocator.alloc(u8, dest_path.len + base64.Base64Encoder.calcSize(rand_buf.len));
defer allocator.free(tmp_path);
mem.copy(u8, tmp_path[0..], dest_path);
%return getRandomBytes(rand_buf[0..]);
try getRandomBytes(rand_buf[0..]);
b64_fs_encoder.encode(tmp_path[dest_path.len..], rand_buf);
var out_file = %return io.File.openWriteMode(tmp_path, mode, allocator);
var out_file = try io.File.openWriteMode(tmp_path, mode, allocator);
defer out_file.close();
%defer _ = deleteFile(allocator, tmp_path);
var in_file = %return io.File.openRead(source_path, allocator);
var in_file = try io.File.openRead(source_path, allocator);
defer in_file.close();
var buf: [page_size]u8 = undefined;
while (true) {
const amt = %return in_file.read(buf[0..]);
%return out_file.write(buf[0..amt]);
const amt = try in_file.read(buf[0..]);
try out_file.write(buf[0..amt]);
if (amt != buf.len)
return rename(allocator, tmp_path, dest_path);
}
}
pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8) -> %void {
const full_buf = %return allocator.alloc(u8, old_path.len + new_path.len + 2);
const full_buf = try allocator.alloc(u8, old_path.len + new_path.len + 2);
defer allocator.free(full_buf);
const old_buf = full_buf;
@ -797,7 +797,7 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {
}
pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {
const path_buf = %return cstr.addNullByte(allocator, dir_path);
const path_buf = try cstr.addNullByte(allocator, dir_path);
defer allocator.free(path_buf);
if (windows.CreateDirectoryA(path_buf.ptr, null) == 0) {
@ -811,7 +811,7 @@ pub fn makeDirWindows(allocator: &Allocator, dir_path: []const u8) -> %void {
}
pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {
const path_buf = %return cstr.addNullByte(allocator, dir_path);
const path_buf = try cstr.addNullByte(allocator, dir_path);
defer allocator.free(path_buf);
const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755));
@ -837,7 +837,7 @@ pub fn makeDirPosix(allocator: &Allocator, dir_path: []const u8) -> %void {
/// Calls makeDir recursively to make an entire path. Returns success if the path
/// already exists and is a directory.
pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {
const resolved_path = %return path.resolve(allocator, full_path);
const resolved_path = try path.resolve(allocator, full_path);
defer allocator.free(resolved_path);
var end_index: usize = resolved_path.len;
@ -875,7 +875,7 @@ pub fn makePath(allocator: &Allocator, full_path: []const u8) -> %void {
/// Returns ::error.DirNotEmpty if the directory is not empty.
/// To delete a directory recursively, see ::deleteTree
pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {
const path_buf = %return allocator.alloc(u8, dir_path.len + 1);
const path_buf = try allocator.alloc(u8, dir_path.len + 1);
defer allocator.free(path_buf);
mem.copy(u8, path_buf, dir_path);
@ -927,14 +927,14 @@ pub fn deleteTree(allocator: &Allocator, full_path: []const u8) -> %void {
var full_entry_buf = ArrayList(u8).init(allocator);
defer full_entry_buf.deinit();
while (%return dir.next()) |entry| {
%return full_entry_buf.resize(full_path.len + entry.name.len + 1);
while (try dir.next()) |entry| {
try full_entry_buf.resize(full_path.len + entry.name.len + 1);
const full_entry_path = full_entry_buf.toSlice();
mem.copy(u8, full_entry_path, full_path);
full_entry_path[full_path.len] = '/';
mem.copy(u8, full_entry_path[full_path.len + 1..], entry.name);
%return deleteTree(allocator, full_entry_path);
try deleteTree(allocator, full_entry_path);
}
}
return deleteDir(allocator, full_path);
@ -973,7 +973,7 @@ pub const Dir = struct {
};
pub fn open(allocator: &Allocator, dir_path: []const u8) -> %Dir {
const fd = %return posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);
const fd = try posixOpen(dir_path, posix.O_RDONLY|posix.O_DIRECTORY|posix.O_CLOEXEC, 0, allocator);
return Dir {
.allocator = allocator,
.fd = fd,
@ -994,7 +994,7 @@ pub const Dir = struct {
start_over: while (true) {
if (self.index >= self.end_index) {
if (self.buf.len == 0) {
self.buf = %return self.allocator.alloc(u8, page_size);
self.buf = try self.allocator.alloc(u8, page_size);
}
while (true) {
@ -1004,7 +1004,7 @@ pub const Dir = struct {
switch (err) {
posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable,
posix.EINVAL => {
self.buf = %return self.allocator.realloc(u8, self.buf, self.buf.len * 2);
self.buf = try self.allocator.realloc(u8, self.buf, self.buf.len * 2);
continue;
},
else => return unexpectedErrorPosix(err),
@ -1048,7 +1048,7 @@ pub const Dir = struct {
};
pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
const path_buf = %return allocator.alloc(u8, dir_path.len + 1);
const path_buf = try allocator.alloc(u8, dir_path.len + 1);
defer allocator.free(path_buf);
mem.copy(u8, path_buf, dir_path);
@ -1072,13 +1072,13 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
/// Read value of a symbolic link.
pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
const path_buf = %return allocator.alloc(u8, pathname.len + 1);
const path_buf = try allocator.alloc(u8, pathname.len + 1);
defer allocator.free(path_buf);
mem.copy(u8, path_buf, pathname);
path_buf[pathname.len] = 0;
var result_buf = %return allocator.alloc(u8, 1024);
var result_buf = try allocator.alloc(u8, 1024);
%defer allocator.free(result_buf);
while (true) {
const ret_val = posix.readlink(path_buf.ptr, result_buf.ptr, result_buf.len);
@ -1097,7 +1097,7 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
};
}
if (ret_val == result_buf.len) {
result_buf = %return allocator.realloc(u8, result_buf, result_buf.len * 2);
result_buf = try allocator.realloc(u8, result_buf, result_buf.len * 2);
continue;
}
return allocator.shrink(u8, result_buf, ret_val);
@ -1320,7 +1320,7 @@ pub const ArgIteratorWindows = struct {
}
fn internalNext(self: &ArgIteratorWindows, allocator: &Allocator) -> %[]u8 {
var buf = %return Buffer.initSize(allocator, 0);
var buf = try Buffer.initSize(allocator, 0);
defer buf.deinit();
var backslash_count: usize = 0;
@ -1330,34 +1330,34 @@ pub const ArgIteratorWindows = struct {
0 => return buf.toOwnedSlice(),
'"' => {
const quote_is_real = backslash_count % 2 == 0;
%return self.emitBackslashes(&buf, backslash_count / 2);
try self.emitBackslashes(&buf, backslash_count / 2);
backslash_count = 0;
if (quote_is_real) {
self.seen_quote_count += 1;
if (self.seen_quote_count == self.quote_count and self.seen_quote_count % 2 == 1) {
%return buf.appendByte('"');
try buf.appendByte('"');
}
} else {
%return buf.appendByte('"');
try buf.appendByte('"');
}
},
'\\' => {
backslash_count += 1;
},
' ', '\t' => {
%return self.emitBackslashes(&buf, backslash_count);
try self.emitBackslashes(&buf, backslash_count);
backslash_count = 0;
if (self.seen_quote_count % 2 == 1 and self.seen_quote_count != self.quote_count) {
%return buf.appendByte(byte);
try buf.appendByte(byte);
} else {
return buf.toOwnedSlice();
}
},
else => {
%return self.emitBackslashes(&buf, backslash_count);
try self.emitBackslashes(&buf, backslash_count);
backslash_count = 0;
%return buf.appendByte(byte);
try buf.appendByte(byte);
},
}
}
@ -1366,7 +1366,7 @@ pub const ArgIteratorWindows = struct {
fn emitBackslashes(self: &ArgIteratorWindows, buf: &Buffer, emit_count: usize) -> %void {
var i: usize = 0;
while (i < emit_count) : (i += 1) {
%return buf.appendByte('\\');
try buf.appendByte('\\');
}
}
@ -1430,24 +1430,24 @@ pub fn args() -> ArgIterator {
pub fn argsAlloc(allocator: &mem.Allocator) -> %[]const []u8 {
// TODO refactor to only make 1 allocation.
var it = args();
var contents = %return Buffer.initSize(allocator, 0);
var contents = try Buffer.initSize(allocator, 0);
defer contents.deinit();
var slice_list = ArrayList(usize).init(allocator);
defer slice_list.deinit();
while (it.next(allocator)) |arg_or_err| {
const arg = %return arg_or_err;
const arg = try arg_or_err;
defer allocator.free(arg);
%return contents.append(arg);
%return slice_list.append(arg.len);
try contents.append(arg);
try slice_list.append(arg.len);
}
const contents_slice = contents.toSliceConst();
const slice_sizes = slice_list.toSliceConst();
const slice_list_bytes = %return math.mul(usize, @sizeOf([]u8), slice_sizes.len);
const total_bytes = %return math.add(usize, slice_list_bytes, contents_slice.len);
const buf = %return allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
const slice_list_bytes = try math.mul(usize, @sizeOf([]u8), slice_sizes.len);
const total_bytes = try math.add(usize, slice_list_bytes, contents_slice.len);
const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
%defer allocator.free(buf);
const result_slice_list = ([][]u8)(buf[0..slice_list_bytes]);
@ -1560,10 +1560,10 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
return readLink(allocator, "/proc/self/exe");
},
Os.windows => {
var out_path = %return Buffer.initSize(allocator, 0xff);
var out_path = try Buffer.initSize(allocator, 0xff);
%defer out_path.deinit();
while (true) {
const dword_len = %return math.cast(windows.DWORD, out_path.len());
const dword_len = try math.cast(windows.DWORD, out_path.len());
const copied_amt = windows.GetModuleFileNameA(null, out_path.ptr(), dword_len);
if (copied_amt <= 0) {
const err = windows.GetLastError();
@ -1576,14 +1576,14 @@ pub fn selfExePath(allocator: &mem.Allocator) -> %[]u8 {
return out_path.toOwnedSlice();
}
const new_len = (out_path.len() << 1) | 0b1;
%return out_path.resize(new_len);
try out_path.resize(new_len);
}
},
Os.macosx, Os.ios => {
var u32_len: u32 = 0;
const ret1 = c._NSGetExecutablePath(undefined, &u32_len);
assert(ret1 != 0);
const bytes = %return allocator.alloc(u8, u32_len);
const bytes = try allocator.alloc(u8, u32_len);
%defer allocator.free(bytes);
const ret2 = c._NSGetExecutablePath(bytes.ptr, &u32_len);
assert(ret2 == 0);
@ -1602,13 +1602,13 @@ pub fn selfExeDirPath(allocator: &mem.Allocator) -> %[]u8 {
// the file path looks something like `/a/b/c/exe (deleted)`
// This path cannot be opened, but it's valid for determining the directory
// the executable was in when it was run.
const full_exe_path = %return readLink(allocator, "/proc/self/exe");
const full_exe_path = try readLink(allocator, "/proc/self/exe");
%defer allocator.free(full_exe_path);
const dir = path.dirname(full_exe_path);
return allocator.shrink(u8, full_exe_path, dir.len);
},
Os.windows, Os.macosx, Os.ios => {
const self_exe_path = %return selfExePath(allocator);
const self_exe_path = try selfExePath(allocator);
%defer allocator.free(self_exe_path);
const dirname = os.path.dirname(self_exe_path);
return allocator.shrink(u8, self_exe_path, dirname.len);

View File

@ -412,13 +412,13 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
if (have_abs_path) {
switch (have_drive_kind) {
WindowsPath.Kind.Drive => {
result = %return allocator.alloc(u8, max_size);
result = try allocator.alloc(u8, max_size);
mem.copy(u8, result, result_disk_designator);
result_index += result_disk_designator.len;
},
WindowsPath.Kind.NetworkShare => {
result = %return allocator.alloc(u8, max_size);
result = try allocator.alloc(u8, max_size);
var it = mem.split(paths[first_index], "/\\");
const server_name = ??it.next();
const other_name = ??it.next();
@ -438,10 +438,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
},
WindowsPath.Kind.None => {
assert(is_windows); // resolveWindows called on non windows can't use getCwd
const cwd = %return os.getCwd(allocator);
const cwd = try os.getCwd(allocator);
defer allocator.free(cwd);
const parsed_cwd = windowsParsePath(cwd);
result = %return allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);
result = try allocator.alloc(u8, max_size + parsed_cwd.disk_designator.len + 1);
mem.copy(u8, result, parsed_cwd.disk_designator);
result_index += parsed_cwd.disk_designator.len;
result_disk_designator = result[0..parsed_cwd.disk_designator.len];
@ -454,10 +454,10 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) -> %[]u8
} else {
assert(is_windows); // resolveWindows called on non windows can't use getCwd
// TODO call get cwd for the result_disk_designator instead of the global one
const cwd = %return os.getCwd(allocator);
const cwd = try os.getCwd(allocator);
defer allocator.free(cwd);
result = %return allocator.alloc(u8, max_size + cwd.len + 1);
result = try allocator.alloc(u8, max_size + cwd.len + 1);
mem.copy(u8, result, cwd);
result_index += cwd.len;
@ -542,12 +542,12 @@ pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) -> %[]u8 {
var result_index: usize = 0;
if (have_abs) {
result = %return allocator.alloc(u8, max_size);
result = try allocator.alloc(u8, max_size);
} else {
assert(!is_windows); // resolvePosix called on windows can't use getCwd
const cwd = %return os.getCwd(allocator);
const cwd = try os.getCwd(allocator);
defer allocator.free(cwd);
result = %return allocator.alloc(u8, max_size + cwd.len + 1);
result = try allocator.alloc(u8, max_size + cwd.len + 1);
mem.copy(u8, result, cwd);
result_index += cwd.len;
}
@ -899,11 +899,11 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u
}
pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 {
const resolved_from = %return resolveWindows(allocator, [][]const u8{from});
const resolved_from = try resolveWindows(allocator, [][]const u8{from});
defer allocator.free(resolved_from);
var clean_up_resolved_to = true;
const resolved_to = %return resolveWindows(allocator, [][]const u8{to});
const resolved_to = try resolveWindows(allocator, [][]const u8{to});
defer if (clean_up_resolved_to) allocator.free(resolved_to);
const parsed_from = windowsParsePath(resolved_from);
@ -942,7 +942,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
up_count += 1;
}
const up_index_end = up_count * "..\\".len;
const result = %return allocator.alloc(u8, up_index_end + to_rest.len);
const result = try allocator.alloc(u8, up_index_end + to_rest.len);
%defer allocator.free(result);
var result_index: usize = 0;
@ -972,10 +972,10 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
}
pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) -> %[]u8 {
const resolved_from = %return resolvePosix(allocator, [][]const u8{from});
const resolved_from = try resolvePosix(allocator, [][]const u8{from});
defer allocator.free(resolved_from);
const resolved_to = %return resolvePosix(allocator, [][]const u8{to});
const resolved_to = try resolvePosix(allocator, [][]const u8{to});
defer allocator.free(resolved_to);
var from_it = mem.split(resolved_from, "/");
@ -992,7 +992,7 @@ pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ->
up_count += 1;
}
const up_index_end = up_count * "../".len;
const result = %return allocator.alloc(u8, up_index_end + to_rest.len);
const result = try allocator.alloc(u8, up_index_end + to_rest.len);
%defer allocator.free(result);
var result_index: usize = 0;
@ -1080,7 +1080,7 @@ error InputOutput;
pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
switch (builtin.os) {
Os.windows => {
const pathname_buf = %return allocator.alloc(u8, pathname.len + 1);
const pathname_buf = try allocator.alloc(u8, pathname.len + 1);
defer allocator.free(pathname_buf);
mem.copy(u8, pathname_buf, pathname);
@ -1099,7 +1099,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
};
}
defer os.close(h_file);
var buf = %return allocator.alloc(u8, 256);
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;
@ -1116,7 +1116,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
}
if (result > buf.len) {
buf = %return allocator.realloc(u8, buf, result);
buf = try allocator.realloc(u8, buf, result);
continue;
}
@ -1140,10 +1140,10 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
Os.macosx, Os.ios => {
// TODO instead of calling the libc function here, port the implementation
// to Zig, and then remove the NameTooLong error possibility.
const pathname_buf = %return allocator.alloc(u8, pathname.len + 1);
const pathname_buf = try allocator.alloc(u8, pathname.len + 1);
defer allocator.free(pathname_buf);
const result_buf = %return allocator.alloc(u8, posix.PATH_MAX);
const result_buf = try allocator.alloc(u8, posix.PATH_MAX);
%defer allocator.free(result_buf);
mem.copy(u8, pathname_buf, pathname);
@ -1168,7 +1168,7 @@ pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
return allocator.shrink(u8, result_buf, cstr.len(result_buf.ptr));
},
Os.linux => {
const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator);
const fd = try os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator);
defer os.close(fd);
var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;

View File

@ -93,7 +93,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
if (file_path.len < stack_buf.len) {
path0 = stack_buf[0..file_path.len + 1];
} else if (allocator) |a| {
path0 = %return a.alloc(u8, file_path.len + 1);
path0 = try a.alloc(u8, file_path.len + 1);
need_free = true;
} else {
return error.NameTooLong;
@ -132,7 +132,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
}
break :x bytes_needed;
};
const result = %return allocator.alloc(u8, bytes_needed);
const result = try allocator.alloc(u8, bytes_needed);
%defer allocator.free(result);
var it = env_map.iterator();
@ -153,7 +153,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
error DllNotFound;
pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) -> %windows.HMODULE {
const padded_buff = %return cstr.addNullByte(allocator, dll_path);
const padded_buff = try cstr.addNullByte(allocator, dll_path);
defer allocator.free(padded_buff);
return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;
}

View File

@ -23,15 +23,15 @@ pub fn main() -> %void {
// skip my own exe name
_ = arg_it.skip();
const zig_exe = %return unwrapArg(arg_it.next(allocator) ?? {
const zig_exe = try unwrapArg(arg_it.next(allocator) ?? {
warn("Expected first argument to be path to zig compiler\n");
return error.InvalidArgs;
});
const build_root = %return unwrapArg(arg_it.next(allocator) ?? {
const build_root = try unwrapArg(arg_it.next(allocator) ?? {
warn("Expected second argument to be build root directory path\n");
return error.InvalidArgs;
});
const cache_root = %return unwrapArg(arg_it.next(allocator) ?? {
const cache_root = try unwrapArg(arg_it.next(allocator) ?? {
warn("Expected third argument to be cache root directory path\n");
return error.InvalidArgs;
});
@ -58,36 +58,36 @@ pub fn main() -> %void {
} else |err| err;
while (arg_it.next(allocator)) |err_or_arg| {
const arg = %return unwrapArg(err_or_arg);
const arg = try unwrapArg(err_or_arg);
if (mem.startsWith(u8, arg, "-D")) {
const option_contents = arg[2..];
if (option_contents.len == 0) {
warn("Expected option name after '-D'\n\n");
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
}
if (mem.indexOfScalar(u8, option_contents, '=')) |name_end| {
const option_name = option_contents[0..name_end];
const option_value = option_contents[name_end + 1..];
if (builder.addUserInputOption(option_name, option_value))
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
} else {
if (builder.addUserInputFlag(option_contents))
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
}
} else if (mem.startsWith(u8, arg, "-")) {
if (mem.eql(u8, arg, "--verbose")) {
builder.verbose = true;
} else if (mem.eql(u8, arg, "--help")) {
return usage(&builder, false, %return stdout_stream);
return usage(&builder, false, try stdout_stream);
} else if (mem.eql(u8, arg, "--prefix")) {
prefix = %return unwrapArg(arg_it.next(allocator) ?? {
prefix = try unwrapArg(arg_it.next(allocator) ?? {
warn("Expected argument after --prefix\n\n");
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
});
} else if (mem.eql(u8, arg, "--search-prefix")) {
const search_prefix = %return unwrapArg(arg_it.next(allocator) ?? {
const search_prefix = try unwrapArg(arg_it.next(allocator) ?? {
warn("Expected argument after --search-prefix\n\n");
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
});
builder.addSearchPrefix(search_prefix);
} else if (mem.eql(u8, arg, "--verbose-tokenize")) {
@ -104,7 +104,7 @@ pub fn main() -> %void {
builder.verbose_cimport = true;
} else {
warn("Unrecognized argument: {}\n\n", arg);
return usageAndErr(&builder, false, %return stderr_stream);
return usageAndErr(&builder, false, try stderr_stream);
}
} else {
%%targets.append(arg);
@ -115,11 +115,11 @@ pub fn main() -> %void {
root.build(&builder);
if (builder.validateUserInputDidItFail())
return usageAndErr(&builder, true, %return stderr_stream);
return usageAndErr(&builder, true, try stderr_stream);
builder.make(targets.toSliceConst()) %% |err| {
if (err == error.InvalidStepName) {
return usageAndErr(&builder, true, %return stderr_stream);
return usageAndErr(&builder, true, try stderr_stream);
}
return err;
};
@ -133,7 +133,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
}
// This usage text has to be synchronized with src/main.cpp
%return out_stream.print(
try out_stream.print(
\\Usage: {} build [steps] [options]
\\
\\Steps:
@ -142,10 +142,10 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
const allocator = builder.allocator;
for (builder.top_level_steps.toSliceConst()) |top_level_step| {
%return out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description);
try out_stream.print(" {s22} {}\n", top_level_step.step.name, top_level_step.description);
}
%return out_stream.write(
try out_stream.write(
\\
\\General Options:
\\ --help Print this help and exit
@ -158,17 +158,17 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream)
);
if (builder.available_options_list.len == 0) {
%return out_stream.print(" (none)\n");
try out_stream.print(" (none)\n");
} else {
for (builder.available_options_list.toSliceConst()) |option| {
const name = %return fmt.allocPrint(allocator,
const name = try fmt.allocPrint(allocator,
" -D{}=[{}]", option.name, Builder.typeIdName(option.type_id));
defer allocator.free(name);
%return out_stream.print("{s24} {}\n", name, option.description);
try out_stream.print("{s24} {}\n", name, option.description);
}
}
%return out_stream.write(
try out_stream.write(
\\
\\Advanced Options:
\\ --build-file [file] Override path to build.zig

View File

@ -162,7 +162,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) {
}
fn testDecode(bytes: []const u8) -> %u32 {
const length = %return utf8ByteSequenceLength(bytes[0]);
const length = try utf8ByteSequenceLength(bytes[0]);
if (bytes.len < length) return error.UnexpectedEof;
std.debug.assert(bytes.len == length);
return utf8Decode(bytes);

View File

@ -2,7 +2,7 @@ const assert = @import("std").debug.assert;
const mem = @import("std").mem;
pub fn foo() -> %i32 {
const x = %return bar();
const x = try bar();
return x + 1;
}
@ -77,7 +77,7 @@ test "error return in assignment" {
fn doErrReturnInAssignment() -> %void {
var x : i32 = undefined;
x = %return makeANonErr();
x = try makeANonErr();
}
fn makeANonErr() -> %i32 {

View File

@ -4,8 +4,8 @@ fn foo(id: u64) -> %i32 {
return switch (id) {
1 => getErrInt(),
2 => {
const size = %return getErrInt();
return %return getErrInt();
const size = try getErrInt();
return try getErrInt();
},
else => error.ItBroke,
};

View File

@ -16,7 +16,7 @@ const FormValue = union(enum) {
fn doThing(form_id: u64) -> %FormValue {
return switch (form_id) {
17 => FormValue { .Address = %return readOnce() },
17 => FormValue { .Address = try readOnce() },
else => error.InvalidDebugInfo,
};
}

View File

@ -402,7 +402,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
\\ %%stdout.print("before\n");
\\ defer %%stdout.print("defer1\n");
\\ %defer %%stdout.print("deferErr\n");
\\ %return its_gonna_fail();
\\ try its_gonna_fail();
\\ defer %%stdout.print("defer3\n");
\\ %%stdout.print("after\n");
\\}
@ -422,7 +422,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
\\ %%stdout.print("before\n");
\\ defer %%stdout.print("defer1\n");
\\ %defer %%stdout.print("deferErr\n");
\\ %return its_gonna_pass();
\\ try its_gonna_pass();
\\ defer %%stdout.print("defer3\n");
\\ %%stdout.print("after\n");
\\}
@ -454,14 +454,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
\\
\\pub fn main() -> %void {
\\ var args_it = os.args();
\\ var stdout_file = %return io.getStdOut();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
\\ const stdout = &stdout_adapter.stream;
\\ var index: usize = 0;
\\ _ = args_it.skip();
\\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) {
\\ const arg = %return arg_or_err;
\\ %return stdout.print("{}: {}\n", index, arg);
\\ const arg = try arg_or_err;
\\ try stdout.print("{}: {}\n", index, arg);
\\ }
\\}
,
@ -495,14 +495,14 @@ pub fn addCases(cases: &tests.CompareOutputContext) {
\\
\\pub fn main() -> %void {
\\ var args_it = os.args();
\\ var stdout_file = %return io.getStdOut();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
\\ const stdout = &stdout_adapter.stream;
\\ var index: usize = 0;
\\ _ = args_it.skip();
\\ while (args_it.next(allocator)) |arg_or_err| : (index += 1) {
\\ const arg = %return arg_or_err;
\\ %return stdout.print("{}: {}\n", index, arg);
\\ const arg = try arg_or_err;
\\ try stdout.print("{}: {}\n", index, arg);
\\ }
\\}
,

View File

@ -1051,9 +1051,9 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\export fn entry() -> usize { return @sizeOf(@typeOf(f)); }
, ".tmp_source.zig:3:26: error: expected signed integer type, found 'u32'");
cases.add("%return in function with non error return type",
cases.add("try in function with non error return type",
\\export fn f() {
\\ %return something();
\\ try something();
\\}
\\fn something() -> %void { }
,
@ -1290,7 +1290,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
\\pub fn testTrickyDefer() -> %void {
\\ defer canFail() %% {};
\\
\\ defer %return canFail();
\\ defer try canFail();
\\
\\ const a = maybeInt() ?? return;
\\}