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 @@...@@ -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
23comptime calling fn with inferred error set should give empty error set but still you can use try1comptime calling fn with inferred error set should give empty error set but still you can use try
242
25comptime err to int of empty err set and of size 1 err set3comptime err to int of empty err set and of size 1 err set
...@@ -35,3 +13,4 @@ syntax - (error{}!void) as the return type...@@ -35,3 +13,4 @@ syntax - (error{}!void) as the return type
3513
3614
37passing a fn()error{}!T to a fn()error!T should be a compile error, they're not compatible15passing 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 *...@@ -4800,12 +4800,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
4800 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");4800 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
4801 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd");4801 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd");
48024802
4803 IrInstruction *is_comptime;4803 bool force_comptime = ir_should_inline(irb->exec, scope);
4804 if (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);
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 }
4809 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);4805 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
48104806
4811 ir_set_cursor_at_end_and_append_block(irb, ok_block);4807 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 *...@@ -4814,8 +4810,9 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
4814 if (var_symbol) {4810 if (var_symbol) {
4815 IrInstruction *var_type = nullptr;4811 IrInstruction *var_type = nullptr;
4816 bool is_shadowable = false;4812 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);
4817 VariableTableEntry *var = ir_create_var(irb, node, scope,4814 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
4820 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, scope, node, err_val_ptr, false);4817 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, scope, node, err_val_ptr, false);
4821 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);4818 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 {...@@ -123,3 +123,14 @@ fn testExplicitErrorSetCast(set1: Set1) void {
123 var y = Set1(x);123 var y = Set1(x);
124 assert(y == error.A);124 assert(y == error.A);
125}125}
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}