| ... | ... | @@ -198,6 +198,8 @@ static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNo |
| 198 | 198 | IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, |
| 199 | 199 | LVal lval, ResultLoc *parent_result_loc); |
| 200 | 200 | static void ir_reset_result(ResultLoc *result_loc); |
| 201 | static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, |
| 202 | Scope *scope, AstNode *source_node, Buf *out_bare_name); |
| 201 | 203 | |
| 202 | 204 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 203 | 205 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | ... | @@ -469,6 +471,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { |
| 469 | 471 | return IrInstructionIdBinOp; |
| 470 | 472 | } |
| 471 | 473 | |
| 474 | static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrSets *) { |
| 475 | return IrInstructionIdMergeErrSets; |
| 476 | } |
| 477 | |
| 472 | 478 | static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { |
| 473 | 479 | return IrInstructionIdExport; |
| 474 | 480 | } |
| ... | ... | @@ -1290,6 +1296,20 @@ static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1290 | 1296 | return &bin_op_instruction->base; |
| 1291 | 1297 | } |
| 1292 | 1298 | |
| 1299 | static IrInstruction *ir_build_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 1300 | IrInstruction *op1, IrInstruction *op2, Buf *type_name) |
| 1301 | { |
| 1302 | IrInstructionMergeErrSets *merge_err_sets_instruction = ir_build_instruction<IrInstructionMergeErrSets>(irb, scope, source_node); |
| 1303 | merge_err_sets_instruction->op1 = op1; |
| 1304 | merge_err_sets_instruction->op2 = op2; |
| 1305 | merge_err_sets_instruction->type_name = type_name; |
| 1306 | |
| 1307 | ir_ref_instruction(op1, irb->current_basic_block); |
| 1308 | ir_ref_instruction(op2, irb->current_basic_block); |
| 1309 | |
| 1310 | return &merge_err_sets_instruction->base; |
| 1311 | } |
| 1312 | |
| 1293 | 1313 | static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, |
| 1294 | 1314 | ScopeFnDef *crossed_fndef_scope) |
| 1295 | 1315 | { |
| ... | ... | @@ -3894,6 +3914,20 @@ static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *no |
| 3894 | 3914 | return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); |
| 3895 | 3915 | } |
| 3896 | 3916 | |
| 3917 | static IrInstruction *ir_gen_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3918 | IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); |
| 3919 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3920 | |
| 3921 | if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) |
| 3922 | return irb->codegen->invalid_instruction; |
| 3923 | |
| 3924 | // TODO only pass type_name when the || operator is the top level AST node in the var decl expr |
| 3925 | Buf bare_name = BUF_INIT; |
| 3926 | Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error", scope, node, &bare_name); |
| 3927 | |
| 3928 | return ir_build_merge_err_sets(irb, scope, node, op1, op2, type_name); |
| 3929 | } |
| 3930 | |
| 3897 | 3931 | static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3898 | 3932 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3899 | 3933 | if (lvalue == irb->codegen->invalid_instruction) |
| ... | ... | @@ -3913,6 +3947,19 @@ static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) |
| 3913 | 3947 | return ir_build_const_void(irb, scope, node); |
| 3914 | 3948 | } |
| 3915 | 3949 | |
| 3950 | static IrInstruction *ir_gen_assign_merge_err_sets(IrBuilder *irb, Scope *scope, AstNode *node) { |
| 3951 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3952 | if (lvalue == irb->codegen->invalid_instruction) |
| 3953 | return lvalue; |
| 3954 | IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); |
| 3955 | IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); |
| 3956 | if (op2 == irb->codegen->invalid_instruction) |
| 3957 | return op2; |
| 3958 | IrInstruction *result = ir_build_merge_err_sets(irb, scope, node, op1, op2, nullptr); |
| 3959 | ir_build_store_ptr(irb, scope, node, lvalue, result); |
| 3960 | return ir_build_const_void(irb, scope, node); |
| 3961 | } |
| 3962 | |
| 3916 | 3963 | static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { |
| 3917 | 3964 | IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr, nullptr); |
| 3918 | 3965 | if (lvalue == irb->codegen->invalid_instruction) |
| ... | ... | @@ -4153,7 +4200,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4153 | 4200 | case BinOpTypeAssignBitOr: |
| 4154 | 4201 | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); |
| 4155 | 4202 | case BinOpTypeAssignMergeErrorSets: |
| 4156 | | return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 4203 | return ir_lval_wrap(irb, scope, ir_gen_assign_merge_err_sets(irb, scope, node), lval, result_loc); |
| 4157 | 4204 | case BinOpTypeBoolOr: |
| 4158 | 4205 | return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); |
| 4159 | 4206 | case BinOpTypeBoolAnd: |
| ... | ... | @@ -4201,7 +4248,7 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, |
| 4201 | 4248 | case BinOpTypeArrayMult: |
| 4202 | 4249 | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); |
| 4203 | 4250 | case BinOpTypeMergeErrorSets: |
| 4204 | | return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); |
| 4251 | return ir_lval_wrap(irb, scope, ir_gen_merge_err_sets(irb, scope, node), lval, result_loc); |
| 4205 | 4252 | case BinOpTypeUnwrapOptional: |
| 4206 | 4253 | return ir_gen_orelse(irb, scope, node, lval, result_loc); |
| 4207 | 4254 | case BinOpTypeErrorUnion: |
| ... | ... | @@ -7859,7 +7906,9 @@ static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, |
| 7859 | 7906 | } |
| 7860 | 7907 | |
| 7861 | 7908 | // errors should be populated with set1's values |
| 7862 | | static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2) { |
| 7909 | static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2, |
| 7910 | Buf *type_name) |
| 7911 | { |
| 7863 | 7912 | assert(set1->id == ZigTypeIdErrorSet); |
| 7864 | 7913 | assert(set2->id == ZigTypeIdErrorSet); |
| 7865 | 7914 | |
| ... | ... | @@ -7867,8 +7916,12 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp |
| 7867 | 7916 | err_set_type->size_in_bits = g->builtin_types.entry_global_error_set->size_in_bits; |
| 7868 | 7917 | err_set_type->abi_align = g->builtin_types.entry_global_error_set->abi_align; |
| 7869 | 7918 | err_set_type->abi_size = g->builtin_types.entry_global_error_set->abi_size; |
| 7870 | | buf_resize(&err_set_type->name, 0); |
| 7871 | | buf_appendf(&err_set_type->name, "error{"); |
| 7919 | if (type_name == nullptr) { |
| 7920 | buf_resize(&err_set_type->name, 0); |
| 7921 | buf_appendf(&err_set_type->name, "error{"); |
| 7922 | } else { |
| 7923 | buf_init_from_buf(&err_set_type->name, type_name); |
| 7924 | } |
| 7872 | 7925 | |
| 7873 | 7926 | for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { |
| 7874 | 7927 | assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); |
| ... | ... | @@ -7885,21 +7938,27 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp |
| 7885 | 7938 | err_set_type->data.error_set.err_count = count; |
| 7886 | 7939 | err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); |
| 7887 | 7940 | |
| 7941 | bool need_comma = false; |
| 7888 | 7942 | for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { |
| 7889 | 7943 | ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; |
| 7890 | | buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); |
| 7944 | if (type_name == nullptr) { |
| 7945 | const char *comma = need_comma ? "," : ""; |
| 7946 | need_comma = true; |
| 7947 | buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); |
| 7948 | } |
| 7891 | 7949 | err_set_type->data.error_set.errors[i] = error_entry; |
| 7892 | 7950 | } |
| 7893 | 7951 | |
| 7894 | 7952 | uint32_t index = set1->data.error_set.err_count; |
| 7895 | | bool need_comma = false; |
| 7896 | 7953 | for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { |
| 7897 | 7954 | ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; |
| 7898 | 7955 | if (errors[error_entry->value] == nullptr) { |
| 7899 | 7956 | errors[error_entry->value] = error_entry; |
| 7900 | | const char *comma = need_comma ? "," : ""; |
| 7901 | | need_comma = true; |
| 7902 | | buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); |
| 7957 | if (type_name == nullptr) { |
| 7958 | const char *comma = need_comma ? "," : ""; |
| 7959 | need_comma = true; |
| 7960 | buf_appendf(&err_set_type->name, "%s%s", comma, buf_ptr(&error_entry->name)); |
| 7961 | } |
| 7903 | 7962 | err_set_type->data.error_set.errors[index] = error_entry; |
| 7904 | 7963 | index += 1; |
| 7905 | 7964 | } |
| ... | ... | @@ -7907,7 +7966,9 @@ static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigTyp |
| 7907 | 7966 | assert(index == count); |
| 7908 | 7967 | assert(count != 0); |
| 7909 | 7968 | |
| 7910 | | buf_appendf(&err_set_type->name, "}"); |
| 7969 | if (type_name == nullptr) { |
| 7970 | buf_appendf(&err_set_type->name, "}"); |
| 7971 | } |
| 7911 | 7972 | |
| 7912 | 7973 | return err_set_type; |
| 7913 | 7974 | |
| ... | ... | @@ -9967,7 +10028,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 9967 | 10028 | } |
| 9968 | 10029 | |
| 9969 | 10030 | // neither of them are supersets. so we invent a new error set type that is a union of both of them |
| 9970 | | err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type); |
| 10031 | err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type, nullptr); |
| 9971 | 10032 | assert(errors != nullptr); |
| 9972 | 10033 | continue; |
| 9973 | 10034 | } else if (cur_type->id == ZigTypeIdErrorUnion) { |
| ... | ... | @@ -10018,7 +10079,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10018 | 10079 | } |
| 10019 | 10080 | |
| 10020 | 10081 | // not a subset. invent new error set type, union of both of them |
| 10021 | | err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type); |
| 10082 | err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type, nullptr); |
| 10022 | 10083 | prev_inst = cur_inst; |
| 10023 | 10084 | assert(errors != nullptr); |
| 10024 | 10085 | continue; |
| ... | ... | @@ -10074,7 +10135,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10074 | 10135 | continue; |
| 10075 | 10136 | } |
| 10076 | 10137 | // not a subset. invent new error set type, union of both of them |
| 10077 | | err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type); |
| 10138 | err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type, nullptr); |
| 10078 | 10139 | assert(errors != nullptr); |
| 10079 | 10140 | continue; |
| 10080 | 10141 | } |
| ... | ... | @@ -10160,7 +10221,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10160 | 10221 | continue; |
| 10161 | 10222 | } |
| 10162 | 10223 | |
| 10163 | | err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); |
| 10224 | err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type, nullptr); |
| 10164 | 10225 | continue; |
| 10165 | 10226 | } |
| 10166 | 10227 | } |
| ... | ... | @@ -10286,7 +10347,7 @@ static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigT |
| 10286 | 10347 | |
| 10287 | 10348 | update_errors_helper(ira->codegen, &errors, &errors_count); |
| 10288 | 10349 | |
| 10289 | | err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); |
| 10350 | err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type, nullptr); |
| 10290 | 10351 | } |
| 10291 | 10352 | prev_inst = cur_inst; |
| 10292 | 10353 | continue; |
| ... | ... | @@ -13795,7 +13856,6 @@ static ErrorMsg *ir_eval_math_op_scalar(IrAnalyze *ira, IrInstruction *source_in |
| 13795 | 13856 | case IrBinOpArrayCat: |
| 13796 | 13857 | case IrBinOpArrayMult: |
| 13797 | 13858 | case IrBinOpRemUnspecified: |
| 13798 | | case IrBinOpMergeErrorSets: |
| 13799 | 13859 | zig_unreachable(); |
| 13800 | 13860 | case IrBinOpBinOr: |
| 13801 | 13861 | assert(is_int); |
| ... | ... | @@ -14102,7 +14162,6 @@ static bool ok_float_op(IrBinOp op) { |
| 14102 | 14162 | case IrBinOpRemUnspecified: |
| 14103 | 14163 | case IrBinOpArrayCat: |
| 14104 | 14164 | case IrBinOpArrayMult: |
| 14105 | | case IrBinOpMergeErrorSets: |
| 14106 | 14165 | return false; |
| 14107 | 14166 | } |
| 14108 | 14167 | zig_unreachable(); |
| ... | ... | @@ -14603,7 +14662,9 @@ static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp * |
| 14603 | 14662 | return result; |
| 14604 | 14663 | } |
| 14605 | 14664 | |
| 14606 | | static IrInstruction *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionBinOp *instruction) { |
| 14665 | static IrInstruction *ir_analyze_instruction_merge_err_sets(IrAnalyze *ira, |
| 14666 | IrInstructionMergeErrSets *instruction) |
| 14667 | { |
| 14607 | 14668 | ZigType *op1_type = ir_resolve_error_set_type(ira, &instruction->base, instruction->op1->child); |
| 14608 | 14669 | if (type_is_invalid(op1_type)) |
| 14609 | 14670 | return ira->codegen->invalid_instruction; |
| ... | ... | @@ -14632,12 +14693,13 @@ static IrInstruction *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionB |
| 14632 | 14693 | assert(errors[error_entry->value] == nullptr); |
| 14633 | 14694 | errors[error_entry->value] = error_entry; |
| 14634 | 14695 | } |
| 14635 | | ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); |
| 14696 | ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type, instruction->type_name); |
| 14636 | 14697 | free(errors); |
| 14637 | 14698 | |
| 14638 | 14699 | return ir_const_type(ira, &instruction->base, result_type); |
| 14639 | 14700 | } |
| 14640 | 14701 | |
| 14702 | |
| 14641 | 14703 | static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { |
| 14642 | 14704 | IrBinOp op_id = bin_op_instruction->op_id; |
| 14643 | 14705 | switch (op_id) { |
| ... | ... | @@ -14679,8 +14741,6 @@ static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructio |
| 14679 | 14741 | return ir_analyze_array_cat(ira, bin_op_instruction); |
| 14680 | 14742 | case IrBinOpArrayMult: |
| 14681 | 14743 | return ir_analyze_array_mult(ira, bin_op_instruction); |
| 14682 | | case IrBinOpMergeErrorSets: |
| 14683 | | return ir_analyze_merge_error_sets(ira, bin_op_instruction); |
| 14684 | 14744 | } |
| 14685 | 14745 | zig_unreachable(); |
| 14686 | 14746 | } |
| ... | ... | @@ -25945,6 +26005,8 @@ static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction |
| 25945 | 26005 | return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); |
| 25946 | 26006 | case IrInstructionIdBinOp: |
| 25947 | 26007 | return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); |
| 26008 | case IrInstructionIdMergeErrSets: |
| 26009 | return ir_analyze_instruction_merge_err_sets(ira, (IrInstructionMergeErrSets *)instruction); |
| 25948 | 26010 | case IrInstructionIdDeclVarSrc: |
| 25949 | 26011 | return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVarSrc *)instruction); |
| 25950 | 26012 | case IrInstructionIdLoadPtr: |
| ... | ... | @@ -26370,6 +26432,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 26370 | 26432 | case IrInstructionIdPhi: |
| 26371 | 26433 | case IrInstructionIdUnOp: |
| 26372 | 26434 | case IrInstructionIdBinOp: |
| 26435 | case IrInstructionIdMergeErrSets: |
| 26373 | 26436 | case IrInstructionIdLoadPtr: |
| 26374 | 26437 | case IrInstructionIdConst: |
| 26375 | 26438 | case IrInstructionIdCast: |