diff --git a/doc/langref.html.in b/doc/langref.html.in index 24c4b324b..9e224b2e7 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -108,7 +108,7 @@ {#code_begin|exe|hello#} 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 @@ -129,8 +129,8 @@ pub fn main() void { } {#code_end#}
- Note that we also left off the %
from the return type.
- In Zig, if your main function cannot fail, you may use the void
return type.
+ Note that we also left off the !
from the return type.
+ In Zig, if your main function cannot fail, you must use the void
return type.
err
is the error
and is in scope of the expression b
.
const value: %u32 = null;
+ const value: error!u32 = error.Broken;
const unwrapped = value catch 1234;
unwrapped == 1234
x() x[] x.y
-!x -x -%x ~x *x &x ?x %x ??x
+a!b
+!x -x -%x ~x *x &x ?x ??x
x{}
! * / % ** *%
+ - ++ +% -%
@@ -2278,8 +2276,8 @@ fn eventuallyNullSequence() ?u32 {
break :blk numbers_left;
};
}
-error ReachedZero;
-fn eventuallyErrorSequence() %u32 {
+
+fn eventuallyErrorSequence() error!u32 {
return if (numbers_left == 0) error.ReachedZero else blk: {
numbers_left -= 1;
break :blk numbers_left;
@@ -2408,7 +2406,7 @@ fn typeNameLength(comptime T: type) usize {
// If expressions have three uses, corresponding to the three types:
// * bool
// * ?T
-// * %T
+// * error!T
const assert = @import("std").debug.assert;
@@ -2469,20 +2467,18 @@ test "if nullable" {
}
}
-error BadValue;
-error LessBadValue;
test "if error union" {
// If expressions test for errors.
// Note the |err| capture on the else.
- const a: %u32 = 0;
+ const a: error!u32 = 0;
if (a) |value| {
assert(value == 0);
} else |err| {
unreachable;
}
- const b: %u32 = error.BadValue;
+ const b: error!u32 = error.BadValue;
if (b) |value| {
unreachable;
} else |err| {
@@ -2500,7 +2496,7 @@ test "if error union" {
}
// Access the value by reference using a pointer capture.
- var c: %u32 = 3;
+ var c: error!u32 = 3;
if (c) |*value| {
*value = 9;
} else |err| {
@@ -2568,8 +2564,7 @@ test "defer unwinding" {
//
// This is especially useful in allowing a function to clean up properly
// on error, and replaces goto error handling tactics as seen in c.
-error DeferError;
-fn deferErrorExample(is_error: bool) %void {
+fn deferErrorExample(is_error: bool) !void {
warn("\nstart of function\n");
// This will always be executed on exit
@@ -2678,7 +2673,7 @@ test "foo" {
assert(value == 1234);
}
-fn bar() %u32 {
+fn bar() error!u32 {
return 1234;
}
@@ -2791,13 +2786,8 @@ test "implicitly cast to const pointer" {
One of the distinguishing features of Zig is its exception handling strategy.
- Among the top level declarations available is the error value declaration:
+ TODO rewrite the errors section to take into account error sets
- {#code_begin|syntax#}
-error FileNotFound;
-error OutOfMemory;
-error UnexpectedToken;
- {#code_end#}
These error values are assigned an unsigned integer value greater than 0 at
compile time. You are allowed to declare the same error value more than once,
@@ -2809,26 +2799,23 @@ error UnexpectedToken;
Each error value across the entire compilation unit gets a unique integer,
- and this determines the size of the pure error type.
+ and this determines the size of the error set type.
- The pure error type is one of the error values, and in the same way that pointers
- cannot be null, a pure error is always an error.
+ The error set type is one of the error values, and in the same way that pointers
+ cannot be null, a error set instance is always an error.
{#code_begin|syntax#}const pure_error = error.FileNotFound;{#code_end#}
- Most of the time you will not find yourself using a pure error type. Instead,
- likely you will be using the error union type. This is when you take a normal type,
- and prefix it with the %
operator.
+ Most of the time you will not find yourself using an error set type. Instead,
+ likely you will be using the error union type. This is when you take an error set
+ and a normal type, and create an error union with the !
binary operator.
Here is a function to parse a string into a 64-bit integer:
{#code_begin|test#}
-error InvalidChar;
-error Overflow;
-
-pub fn parseU64(buf: []const u8, radix: u8) %u64 {
+pub fn parseU64(buf: []const u8, radix: u8) !u64 {
var x: u64 = 0;
for (buf) |c| {
@@ -2867,13 +2854,14 @@ test "parse u64" {
}
{#code_end#}
- Notice the return type is %u64
. This means that the function
- either returns an unsigned 64 bit integer, or an error.
+ Notice the return type is !u64
. This means that the function
+ either returns an unsigned 64 bit integer, or an error. We left off the error set
+ to the left of the !
, so the error set is inferred.
Within the function definition, you can see some return statements that return
- a pure error, and at the bottom a return statement that returns a u64
.
- Both types implicitly cast to %u64
.
+ an error, and at the bottom a return statement that returns a u64
.
+ Both types implicitly cast to error!u64
.
What it looks like to use this function varies depending on what you're
@@ -2900,7 +2888,7 @@ fn doAThing(str: []u8) void {
Let's say you wanted to return the error if you got one, otherwise continue with the
function logic:
{#code_begin|syntax#}
-fn doAThing(str: []u8) %void {
+fn doAThing(str: []u8) !void {
const number = parseU64(str, 10) catch |err| return err;
// ...
}
@@ -2909,7 +2897,7 @@ fn doAThing(str: []u8) %void {
There is a shortcut for this. The try
expression:
{#code_begin|syntax#}
-fn doAThing(str: []u8) %void {
+fn doAThing(str: []u8) !void {
const number = try parseU64(str, 10);
// ...
}
@@ -2959,7 +2947,7 @@ fn doAThing(str: []u8) void {
Example:
{#code_begin|syntax#}
-fn createFoo(param: i32) %Foo {
+fn createFoo(param: i32) !Foo {
const foo = try tryToAllocateFoo();
// now we have allocated foo. we need to free it if the function fails.
// but we want to return it if the function succeeds.
@@ -3567,7 +3555,7 @@ pub fn main() void {
{#code_begin|syntax#}
/// Calls print and then flushes the buffer.
-pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void {
+pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) error!void {
const State = enum {
Start,
OpenBrace,
@@ -3639,7 +3627,7 @@ pub fn printf(self: &OutStream, comptime format: []const u8, args: ...) %void {
and emits a function that actually looks like this:
{#code_begin|syntax#}
-pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) %void {
+pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) !void {
try self.write("here is a string: '");
try self.printValue(arg0);
try self.write("' here is a number: ");
@@ -3653,7 +3641,7 @@ pub fn printf(self: &OutStream, arg0: i32, arg1: []const u8) %void {
on the type:
{#code_begin|syntax#}
-pub fn printValue(self: &OutStream, value: var) %void {
+pub fn printValue(self: &OutStream, value: var) !void {
const T = @typeOf(value);
if (@isInteger(T)) {
return self.printInt(T, value);
@@ -4582,7 +4570,7 @@ pub const TypeId = enum {
{#code_begin|syntax#}
const Builder = @import("std").build.Builder;
-pub fn build(b: &Builder) %void {
+pub fn build(b: &Builder) void {
const exe = b.addExecutable("example", "example.zig");
exe.setBuildMode(b.standardReleaseOptions());
b.default_step.dependOn(&exe.step);
@@ -4724,7 +4712,7 @@ comptime {
{#code_begin|exe_err#}
const math = @import("std").math;
const warn = @import("std").debug.warn;
-pub fn main() %void {
+pub fn main() !void {
var byte: u8 = 255;
byte = if (math.add(u8, byte, 1)) |result| result else |err| {
@@ -4752,7 +4740,7 @@ pub fn main() %void {
{#code_begin|exe#}
const warn = @import("std").debug.warn;
-pub fn main() %void {
+pub fn main() void {
var byte: u8 = 255;
var result: u8 = undefined;
@@ -4861,14 +4849,12 @@ pub fn main() void {
{#header_close#}
{#header_open|Attempt to Unwrap Error#}
At compile-time:
- {#code_begin|test_err|unable to unwrap error 'UnableToReturnNumber'#}
+ {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#}
comptime {
const number = getNumberOrFail() catch unreachable;
}
-error UnableToReturnNumber;
-
-fn getNumberOrFail() %i32 {
+fn getNumberOrFail() !i32 {
return error.UnableToReturnNumber;
}
{#code_end#}
@@ -4888,9 +4874,7 @@ pub fn main() void {
}
}
-error UnableToReturnNumber;
-
-fn getNumberOrFail() %i32 {
+fn getNumberOrFail() !i32 {
return error.UnableToReturnNumber;
}
{#code_end#}
@@ -4898,7 +4882,6 @@ fn getNumberOrFail() %i32 {
{#header_open|Invalid Error Code#}
At compile-time:
{#code_begin|test_err|integer value 11 represents no error#}
-error AnError;
comptime {
const err = error.AnError;
const number = u32(err) + 10;
@@ -5298,7 +5281,7 @@ int main(int argc, char **argv) {
{#code_begin|syntax#}
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");
diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig
index 20b905b59..def643096 100644
--- a/test/runtime_safety.zig
+++ b/test/runtime_safety.zig
@@ -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));
\\}
@@ -28,7 +28,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = add(65530, 10);
\\ if (x == 0) return error.Whatever;
@@ -42,7 +41,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = sub(10, 20);
\\ if (x == 0) return error.Whatever;
@@ -56,7 +54,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = mul(300, 6000);
\\ if (x == 0) return error.Whatever;
@@ -70,7 +67,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = neg(-32768);
\\ if (x == 32767) return error.Whatever;
@@ -84,7 +80,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = div(-32768, -1);
\\ if (x == 32767) return error.Whatever;
@@ -98,7 +93,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = shl(-16385, 1);
\\ if (x == 0) return error.Whatever;
@@ -112,7 +106,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = shl(0b0010111111111111, 3);
\\ if (x == 0) return error.Whatever;
@@ -126,7 +119,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = shr(-16385, 1);
\\ if (x == 0) return error.Whatever;
@@ -140,7 +132,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = shr(0b0010111111111111, 3);
\\ if (x == 0) return error.Whatever;
@@ -154,8 +145,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);
\\}
- \\error Whatever;
- \\pub fn main() !void {
+ \\pub fn main() void {
\\ const x = div0(999, 0);
\\}
\\fn div0(a: i32, b: i32) i32 {
@@ -167,7 +157,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = divExact(10, 3);
\\ if (x == 0) return error.Whatever;
@@ -181,7 +170,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
\\ if (x.len == 0) return error.Whatever;
@@ -195,7 +183,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = shorten_cast(200);
\\ if (x == 0) return error.Whatever;
@@ -209,7 +196,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Whatever;
\\pub fn main() !void {
\\ const x = unsigned_cast(-10);
\\ if (x == 0) return error.Whatever;
@@ -226,8 +212,7 @@ 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 {
@@ -239,7 +224,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 {
@@ -251,7 +236,6 @@ pub fn addCases(cases: &tests.CompareOutputContext) void {
\\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) noreturn {
\\ @import("std").os.exit(126);
\\}
- \\error Wrong;
\\pub fn main() !void {
\\ var array align(4) = []u32{0x11111111, 0x11111111};
\\ const bytes = ([]u8)(array[0..]);
@@ -274,7 +258,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);
\\}