diff --git a/TODO b/TODO index 2f3f25c3d3f438dd972309a27efe168ff80caa2b..f67feb1630c0602ec4037a1c477c7ff233e0be7f 100644 --- a/TODO +++ b/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 + diff --git a/src/ir.cpp b/src/ir.cpp index fa2815d6ddc4b73f107cefcd67728e1a4f81e591..5f7e02848ad96115c8ee9cca07563a1bd98e6911 100644 --- a/src/ir.cpp +++ b/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); diff --git a/test/cases/error.zig b/test/cases/error.zig index 3d2835e723c195d1e8139665206a92610b5416ce..a8150620b261dfb26252fa63678350b548fe33f4 100644 --- a/test/cases/error.zig +++ b/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"); +}