| ... | @@ -7584,6 +7584,8 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -7584,6 +7584,8 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 7584 | switch (cast_op) { | 7584 | switch (cast_op) { |
| 7585 | case CastOpNoCast: | 7585 | case CastOpNoCast: |
| 7586 | zig_unreachable(); | 7586 | zig_unreachable(); |
| | 7587 | case CastOpErrSet: |
| | 7588 | zig_panic("TODO"); |
| 7587 | case CastOpNoop: | 7589 | case CastOpNoop: |
| 7588 | { | 7590 | { |
| 7589 | copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic); | 7591 | copy_const_val(const_val, other_val, other_val->special == ConstValSpecialStatic); |
| ... | @@ -8039,52 +8041,35 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction | ... | @@ -8039,52 +8041,35 @@ static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction |
| 8039 | return result; | 8041 | return result; |
| 8040 | } | 8042 | } |
| 8041 | | 8043 | |
| 8042 | // TODO this is an explicit cast and should actually coerce the type | | |
| 8043 | static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 8044 | static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 8044 | TypeTableEntry *wanted_type) | 8045 | TypeTableEntry *wanted_type) |
| 8045 | { | 8046 | { |
| 8046 | TypeTableEntry *contained_set = value->value.type; | 8047 | assert(value->value.type->id == TypeTableEntryIdErrorSet); |
| 8047 | TypeTableEntry *container_set = wanted_type; | 8048 | assert(wanted_type->id == TypeTableEntryIdErrorSet); |
| 8048 | | | |
| 8049 | assert(contained_set->id == TypeTableEntryIdErrorSet); | | |
| 8050 | assert(container_set->id == TypeTableEntryIdErrorSet); | | |
| 8051 | | 8049 | |
| 8052 | zig_panic("TODO explicit error set cast"); | 8050 | if (instr_is_comptime(value)) { |
| | 8051 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); |
| | 8052 | if (!val) |
| | 8053 | return ira->codegen->invalid_instruction; |
| 8053 | | 8054 | |
| 8054 | if (container_set->data.error_set.infer_fn == nullptr && | 8055 | if (!resolve_inferred_error_set(ira, wanted_type, source_instr->source_node)) { |
| 8055 | !type_is_global_error_set(container_set)) | 8056 | return ira->codegen->invalid_instruction; |
| 8056 | { | | |
| 8057 | ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); | | |
| 8058 | for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { | | |
| 8059 | ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; | | |
| 8060 | assert(errors[error_entry->value] == nullptr); | | |
| 8061 | errors[error_entry->value] = error_entry; | | |
| 8062 | } | 8057 | } |
| 8063 | ErrorMsg *err_msg = nullptr; | 8058 | if (!type_is_global_error_set(wanted_type)) { |
| 8064 | for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { | 8059 | bool subset = false; |
| 8065 | ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; | 8060 | for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { |
| 8066 | ErrorTableEntry *error_entry = errors[contained_error_entry->value]; | 8061 | if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { |
| 8067 | if (error_entry == nullptr) { | 8062 | subset = true; |
| 8068 | if (err_msg == nullptr) { | 8063 | break; |
| 8069 | err_msg = ir_add_error(ira, source_instr, | | |
| 8070 | buf_sprintf("invalid cast of error set '%s' to error set '%s'", | | |
| 8071 | buf_ptr(&contained_set->name), buf_ptr(&container_set->name))); | | |
| 8072 | } | 8064 | } |
| 8073 | add_error_note(ira->codegen, err_msg, contained_error_entry->decl_node, | 8065 | } |
| 8074 | buf_sprintf("'%s.%s' not present in '%s'", buf_ptr(&contained_set->name), | 8066 | if (!subset) { |
| 8075 | buf_ptr(&contained_error_entry->name), buf_ptr(&container_set->name))); | 8067 | ir_add_error(ira, source_instr, |
| | 8068 | buf_sprintf("error.%s not a member of error set '%s'", |
| | 8069 | buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); |
| | 8070 | return ira->codegen->invalid_instruction; |
| 8076 | } | 8071 | } |
| 8077 | } | 8072 | } |
| 8078 | free(errors); | | |
| 8079 | if (err_msg != nullptr) { | | |
| 8080 | return ira->codegen->invalid_instruction; | | |
| 8081 | } | | |
| 8082 | } | | |
| 8083 | | | |
| 8084 | if (instr_is_comptime(value)) { | | |
| 8085 | ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); | | |
| 8086 | if (!val) | | |
| 8087 | return ira->codegen->invalid_instruction; | | |
| 8088 | | 8073 | |
| 8089 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, | 8074 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 8090 | source_instr->scope, source_instr->source_node); | 8075 | source_instr->scope, source_instr->source_node); |
| ... | @@ -8094,7 +8079,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou | ... | @@ -8094,7 +8079,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 8094 | return &const_instruction->base; | 8079 | return &const_instruction->base; |
| 8095 | } | 8080 | } |
| 8096 | | 8081 | |
| 8097 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpNoop); | 8082 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); |
| 8098 | result->value.type = wanted_type; | 8083 | result->value.type = wanted_type; |
| 8099 | return result; | 8084 | return result; |
| 8100 | } | 8085 | } |