| ... | ... | @@ -7584,6 +7584,8 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 7584 | 7584 | switch (cast_op) { |
| 7585 | 7585 | case CastOpNoCast: |
| 7586 | 7586 | zig_unreachable(); |
| 7587 | case CastOpErrSet: |
| 7588 | zig_panic("TODO"); |
| 7587 | 7589 | case CastOpNoop: |
| 7588 | 7590 | { |
| 7589 | 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 | 8041 | return result; |
| 8040 | 8042 | } |
| 8041 | 8043 | |
| 8042 | | // TODO this is an explicit cast and should actually coerce the type |
| 8043 | 8044 | static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 8044 | 8045 | TypeTableEntry *wanted_type) |
| 8045 | 8046 | { |
| 8046 | | TypeTableEntry *contained_set = value->value.type; |
| 8047 | | TypeTableEntry *container_set = wanted_type; |
| 8048 | | |
| 8049 | | assert(contained_set->id == TypeTableEntryIdErrorSet); |
| 8050 | | assert(container_set->id == TypeTableEntryIdErrorSet); |
| 8047 | assert(value->value.type->id == TypeTableEntryIdErrorSet); |
| 8048 | assert(wanted_type->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 | | !type_is_global_error_set(container_set)) |
| 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; |
| 8055 | if (!resolve_inferred_error_set(ira, wanted_type, source_instr->source_node)) { |
| 8056 | return ira->codegen->invalid_instruction; |
| 8062 | 8057 | } |
| 8063 | | ErrorMsg *err_msg = nullptr; |
| 8064 | | for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { |
| 8065 | | ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; |
| 8066 | | ErrorTableEntry *error_entry = errors[contained_error_entry->value]; |
| 8067 | | if (error_entry == nullptr) { |
| 8068 | | if (err_msg == nullptr) { |
| 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))); |
| 8058 | if (!type_is_global_error_set(wanted_type)) { |
| 8059 | bool subset = false; |
| 8060 | for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { |
| 8061 | if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { |
| 8062 | subset = true; |
| 8063 | break; |
| 8072 | 8064 | } |
| 8073 | | add_error_note(ira->codegen, err_msg, contained_error_entry->decl_node, |
| 8074 | | buf_sprintf("'%s.%s' not present in '%s'", buf_ptr(&contained_set->name), |
| 8075 | | buf_ptr(&contained_error_entry->name), buf_ptr(&container_set->name))); |
| 8065 | } |
| 8066 | if (!subset) { |
| 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 | 8074 | IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, |
| 8090 | 8075 | source_instr->scope, source_instr->source_node); |
| ... | ... | @@ -8094,7 +8079,7 @@ static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *sou |
| 8094 | 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 | 8083 | result->value.type = wanted_type; |
| 8099 | 8084 | return result; |
| 8100 | 8085 | } |