authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-08 22:18:13-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-08 22:18:13-05:00
log0efe441dfd422d4bfe501d5fbfbf15bd5951b494
treefb04d5fe84ebb766358331ca267467d22bc22193
parent54c06bf7158ce52c5de8d09f109215c467a3bf6a

if statements support comptime known test error, runtime payload


3 files changed, 16 insertions(+), 29 deletions(-)

TODO+1-22
......@@ -1,25 +1,3 @@
1sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find . -name "*.zig")
2
3
4the literal translation of `%T` to this new code is `error!T`.
5however this would not take advantage of error sets. It's
6recommended to generally have all your functions which return possible
7errors to use error set inference, like this:
8
9fn foo() !void {
10
11}
12
13then you can return void, or any error, and the error set is inferred.
14
15
16you can get the compiler to tell you the possible errors for an inferred error set like this:
17
18foo() catch |err| switch (err) {};
19
20
21test err should be comptime if error set has 0 members
22
231comptime calling fn with inferred error set should give empty error set but still you can use try
242
253comptime err to int of empty err set and of size 1 err set
......@@ -35,3 +13,4 @@ syntax - (error{}!void) as the return type
3513
3614
3715passing a fn()error{}!T to a fn()error!T should be a compile error, they're not compatible
16
src/ir.cpp+4-7
......@@ -4800,12 +4800,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
48004800 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
48014801 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd");
48024802
4803 IrInstruction *is_comptime;
4804 if (ir_should_inline(irb->exec, scope)) {
4805 is_comptime = ir_build_const_bool(irb, scope, node, true);
4806 } else {
4807 is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
4808 }
4803 bool force_comptime = ir_should_inline(irb->exec, scope);
4804 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
48094805 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
48104806
48114807 ir_set_cursor_at_end_and_append_block(irb, ok_block);
......@@ -4814,8 +4810,9 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
48144810 if (var_symbol) {
48154811 IrInstruction *var_type = nullptr;
48164812 bool is_shadowable = false;
4813 IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, err_val);
48174814 VariableTableEntry *var = ir_create_var(irb, node, scope,
4818 var_symbol, var_is_const, var_is_const, is_shadowable, is_comptime);
4815 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
48194816
48204817 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, scope, node, err_val_ptr, false);
48214818 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
test/cases/error.zig+11
......@@ -123,3 +123,14 @@ fn testExplicitErrorSetCast(set1: Set1) void {
123123 var y = Set1(x);
124124 assert(y == error.A);
125125}
126
127test "comptime test error for empty error set" {
128 testComptimeTestErrorEmptySet(1234);
129 comptime testComptimeTestErrorEmptySet(1234);
130}
131
132const EmptyErrorSet = error {};
133
134fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
135 if (x) |v| assert(v == 1234) else |err| @compileError("bad");
136}