@@ -903,6 +903,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonError *
903
903
return IrInstructionIdAssertNonError;
904
904
}
905
905
906
+ static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnionFieldErrorSet *) {
907
+ return IrInstructionIdErrorUnionFieldErrorSet;
908
+ }
909
+
906
910
template<typename T>
907
911
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
908
912
T *special_instruction = allocate<T>(1);
@@ -2921,6 +2925,17 @@ static IrInstruction *ir_build_assert_non_error(IrBuilder *irb, Scope *scope, As
2921
2925
return &instruction->base;
2922
2926
}
2923
2927
2928
+ static IrInstruction *ir_build_error_union_field_error_set(IrBuilder *irb, Scope *scope, AstNode *source_node,
2929
+ IrInstruction *ptr)
2930
+ {
2931
+ IrInstructionErrorUnionFieldErrorSet *instruction = ir_build_instruction<IrInstructionErrorUnionFieldErrorSet>(irb, scope, source_node);
2932
+ instruction->ptr = ptr;
2933
+
2934
+ ir_ref_instruction(ptr, irb->current_basic_block);
2935
+
2936
+ return &instruction->base;
2937
+ }
2938
+
2924
2939
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2925
2940
results[ReturnKindUnconditional] = 0;
2926
2941
results[ReturnKindError] = 0;
@@ -3153,7 +3168,7 @@ static IrInstruction *ir_gen_ptr(IrBuilder *irb, Scope *scope, AstNode *node, LV
3153
3168
// must return the error code
3154
3169
IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, node, ptr, false);
3155
3170
ir_build_load_ptr(irb, scope, node, payload_ptr, result_loc);
3156
- return ir_build_unwrap_err_code (irb, scope, node, ptr);
3171
+ return ir_build_error_union_field_error_set (irb, scope, node, ptr);
3157
3172
}
3158
3173
case LValOptional:
3159
3174
zig_panic("TODO");
@@ -5109,11 +5124,12 @@ static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode
5109
5124
static IrInstruction *ir_gen_catch_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node,
5110
5125
AstNode *expr_node, LVal lval, IrInstruction *result_loc)
5111
5126
{
5112
- IrInstruction *err_val = ir_gen_node(irb, expr_node, scope, LValErrorUnion, result_loc);
5113
- if (err_val == irb->codegen->invalid_instruction)
5127
+ IrInstruction *err_code_ptr = ir_gen_node(irb, expr_node, scope, LValErrorUnion, result_loc);
5128
+ if (err_code_ptr == irb->codegen->invalid_instruction)
5114
5129
return irb->codegen->invalid_instruction;
5115
5130
5116
- ir_build_assert_non_error(irb, scope, source_node, err_val);
5131
+ IrInstruction *err_code = ir_build_load_ptr(irb, scope, source_node, err_code_ptr, nullptr);
5132
+ ir_build_assert_non_error(irb, scope, source_node, err_code);
5117
5133
5118
5134
return ir_gen_lval_ptr(irb, scope, source_node, lval, result_loc);
5119
5135
}
@@ -6453,11 +6469,12 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6453
6469
return ir_gen_catch_unreachable(irb, parent_scope, node, op1_node, lval, result_loc);
6454
6470
}
6455
6471
6456
- IrInstruction *err_val = ir_gen_node(irb, op1_node, parent_scope, LValErrorUnion, result_loc);
6457
- if (err_val == irb->codegen->invalid_instruction)
6472
+ IrInstruction *err_code_ptr = ir_gen_node(irb, op1_node, parent_scope, LValErrorUnion, result_loc);
6473
+ if (err_code_ptr == irb->codegen->invalid_instruction)
6458
6474
return irb->codegen->invalid_instruction;
6459
6475
6460
- IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_val);
6476
+ IrInstruction *opt_err_code = ir_build_load_ptr(irb, parent_scope, node, err_code_ptr, nullptr);
6477
+ IrInstruction *is_err = ir_build_test_nonnull(irb, parent_scope, node, opt_err_code);
6461
6478
6462
6479
IrInstruction *is_comptime;
6463
6480
if (ir_should_inline(irb->exec, parent_scope)) {
@@ -6480,7 +6497,9 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode
6480
6497
ZigVar *var = ir_create_var(irb, node, parent_scope, var_name,
6481
6498
is_const, is_const, is_shadowable, is_comptime);
6482
6499
err_scope = var->child_scope;
6483
- ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, err_val);
6500
+ IrInstruction *unwrapped_err_code_ptr = ir_build_unwrap_maybe(irb, err_scope, var_node,
6501
+ err_code_ptr, false);
6502
+ ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, nullptr, unwrapped_err_code_ptr);
6484
6503
} else {
6485
6504
err_scope = parent_scope;
6486
6505
}
@@ -19573,6 +19592,40 @@ static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstruct
19573
19592
}
19574
19593
}
19575
19594
19595
+ static IrInstruction *ir_analyze_instruction_error_union_field_error_set(IrAnalyze *ira,
19596
+ IrInstructionErrorUnionFieldErrorSet *instruction)
19597
+ {
19598
+ IrInstruction *ptr = instruction->ptr->child;
19599
+ if (type_is_invalid(ptr->value.type))
19600
+ return ira->codegen->invalid_instruction;
19601
+ ZigType *ptr_type = ptr->value.type;
19602
+
19603
+ assert(ptr_type->id == ZigTypeIdPointer);
19604
+
19605
+ ZigType *type_entry = ptr_type->data.pointer.child_type;
19606
+ if (type_is_invalid(type_entry))
19607
+ return ira->codegen->invalid_instruction;
19608
+
19609
+ if (type_entry->id != ZigTypeIdErrorUnion) {
19610
+ ir_add_error(ira, ptr,
19611
+ buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name)));
19612
+ return ira->codegen->invalid_instruction;
19613
+ }
19614
+
19615
+ ZigType *opt_err_set = get_optional_type(ira->codegen, type_entry->data.error_union.err_set_type);
19616
+ ZigType *result_type = get_pointer_to_type_extra(ira->codegen, opt_err_set,
19617
+ ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0);
19618
+
19619
+ if (instr_is_comptime(ptr)) {
19620
+ zig_panic("TODO need to change ConstExprValue x_err_union to have a ConstExprValue for error set value");
19621
+ }
19622
+
19623
+ IrInstruction *result = ir_build_error_union_field_error_set(&ira->new_irb,
19624
+ instruction->base.scope, instruction->base.source_node, ptr);
19625
+ result->value.type = result_type;
19626
+ return result;
19627
+ }
19628
+
19576
19629
static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira,
19577
19630
IrInstructionUnwrapErrCode *instruction)
19578
19631
{
@@ -19681,19 +19734,21 @@ static IrInstruction *ir_analyze_instruction_assert_non_error(IrAnalyze *ira,
19681
19734
if (type_is_invalid(err_code->value.type))
19682
19735
return ira->codegen->invalid_instruction;
19683
19736
19684
- assert(err_code->value.type->id == ZigTypeIdErrorSet);
19737
+ assert(err_code->value.type->id == ZigTypeIdOptional);
19738
+ assert(err_code->value.type->data.maybe.child_type->id == ZigTypeIdErrorSet);
19685
19739
19686
19740
if (instr_is_comptime(err_code)) {
19687
- ConstExprValue *err_val = ir_resolve_const(ira, err_code, UndefBad);
19688
- if (err_val == nullptr)
19741
+ ConstExprValue *opt_val = ir_resolve_const(ira, err_code, UndefBad);
19742
+ if (opt_val == nullptr)
19689
19743
return ira->codegen->invalid_instruction;
19744
+ ConstExprValue *err_val = opt_val->data.x_optional;
19745
+ if (err_val == nullptr)
19746
+ return ir_const_void(ira, &instruction->base);
19690
19747
ErrorTableEntry *err = err_val->data.x_err_set;
19691
- if (err != nullptr) {
19692
- ir_add_error(ira, &instruction->base,
19693
- buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
19694
- return ira->codegen->invalid_instruction;
19695
- }
19696
- return ir_const_void(ira, &instruction->base);
19748
+ assert(err != nullptr);
19749
+ ir_add_error(ira, &instruction->base,
19750
+ buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
19751
+ return ira->codegen->invalid_instruction;
19697
19752
}
19698
19753
19699
19754
ir_build_assert_non_error(&ira->new_irb, instruction->base.scope,
@@ -21593,6 +21648,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio
21593
21648
return ir_analyze_instruction_result_ptr_cast(ira, (IrInstructionResultPtrCast *)instruction);
21594
21649
case IrInstructionIdAllocaSrc:
21595
21650
return ir_analyze_instruction_alloca(ira, (IrInstructionAllocaSrc *)instruction);
21651
+ case IrInstructionIdErrorUnionFieldErrorSet:
21652
+ return ir_analyze_instruction_error_union_field_error_set(ira, (IrInstructionErrorUnionFieldErrorSet *)instruction);
21596
21653
case IrInstructionIdResultBytesToSlice:
21597
21654
zig_panic("TODO");
21598
21655
case IrInstructionIdResultSliceToBytes:
@@ -21829,6 +21886,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
21829
21886
case IrInstructionIdResultBytesToSlice:
21830
21887
case IrInstructionIdAllocaSrc:
21831
21888
case IrInstructionIdAllocaGen:
21889
+ case IrInstructionIdErrorUnionFieldErrorSet:
21832
21890
return false;
21833
21891
21834
21892
case IrInstructionIdLoadPtr:
0 commit comments