| ... | ... | @@ -1934,10 +1934,27 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 1934 | 1934 | size_t defer_counts[3]; |
| 1935 | 1935 | ir_count_defers(irb, scope, outer_scope, defer_counts); |
| 1936 | 1936 | if (defer_counts[ReturnKindError] > 0) { |
| 1937 | | // TODO in this situation we need to make a conditional |
| 1938 | | // branch on the return value. we potentially must make multiple conditional branches, |
| 1939 | | // if unconditional defers are interleaved with error defers. |
| 1940 | | zig_panic("TODO handle error defers"); |
| 1937 | IrBasicBlock *err_block = ir_build_basic_block(irb, scope, "ErrRetErr"); |
| 1938 | IrBasicBlock *ok_block = ir_build_basic_block(irb, scope, "ErrRetOk"); |
| 1939 | |
| 1940 | IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); |
| 1941 | |
| 1942 | IrInstruction *is_comptime; |
| 1943 | if (ir_should_inline(irb)) { |
| 1944 | is_comptime = ir_build_const_bool(irb, scope, node, true); |
| 1945 | } else { |
| 1946 | is_comptime = ir_build_test_comptime(irb, scope, node, is_err); |
| 1947 | } |
| 1948 | |
| 1949 | ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime); |
| 1950 | |
| 1951 | ir_set_cursor_at_end(irb, err_block); |
| 1952 | ir_gen_defers_for_block(irb, scope, outer_scope, true, false); |
| 1953 | ir_build_return(irb, scope, node, return_value); |
| 1954 | |
| 1955 | ir_set_cursor_at_end(irb, ok_block); |
| 1956 | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 1957 | return ir_build_return(irb, scope, node, return_value); |
| 1941 | 1958 | } else if (defer_counts[ReturnKindMaybe] > 0) { |
| 1942 | 1959 | // TODO in this situation we need to make a conditional |
| 1943 | 1960 | // branch on the maybe value. we potentially must make multiple conditional branches, |
| ... | ... | @@ -1946,8 +1963,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 1946 | 1963 | } else { |
| 1947 | 1964 | // generate unconditional defers |
| 1948 | 1965 | ir_gen_defers_for_block(irb, scope, outer_scope, false, false); |
| 1966 | return ir_build_return(irb, scope, node, return_value); |
| 1949 | 1967 | } |
| 1950 | | return ir_build_return(irb, scope, node, return_value); |
| 1951 | 1968 | } |
| 1952 | 1969 | case ReturnKindError: |
| 1953 | 1970 | { |
| ... | ... | @@ -1955,7 +1972,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, |
| 1955 | 1972 | IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPurposeAddressOf); |
| 1956 | 1973 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 1957 | 1974 | return irb->codegen->invalid_instruction; |
| 1958 | | IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_ptr); |
| 1975 | IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); |
| 1976 | IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); |
| 1959 | 1977 | |
| 1960 | 1978 | IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "ErrRetReturn"); |
| 1961 | 1979 | IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "ErrRetContinue"); |
| ... | ... | @@ -3932,7 +3950,8 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN |
| 3932 | 3950 | if (err_union_ptr == irb->codegen->invalid_instruction) |
| 3933 | 3951 | return irb->codegen->invalid_instruction; |
| 3934 | 3952 | |
| 3935 | | IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_ptr); |
| 3953 | IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); |
| 3954 | IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); |
| 3936 | 3955 | |
| 3937 | 3956 | IrInstruction *is_comptime; |
| 3938 | 3957 | if (ir_should_inline(irb)) { |
| ... | ... | @@ -9443,26 +9462,20 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc |
| 9443 | 9462 | if (value->type_entry->id == TypeTableEntryIdInvalid) |
| 9444 | 9463 | return ira->codegen->builtin_types.entry_invalid; |
| 9445 | 9464 | |
| 9446 | | TypeTableEntry *ptr_type = value->type_entry; |
| 9447 | | |
| 9448 | | // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. |
| 9449 | | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 9465 | TypeTableEntry *non_canon_type = value->type_entry; |
| 9450 | 9466 | |
| 9451 | | TypeTableEntry *non_canon_type = ptr_type->data.pointer.child_type; |
| 9452 | 9467 | TypeTableEntry *canon_type = get_underlying_type(non_canon_type); |
| 9453 | 9468 | if (canon_type->id == TypeTableEntryIdInvalid) { |
| 9454 | 9469 | return ira->codegen->builtin_types.entry_invalid; |
| 9455 | 9470 | } else if (canon_type->id == TypeTableEntryIdErrorUnion) { |
| 9456 | 9471 | if (instr_is_comptime(value)) { |
| 9457 | | ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); |
| 9458 | | if (!ptr_val) |
| 9472 | ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); |
| 9473 | if (!err_union_val) |
| 9459 | 9474 | return ira->codegen->builtin_types.entry_invalid; |
| 9460 | | ConstExprValue *err_union_val = ptr_val->data.x_ptr.base_ptr; |
| 9461 | | assert(ptr_val->data.x_ptr.index == SIZE_MAX); |
| 9462 | 9475 | |
| 9463 | 9476 | if (err_union_val->special != ConstValSpecialRuntime) { |
| 9464 | | bool depends_on_compile_var = ptr_val->depends_on_compile_var || err_union_val->depends_on_compile_var; |
| 9465 | | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, depends_on_compile_var); |
| 9477 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, |
| 9478 | err_union_val->depends_on_compile_var); |
| 9466 | 9479 | out_val->data.x_bool = (err_union_val->data.x_err_union.err != nullptr); |
| 9467 | 9480 | return ira->codegen->builtin_types.entry_bool; |
| 9468 | 9481 | } |
| ... | ... | @@ -9470,11 +9483,14 @@ static TypeTableEntry *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruc |
| 9470 | 9483 | |
| 9471 | 9484 | ir_build_test_err_from(&ira->new_irb, &instruction->base, value); |
| 9472 | 9485 | return ira->codegen->builtin_types.entry_bool; |
| 9486 | } else if (canon_type->id == TypeTableEntryIdPureError) { |
| 9487 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, false); |
| 9488 | out_val->data.x_bool = true; |
| 9489 | return ira->codegen->builtin_types.entry_bool; |
| 9473 | 9490 | } else { |
| 9474 | | ir_add_error(ira, value, |
| 9475 | | buf_sprintf("expected error union type, found '%s'", buf_ptr(&non_canon_type->name))); |
| 9476 | | // TODO if this is a typedecl, add error note showing the declaration of the type decl |
| 9477 | | return ira->codegen->builtin_types.entry_invalid; |
| 9491 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base, false); |
| 9492 | out_val->data.x_bool = false; |
| 9493 | return ira->codegen->builtin_types.entry_bool; |
| 9478 | 9494 | } |
| 9479 | 9495 | } |
| 9480 | 9496 | |