*WIP* error sets converting std lib

This commit is contained in:
Andrew Kelley 2018-01-31 22:48:40 -05:00
parent 5161d70620
commit 5f518dbeb9
62 changed files with 389 additions and 510 deletions

5
TODO Normal file
View File

@ -0,0 +1,5 @@
sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find .. -name "*.zig")
comptime assert(error{} ! i32 == i32);

View File

@ -10,7 +10,7 @@ const ArrayList = std.ArrayList;
const Buffer = std.Buffer;
const io = std.io;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const mode = b.standardReleaseOptions();
var docgen_exe = b.addExecutable("docgen", "doc/docgen.zig");
@ -149,7 +149,7 @@ const LibraryDep = struct {
includes: ArrayList([]const u8),
};
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) %LibraryDep {
fn findLLVM(b: &Builder, llvm_config_exe: []const u8) !LibraryDep {
const libs_output = try b.exec([][]const u8{llvm_config_exe, "--libs", "--system-libs"});
const includes_output = try b.exec([][]const u8{llvm_config_exe, "--includedir"});
const libdir_output = try b.exec([][]const u8{llvm_config_exe, "--libdir"});

View File

@ -12,7 +12,7 @@ const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
const tmp_dir_name = "docgen_tmp";
pub fn main() %void {
pub fn main() !void {
// TODO use a more general purpose allocator here
var inc_allocator = try std.heap.IncrementingAllocator.init(max_doc_file_size);
defer inc_allocator.deinit();
@ -243,13 +243,13 @@ fn parseError(tokenizer: &Tokenizer, token: &const Token, comptime fmt: []const
return error.ParseError;
}
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) %void {
fn assertToken(tokenizer: &Tokenizer, token: &const Token, id: Token.Id) !void {
if (token.id != id) {
return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
}
}
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) %Token {
fn eatToken(tokenizer: &Tokenizer, id: Token.Id) !Token {
const token = tokenizer.next();
try assertToken(tokenizer, token, id);
return token;
@ -316,7 +316,7 @@ const Action = enum {
Close,
};
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) !Toc {
var urls = std.HashMap([]const u8, Token, mem.hash_slice_u8, mem.eql_slice_u8).init(allocator);
errdefer urls.deinit();
@ -540,7 +540,7 @@ fn genToc(allocator: &mem.Allocator, tokenizer: &Tokenizer) %Toc {
};
}
fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
fn urlize(allocator: &mem.Allocator, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -560,7 +560,7 @@ fn urlize(allocator: &mem.Allocator, input: []const u8) %[]u8 {
return buf.toOwnedSlice();
}
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) %[]u8 {
fn escapeHtml(allocator: &mem.Allocator, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -604,7 +604,7 @@ test "term color" {
assert(mem.eql(u8, result, "A<span class=\"t32\">green</span>B"));
}
fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
fn termColor(allocator: &mem.Allocator, input: []const u8) ![]u8 {
var buf = try std.Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -686,7 +686,7 @@ fn termColor(allocator: &mem.Allocator, input: []const u8) %[]u8 {
error ExampleFailedToCompile;
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) %void {
fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io.OutStream, zig_exe: []const u8) !void {
var code_progress_index: usize = 0;
for (toc.nodes) |node| {
switch (node) {
@ -977,7 +977,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
error ChildCrashed;
error ChildExitError;
fn exec(allocator: &mem.Allocator, args: []const []const u8) %os.ChildProcess.ExecResult {
fn exec(allocator: &mem.Allocator, args: []const []const u8) !os.ChildProcess.ExecResult {
const result = try os.ChildProcess.exec(allocator, args, null, null, max_doc_file_size);
switch (result.term) {
os.ChildProcess.Term.Exited => |exit_code| {

View File

@ -5598,7 +5598,9 @@ Block = option(Symbol ":") "{" many(Statement) "}"
Statement = LocalVarDecl ";" | Defer(Block) | Defer(Expression) ";" | BlockExpression(Block) | Expression ";" | ";"
TypeExpr = PrefixOpExpression | "var"
TypeExpr = ErrorSetExpr | "var"
ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
BlockOrExpression = Block | Expression
@ -5680,7 +5682,7 @@ MultiplyExpression = CurlySuffixExpression MultiplyOperator MultiplyExpression |
CurlySuffixExpression = TypeExpr option(ContainerInitExpression)
MultiplyOperator = "!" | "*" | "/" | "%" | "**" | "*%"
MultiplyOperator = "*" | "/" | "%" | "**" | "*%"
PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression

View File

@ -5,7 +5,7 @@ const os = std.os;
const warn = std.debug.warn;
const allocator = std.debug.global_allocator;
pub fn main() %void {
pub fn main() !void {
var args_it = os.args();
const exe = try unwrapArg(??args_it.next(allocator));
var catted_anything = false;
@ -36,12 +36,12 @@ pub fn main() %void {
}
}
fn usage(exe: []const u8) %void {
fn usage(exe: []const u8) !void {
warn("Usage: {} [FILE]...\n", exe);
return error.Invalid;
}
fn cat_file(stdout: &io.File, file: &io.File) %void {
fn cat_file(stdout: &io.File, file: &io.File) !void {
var buf: [1024 * 4]u8 = undefined;
while (true) {
@ -61,7 +61,7 @@ fn cat_file(stdout: &io.File, file: &io.File) %void {
}
}
fn unwrapArg(arg: %[]u8) %[]u8 {
fn unwrapArg(arg: %[]u8) ![]u8 {
return arg catch |err| {
warn("Unable to parse command line: {}\n", err);
return err;

View File

@ -5,7 +5,7 @@ const fmt = std.fmt;
const Rand = std.rand.Rand;
const os = std.os;
pub fn main() %void {
pub fn main() !void {
var stdout_file = try io.getStdOut();
var stdout_file_stream = io.FileOutStream.init(&stdout_file);
const stdout = &stdout_file_stream.stream;

View File

@ -1,6 +1,6 @@
const std = @import("std");
pub fn main() %void {
pub fn main() !void {
// If this program is run without stdout attached, exit with an error.
var stdout_file = try std.io.getStdOut();
// If this program encounters pipe failure when printing to stdout, exit

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const obj = b.addObject("base64", "base64.zig");
const exe = b.addCExecutable("test");

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
const exe = b.addCExecutable("test");

View File

@ -20,7 +20,7 @@ error ZigInstallationNotFound;
const default_zig_cache_name = "zig-cache";
pub fn main() %void {
pub fn main() !void {
main2() catch |err| {
if (err != error.InvalidCommandLineArguments) {
warn("{}\n", @errorName(err));
@ -48,7 +48,7 @@ fn badArgs(comptime format: []const u8, args: ...) error {
return error.InvalidCommandLineArguments;
}
pub fn main2() %void {
pub fn main2() !void {
const allocator = std.heap.c_allocator;
const args = try os.argsAlloc(allocator);
@ -472,7 +472,7 @@ pub fn main2() %void {
}
}
fn printUsage(stream: &io.OutStream) %void {
fn printUsage(stream: &io.OutStream) !void {
try stream.write(
\\Usage: zig [command] [options]
\\
@ -548,7 +548,7 @@ fn printUsage(stream: &io.OutStream) %void {
);
}
fn printZen() %void {
fn printZen() !void {
var stdout_file = try io.getStdErr();
try stdout_file.write(
\\
@ -569,7 +569,7 @@ fn printZen() %void {
}
/// Caller must free result
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) %[]u8 {
fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const u8) ![]u8 {
if (zig_install_prefix_arg) |zig_install_prefix| {
return testZigInstallPrefix(allocator, zig_install_prefix) catch |err| {
warn("No Zig installation found at prefix {}: {}\n", zig_install_prefix_arg, @errorName(err));
@ -585,7 +585,7 @@ fn resolveZigLibDir(allocator: &mem.Allocator, zig_install_prefix_arg: ?[]const
}
/// Caller must free result
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8 {
fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) ![]u8 {
const test_zig_dir = try os.path.join(allocator, test_path, "lib", "zig");
errdefer allocator.free(test_zig_dir);
@ -599,7 +599,7 @@ fn testZigInstallPrefix(allocator: &mem.Allocator, test_path: []const u8) %[]u8
}
/// Caller must free result
fn findZigLibDir(allocator: &mem.Allocator) %[]u8 {
fn findZigLibDir(allocator: &mem.Allocator) ![]u8 {
const self_exe_path = try os.selfExeDirPath(allocator);
defer allocator.free(self_exe_path);

View File

@ -198,7 +198,7 @@ pub const Module = struct {
self.allocator.destroy(self);
}
pub fn build(self: &Module) %void {
pub fn build(self: &Module) !void {
if (self.llvm_argv.len != 0) {
var c_compatible_args = try std.cstr.NullTerminated2DArray.fromSlices(self.allocator,
[][]const []const u8 { [][]const u8{"zig (LLVM option parsing)"}, self.llvm_argv, });
@ -263,11 +263,11 @@ pub const Module = struct {
}
pub fn link(self: &Module, out_file: ?[]const u8) %void {
pub fn link(self: &Module, out_file: ?[]const u8) !void {
warn("TODO link");
}
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) %&LinkLib {
pub fn addLinkLib(self: &Module, name: []const u8, provided_explicitly: bool) !&LinkLib {
const is_libc = mem.eql(u8, name, "c");
if (is_libc) {
@ -297,7 +297,7 @@ pub const Module = struct {
}
};
fn printError(comptime format: []const u8, args: ...) %void {
fn printError(comptime format: []const u8, args: ...) !void {
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;

View File

@ -63,7 +63,7 @@ pub const Parser = struct {
NullableField: &?&ast.Node,
List: &ArrayList(&ast.Node),
pub fn store(self: &const DestPtr, value: &ast.Node) %void {
pub fn store(self: &const DestPtr, value: &ast.Node) !void {
switch (*self) {
DestPtr.Field => |ptr| *ptr = value,
DestPtr.NullableField => |ptr| *ptr = value,
@ -99,7 +99,7 @@ pub const Parser = struct {
/// Returns an AST tree, allocated with the parser's allocator.
/// Result should be freed with `freeAst` when done.
pub fn parse(self: &Parser) %Tree {
pub fn parse(self: &Parser) !Tree {
var stack = self.initUtilityArrayList(State);
defer self.deinitUtilityArrayList(stack);
@ -544,7 +544,7 @@ pub const Parser = struct {
}
}
fn createRoot(self: &Parser) %&ast.NodeRoot {
fn createRoot(self: &Parser) !&ast.NodeRoot {
const node = try self.allocator.create(ast.NodeRoot);
*node = ast.NodeRoot {
@ -599,7 +599,7 @@ pub const Parser = struct {
return node;
}
fn createParamDecl(self: &Parser) %&ast.NodeParamDecl {
fn createParamDecl(self: &Parser) !&ast.NodeParamDecl {
const node = try self.allocator.create(ast.NodeParamDecl);
*node = ast.NodeParamDecl {
@ -613,7 +613,7 @@ pub const Parser = struct {
return node;
}
fn createBlock(self: &Parser, begin_token: &const Token) %&ast.NodeBlock {
fn createBlock(self: &Parser, begin_token: &const Token) !&ast.NodeBlock {
const node = try self.allocator.create(ast.NodeBlock);
*node = ast.NodeBlock {
@ -625,7 +625,7 @@ pub const Parser = struct {
return node;
}
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) %&ast.NodeInfixOp {
fn createInfixOp(self: &Parser, op_token: &const Token, op: &const ast.NodeInfixOp.InfixOp) !&ast.NodeInfixOp {
const node = try self.allocator.create(ast.NodeInfixOp);
*node = ast.NodeInfixOp {
@ -638,7 +638,7 @@ pub const Parser = struct {
return node;
}
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) %&ast.NodePrefixOp {
fn createPrefixOp(self: &Parser, op_token: &const Token, op: &const ast.NodePrefixOp.PrefixOp) !&ast.NodePrefixOp {
const node = try self.allocator.create(ast.NodePrefixOp);
*node = ast.NodePrefixOp {
@ -650,7 +650,7 @@ pub const Parser = struct {
return node;
}
fn createIdentifier(self: &Parser, name_token: &const Token) %&ast.NodeIdentifier {
fn createIdentifier(self: &Parser, name_token: &const Token) !&ast.NodeIdentifier {
const node = try self.allocator.create(ast.NodeIdentifier);
*node = ast.NodeIdentifier {
@ -660,7 +660,7 @@ pub const Parser = struct {
return node;
}
fn createIntegerLiteral(self: &Parser, token: &const Token) %&ast.NodeIntegerLiteral {
fn createIntegerLiteral(self: &Parser, token: &const Token) !&ast.NodeIntegerLiteral {
const node = try self.allocator.create(ast.NodeIntegerLiteral);
*node = ast.NodeIntegerLiteral {
@ -670,7 +670,7 @@ pub const Parser = struct {
return node;
}
fn createFloatLiteral(self: &Parser, token: &const Token) %&ast.NodeFloatLiteral {
fn createFloatLiteral(self: &Parser, token: &const Token) !&ast.NodeFloatLiteral {
const node = try self.allocator.create(ast.NodeFloatLiteral);
*node = ast.NodeFloatLiteral {
@ -680,13 +680,13 @@ pub const Parser = struct {
return node;
}
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) %&ast.NodeIdentifier {
fn createAttachIdentifier(self: &Parser, dest_ptr: &const DestPtr, name_token: &const Token) !&ast.NodeIdentifier {
const node = try self.createIdentifier(name_token);
try dest_ptr.store(&node.base);
return node;
}
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) %&ast.NodeParamDecl {
fn createAttachParamDecl(self: &Parser, list: &ArrayList(&ast.Node)) !&ast.NodeParamDecl {
const node = try self.createParamDecl();
try list.append(&node.base);
return node;
@ -730,13 +730,13 @@ pub const Parser = struct {
return error.ParseError;
}
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) %void {
fn expectToken(self: &Parser, token: &const Token, id: @TagType(Token.Id)) !void {
if (token.id != id) {
return self.parseError(token, "expected {}, found {}", @tagName(id), @tagName(token.id));
}
}
fn eatToken(self: &Parser, id: @TagType(Token.Id)) %Token {
fn eatToken(self: &Parser, id: @TagType(Token.Id)) !Token {
const token = self.getNextToken();
try self.expectToken(token, id);
return token;
@ -763,7 +763,7 @@ pub const Parser = struct {
indent: usize,
};
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
pub fn renderAst(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void {
var stack = self.initUtilityArrayList(RenderAstFrame);
defer self.deinitUtilityArrayList(stack);
@ -802,7 +802,7 @@ pub const Parser = struct {
Indent: usize,
};
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) %void {
pub fn renderSource(self: &Parser, stream: &std.io.OutStream, root_node: &ast.NodeRoot) !void {
var stack = self.initUtilityArrayList(RenderState);
defer self.deinitUtilityArrayList(stack);
@ -1038,7 +1038,7 @@ pub const Parser = struct {
var fixed_buffer_mem: [100 * 1024]u8 = undefined;
fn testParse(source: []const u8, allocator: &mem.Allocator) %[]u8 {
fn testParse(source: []const u8, allocator: &mem.Allocator) ![]u8 {
var padded_source: [0x100]u8 = undefined;
std.mem.copy(u8, padded_source[0..source.len], source);
padded_source[source.len + 0] = '\n';
@ -1064,7 +1064,7 @@ error MemoryLeakDetected;
// TODO test for memory leaks
// TODO test for valid frees
fn testCanonical(source: []const u8) %void {
fn testCanonical(source: []const u8) !void {
const needed_alloc_count = x: {
// Try it once with unlimited memory, make sure it works
var fixed_allocator = mem.FixedBufferAllocator.init(fixed_buffer_mem[0..]);

View File

@ -516,6 +516,7 @@ TypeTableEntry *get_maybe_type(CodeGen *g, TypeTableEntry *child_type) {
TypeTableEntry *get_error_union_type(CodeGen *g, TypeTableEntry *err_set_type, TypeTableEntry *payload_type) {
assert(err_set_type->id == TypeTableEntryIdErrorSet);
assert(!type_is_invalid(payload_type));
TypeId type_id = {};
type_id.id = TypeTableEntryIdErrorUnion;
@ -1409,6 +1410,11 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
}
TypeTableEntry *specified_return_type = analyze_type_expr(g, child_scope, fn_proto->return_type);
if (type_is_invalid(specified_return_type)) {
fn_type_id.return_type = g->builtin_types.entry_invalid;
return g->builtin_types.entry_invalid;
}
if (fn_proto->auto_err_set) {
TypeTableEntry *inferred_err_set_type = get_auto_err_set_type(g, fn_entry);
fn_type_id.return_type = get_error_union_type(g, inferred_err_set_type, specified_return_type);
@ -1416,10 +1422,6 @@ static TypeTableEntry *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *c
fn_type_id.return_type = specified_return_type;
}
if (type_is_invalid(fn_type_id.return_type)) {
return g->builtin_types.entry_invalid;
}
if (fn_type_id.cc != CallingConventionUnspecified && !type_allowed_in_extern(g, fn_type_id.return_type)) {
add_node_error(g, fn_proto->return_type,
buf_sprintf("return type '%s' not allowed in function with calling convention '%s'",

View File

@ -241,7 +241,28 @@ static Token *ast_eat_token(ParseContext *pc, size_t *token_index, TokenId token
}
/*
TypeExpr = PrefixOpExpression | "var"
ErrorSetExpr = (PrefixOpExpression "!" PrefixOpExpression) | PrefixOpExpression
*/
static AstNode *ast_parse_error_set_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
AstNode *prefix_op_expr = ast_parse_prefix_op_expr(pc, token_index, mandatory);
if (!prefix_op_expr) {
return nullptr;
}
Token *token = &pc->tokens->at(*token_index);
if (token->id == TokenIdBang) {
*token_index += 1;
AstNode *node = ast_create_node(pc, NodeTypeBinOpExpr, token);
node->data.bin_op_expr.op1 = prefix_op_expr;
node->data.bin_op_expr.bin_op = BinOpTypeErrorUnion;
node->data.bin_op_expr.op2 = ast_parse_prefix_op_expr(pc, token_index, true);
return node;
} else {
return prefix_op_expr;
}
}
/*
TypeExpr = ErrorSetExpr | "var"
*/
static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool mandatory) {
Token *token = &pc->tokens->at(*token_index);
@ -250,7 +271,7 @@ static AstNode *ast_parse_type_expr(ParseContext *pc, size_t *token_index, bool
*token_index += 1;
return node;
} else {
return ast_parse_prefix_op_expr(pc, token_index, mandatory);
return ast_parse_error_set_expr(pc, token_index, mandatory);
}
}
@ -2346,10 +2367,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
node->data.fn_proto.return_type = ast_create_node(pc, NodeTypeErrorType, next_token);
return node;
}
return node;
}
if (next_token->id == TokenIdBang) {
} else if (next_token->id == TokenIdBang) {
*token_index += 1;
node->data.fn_proto.auto_err_set = true;
next_token = &pc->tokens->at(*token_index);

View File

@ -59,18 +59,18 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
return result;
}
pub fn append(l: &Self, item: &const T) %void {
pub fn append(l: &Self, item: &const T) !void {
const new_item_ptr = try l.addOne();
*new_item_ptr = *item;
}
pub fn appendSlice(l: &Self, items: []align(A) const T) %void {
pub fn appendSlice(l: &Self, items: []align(A) const T) !void {
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 {
pub fn resize(l: &Self, new_len: usize) !void {
try l.ensureCapacity(new_len);
l.len = new_len;
}
@ -80,7 +80,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
l.len = new_len;
}
pub fn ensureCapacity(l: &Self, new_capacity: usize) %void {
pub fn ensureCapacity(l: &Self, new_capacity: usize) !void {
var better_capacity = l.items.len;
if (better_capacity >= new_capacity) return;
while (true) {
@ -90,7 +90,7 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
l.items = try l.allocator.alignedRealloc(T, A, l.items, better_capacity);
}
pub fn addOne(l: &Self) %&T {
pub fn addOne(l: &Self) !&T {
const new_length = l.len + 1;
try l.ensureCapacity(new_length);
const result = &l.items[l.len];

View File

@ -79,8 +79,6 @@ pub const Base64Encoder = struct {
};
pub const standard_decoder = Base64Decoder.init(standard_alphabet_chars, standard_pad_char);
error InvalidPadding;
error InvalidCharacter;
pub const Base64Decoder = struct {
/// e.g. 'A' => 0.
@ -111,7 +109,7 @@ pub const Base64Decoder = struct {
}
/// If the encoded buffer is detected to be invalid, returns error.InvalidPadding.
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) %usize {
pub fn calcSize(decoder: &const Base64Decoder, source: []const u8) !usize {
if (source.len % 4 != 0) return error.InvalidPadding;
return calcDecodedSizeExactUnsafe(source, decoder.pad_char);
}
@ -119,7 +117,7 @@ pub const Base64Decoder = struct {
/// dest.len must be what you get from ::calcSize.
/// invalid characters result in error.InvalidCharacter.
/// invalid padding results in error.InvalidPadding.
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) %void {
pub fn decode(decoder: &const Base64Decoder, dest: []u8, source: []const u8) !void {
assert(dest.len == (decoder.calcSize(source) catch unreachable));
assert(source.len % 4 == 0);
@ -163,8 +161,6 @@ pub const Base64Decoder = struct {
}
};
error OutputTooSmall;
pub const Base64DecoderWithIgnore = struct {
decoder: Base64Decoder,
char_is_ignored: [256]bool,
@ -185,7 +181,7 @@ pub const Base64DecoderWithIgnore = struct {
}
/// If no characters end up being ignored or padding, this will be the exact decoded size.
pub fn calcSizeUpperBound(encoded_len: usize) %usize {
pub fn calcSizeUpperBound(encoded_len: usize) !usize {
return @divTrunc(encoded_len, 4) * 3;
}
@ -193,7 +189,7 @@ pub const Base64DecoderWithIgnore = struct {
/// Invalid padding results in error.InvalidPadding.
/// Decoding more data than can fit in dest results in error.OutputTooSmall. See also ::calcSizeUpperBound.
/// Returns the number of bytes writen to dest.
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) %usize {
pub fn decode(decoder_with_ignore: &const Base64DecoderWithIgnore, dest: []u8, source: []const u8) !usize {
const decoder = &decoder_with_ignore.decoder;
var src_cursor: usize = 0;
@ -378,7 +374,7 @@ test "base64" {
comptime (testBase64() catch unreachable);
}
fn testBase64() %void {
fn testBase64() !void {
try testAllApis("", "");
try testAllApis("f", "Zg==");
try testAllApis("fo", "Zm8=");
@ -412,7 +408,7 @@ fn testBase64() %void {
try testOutputTooSmallError("AAAAAA==");
}
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void {
fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) !void {
// Base64Encoder
{
var buffer: [0x100]u8 = undefined;
@ -449,7 +445,7 @@ fn testAllApis(expected_decoded: []const u8, expected_encoded: []const u8) %void
}
}
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %void {
fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) !void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
@ -458,8 +454,7 @@ fn testDecodeIgnoreSpace(expected_decoded: []const u8, encoded: []const u8) %voi
assert(mem.eql(u8, decoded[0..written], expected_decoded));
}
error ExpectedError;
fn testError(encoded: []const u8, expected_err: error) %void {
fn testError(encoded: []const u8, expected_err: error) !void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;
@ -475,7 +470,7 @@ fn testError(encoded: []const u8, expected_err: error) %void {
} else |err| if (err != expected_err) return err;
}
fn testOutputTooSmallError(encoded: []const u8) %void {
fn testOutputTooSmallError(encoded: []const u8) !void {
const standard_decoder_ignore_space = Base64DecoderWithIgnore.init(
standard_alphabet_chars, standard_pad_char, " ");
var buffer: [0x100]u8 = undefined;

View File

@ -27,7 +27,7 @@ pub const BufMap = struct {
self.hash_map.deinit();
}
pub fn set(self: &BufMap, key: []const u8, value: []const u8) %void {
pub fn set(self: &BufMap, key: []const u8, value: []const u8) !void {
if (self.hash_map.get(key)) |entry| {
const value_copy = try self.copy(value);
errdefer self.free(value_copy);
@ -67,7 +67,7 @@ pub const BufMap = struct {
self.hash_map.allocator.free(mut_value);
}
fn copy(self: &BufMap, value: []const u8) %[]const u8 {
fn copy(self: &BufMap, value: []const u8) ![]const u8 {
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;

View File

@ -24,7 +24,7 @@ pub const BufSet = struct {
self.hash_map.deinit();
}
pub fn put(self: &BufSet, key: []const u8) %void {
pub fn put(self: &BufSet, key: []const u8) !void {
if (self.hash_map.get(key) == null) {
const key_copy = try self.copy(key);
errdefer self.free(key_copy);
@ -55,7 +55,7 @@ pub const BufSet = struct {
self.hash_map.allocator.free(mut_value);
}
fn copy(self: &BufSet, value: []const u8) %[]const u8 {
fn copy(self: &BufSet, value: []const u8) ![]const u8 {
const result = try self.hash_map.allocator.alloc(u8, value.len);
mem.copy(u8, result, value);
return result;

View File

@ -12,14 +12,14 @@ pub const Buffer = struct {
list: ArrayList(u8),
/// Must deinitialize with deinit.
pub fn init(allocator: &Allocator, m: []const u8) %Buffer {
pub fn init(allocator: &Allocator, m: []const u8) !Buffer {
var self = try initSize(allocator, m.len);
mem.copy(u8, self.list.items, m);
return self;
}
/// Must deinitialize with deinit.
pub fn initSize(allocator: &Allocator, size: usize) %Buffer {
pub fn initSize(allocator: &Allocator, size: usize) !Buffer {
var self = initNull(allocator);
try self.resize(size);
return self;
@ -37,7 +37,7 @@ pub const Buffer = struct {
}
/// Must deinitialize with deinit.
pub fn initFromBuffer(buffer: &const Buffer) %Buffer {
pub fn initFromBuffer(buffer: &const Buffer) !Buffer {
return Buffer.init(buffer.list.allocator, buffer.toSliceConst());
}
@ -80,7 +80,7 @@ pub const Buffer = struct {
self.list.items[self.len()] = 0;
}
pub fn resize(self: &Buffer, new_len: usize) %void {
pub fn resize(self: &Buffer, new_len: usize) !void {
try self.list.resize(new_len + 1);
self.list.items[self.len()] = 0;
}
@ -93,24 +93,24 @@ pub const Buffer = struct {
return self.list.len - 1;
}
pub fn append(self: &Buffer, m: []const u8) %void {
pub fn append(self: &Buffer, m: []const u8) !void {
const old_len = self.len();
try self.resize(old_len + m.len);
mem.copy(u8, self.list.toSlice()[old_len..], m);
}
// TODO: remove, use OutStream for this
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) %void {
pub fn appendFormat(self: &Buffer, comptime format: []const u8, args: ...) !void {
return fmt.format(self, append, format, args);
}
// TODO: remove, use OutStream for this
pub fn appendByte(self: &Buffer, byte: u8) %void {
pub fn appendByte(self: &Buffer, byte: u8) !void {
return self.appendByteNTimes(byte, 1);
}
// TODO: remove, use OutStream for this
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) %void {
pub fn appendByteNTimes(self: &Buffer, byte: u8, count: usize) !void {
var prev_size: usize = self.len();
const new_size = prev_size + count;
try self.resize(new_size);
@ -137,7 +137,7 @@ pub const Buffer = struct {
return mem.eql(u8, self.list.items[start..l], m);
}
pub fn replaceContents(self: &const Buffer, m: []const u8) %void {
pub fn replaceContents(self: &const Buffer, m: []const u8) !void {
try self.resize(m.len);
mem.copy(u8, self.list.toSlice(), m);
}

View File

@ -15,13 +15,6 @@ const BufSet = std.BufSet;
const BufMap = std.BufMap;
const fmt_lib = std.fmt;
error ExtraArg;
error UncleanExit;
error InvalidStepName;
error DependencyLoopDetected;
error NoCompilerFound;
error NeedAnObject;
pub const Builder = struct {
uninstall_tls: TopLevelStep,
install_tls: TopLevelStep,
@ -242,7 +235,7 @@ pub const Builder = struct {
self.lib_paths.append(path) catch unreachable;
}
pub fn make(self: &Builder, step_names: []const []const u8) %void {
pub fn make(self: &Builder, step_names: []const []const u8) !void {
var wanted_steps = ArrayList(&Step).init(self.allocator);
defer wanted_steps.deinit();
@ -278,7 +271,7 @@ pub const Builder = struct {
return &self.uninstall_tls.step;
}
fn makeUninstall(uninstall_step: &Step) %void {
fn makeUninstall(uninstall_step: &Step) !void {
const uninstall_tls = @fieldParentPtr(TopLevelStep, "step", uninstall_step);
const self = @fieldParentPtr(Builder, "uninstall_tls", uninstall_tls);
@ -292,7 +285,7 @@ pub const Builder = struct {
// TODO remove empty directories
}
fn makeOneStep(self: &Builder, s: &Step) %void {
fn makeOneStep(self: &Builder, s: &Step) !void {
if (s.loop_flag) {
warn("Dependency loop detected:\n {}\n", s.name);
return error.DependencyLoopDetected;
@ -313,7 +306,7 @@ pub const Builder = struct {
try s.make();
}
fn getTopLevelStepByName(self: &Builder, name: []const u8) %&Step {
fn getTopLevelStepByName(self: &Builder, name: []const u8) !&Step {
for (self.top_level_steps.toSliceConst()) |top_level_step| {
if (mem.eql(u8, top_level_step.step.name, name)) {
return &top_level_step.step;
@ -548,7 +541,7 @@ pub const Builder = struct {
return self.invalid_user_input;
}
fn spawnChild(self: &Builder, argv: []const []const u8) %void {
fn spawnChild(self: &Builder, argv: []const []const u8) !void {
return self.spawnChildEnvMap(null, &self.env_map, argv);
}
@ -595,7 +588,7 @@ pub const Builder = struct {
}
}
pub fn makePath(self: &Builder, path: []const u8) %void {
pub fn makePath(self: &Builder, path: []const u8) !void {
os.makePath(self.allocator, self.pathFromRoot(path)) catch |err| {
warn("Unable to create path {}: {}\n", path, @errorName(err));
return err;
@ -630,11 +623,11 @@ pub const Builder = struct {
self.installed_files.append(full_path) catch unreachable;
}
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) %void {
fn copyFile(self: &Builder, source_path: []const u8, dest_path: []const u8) !void {
return self.copyFileMode(source_path, dest_path, 0o666);
}
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) %void {
fn copyFileMode(self: &Builder, source_path: []const u8, dest_path: []const u8, mode: usize) !void {
if (self.verbose) {
warn("cp {} {}\n", source_path, dest_path);
}
@ -672,7 +665,7 @@ pub const Builder = struct {
}
}
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) %[]const u8 {
pub fn findProgram(self: &Builder, names: []const []const u8, paths: []const []const u8) ![]const u8 {
// TODO report error for ambiguous situations
const exe_extension = (Target { .Native = {}}).exeFileExt();
for (self.search_prefixes.toSliceConst()) |search_prefix| {
@ -721,7 +714,7 @@ pub const Builder = struct {
return error.FileNotFound;
}
pub fn exec(self: &Builder, argv: []const []const u8) %[]u8 {
pub fn exec(self: &Builder, argv: []const []const u8) ![]u8 {
const max_output_size = 100 * 1024;
const result = try os.ChildProcess.exec(self.allocator, argv, null, null, max_output_size);
switch (result.term) {
@ -1180,12 +1173,12 @@ pub const LibExeObjStep = struct {
self.disable_libc = disable;
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(LibExeObjStep, "step", step);
return if (self.is_zig) self.makeZig() else self.makeC();
}
fn makeZig(self: &LibExeObjStep) %void {
fn makeZig(self: &LibExeObjStep) !void {
const builder = self.builder;
assert(self.is_zig);
@ -1396,7 +1389,7 @@ pub const LibExeObjStep = struct {
}
}
fn makeC(self: &LibExeObjStep) %void {
fn makeC(self: &LibExeObjStep) !void {
const builder = self.builder;
const cc = builder.getCCExe();
@ -1687,7 +1680,7 @@ pub const TestStep = struct {
self.exec_cmd_args = args;
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(TestStep, "step", step);
const builder = self.builder;
@ -1796,7 +1789,7 @@ pub const CommandStep = struct {
return self;
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(CommandStep, "step", step);
const cwd = if (self.cwd) |cwd| self.builder.pathFromRoot(cwd) else self.builder.build_root;
@ -1836,7 +1829,7 @@ const InstallArtifactStep = struct {
return self;
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(Self, "step", step);
const builder = self.builder;
@ -1868,7 +1861,7 @@ pub const InstallFileStep = struct {
};
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(InstallFileStep, "step", step);
try self.builder.copyFile(self.src_path, self.dest_path);
}
@ -1889,7 +1882,7 @@ pub const WriteFileStep = struct {
};
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(WriteFileStep, "step", step);
const full_path = self.builder.pathFromRoot(self.file_path);
const full_path_dir = os.path.dirname(full_path);
@ -1917,7 +1910,7 @@ pub const LogStep = struct {
};
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(LogStep, "step", step);
warn("{}", self.data);
}
@ -1936,7 +1929,7 @@ pub const RemoveDirStep = struct {
};
}
fn make(step: &Step) %void {
fn make(step: &Step) !void {
const self = @fieldParentPtr(RemoveDirStep, "step", step);
const full_path = self.builder.pathFromRoot(self.dir_path);
@ -1967,7 +1960,7 @@ pub const Step = struct {
return init(name, allocator, makeNoOp);
}
pub fn make(self: &Step) %void {
pub fn make(self: &Step) !void {
if (self.done_flag)
return;

View File

@ -18,7 +18,7 @@ const c = @cImport({
const Mb = 1024 * 1024;
pub fn main() %void {
pub fn main() !void {
var stdout_file = try std.io.getStdOut();
var stdout_out_stream = std.io.FileOutStream.init(&stdout_file);
const stdout = &stdout_out_stream.stream;

View File

@ -42,7 +42,7 @@ fn testCStrFnsImpl() void {
/// Returns a mutable slice with exactly the same size which is guaranteed to
/// have a null byte after it.
/// Caller owns the returned memory.
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) %[]u8 {
pub fn addNullByte(allocator: &mem.Allocator, slice: []const u8) ![]u8 {
const result = try allocator.alloc(u8, slice.len + 1);
mem.copy(u8, result, slice);
result[slice.len] = 0;
@ -56,7 +56,7 @@ pub const NullTerminated2DArray = struct {
/// Takes N lists of strings, concatenates the lists together, and adds a null terminator
/// Caller must deinit result
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) %NullTerminated2DArray {
pub fn fromSlices(allocator: &mem.Allocator, slices: []const []const []const u8) !NullTerminated2DArray {
var new_len: usize = 1; // 1 for the list null
var byte_count: usize = 0;
for (slices) |slice| {

View File

@ -28,7 +28,7 @@ pub const FailingAllocator = struct {
};
}
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) %[]u8 {
fn alloc(allocator: &mem.Allocator, n: usize, alignment: u29) ![]u8 {
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
if (self.index == self.fail_index) {
return error.OutOfMemory;
@ -39,7 +39,7 @@ pub const FailingAllocator = struct {
return result;
}
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
fn realloc(allocator: &mem.Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
const self = @fieldParentPtr(FailingAllocator, "allocator", allocator);
if (new_size <= old_mem.len) {
self.freed_bytes += old_mem.len - new_size;

View File

@ -6,8 +6,6 @@ const mem = std.mem;
const debug = std.debug;
const InStream = std.stream.InStream;
error InvalidFormat;
pub const SHT_NULL = 0;
pub const SHT_PROGBITS = 1;
pub const SHT_SYMTAB = 2;
@ -81,14 +79,14 @@ pub const Elf = struct {
prealloc_file: io.File,
/// Call close when done.
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) %void {
pub fn openPath(elf: &Elf, allocator: &mem.Allocator, path: []const u8) !void {
try elf.prealloc_file.open(path);
try elf.openFile(allocator, &elf.prealloc_file);
elf.auto_close_stream = true;
}
/// Call close when done.
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) %void {
pub fn openFile(elf: &Elf, allocator: &mem.Allocator, file: &io.File) !void {
elf.allocator = allocator;
elf.in_file = file;
elf.auto_close_stream = false;
@ -239,7 +237,7 @@ pub const Elf = struct {
elf.in_file.close();
}
pub fn findSection(elf: &Elf, name: []const u8) %?&SectionHeader {
pub fn findSection(elf: &Elf, name: []const u8) !?&SectionHeader {
var file_stream = io.FileInStream.init(elf.in_file);
const in = &file_stream.stream;
@ -263,7 +261,7 @@ pub const Elf = struct {
return null;
}
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) %void {
pub fn seekToSection(elf: &Elf, elf_section: &SectionHeader) !void {
try elf.in_file.seekTo(elf_section.offset);
}
};

View File

@ -24,8 +24,8 @@ const State = enum { // TODO put inside format function and make sure the name a
/// Renders fmt string with args, calling output with slices of bytes.
/// If `output` returns an error, the error is returned from `format` and
/// `output` is not called again.
pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
comptime fmt: []const u8, args: ...) %void
pub fn format(context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8) Errors!void,
comptime fmt: []const u8, args: ...) Errors!void
{
comptime var start_index = 0;
comptime var state = State.Start;
@ -58,7 +58,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
start_index = i;
},
'}' => {
try formatValue(args[next_arg], context, output);
try formatValue(args[next_arg], context, Errors, 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) {
'}' => {
try formatInt(args[next_arg], radix, uppercase, width, context, output);
try formatInt(args[next_arg], radix, uppercase, width, context, Errors, 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) catch unreachable);
try formatInt(args[next_arg], radix, uppercase, width, context, output);
try formatInt(args[next_arg], radix, uppercase, width, context, Errors, 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) {
'}' => {
try formatFloatDecimal(args[next_arg], 0, context, output);
try formatFloatDecimal(args[next_arg], 0, context, Errors, 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) catch unreachable);
try formatFloatDecimal(args[next_arg], width, context, output);
try formatFloatDecimal(args[next_arg], width, context, Errors, 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) catch unreachable);
try formatBuf(args[next_arg], width, context, output);
try formatBuf(args[next_arg], width, context, Errors, 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) {
'}' => {
try formatAsciiChar(args[next_arg], context, output);
try formatAsciiChar(args[next_arg], context, Errors, output);
next_arg += 1;
state = State.Start;
start_index = i + 1;
@ -191,7 +191,7 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)%void,
}
}
pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
pub fn formatValue(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
const T = @typeOf(value);
switch (@typeId(T)) {
builtin.TypeId.Int => {
@ -208,16 +208,16 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
},
builtin.TypeId.Nullable => {
if (value) |payload| {
return formatValue(payload, context, output);
return formatValue(payload, context, Errors, output);
} else {
return output(context, "null");
}
},
builtin.TypeId.ErrorUnion => {
if (value) |payload| {
return formatValue(payload, context, output);
return formatValue(payload, context, Errors, output);
} else |err| {
return formatValue(err, context, output);
return formatValue(err, context, Errors, output);
}
},
builtin.TypeId.Error => {
@ -240,12 +240,12 @@ pub fn formatValue(value: var, context: var, output: fn(@typeOf(context), []cons
}
}
pub fn formatAsciiChar(c: u8, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
pub fn formatAsciiChar(c: u8, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
return output(context, (&c)[0..1]);
}
pub fn formatBuf(buf: []const u8, width: usize,
context: var, output: fn(@typeOf(context), []const u8)%void) %void
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
{
try output(context, buf);
@ -256,7 +256,7 @@ pub fn formatBuf(buf: []const u8, width: usize,
}
}
pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
pub fn formatFloat(value: var, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
var x = f64(value);
// Errol doesn't handle these special cases.
@ -294,7 +294,7 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
}
}
pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)%void) %void {
pub fn formatFloatDecimal(value: var, precision: usize, context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void {
var x = f64(value);
// Errol doesn't handle these special cases.
@ -336,7 +336,7 @@ pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn
pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)%void) %void
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)errors!void) errors!void
{
if (@typeOf(value).is_signed) {
return formatIntSigned(value, base, uppercase, width, context, output);
@ -346,7 +346,7 @@ pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
}
fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)%void) %void
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
{
const uint = @IntType(false, @typeOf(value).bit_count);
if (value < 0) {
@ -367,7 +367,7 @@ fn formatIntSigned(value: var, base: u8, uppercase: bool, width: usize,
}
fn formatIntUnsigned(value: var, base: u8, uppercase: bool, width: usize,
context: var, output: fn(@typeOf(context), []const u8)%void) %void
context: var, comptime Errors: type, output: fn(@typeOf(context), []const u8)Errors!void) Errors!void
{
// max_int_digits accounts for the minus sign. when printing an unsigned
// number we don't need to do that.
@ -417,12 +417,12 @@ const FormatIntBuf = struct {
out_buf: []u8,
index: usize,
};
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) %void {
fn formatIntCallback(context: &FormatIntBuf, bytes: []const u8) !void {
mem.copy(u8, context.out_buf[context.index..], bytes);
context.index += bytes.len;
}
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) %T {
pub fn parseInt(comptime T: type, buf: []const u8, radix: u8) !T {
if (!T.is_signed)
return parseUnsigned(T, buf, radix);
if (buf.len == 0)
@ -446,7 +446,7 @@ test "fmt.parseInt" {
assert(if (parseInt(u8, "256", 10)) |_| false else |err| err == error.Overflow);
}
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) !T {
var x: T = 0;
for (buf) |c| {
@ -458,8 +458,7 @@ pub fn parseUnsigned(comptime T: type, buf: []const u8, radix: u8) %T {
return x;
}
error InvalidChar;
fn charToDigit(c: u8, radix: u8) %u8 {
fn charToDigit(c: u8, radix: u8) !u8 {
const value = switch (c) {
'0' ... '9' => c - '0',
'A' ... 'Z' => c - 'A' + 10,
@ -485,28 +484,26 @@ const BufPrintContext = struct {
remaining: []u8,
};
error BufferTooSmall;
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) %void {
fn bufPrintWrite(context: &BufPrintContext, bytes: []const u8) !void {
if (context.remaining.len < bytes.len) return error.BufferTooSmall;
mem.copy(u8, context.remaining, bytes);
context.remaining = context.remaining[bytes.len..];
}
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) %[]u8 {
pub fn bufPrint(buf: []u8, comptime fmt: []const u8, args: ...) ![]u8 {
var context = BufPrintContext { .remaining = buf, };
try format(&context, bufPrintWrite, fmt, args);
return buf[0..buf.len - context.remaining.len];
}
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) %[]u8 {
pub fn allocPrint(allocator: &mem.Allocator, comptime fmt: []const u8, args: ...) ![]u8 {
var size: usize = 0;
// Cannot fail because `countSize` cannot fail.
format(&size, countSize, fmt, args) catch unreachable;
format(&size, error{}, countSize, fmt, args);
const buf = try allocator.alloc(u8, size);
return bufPrint(buf, fmt, args);
}
fn countSize(size: &usize, bytes: []const u8) %void {
fn countSize(size: &usize, bytes: []const u8) void {
*size += bytes.len;
}
@ -561,13 +558,13 @@ test "fmt.format" {
}
{
var buf1: [32]u8 = undefined;
const value: %i32 = 1234;
const value: error!i32 = 1234;
const result = try bufPrint(buf1[0..], "error union: {}\n", value);
assert(mem.eql(u8, result, "error union: 1234\n"));
}
{
var buf1: [32]u8 = undefined;
const value: %i32 = error.InvalidChar;
const value: error!i32 = error.InvalidChar;
const result = try bufPrint(buf1[0..], "error union: {}\n", value);
assert(mem.eql(u8, result, "error union: error.InvalidChar\n"));
}

View File

@ -80,7 +80,7 @@ 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 {
pub fn put(hm: &Self, key: K, value: &const V) !?V {
if (hm.entries.len == 0) {
try hm.initCapacity(16);
}
@ -151,7 +151,7 @@ pub fn HashMap(comptime K: type, comptime V: type,
};
}
fn initCapacity(hm: &Self, capacity: usize) %void {
fn initCapacity(hm: &Self, capacity: usize) !void {
hm.entries = try hm.allocator.alloc(Entry, capacity);
hm.size = 0;
hm.max_distance_from_start_index = 0;

View File

@ -9,8 +9,6 @@ const c = std.c;
const Allocator = mem.Allocator;
error OutOfMemory;
pub const c_allocator = &c_allocator_state;
var c_allocator_state = Allocator {
.allocFn = cAlloc,
@ -18,14 +16,14 @@ var c_allocator_state = Allocator {
.freeFn = cFree,
};
fn cAlloc(self: &Allocator, n: usize, alignment: u29) %[]u8 {
fn cAlloc(self: &Allocator, n: usize, alignment: u29) ![]u8 {
return if (c.malloc(usize(n))) |buf|
@ptrCast(&u8, buf)[0..n]
else
error.OutOfMemory;
}
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
fn cRealloc(self: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
const old_ptr = @ptrCast(&c_void, old_mem.ptr);
if (c.realloc(old_ptr, new_size)) |buf| {
return @ptrCast(&u8, buf)[0..new_size];
@ -47,7 +45,7 @@ pub const IncrementingAllocator = struct {
end_index: usize,
heap_handle: if (builtin.os == Os.windows) os.windows.HANDLE else void,
fn init(capacity: usize) %IncrementingAllocator {
fn init(capacity: usize) !IncrementingAllocator {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const p = os.posix;
@ -105,7 +103,7 @@ pub const IncrementingAllocator = struct {
return self.bytes.len - self.end_index;
}
fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
const self = @fieldParentPtr(IncrementingAllocator, "allocator", allocator);
const addr = @ptrToInt(&self.bytes[self.end_index]);
const rem = @rem(addr, alignment);
@ -120,7 +118,7 @@ pub const IncrementingAllocator = struct {
return result;
}
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
if (new_size <= old_mem.len) {
return old_mem[0..new_size];
} else {

View File

@ -26,31 +26,7 @@ test "import io tests" {
}
}
/// The function received invalid input at runtime. An Invalid error means a
/// bug in the program that called the function.
error Invalid;
error DiskQuota;
error FileTooBig;
error Io;
error NoSpaceLeft;
error BadPerm;
error BrokenPipe;
error BadFd;
error IsDir;
error NotDir;
error SymLinkLoop;
error ProcessFdQuotaExceeded;
error SystemFdQuotaExceeded;
error NameTooLong;
error NoDevice;
error PathNotFound;
error OutOfMemory;
error Unseekable;
error EndOfFile;
error FilePosLargerThanPointerRange;
pub fn getStdErr() %File {
pub fn getStdErr() !File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_ERROR_HANDLE)
else if (is_posix)
@ -60,7 +36,7 @@ pub fn getStdErr() %File {
return File.openHandle(handle);
}
pub fn getStdOut() %File {
pub fn getStdOut() !File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_OUTPUT_HANDLE)
else if (is_posix)
@ -70,7 +46,7 @@ pub fn getStdOut() %File {
return File.openHandle(handle);
}
pub fn getStdIn() %File {
pub fn getStdIn() !File {
const handle = if (is_windows)
try os.windowsGetStdHandle(system.STD_INPUT_HANDLE)
else if (is_posix)
@ -94,7 +70,7 @@ pub const FileInStream = struct {
};
}
fn readFn(in_stream: &InStream, buffer: []u8) %usize {
fn readFn(in_stream: &InStream, buffer: []u8) !usize {
const self = @fieldParentPtr(FileInStream, "stream", in_stream);
return self.file.read(buffer);
}
@ -114,7 +90,7 @@ pub const FileOutStream = struct {
};
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
const self = @fieldParentPtr(FileOutStream, "stream", out_stream);
return self.file.write(bytes);
}
@ -129,7 +105,7 @@ pub const File = 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.
/// Call close to clean up.
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) %File {
pub fn openRead(path: []const u8, allocator: ?&mem.Allocator) !File {
if (is_posix) {
const flags = system.O_LARGEFILE|system.O_RDONLY;
const fd = try os.posixOpen(path, flags, 0, allocator);
@ -144,7 +120,7 @@ pub const File = struct {
}
/// Calls `openWriteMode` with 0o666 for the mode.
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) %File {
pub fn openWrite(path: []const u8, allocator: ?&mem.Allocator) !File {
return openWriteMode(path, 0o666, allocator);
}
@ -154,7 +130,7 @@ pub const File = 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.
/// Call close to clean up.
pub fn openWriteMode(path: []const u8, mode: usize, allocator: ?&mem.Allocator) %File {
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 = try os.posixOpen(path, flags, mode, allocator);
@ -189,7 +165,7 @@ pub const File = struct {
return os.isTty(self.handle);
}
pub fn seekForward(self: &File, amount: isize) %void {
pub fn seekForward(self: &File, amount: isize) !void {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const result = system.lseek(self.handle, amount, system.SEEK_CUR);
@ -218,7 +194,7 @@ pub const File = struct {
}
}
pub fn seekTo(self: &File, pos: usize) %void {
pub fn seekTo(self: &File, pos: usize) !void {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const ipos = try math.cast(isize, pos);
@ -249,7 +225,7 @@ pub const File = struct {
}
}
pub fn getPos(self: &File) %usize {
pub fn getPos(self: &File) !usize {
switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => {
const result = system.lseek(self.handle, 0, system.SEEK_CUR);
@ -289,7 +265,7 @@ pub const File = struct {
}
}
pub fn getEndPos(self: &File) %usize {
pub fn getEndPos(self: &File) !usize {
if (is_posix) {
var stat: system.Stat = undefined;
const err = system.getErrno(system.fstat(self.handle, &stat));
@ -318,7 +294,7 @@ pub const File = struct {
}
}
pub fn read(self: &File, buffer: []u8) %usize {
pub fn read(self: &File, buffer: []u8) !usize {
if (is_posix) {
var index: usize = 0;
while (index < buffer.len) {
@ -360,7 +336,7 @@ pub const File = struct {
}
}
fn write(self: &File, bytes: []const u8) %void {
fn write(self: &File, bytes: []const u8) !void {
if (is_posix) {
try os.posixWrite(self.handle, bytes);
} else if (is_windows) {
@ -371,19 +347,16 @@ pub const File = struct {
}
};
error StreamTooLong;
error EndOfStream;
pub const InStream = struct {
/// Return the number of bytes read. If the number read is smaller than buf.len, it
/// means the stream reached the end. Reaching the end of a stream is not an error
/// condition.
readFn: fn(self: &InStream, buffer: []u8) %usize,
readFn: fn(self: &InStream, buffer: []u8) !usize,
/// Replaces `buffer` contents by reading from the stream until it is finished.
/// 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 {
pub fn readAllBuffer(self: &InStream, buffer: &Buffer, max_size: usize) !void {
try buffer.resize(0);
var actual_buf_len: usize = 0;
@ -408,7 +381,7 @@ pub const InStream = struct {
/// memory would be greater than `max_size`, returns `error.StreamTooLong`.
/// Caller owns returned memory.
/// If this function returns an error, the contents from the stream read so far are lost.
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) %[]u8 {
pub fn readAllAlloc(self: &InStream, allocator: &mem.Allocator, max_size: usize) ![]u8 {
var buf = Buffer.initNull(allocator);
defer buf.deinit();
@ -420,7 +393,7 @@ pub const InStream = struct {
/// Does not include the delimiter in the result.
/// 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 {
pub fn readUntilDelimiterBuffer(self: &InStream, buffer: &Buffer, delimiter: u8, max_size: usize) !void {
try buf.resize(0);
while (true) {
@ -443,7 +416,7 @@ pub const InStream = struct {
/// Caller owns returned memory.
/// If this function returns an error, the contents from the stream read so far are lost.
pub fn readUntilDelimiterAlloc(self: &InStream, allocator: &mem.Allocator,
delimiter: u8, max_size: usize) %[]u8
delimiter: u8, max_size: usize) ![]u8
{
var buf = Buffer.initNull(allocator);
defer buf.deinit();
@ -455,43 +428,43 @@ pub const InStream = struct {
/// Returns the number of bytes read. If the number read is smaller than buf.len, it
/// means the stream reached the end. Reaching the end of a stream is not an error
/// condition.
pub fn read(self: &InStream, buffer: []u8) %usize {
pub fn read(self: &InStream, buffer: []u8) !usize {
return self.readFn(self, buffer);
}
/// Same as `read` but end of stream returns `error.EndOfStream`.
pub fn readNoEof(self: &InStream, buf: []u8) %void {
pub fn readNoEof(self: &InStream, buf: []u8) !void {
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 {
pub fn readByte(self: &InStream) !u8 {
var result: [1]u8 = undefined;
try self.readNoEof(result[0..]);
return result[0];
}
/// Same as `readByte` except the returned byte is signed.
pub fn readByteSigned(self: &InStream) %i8 {
pub fn readByteSigned(self: &InStream) !i8 {
return @bitCast(i8, try self.readByte());
}
pub fn readIntLe(self: &InStream, comptime T: type) %T {
pub fn readIntLe(self: &InStream, comptime T: type) !T {
return self.readInt(builtin.Endian.Little, T);
}
pub fn readIntBe(self: &InStream, comptime T: type) %T {
pub fn readIntBe(self: &InStream, comptime T: type) !T {
return self.readInt(builtin.Endian.Big, T);
}
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) %T {
pub fn readInt(self: &InStream, endian: builtin.Endian, comptime T: type) !T {
var bytes: [@sizeOf(T)]u8 = undefined;
try self.readNoEof(bytes[0..]);
return mem.readInt(bytes, T, endian);
}
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) %T {
pub fn readVarInt(self: &InStream, endian: builtin.Endian, comptime T: type, size: usize) !T {
assert(size <= @sizeOf(T));
assert(size <= 8);
var input_buf: [8]u8 = undefined;
@ -504,22 +477,23 @@ pub const InStream = struct {
};
pub const OutStream = struct {
writeFn: fn(self: &OutStream, bytes: []const u8) %void,
// TODO allow specifying the error set
writeFn: fn(self: &OutStream, bytes: []const u8) error!void,
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) %void {
return std.fmt.format(self, self.writeFn, format, args);
pub fn print(self: &OutStream, comptime format: []const u8, args: ...) !void {
return std.fmt.format(self, error, self.writeFn, format, args);
}
pub fn write(self: &OutStream, bytes: []const u8) %void {
pub fn write(self: &OutStream, bytes: []const u8) !void {
return self.writeFn(self, bytes);
}
pub fn writeByte(self: &OutStream, byte: u8) %void {
pub fn writeByte(self: &OutStream, byte: u8) !void {
const slice = (&byte)[0..1];
return self.writeFn(self, slice);
}
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) %void {
pub fn writeByteNTimes(self: &OutStream, byte: u8, n: usize) !void {
const slice = (&byte)[0..1];
var i: usize = 0;
while (i < n) : (i += 1) {
@ -532,19 +506,19 @@ pub const OutStream = struct {
/// a fixed size buffer of size `std.os.max_noalloc_path_len` is an attempted solution. If the fixed
/// 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 {
pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator) !void {
var file = try File.openWrite(path, allocator);
defer file.close();
try file.write(data);
}
/// On success, caller owns returned buffer.
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) %[]u8 {
pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) ![]u8 {
return readFileAllocExtra(path, allocator, 0);
}
/// 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 {
pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) ![]u8 {
var file = try File.openRead(path, allocator);
defer file.close();
@ -589,7 +563,7 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize) type {
};
}
fn readFn(in_stream: &InStream, dest: []u8) %usize {
fn readFn(in_stream: &InStream, dest: []u8) !usize {
const self = @fieldParentPtr(Self, "stream", in_stream);
var dest_index: usize = 0;
@ -652,7 +626,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
};
}
pub fn flush(self: &Self) %void {
pub fn flush(self: &Self) !void {
if (self.index == 0)
return;
@ -660,7 +634,7 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize) type {
self.index = 0;
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
const self = @fieldParentPtr(Self, "stream", out_stream);
if (bytes.len >= self.buffer.len) {
@ -698,7 +672,7 @@ pub const BufferOutStream = struct {
};
}
fn writeFn(out_stream: &OutStream, bytes: []const u8) %void {
fn writeFn(out_stream: &OutStream, bytes: []const u8) !void {
const self = @fieldParentPtr(BufferOutStream, "stream", out_stream);
return self.buffer.append(bytes);
}

View File

@ -190,7 +190,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the new node.
pub fn allocateNode(list: &Self, allocator: &Allocator) %&Node {
pub fn allocateNode(list: &Self, allocator: &Allocator) !&Node {
comptime assert(!isIntrusive());
return allocator.create(Node);
}
@ -213,7 +213,7 @@ fn BaseLinkedList(comptime T: type, comptime ParentType: type, comptime field_na
///
/// Returns:
/// A pointer to the new node.
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) %&Node {
pub fn createNode(list: &Self, data: &const T, allocator: &Allocator) !&Node {
comptime assert(!isIntrusive());
var node = try list.allocateNode(allocator);
*node = Node.init(data);

View File

@ -191,30 +191,26 @@ test "math.max" {
assert(max(i32(-1), i32(2)) == 2);
}
error Overflow;
pub fn mul(comptime T: type, a: T, b: T) %T {
pub fn mul(comptime T: type, a: T, b: T) !T {
var answer: T = undefined;
return if (@mulWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn add(comptime T: type, a: T, b: T) %T {
pub fn add(comptime T: type, a: T, b: T) !T {
var answer: T = undefined;
return if (@addWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
error Overflow;
pub fn sub(comptime T: type, a: T, b: T) %T {
pub fn sub(comptime T: type, a: T, b: T) !T {
var answer: T = undefined;
return if (@subWithOverflow(T, a, b, &answer)) error.Overflow else answer;
}
pub fn negate(x: var) %@typeOf(x) {
pub fn negate(x: var) !@typeOf(x) {
return sub(@typeOf(x), 0, x);
}
error Overflow;
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) %T {
pub fn shlExact(comptime T: type, a: T, shift_amt: Log2Int(T)) !T {
var answer: T = undefined;
return if (@shlWithOverflow(T, a, shift_amt, &answer)) error.Overflow else answer;
}
@ -323,8 +319,7 @@ fn testOverflow() void {
}
error Overflow;
pub fn absInt(x: var) %@typeOf(x) {
pub fn absInt(x: var) !@typeOf(x) {
const T = @typeOf(x);
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt
comptime assert(T.is_signed); // must pass a signed integer to absInt
@ -347,9 +342,7 @@ fn testAbsInt() void {
pub const absFloat = @import("fabs.zig").fabs;
error DivisionByZero;
error Overflow;
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) %T {
pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
@ -372,9 +365,7 @@ fn testDivTrunc() void {
assert((divTrunc(f32, -5.0, 3.0) catch unreachable) == -1.0);
}
error DivisionByZero;
error Overflow;
pub fn divFloor(comptime T: type, numerator: T, denominator: T) %T {
pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
@ -397,10 +388,7 @@ fn testDivFloor() void {
assert((divFloor(f32, -5.0, 3.0) catch unreachable) == -2.0);
}
error DivisionByZero;
error Overflow;
error UnexpectedRemainder;
pub fn divExact(comptime T: type, numerator: T, denominator: T) %T {
pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
@ -428,9 +416,7 @@ fn testDivExact() void {
if (divExact(f32, 5.0, 2.0)) |_| unreachable else |err| assert(err == error.UnexpectedRemainder);
}
error DivisionByZero;
error NegativeDenominator;
pub fn mod(comptime T: type, numerator: T, denominator: T) %T {
pub fn mod(comptime T: type, numerator: T, denominator: T) !T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
@ -455,9 +441,7 @@ fn testMod() void {
if (mod(f32, 10, 0)) |_| unreachable else |err| assert(err == error.DivisionByZero);
}
error DivisionByZero;
error NegativeDenominator;
pub fn rem(comptime T: type, numerator: T, denominator: T) %T {
pub fn rem(comptime T: type, numerator: T, denominator: T) !T {
@setRuntimeSafety(false);
if (denominator == 0)
return error.DivisionByZero;
@ -505,8 +489,7 @@ test "math.absCast" {
/// Returns the negation of the integer parameter.
/// Result is a signed integer.
error Overflow;
pub fn negateCast(x: var) %@IntType(true, @typeOf(x).bit_count) {
pub fn negateCast(x: var) !@IntType(true, @typeOf(x).bit_count) {
if (@typeOf(x).is_signed)
return negate(x);
@ -532,8 +515,7 @@ test "math.negateCast" {
/// Cast an integer to a different integer type. If the value doesn't fit,
/// return an error.
error Overflow;
pub fn cast(comptime T: type, x: var) %T {
pub fn cast(comptime T: type, x: var) !T {
comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer
if (x > @maxValue(T)) {
return error.Overflow;

View File

@ -4,13 +4,13 @@ const assert = debug.assert;
const math = std.math;
const builtin = @import("builtin");
error OutOfMemory;
pub const Allocator = struct {
const Errors = error {OutOfMemory};
/// Allocate byte_count bytes and return them in a slice, with the
/// slice's pointer aligned at least to alignment bytes.
/// The returned newly allocated memory is undefined.
allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) %[]u8,
allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) Errors![]u8,
/// If `new_byte_count > old_mem.len`:
/// * `old_mem.len` is the same as what was returned from allocFn or reallocFn.
@ -21,12 +21,12 @@ pub const Allocator = struct {
/// * alignment <= alignment of old_mem.ptr
///
/// The returned newly allocated memory is undefined.
reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) %[]u8,
reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) Errors![]u8,
/// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn`
freeFn: fn (self: &Allocator, old_mem: []u8) void,
fn create(self: &Allocator, comptime T: type) %&T {
fn create(self: &Allocator, comptime T: type) !&T {
const slice = try self.alloc(T, 1);
return &slice[0];
}
@ -35,7 +35,7 @@ pub const Allocator = struct {
self.free(ptr[0..1]);
}
fn alloc(self: &Allocator, comptime T: type, n: usize) %[]T {
fn alloc(self: &Allocator, comptime T: type, n: usize) ![]T {
return self.alignedAlloc(T, @alignOf(T), n);
}
@ -51,7 +51,7 @@ pub const Allocator = struct {
return ([]align(alignment) T)(@alignCast(alignment, byte_slice));
}
fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) %[]T {
fn realloc(self: &Allocator, comptime T: type, old_mem: []T, n: usize) ![]T {
return self.alignedRealloc(T, @alignOf(T), @alignCast(@alignOf(T), old_mem), n);
}
@ -123,7 +123,7 @@ pub const FixedBufferAllocator = struct {
};
}
fn alloc(allocator: &Allocator, n: usize, alignment: u29) %[]u8 {
fn alloc(allocator: &Allocator, n: usize, alignment: u29) ![]u8 {
const self = @fieldParentPtr(FixedBufferAllocator, "allocator", allocator);
const addr = @ptrToInt(&self.buffer[self.end_index]);
const rem = @rem(addr, alignment);
@ -138,7 +138,7 @@ pub const FixedBufferAllocator = struct {
return result;
}
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) %[]u8 {
fn realloc(allocator: &Allocator, old_mem: []u8, new_size: usize, alignment: u29) ![]u8 {
if (new_size <= old_mem.len) {
return old_mem[0..new_size];
} else {
@ -197,7 +197,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 {
pub fn dupe(allocator: &Allocator, comptime T: type, m: []const T) ![]T {
const new_buf = try allocator.alloc(T, m.len);
copy(T, new_buf, m);
return new_buf;
@ -428,7 +428,7 @@ const SplitIterator = struct {
/// Naively combines a series of strings with a separator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: &Allocator, sep: u8, strings: ...) %[]u8 {
pub fn join(allocator: &Allocator, sep: u8, strings: ...) ![]u8 {
comptime assert(strings.len >= 1);
var total_strings_len: usize = strings.len; // 1 sep per string
{

View File

@ -5,19 +5,10 @@ const endian = std.endian;
// TODO don't trust this file, it bit rotted. start over
error SigInterrupt;
error Io;
error TimedOut;
error ConnectionReset;
error ConnectionRefused;
error OutOfMemory;
error NotSocket;
error BadFd;
const Connection = struct {
socket_fd: i32,
pub fn send(c: Connection, buf: []const u8) %usize {
pub fn send(c: Connection, buf: []const u8) !usize {
const send_ret = linux.sendto(c.socket_fd, buf.ptr, buf.len, 0, null, 0);
const send_err = linux.getErrno(send_ret);
switch (send_err) {
@ -31,7 +22,7 @@ const Connection = struct {
}
}
pub fn recv(c: Connection, buf: []u8) %[]u8 {
pub fn recv(c: Connection, buf: []u8) ![]u8 {
const recv_ret = linux.recvfrom(c.socket_fd, buf.ptr, buf.len, 0, null, null);
const recv_err = linux.getErrno(recv_ret);
switch (recv_err) {
@ -48,7 +39,7 @@ const Connection = struct {
}
}
pub fn close(c: Connection) %void {
pub fn close(c: Connection) !void {
switch (linux.getErrno(linux.close(c.socket_fd))) {
0 => return,
linux.EBADF => unreachable,
@ -66,7 +57,7 @@ const Address = struct {
sort_key: i32,
};
pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
pub fn lookup(hostname: []const u8, out_addrs: []Address) ![]Address {
if (hostname.len == 0) {
unreachable; // TODO
@ -75,7 +66,7 @@ pub fn lookup(hostname: []const u8, out_addrs: []Address) %[]Address {
unreachable; // TODO
}
pub fn connectAddr(addr: &Address, port: u16) %Connection {
pub fn connectAddr(addr: &Address, port: u16) !Connection {
const socket_ret = linux.socket(addr.family, linux.SOCK_STREAM, linux.PROTO_tcp);
const socket_err = linux.getErrno(socket_ret);
if (socket_err > 0) {
@ -118,7 +109,7 @@ pub fn connectAddr(addr: &Address, port: u16) %Connection {
};
}
pub fn connect(hostname: []const u8, port: u16) %Connection {
pub fn connect(hostname: []const u8, port: u16) !Connection {
var addrs_buf: [1]Address = undefined;
const addrs_slice = try lookup(hostname, addrs_buf[0..]);
const main_addr = &addrs_slice[0];
@ -126,9 +117,7 @@ pub fn connect(hostname: []const u8, port: u16) %Connection {
return connectAddr(main_addr, port);
}
error InvalidIpLiteral;
pub fn parseIpLiteral(buf: []const u8) %Address {
pub fn parseIpLiteral(buf: []const u8) !Address {
return error.InvalidIpLiteral;
}
@ -146,12 +135,7 @@ fn hexDigit(c: u8) u8 {
}
}
error InvalidChar;
error Overflow;
error JunkAtEnd;
error Incomplete;
fn parseIp6(buf: []const u8) %Address {
fn parseIp6(buf: []const u8) !Address {
var result: Address = undefined;
result.family = linux.AF_INET6;
result.scope_id = 0;
@ -232,7 +216,7 @@ fn parseIp6(buf: []const u8) %Address {
return error.Incomplete;
}
fn parseIp4(buf: []const u8) %u32 {
fn parseIp4(buf: []const u8) !u32 {
var result: u32 = undefined;
const out_ptr = ([]u8)((&result)[0..1]);

View File

@ -13,10 +13,6 @@ const builtin = @import("builtin");
const Os = builtin.Os;
const LinkedList = std.LinkedList;
error PermissionDenied;
error ProcessNotFound;
error InvalidName;
var children_nodes = LinkedList(&ChildProcess).init();
const is_windows = builtin.os == Os.windows;
@ -74,7 +70,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 {
pub fn init(argv: []const []const u8, allocator: &mem.Allocator) !&ChildProcess {
const child = try allocator.create(ChildProcess);
errdefer allocator.destroy(child);
@ -103,7 +99,7 @@ pub const ChildProcess = struct {
return child;
}
pub fn setUserName(self: &ChildProcess, name: []const u8) %void {
pub fn setUserName(self: &ChildProcess, name: []const u8) !void {
const user_info = try os.getUserInfo(name);
self.uid = user_info.uid;
self.gid = user_info.gid;
@ -111,7 +107,7 @@ pub const ChildProcess = struct {
/// onTerm can be called before `spawn` returns.
/// On success must call `kill` or `wait`.
pub fn spawn(self: &ChildProcess) %void {
pub fn spawn(self: &ChildProcess) !void {
if (is_windows) {
return self.spawnWindows();
} else {
@ -119,13 +115,13 @@ pub const ChildProcess = struct {
}
}
pub fn spawnAndWait(self: &ChildProcess) %Term {
pub fn spawnAndWait(self: &ChildProcess) !Term {
try self.spawn();
return self.wait();
}
/// Forcibly terminates child process and then cleans up all resources.
pub fn kill(self: &ChildProcess) %Term {
pub fn kill(self: &ChildProcess) !Term {
if (is_windows) {
return self.killWindows(1);
} else {
@ -133,7 +129,7 @@ pub const ChildProcess = struct {
}
}
pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) %Term {
pub fn killWindows(self: &ChildProcess, exit_code: windows.UINT) !Term {
if (self.term) |term| {
self.cleanupStreams();
return term;
@ -149,7 +145,7 @@ pub const ChildProcess = struct {
return ??self.term;
}
pub fn killPosix(self: &ChildProcess) %Term {
pub fn killPosix(self: &ChildProcess) !Term {
block_SIGCHLD();
defer restore_SIGCHLD();
@ -172,7 +168,7 @@ pub const ChildProcess = struct {
}
/// Blocks until child process terminates and then cleans up all resources.
pub fn wait(self: &ChildProcess) %Term {
pub fn wait(self: &ChildProcess) !Term {
if (is_windows) {
return self.waitWindows();
} else {
@ -220,7 +216,7 @@ pub const ChildProcess = struct {
};
}
fn waitWindows(self: &ChildProcess) %Term {
fn waitWindows(self: &ChildProcess) !Term {
if (self.term) |term| {
self.cleanupStreams();
return term;
@ -230,7 +226,7 @@ pub const ChildProcess = struct {
return ??self.term;
}
fn waitPosix(self: &ChildProcess) %Term {
fn waitPosix(self: &ChildProcess) !Term {
block_SIGCHLD();
defer restore_SIGCHLD();
@ -247,7 +243,7 @@ pub const ChildProcess = struct {
self.allocator.destroy(self);
}
fn waitUnwrappedWindows(self: &ChildProcess) %void {
fn waitUnwrappedWindows(self: &ChildProcess) !void {
const result = os.windowsWaitSingle(self.handle, windows.INFINITE);
self.term = (%Term)(x: {
@ -295,7 +291,7 @@ pub const ChildProcess = struct {
if (self.stderr) |*stderr| { stderr.close(); self.stderr = null; }
}
fn cleanupAfterWait(self: &ChildProcess, status: i32) %Term {
fn cleanupAfterWait(self: &ChildProcess, status: i32) !Term {
children_nodes.remove(&self.llnode);
defer {
@ -331,7 +327,7 @@ pub const ChildProcess = struct {
;
}
fn spawnPosix(self: &ChildProcess) %void {
fn spawnPosix(self: &ChildProcess) !void {
// TODO atomically set a flag saying that we already did this
install_SIGCHLD_handler();
@ -440,7 +436,7 @@ pub const ChildProcess = struct {
if (self.stderr_behavior == StdIo.Pipe) { os.close(stderr_pipe[1]); }
}
fn spawnWindows(self: &ChildProcess) %void {
fn spawnWindows(self: &ChildProcess) !void {
const saAttr = windows.SECURITY_ATTRIBUTES {
.nLength = @sizeOf(windows.SECURITY_ATTRIBUTES),
.bInheritHandle = windows.TRUE,
@ -623,7 +619,7 @@ pub const ChildProcess = struct {
if (self.stdout_behavior == StdIo.Pipe) { os.close(??g_hChildStd_OUT_Wr); }
}
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) %void {
fn setUpChildIo(stdio: StdIo, pipe_fd: i32, std_fileno: i32, dev_null_fd: i32) !void {
switch (stdio) {
StdIo.Pipe => try os.posixDup2(pipe_fd, std_fileno),
StdIo.Close => os.close(std_fileno),
@ -655,7 +651,7 @@ 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 {
fn windowsCreateCommandLine(allocator: &mem.Allocator, argv: []const []const u8) ![]u8 {
var buf = try Buffer.initSize(allocator, 0);
defer buf.deinit();
@ -700,7 +696,7 @@ fn windowsDestroyPipe(rd: ?windows.HANDLE, wr: ?windows.HANDLE) void {
// a namespace field lookup
const SECURITY_ATTRIBUTES = windows.SECURITY_ATTRIBUTES;
fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) !void {
if (windows.CreatePipe(rd, wr, sattr, 0) == 0) {
const err = windows.GetLastError();
return switch (err) {
@ -709,7 +705,7 @@ fn windowsMakePipe(rd: &windows.HANDLE, wr: &windows.HANDLE, sattr: &const SECUR
}
}
fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) %void {
fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.DWORD) !void {
if (windows.SetHandleInformation(h, mask, flags) == 0) {
const err = windows.GetLastError();
return switch (err) {
@ -718,7 +714,7 @@ fn windowsSetHandleInfo(h: windows.HANDLE, mask: windows.DWORD, flags: windows.D
}
}
fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
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;
try windowsMakePipe(&rd_h, &wr_h, sattr);
@ -728,7 +724,7 @@ fn windowsMakePipeIn(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const S
*wr = wr_h;
}
fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const SECURITY_ATTRIBUTES) %void {
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;
try windowsMakePipe(&rd_h, &wr_h, sattr);
@ -738,7 +734,7 @@ fn windowsMakePipeOut(rd: &?windows.HANDLE, wr: &?windows.HANDLE, sattr: &const
*wr = wr_h;
}
fn makePipe() %[2]i32 {
fn makePipe() ![2]i32 {
var fds: [2]i32 = undefined;
const err = posix.getErrno(posix.pipe(&fds));
if (err > 0) {
@ -764,13 +760,13 @@ fn forkChildErrReport(fd: i32, err: error) noreturn {
const ErrInt = @IntType(false, @sizeOf(error) * 8);
fn writeIntFd(fd: i32, value: ErrInt) %void {
fn writeIntFd(fd: i32, value: ErrInt) !void {
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
mem.writeInt(bytes[0..], value, builtin.endian);
os.posixWrite(fd, bytes[0..]) catch return error.SystemResources;
}
fn readIntFd(fd: i32) %ErrInt {
fn readIntFd(fd: i32) !ErrInt {
var bytes: [@sizeOf(ErrInt)]u8 = undefined;
os.posixRead(fd, bytes[0..]) catch return error.SystemResources;
return mem.readInt(bytes[0..], ErrInt, builtin.endian);

View File

@ -9,7 +9,7 @@ pub const UserInfo = struct {
};
/// POSIX function which gets a uid from username.
pub fn getUserInfo(name: []const u8) %UserInfo {
pub fn getUserInfo(name: []const u8) !UserInfo {
return switch (builtin.os) {
Os.linux, Os.macosx, Os.ios => posixGetUserInfo(name),
else => @compileError("Unsupported OS"),
@ -24,13 +24,10 @@ const State = enum {
ReadGroupId,
};
error UserNotFound;
error CorruptPasswordFile;
// TODO this reads /etc/passwd. But sometimes the user/id mapping is in something else
// like NIS, AD, etc. See `man nss` or look at an strace for `id myuser`.
pub fn posixGetUserInfo(name: []const u8) %UserInfo {
pub fn posixGetUserInfo(name: []const u8) !UserInfo {
var in_stream = try io.InStream.open("/etc/passwd", null);
defer in_stream.close();

View File

@ -1470,8 +1470,6 @@ test "std.os" {
}
error Unexpected;
// TODO make this a build variable that you can set
const unexpected_error_tracing = false;

View File

@ -720,7 +720,7 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
// error SystemResources;
// error Io;
//
// pub fn if_nametoindex(name: []u8) %u32 {
// pub fn if_nametoindex(name: []u8) !u32 {
// var ifr: ifreq = undefined;
//
// if (name.len >= ifr.ifr_name.len) {

View File

@ -32,7 +32,7 @@ pub fn isSep(byte: u8) bool {
/// Naively combines a series of paths with the native path seperator.
/// Allocates memory for the result, which must be freed by the caller.
pub fn join(allocator: &Allocator, paths: ...) %[]u8 {
pub fn join(allocator: &Allocator, paths: ...) ![]u8 {
if (is_windows) {
return joinWindows(allocator, paths);
} else {
@ -40,11 +40,11 @@ pub fn join(allocator: &Allocator, paths: ...) %[]u8 {
}
}
pub fn joinWindows(allocator: &Allocator, paths: ...) %[]u8 {
pub fn joinWindows(allocator: &Allocator, paths: ...) ![]u8 {
return mem.join(allocator, sep_windows, paths);
}
pub fn joinPosix(allocator: &Allocator, paths: ...) %[]u8 {
pub fn joinPosix(allocator: &Allocator, paths: ...) ![]u8 {
return mem.join(allocator, sep_posix, paths);
}
@ -313,7 +313,7 @@ fn asciiEqlIgnoreCase(s1: []const u8, s2: []const u8) bool {
}
/// Converts the command line arguments into a slice and calls `resolveSlice`.
pub fn resolve(allocator: &Allocator, args: ...) %[]u8 {
pub fn resolve(allocator: &Allocator, args: ...) ![]u8 {
var paths: [args.len][]const u8 = undefined;
comptime var arg_i = 0;
inline while (arg_i < args.len) : (arg_i += 1) {
@ -323,7 +323,7 @@ pub fn resolve(allocator: &Allocator, args: ...) %[]u8 {
}
/// On Windows, this calls `resolveWindows` and on POSIX it calls `resolvePosix`.
pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) %[]u8 {
pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) ![]u8 {
if (is_windows) {
return resolveWindows(allocator, paths);
} else {
@ -337,7 +337,7 @@ pub fn resolveSlice(allocator: &Allocator, paths: []const []const u8) %[]u8 {
/// If all paths are relative it uses the current working directory as a starting point.
/// Each drive has its own current working directory.
/// Path separators are canonicalized to '\\' and drives are canonicalized to capital letters.
pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) %[]u8 {
pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(is_windows); // resolveWindows called on non windows can't use getCwd
return os.getCwd(allocator);
@ -520,7 +520,7 @@ pub fn resolveWindows(allocator: &Allocator, paths: []const []const u8) %[]u8 {
/// It resolves "." and "..".
/// The result does not have a trailing path separator.
/// If all paths are relative it uses the current working directory as a starting point.
pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) %[]u8 {
pub fn resolvePosix(allocator: &Allocator, paths: []const []const u8) ![]u8 {
if (paths.len == 0) {
assert(!is_windows); // resolvePosix called on windows can't use getCwd
return os.getCwd(allocator);
@ -890,7 +890,7 @@ fn testBasenameWindows(input: []const u8, expected_output: []const u8) void {
/// resolve to the same path (after calling `resolve` on each), a zero-length
/// string is returned.
/// On Windows this canonicalizes the drive to a capital letter and paths to `\\`.
pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
if (is_windows) {
return relativeWindows(allocator, from, to);
} else {
@ -898,7 +898,7 @@ pub fn relative(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
}
}
pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
const resolved_from = try resolveWindows(allocator, [][]const u8{from});
defer allocator.free(resolved_from);
@ -971,7 +971,7 @@ pub fn relativeWindows(allocator: &Allocator, from: []const u8, to: []const u8)
return []u8{};
}
pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) %[]u8 {
pub fn relativePosix(allocator: &Allocator, from: []const u8, to: []const u8) ![]u8 {
const resolved_from = try resolvePosix(allocator, [][]const u8{from});
defer allocator.free(resolved_from);
@ -1066,18 +1066,11 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons
assert(mem.eql(u8, result, expected_output));
}
error AccessDenied;
error FileNotFound;
error NotSupported;
error NotDir;
error NameTooLong;
error SymLinkLoop;
error InputOutput;
/// Return the canonicalized absolute pathname.
/// Expands all symbolic links and resolves references to `.`, `..`, and
/// extra `/` characters in ::pathname.
/// Caller must deallocate result.
pub fn real(allocator: &Allocator, pathname: []const u8) %[]u8 {
pub fn real(allocator: &Allocator, pathname: []const u8) ![]u8 {
switch (builtin.os) {
Os.windows => {
const pathname_buf = try allocator.alloc(u8, pathname.len + 1);

View File

@ -6,11 +6,7 @@ const mem = std.mem;
const BufMap = std.BufMap;
const cstr = std.cstr;
error WaitAbandoned;
error WaitTimeOut;
error Unexpected;
pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) %void {
pub fn windowsWaitSingle(handle: windows.HANDLE, milliseconds: windows.DWORD) !void {
const result = windows.WaitForSingleObject(handle, milliseconds);
return switch (result) {
windows.WAIT_ABANDONED => error.WaitAbandoned,
@ -30,12 +26,7 @@ pub fn windowsClose(handle: windows.HANDLE) void {
assert(windows.CloseHandle(handle) != 0);
}
error SystemResources;
error OperationAborted;
error IoPending;
error BrokenPipe;
pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) %void {
pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) !void {
if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
const err = windows.GetLastError();
return switch (err) {
@ -75,9 +66,6 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;
}
error SharingViolation;
error PipeBusy;
/// `file_path` may need to be copied in memory to add a null terminating byte. In this case
/// a fixed size buffer of size ::max_noalloc_path_len is an attempted solution. If the fixed
/// size buffer is too small, and the provided allocator is null, ::error.NameTooLong is returned.
@ -120,7 +108,7 @@ pub fn windowsOpen(file_path: []const u8, desired_access: windows.DWORD, share_m
}
/// Caller must free result.
pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) %[]u8 {
pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) ![]u8 {
// count bytes needed
const bytes_needed = x: {
var bytes_needed: usize = 1; // 1 for the final null byte
@ -151,8 +139,7 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
return result;
}
error DllNotFound;
pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) %windows.HMODULE {
pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) !windows.HMODULE {
const padded_buff = try cstr.addNullByte(allocator, dll_path);
defer allocator.free(padded_buff);
return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("YOUR_NAME_HERE", "src/main.zig");
exe.setBuildMode(mode);

View File

@ -8,9 +8,7 @@ const mem = std.mem;
const ArrayList = std.ArrayList;
const warn = std.debug.warn;
error InvalidArgs;
pub fn main() %void {
pub fn main() !void {
var arg_it = os.args();
// TODO use a more general purpose allocator here
@ -125,7 +123,7 @@ pub fn main() %void {
};
}
fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) %void {
fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) !void {
// run the build script to collect the options
if (!already_ran_build) {
builder.setInstallPrefix(null);
@ -188,7 +186,7 @@ fn usageAndErr(builder: &Builder, already_ran_build: bool, out_stream: &io.OutSt
return error.InvalidArgs;
}
fn unwrapArg(arg: %[]u8) %[]u8 {
fn unwrapArg(arg: %[]u8) ![]u8 {
return arg catch |err| {
warn("Unable to parse command line: {}\n", err);
return err;

View File

@ -1,11 +1,9 @@
const std = @import("./index.zig");
error Utf8InvalidStartByte;
/// Given the first byte of a UTF-8 codepoint,
/// returns a number 1-4 indicating the total length of the codepoint in bytes.
/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
pub fn utf8ByteSequenceLength(first_byte: u8) %u3 {
pub fn utf8ByteSequenceLength(first_byte: u8) !u3 {
if (first_byte < 0b10000000) return u3(1);
if (first_byte & 0b11100000 == 0b11000000) return u3(2);
if (first_byte & 0b11110000 == 0b11100000) return u3(3);
@ -13,16 +11,11 @@ pub fn utf8ByteSequenceLength(first_byte: u8) %u3 {
return error.Utf8InvalidStartByte;
}
error Utf8OverlongEncoding;
error Utf8ExpectedContinuation;
error Utf8EncodesSurrogateHalf;
error Utf8CodepointTooLarge;
/// Decodes the UTF-8 codepoint encoded in the given slice of bytes.
/// bytes.len must be equal to utf8ByteSequenceLength(bytes[0]) catch unreachable.
/// If you already know the length at comptime, you can call one of
/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
pub fn utf8Decode(bytes: []const u8) %u32 {
pub fn utf8Decode(bytes: []const u8) !u32 {
return switch (bytes.len) {
1 => u32(bytes[0]),
2 => utf8Decode2(bytes),
@ -31,7 +24,7 @@ pub fn utf8Decode(bytes: []const u8) %u32 {
else => unreachable,
};
}
pub fn utf8Decode2(bytes: []const u8) %u32 {
pub fn utf8Decode2(bytes: []const u8) !u32 {
std.debug.assert(bytes.len == 2);
std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);
var value: u32 = bytes[0] & 0b00011111;
@ -44,7 +37,7 @@ pub fn utf8Decode2(bytes: []const u8) %u32 {
return value;
}
pub fn utf8Decode3(bytes: []const u8) %u32 {
pub fn utf8Decode3(bytes: []const u8) !u32 {
std.debug.assert(bytes.len == 3);
std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);
var value: u32 = bytes[0] & 0b00001111;
@ -62,7 +55,7 @@ pub fn utf8Decode3(bytes: []const u8) %u32 {
return value;
}
pub fn utf8Decode4(bytes: []const u8) %u32 {
pub fn utf8Decode4(bytes: []const u8) !u32 {
std.debug.assert(bytes.len == 4);
std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);
var value: u32 = bytes[0] & 0b00000111;
@ -85,7 +78,6 @@ pub fn utf8Decode4(bytes: []const u8) %u32 {
return value;
}
error UnexpectedEof;
test "valid utf8" {
testValid("\x00", 0x0);
testValid("\x20", 0x20);
@ -161,7 +153,7 @@ fn testValid(bytes: []const u8, expected_codepoint: u32) void {
std.debug.assert((testDecode(bytes) catch unreachable) == expected_codepoint);
}
fn testDecode(bytes: []const u8) %u32 {
fn testDecode(bytes: []const u8) !u32 {
const length = try utf8ByteSequenceLength(bytes[0]);
if (bytes.len < length) return error.UnexpectedEof;
std.debug.assert(bytes.len == length);

View File

@ -32,7 +32,6 @@ fn funcWithConstPtrPtr(x: &const &i32) void {
**x += 1;
}
error ItBroke;
test "explicit cast from integer to error type" {
testCastIntToErr(error.ItBroke);
comptime testCastIntToErr(error.ItBroke);
@ -110,11 +109,11 @@ test "return null from fn() %?&T" {
const b = returnNullLitFromMaybeTypeErrorRef();
assert((try a) == null and (try b) == null);
}
fn returnNullFromMaybeTypeErrorRef() %?&A {
fn returnNullFromMaybeTypeErrorRef() !?&A {
const a: ?&A = null;
return a;
}
fn returnNullLitFromMaybeTypeErrorRef() %?&A {
fn returnNullLitFromMaybeTypeErrorRef() !?&A {
return null;
}
@ -170,7 +169,7 @@ fn testCastZeroArrayToErrSliceMut() void {
assert((gimmeErrOrSlice() catch unreachable).len == 0);
}
fn gimmeErrOrSlice() %[]u8 {
fn gimmeErrOrSlice() ![]u8 {
return []u8{};
}
@ -188,7 +187,7 @@ test "peer type resolution: [0]u8, []const u8, and %[]u8" {
assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
}
}
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) %[]u8 {
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) ![]u8 {
if (a) {
return []u8{};
}
@ -238,14 +237,13 @@ test "peer type resolution: error and [N]T" {
comptime assert(mem.eql(u8, try testPeerErrorAndArray2(1), "OKK"));
}
error BadValue;
//fn testPeerErrorAndArray(x: u8) %[]const u8 {
//fn testPeerErrorAndArray(x: u8) ![]const u8 {
// return switch (x) {
// 0x00 => "OK",
// else => error.BadValue,
// };
//}
fn testPeerErrorAndArray2(x: u8) %[]const u8 {
fn testPeerErrorAndArray2(x: u8) ![]const u8 {
return switch (x) {
0x00 => "OK",
0x01 => "OKK",

View File

@ -3,9 +3,7 @@ const assert = @import("std").debug.assert;
var result: [3]u8 = undefined;
var index: usize = undefined;
error FalseNotAllowed;
fn runSomeErrorDefers(x: bool) %bool {
fn runSomeErrorDefers(x: bool) !bool {
index = 0;
defer {result[index] = 'a'; index += 1;}
errdefer {result[index] = 'b'; index += 1;}

View File

@ -6,7 +6,7 @@ const ET = union(enum) {
SINT: i32,
UINT: u32,
pub fn print(a: &const ET, buf: []u8) %usize {
pub fn print(a: &const ET, buf: []u8) !usize {
return switch (*a) {
ET.SINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),
ET.UINT => |x| fmt.formatIntBuf(buf, x, 10, false, 0),

View File

@ -1,16 +1,16 @@
const assert = @import("std").debug.assert;
const mem = @import("std").mem;
pub fn foo() %i32 {
pub fn foo() !i32 {
const x = try bar();
return x + 1;
}
pub fn bar() %i32 {
pub fn bar() !i32 {
return 13;
}
pub fn baz() %i32 {
pub fn baz() !i32 {
const y = foo() catch 1234;
return y + 1;
}
@ -19,7 +19,6 @@ test "error wrapping" {
assert((baz() catch unreachable) == 15);
}
error ItBroke;
fn gimmeItBroke() []const u8 {
return @errorName(error.ItBroke);
}
@ -28,8 +27,6 @@ test "@errorName" {
assert(mem.eql(u8, @errorName(error.AnError), "AnError"));
assert(mem.eql(u8, @errorName(error.ALongerErrorName), "ALongerErrorName"));
}
error AnError;
error ALongerErrorName;
test "error values" {
@ -37,16 +34,11 @@ test "error values" {
const b = i32(error.err2);
assert(a != b);
}
error err1;
error err2;
test "redefinition of error values allowed" {
shouldBeNotEqual(error.AnError, error.SecondError);
}
error AnError;
error AnError;
error SecondError;
fn shouldBeNotEqual(a: error, b: error) void {
if (a == b) unreachable;
}
@ -58,8 +50,7 @@ test "error binary operator" {
assert(a == 3);
assert(b == 10);
}
error ItBroke;
fn errBinaryOperatorG(x: bool) %isize {
fn errBinaryOperatorG(x: bool) !isize {
return if (x) error.ItBroke else isize(10);
}
@ -75,11 +66,11 @@ test "error return in assignment" {
doErrReturnInAssignment() catch unreachable;
}
fn doErrReturnInAssignment() %void {
fn doErrReturnInAssignment() !void {
var x : i32 = undefined;
x = try makeANonErr();
}
fn makeANonErr() %i32 {
fn makeANonErr() !i32 {
return 1;
}

View File

@ -1,6 +1,6 @@
const assert = @import("std").debug.assert;
fn foo(id: u64) %i32 {
fn foo(id: u64) !i32 {
return switch (id) {
1 => getErrInt(),
2 => {
@ -13,8 +13,6 @@ fn foo(id: u64) %i32 {
fn getErrInt() %i32 { return 0; }
error ItBroke;
test "ir block deps" {
assert((foo(1) catch unreachable) == 0);
assert((foo(2) catch unreachable) == 0);

View File

@ -262,7 +262,7 @@ test "generic malloc free" {
memFree(u8, a);
}
const some_mem : [100]u8 = undefined;
fn memAlloc(comptime T: type, n: usize) %[]T {
fn memAlloc(comptime T: type, n: usize) ![]T {
return @ptrCast(&T, &some_mem[0])[0..n];
}
fn memFree(comptime T: type, memory: []T) void { }
@ -419,7 +419,7 @@ test "cast slice to u8 slice" {
test "pointer to void return type" {
testPointerToVoidReturnType() catch unreachable;
}
fn testPointerToVoidReturnType() %void {
fn testPointerToVoidReturnType() !void {
const a = testPointerToVoidReturnType2();
return *a;
}

View File

@ -225,7 +225,7 @@ fn switchWithUnreachable(x: i32) i32 {
return 10;
}
fn return_a_number() %i32 {
fn return_a_number() !i32 {
return 1;
}

View File

@ -2,19 +2,17 @@ const assert = @import("std").debug.assert;
var read_count: u64 = 0;
fn readOnce() %u64 {
fn readOnce() !u64 {
read_count += 1;
return read_count;
}
error InvalidDebugInfo;
const FormValue = union(enum) {
Address: u64,
Other: bool,
};
fn doThing(form_id: u64) %FormValue {
fn doThing(form_id: u64) !FormValue {
return switch (form_id) {
17 => FormValue { .Address = try readOnce() },
else => error.InvalidDebugInfo,

View File

@ -5,9 +5,7 @@ const FormValue = union(enum) {
Two: bool,
};
error Whatever;
fn foo(id: u64) %FormValue {
fn foo(id: u64) !FormValue {
return switch (id) {
2 => FormValue { .Two = true },
1 => FormValue { .One = {} },

View File

@ -17,10 +17,7 @@ fn tryOnErrorUnionImpl() void {
assert(x == 11);
}
error ItBroke;
error NoMem;
error CrappedOut;
fn returnsTen() %i32 {
fn returnsTen() !i32 {
return 10;
}
@ -32,7 +29,7 @@ test "try without vars" {
assert(result2 == 1);
}
fn failIfTrue(ok: bool) %void {
fn failIfTrue(ok: bool) !void {
if (ok) {
return error.ItBroke;
} else {

View File

@ -50,7 +50,7 @@ fn runContinueAndBreakTest() void {
test "return with implicit cast from while loop" {
returnWithImplicitCastFromWhileLoopTest() catch unreachable;
}
fn returnWithImplicitCastFromWhileLoopTest() %void {
fn returnWithImplicitCastFromWhileLoopTest() !void {
while (true) {
return;
}
@ -116,8 +116,7 @@ test "while with error union condition" {
}
var numbers_left: i32 = undefined;
error OutOfNumbers;
fn getNumberOrErr() %i32 {
fn getNumberOrErr() !i32 {
return if (numbers_left == 0)
error.OutOfNumbers
else x: {
@ -205,7 +204,6 @@ fn testContinueOuter() void {
fn returnNull() ?i32 { return null; }
fn returnMaybe(x: i32) ?i32 { return x; }
error YouWantedAnError;
fn returnError() %i32 { return error.YouWantedAnError; }
fn returnSuccess(x: i32) %i32 { return x; }
fn returnFalse() bool { return false; }

View File

@ -15,7 +15,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\use @import("std").io;
\\use @import("foo.zig");
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ privateFunction();
\\ const stdout = &(FileOutStream.init(&(getStdOut() catch unreachable)).stream);
\\ stdout.print("OK 2\n") catch unreachable;
@ -49,7 +49,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\use @import("foo.zig");
\\use @import("bar.zig");
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ foo_function();
\\ bar_function();
\\}
@ -89,7 +89,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
var tc = cases.create("two files use import each other",
\\use @import("a.zig");
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ ok();
\\}
, "OK\n");
@ -118,7 +118,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.add("hello world without libc",
\\const io = @import("std").io;
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print("Hello, world!\n{d4} {x3} {c}\n", u32(12), u16(0x12), u8('a')) catch unreachable;
\\}
@ -268,7 +268,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const z = io.stdin_fileno;
\\const x : @typeOf(y) = 1234;
\\const y : u16 = 5678;
\\pub fn main() %void {
\\pub fn main() !void {
\\ var x_local : i32 = print_ok(x);
\\}
\\fn print_ok(val: @typeOf(x)) @typeOf(foo) {
@ -351,7 +351,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ fn method(b: &const Bar) bool { return true; }
\\};
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ const bar = Bar {.field2 = 13,};
\\ const foo = Foo {.field1 = bar,};
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
@ -367,7 +367,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.add("defer with only fallthrough",
\\const io = @import("std").io;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
@ -380,7 +380,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.add("defer with return",
\\const io = @import("std").io;
\\const os = @import("std").os;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
@ -394,10 +394,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
cases.add("errdefer and it fails",
\\const io = @import("std").io;
\\pub fn main() %void {
\\pub fn main() !void {
\\ do_test() catch return;
\\}
\\fn do_test() %void {
\\fn do_test() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
@ -407,17 +407,17 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ stdout.print("after\n") catch unreachable;
\\}
\\error IToldYouItWouldFail;
\\fn its_gonna_fail() %void {
\\fn its_gonna_fail() !void {
\\ return error.IToldYouItWouldFail;
\\}
, "before\ndeferErr\ndefer1\n");
cases.add("errdefer and it passes",
\\const io = @import("std").io;
\\pub fn main() %void {
\\pub fn main() !void {
\\ do_test() catch return;
\\}
\\fn do_test() %void {
\\fn do_test() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print("before\n") catch unreachable;
\\ defer stdout.print("defer1\n") catch unreachable;
@ -434,7 +434,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const foo_txt = @embedFile("foo.txt");
\\const io = @import("std").io;
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ const stdout = &(io.FileOutStream.init(&(io.getStdOut() catch unreachable)).stream);
\\ stdout.print(foo_txt) catch unreachable;
\\}
@ -452,7 +452,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const os = std.os;
\\const allocator = std.debug.global_allocator;
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ var args_it = os.args();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);
@ -493,7 +493,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\const os = std.os;
\\const allocator = std.debug.global_allocator;
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ var args_it = os.args();
\\ var stdout_file = try io.getStdOut();
\\ var stdout_adapter = io.FileOutStream.init(&stdout_file);

View File

@ -1383,7 +1383,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
, ".tmp_source.zig:6:13: error: cannot assign to constant");
cases.add("return from defer expression",
\\pub fn testTrickyDefer() %void {
\\pub fn testTrickyDefer() !void {
\\ defer canFail() catch {};
\\
\\ defer try canFail();
@ -1970,7 +1970,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\fn foo1(args: ...) void {}
\\fn foo2(args: ...) void {}
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ foos[0]();
\\}
,
@ -1982,7 +1982,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
\\fn foo1(arg: var) void {}
\\fn foo2(arg: var) void {}
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ foos[0](true);
\\}
,

View File

@ -5,7 +5,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() %void {
\\pub fn main() !void {
\\ @panic("oh no");
\\}
);
@ -14,7 +14,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() %void {
\\pub fn main() !void {
\\ const a = []i32{1, 2, 3, 4};
\\ baz(bar(a));
\\}
@ -29,7 +29,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = add(65530, 10);
\\ if (x == 0) return error.Whatever;
\\}
@ -43,7 +43,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = sub(10, 20);
\\ if (x == 0) return error.Whatever;
\\}
@ -57,7 +57,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = mul(300, 6000);
\\ if (x == 0) return error.Whatever;
\\}
@ -71,7 +71,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = neg(-32768);
\\ if (x == 32767) return error.Whatever;
\\}
@ -85,7 +85,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = div(-32768, -1);
\\ if (x == 32767) return error.Whatever;
\\}
@ -99,7 +99,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = shl(-16385, 1);
\\ if (x == 0) return error.Whatever;
\\}
@ -113,7 +113,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = shl(0b0010111111111111, 3);
\\ if (x == 0) return error.Whatever;
\\}
@ -127,7 +127,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = shr(-16385, 1);
\\ if (x == 0) return error.Whatever;
\\}
@ -141,7 +141,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = shr(0b0010111111111111, 3);
\\ if (x == 0) return error.Whatever;
\\}
@ -155,7 +155,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = div0(999, 0);
\\}
\\fn div0(a: i32, b: i32) i32 {
@ -168,7 +168,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = divExact(10, 3);
\\ if (x == 0) return error.Whatever;
\\}
@ -182,7 +182,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
\\ if (x.len == 0) return error.Whatever;
\\}
@ -196,7 +196,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = shorten_cast(200);
\\ if (x == 0) return error.Whatever;
\\}
@ -210,7 +210,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ const x = unsigned_cast(-10);
\\ if (x == 0) return error.Whatever;
\\}
@ -227,10 +227,10 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(0); // test failed
\\}
\\error Whatever;
\\pub fn main() %void {
\\pub fn main() !void {
\\ bar() catch unreachable;
\\}
\\fn bar() %void {
\\fn bar() !void {
\\ return error.Whatever;
\\}
);
@ -239,7 +239,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
\\pub fn main() %void {
\\pub fn main() !void {
\\ _ = bar(9999);
\\}
\\fn bar(x: u32) error {
@ -252,7 +252,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ @import("std").os.exit(126);
\\}
\\error Wrong;
\\pub fn main() %void {
\\pub fn main() !void {
\\ var array align(4) = []u32{0x11111111, 0x11111111};
\\ const bytes = ([]u8)(array[0..]);
\\ if (foo(bytes) != 0x11111111) return error.Wrong;
@ -274,7 +274,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\ int: u32,
\\};
\\
\\pub fn main() %void {
\\pub fn main() !void {
\\ var f = Foo { .int = 42 };
\\ bar(&f);
\\}

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const main = b.addTest("main.zig");
main.setBuildMode(b.standardReleaseOptions());

View File

@ -6,9 +6,6 @@ const assert = debug.assert;
const Buffer = std.Buffer;
const ArrayList = std.ArrayList;
error InvalidInput;
error OutOfMem;
const Token = union(enum) {
Word: []const u8,
OpenBrace,
@ -19,7 +16,7 @@ const Token = union(enum) {
var global_allocator: &mem.Allocator = undefined;
fn tokenize(input:[] const u8) %ArrayList(Token) {
fn tokenize(input:[] const u8) !ArrayList(Token) {
const State = enum {
Start,
Word,
@ -71,7 +68,7 @@ const Node = union(enum) {
Combine: []Node,
};
fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
fn parse(tokens: &const ArrayList(Token), token_index: &usize) !Node {
const first_token = tokens.items[*token_index];
*token_index += 1;
@ -107,7 +104,7 @@ fn parse(tokens: &const ArrayList(Token), token_index: &usize) %Node {
}
}
fn expandString(input: []const u8, output: &Buffer) %void {
fn expandString(input: []const u8, output: &Buffer) !void {
const tokens = try tokenize(input);
if (tokens.len == 1) {
return output.resize(0);
@ -135,7 +132,7 @@ fn expandString(input: []const u8, output: &Buffer) %void {
}
}
fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
fn expandNode(node: &const Node, output: &ArrayList(Buffer)) !void {
assert(output.len == 0);
switch (*node) {
Node.Scalar => |scalar| {
@ -172,7 +169,7 @@ fn expandNode(node: &const Node, output: &ArrayList(Buffer)) %void {
}
}
pub fn main() %void {
pub fn main() !void {
var stdin_file = try io.getStdIn();
var stdout_file = try io.getStdOut();

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const obj = b.addObject("test", "test.zig");
const test_step = b.step("test", "Test the program");

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
const exe = b.addExecutable("test", "test.zig");
exe.addPackagePath("my_pkg", "pkg.zig");

View File

@ -1,6 +1,6 @@
const my_pkg = @import("my_pkg");
const assert = @import("std").debug.assert;
pub fn main() %void {
pub fn main() !void {
assert(my_pkg.add(10, 20) == 30);
}

View File

@ -1,6 +1,6 @@
const Builder = @import("std").build.Builder;
pub fn build(b: &Builder) %void {
pub fn build(b: &Builder) !void {
b.addCIncludePath(".");
const main = b.addTest("main.zig");

View File

@ -45,9 +45,6 @@ const test_targets = []TestTarget {
},
};
error TestFailed;
error CompilationIncorrectlySucceeded;
const max_stdout_size = 1 * 1024 * 1024; // 1 MB
pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) &build.Step {
@ -248,7 +245,7 @@ pub const CompareOutputContext = struct {
return ptr;
}
fn make(step: &build.Step) %void {
fn make(step: &build.Step) !void {
const self = @fieldParentPtr(RunCompareOutputStep, "step", step);
const b = self.context.b;
@ -337,7 +334,7 @@ pub const CompareOutputContext = struct {
return ptr;
}
fn make(step: &build.Step) %void {
fn make(step: &build.Step) !void {
const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
const b = self.context.b;
@ -563,7 +560,7 @@ pub const CompileErrorContext = struct {
return ptr;
}
fn make(step: &build.Step) %void {
fn make(step: &build.Step) !void {
const self = @fieldParentPtr(CompileCmpOutputStep, "step", step);
const b = self.context.b;
@ -847,7 +844,7 @@ pub const TranslateCContext = struct {
return ptr;
}
fn make(step: &build.Step) %void {
fn make(step: &build.Step) !void {
const self = @fieldParentPtr(TranslateCCmpOutputStep, "step", step);
const b = self.context.b;
@ -1045,7 +1042,7 @@ pub const GenHContext = struct {
return ptr;
}
fn make(step: &build.Step) %void {
fn make(step: &build.Step) !void {
const self = @fieldParentPtr(GenHCmpOutputStep, "step", step);
const b = self.context.b;