fix comptime test error for empty error set

This commit is contained in:
Andrew Kelley 2019-06-19 16:29:46 -04:00
parent 974db231a0
commit 96931228af
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
4 changed files with 35 additions and 14 deletions

View File

@ -3085,6 +3085,7 @@ struct IrInstructionAlignOf {
struct IrInstructionTestErrSrc {
IrInstruction base;
bool resolve_err_set;
IrInstruction *base_ptr;
};

View File

@ -4913,6 +4913,9 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, IrExecutable *executable, IrI
static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executable,
IrInstructionUnwrapErrCode *instruction)
{
if (instruction->base.value.special != ConstValSpecialRuntime)
return nullptr;
ZigType *ptr_type = instruction->err_union_ptr->value.type;
assert(ptr_type->id == ZigTypeIdPointer);
ZigType *err_union_type = ptr_type->data.pointer.child_type;
@ -4930,6 +4933,9 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, IrExecutable *executab
static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *executable,
IrInstructionUnwrapErrPayload *instruction)
{
if (instruction->base.value.special != ConstValSpecialRuntime)
return nullptr;
bool want_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base) &&
g->errors_by_index.length > 1;
if (!want_safety && !type_has_bits(instruction->base.value.type))

View File

@ -2446,10 +2446,11 @@ static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *s
}
static IrInstruction *ir_build_test_err_src(IrBuilder *irb, Scope *scope, AstNode *source_node,
IrInstruction *base_ptr)
IrInstruction *base_ptr, bool resolve_err_set)
{
IrInstructionTestErrSrc *instruction = ir_build_instruction<IrInstructionTestErrSrc>(irb, scope, source_node);
instruction->base_ptr = base_ptr;
instruction->resolve_err_set = resolve_err_set;
ir_ref_instruction(base_ptr, irb->current_basic_block);
@ -3593,7 +3594,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
IrInstruction *ret_ptr = ir_build_result_ptr(irb, scope, node, &result_loc_ret->base,
return_value);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, ret_ptr, false);
bool should_inline = ir_should_inline(irb->exec, scope);
IrInstruction *is_comptime;
@ -3639,7 +3640,7 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr, nullptr);
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr);
IrInstruction *is_err_val = ir_build_test_err_src(irb, scope, node, err_union_ptr, true);
IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
@ -5987,7 +5988,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
LValPtr, nullptr);
if (err_val_ptr == irb->codegen->invalid_instruction)
return err_val_ptr;
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node->data.while_expr.condition, err_val_ptr, true);
IrBasicBlock *after_cond_block = irb->current_basic_block;
IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node));
IrInstruction *cond_br_inst;
@ -6771,7 +6772,7 @@ static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *
return err_val_ptr;
IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr);
IrInstruction *is_err = ir_build_test_err_src(irb, scope, node, err_val_ptr, true);
IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");
IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
@ -7381,7 +7382,7 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
if (err_union_ptr == irb->codegen->invalid_instruction)
return irb->codegen->invalid_instruction;
IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr);
IrInstruction *is_err = ir_build_test_err_src(irb, parent_scope, node, err_union_ptr, true);
IrInstruction *is_comptime;
if (ir_should_inline(irb->exec, parent_scope)) {
@ -22512,6 +22513,19 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
}
}
if (instruction->resolve_err_set) {
ZigType *err_set_type = type_entry->data.error_union.err_set_type;
if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) {
return ira->codegen->invalid_instruction;
}
if (!type_is_global_error_set(err_set_type) &&
err_set_type->data.error_set.err_count == 0)
{
assert(err_set_type->data.error_set.infer_fn == nullptr);
return ir_const_bool(ira, &instruction->base, false);
}
}
return ir_build_test_err_gen(ira, &instruction->base, value);
} else if (type_entry->id == ZigTypeIdErrorSet) {
return ir_const_bool(ira, &instruction->base, true);

View File

@ -130,10 +130,10 @@ fn testExplicitErrorSetCast(set1: Set1) void {
expect(y == error.A);
}
//test "comptime test error for empty error set" {
// testComptimeTestErrorEmptySet(1234);
// comptime testComptimeTestErrorEmptySet(1234);
//}
test "comptime test error for empty error set" {
testComptimeTestErrorEmptySet(1234);
comptime testComptimeTestErrorEmptySet(1234);
}
const EmptyErrorSet = error{};
@ -204,10 +204,10 @@ fn foo2(f: fn () anyerror!void) void {
fn bar2() (error{}!void) {}
//test "error: Zero sized error set returned with value payload crash" {
// _ = foo3(0) catch {};
// _ = comptime foo3(0) catch {};
//}
test "error: Zero sized error set returned with value payload crash" {
_ = foo3(0) catch {};
_ = comptime foo3(0) catch {};
}
const Error = error{};
fn foo3(b: usize) Error!usize {