Commit 0efe441dfd

Andrew Kelley <superjoe30@gmail.com>
2018-02-09 04:18:13
if statements support comptime known test error, runtime payload
1 parent 54c06bf
Changed files (3)
src
test
cases
src/ir.cpp
@@ -4800,12 +4800,8 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
     IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
     IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd");
 
-    IrInstruction *is_comptime;
-    if (ir_should_inline(irb->exec, scope)) {
-        is_comptime = ir_build_const_bool(irb, scope, node, true);
-    } else {
-        is_comptime = ir_build_test_comptime(irb, scope, node, is_err);
-    }
+    bool force_comptime = ir_should_inline(irb->exec, scope);
+    IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err);
     ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
 
     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 *
     if (var_symbol) {
         IrInstruction *var_type = nullptr;
         bool is_shadowable = false;
+        IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, err_val);
         VariableTableEntry *var = ir_create_var(irb, node, scope,
-                var_symbol, var_is_const, var_is_const, is_shadowable, is_comptime);
+                var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
 
         IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, scope, node, err_val_ptr, false);
         IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, node, var_ptr_value);
test/cases/error.zig
@@ -123,3 +123,14 @@ fn testExplicitErrorSetCast(set1: Set1) void {
     var y = Set1(x);
     assert(y == error.A);
 }
+
+test "comptime test error for empty error set" {
+    testComptimeTestErrorEmptySet(1234);
+    comptime testComptimeTestErrorEmptySet(1234);
+}
+
+const EmptyErrorSet = error {};
+
+fn testComptimeTestErrorEmptySet(x: EmptyErrorSet!i32) void {
+    if (x) |v| assert(v == 1234) else |err| @compileError("bad");
+}
TODO
@@ -1,25 +1,3 @@
-sed -i 's/\(\bfn .*) \)%\(.*{\)$/\1!\2/g' $(find . -name "*.zig")
-
-
-the literal translation of `%T` to this new code is `error!T`.
-however this would not take advantage of error sets. It's
-recommended to generally have all your functions which return possible
-errors to use error set inference, like this:
-
-fn foo() !void {
-
-}
-
-then you can return void, or any error, and the error set is inferred.
-
-
-you can get the compiler to tell you the possible errors for an inferred error set like this:
-
-foo() catch |err| switch (err) {};
-
-
-test err should be comptime if error set has 0 members
-
 comptime calling fn with inferred error set should give empty error set but still you can use try
 
 comptime err to int of empty err set and of size 1 err set
@@ -35,3 +13,4 @@ syntax - (error{}!void) as the return type
 
 
 passing a fn()error{}!T to a fn()error!T should be a compile error, they're not compatible
+