| ... | @@ -138,6 +138,11 @@ struct ConstCastErrSetMismatch { | ... | @@ -138,6 +138,11 @@ struct ConstCastErrSetMismatch { |
| 138 | ZigList<ErrorTableEntry *> missing_errors; | 138 | ZigList<ErrorTableEntry *> missing_errors; |
| 139 | }; | 139 | }; |
| 140 | | 140 | |
| | 141 | enum UndefAllowed { |
| | 142 | UndefOk, |
| | 143 | UndefBad, |
| | 144 | }; |
| | 145 | |
| 141 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); | 146 | static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); |
| 142 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); | 147 | static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); |
| 143 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); | 148 | static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| ... | @@ -157,6 +162,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, | ... | @@ -157,6 +162,7 @@ static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, |
| 157 | ConstExprValue *out_val, ConstExprValue *ptr_val); | 162 | ConstExprValue *out_val, ConstExprValue *ptr_val); |
| 158 | static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, | 163 | static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, |
| 159 | ZigType *dest_type, IrInstruction *dest_type_src); | 164 | ZigType *dest_type, IrInstruction *dest_type_src); |
| | 165 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed); |
| 160 | | 166 | |
| 161 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 167 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 162 | assert(get_src_ptr_type(const_val->type) != nullptr); | 168 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -8063,15 +8069,153 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc | ... | @@ -8063,15 +8069,153 @@ static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruc |
| 8063 | return false; | 8069 | return false; |
| 8064 | } | 8070 | } |
| 8065 | | 8071 | |
| 8066 | ConstExprValue *const_val = &instruction->value; | 8072 | ConstExprValue *const_val = ir_resolve_const(ira, instruction, UndefBad); |
| 8067 | assert(const_val->special != ConstValSpecialRuntime); | 8073 | assert(const_val != nullptr); |
| | 8074 | |
| | 8075 | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt); |
| | 8076 | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat); |
| 8068 | | 8077 | |
| 8069 | bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || | | |
| 8070 | const_val->type->id == ZigTypeIdComptimeInt); | | |
| 8071 | bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || | | |
| 8072 | const_val->type->id == ZigTypeIdComptimeFloat); | | |
| 8073 | if (other_type->id == ZigTypeIdFloat) { | 8078 | if (other_type->id == ZigTypeIdFloat) { |
| 8074 | return true; | 8079 | if (const_val->type->id == ZigTypeIdComptimeInt || const_val->type->id == ZigTypeIdComptimeFloat) { |
| | 8080 | return true; |
| | 8081 | } |
| | 8082 | if (const_val->type->id == ZigTypeIdInt) { |
| | 8083 | BigFloat tmp_bf; |
| | 8084 | bigfloat_init_bigint(&tmp_bf, &const_val->data.x_bigint); |
| | 8085 | BigFloat orig_bf; |
| | 8086 | switch (other_type->data.floating.bit_count) { |
| | 8087 | case 16: { |
| | 8088 | float16_t tmp = bigfloat_to_f16(&tmp_bf); |
| | 8089 | bigfloat_init_16(&orig_bf, tmp); |
| | 8090 | break; |
| | 8091 | } |
| | 8092 | case 32: { |
| | 8093 | float tmp = bigfloat_to_f32(&tmp_bf); |
| | 8094 | bigfloat_init_32(&orig_bf, tmp); |
| | 8095 | break; |
| | 8096 | } |
| | 8097 | case 64: { |
| | 8098 | double tmp = bigfloat_to_f64(&tmp_bf); |
| | 8099 | bigfloat_init_64(&orig_bf, tmp); |
| | 8100 | break; |
| | 8101 | } |
| | 8102 | case 80: |
| | 8103 | zig_panic("TODO"); |
| | 8104 | case 128: { |
| | 8105 | float128_t tmp = bigfloat_to_f128(&tmp_bf); |
| | 8106 | bigfloat_init_128(&orig_bf, tmp); |
| | 8107 | break; |
| | 8108 | } |
| | 8109 | default: |
| | 8110 | zig_unreachable(); |
| | 8111 | } |
| | 8112 | BigInt orig_bi; |
| | 8113 | bigint_init_bigfloat(&orig_bi, &orig_bf); |
| | 8114 | if (bigint_cmp(&orig_bi, &const_val->data.x_bigint) == CmpEQ) { |
| | 8115 | return true; |
| | 8116 | } |
| | 8117 | Buf *val_buf = buf_alloc(); |
| | 8118 | bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); |
| | 8119 | ir_add_error(ira, instruction, |
| | 8120 | buf_sprintf("integer value %s has no representation in type '%s'", |
| | 8121 | buf_ptr(val_buf), |
| | 8122 | buf_ptr(&other_type->name))); |
| | 8123 | return false; |
| | 8124 | } |
| | 8125 | if (other_type->data.floating.bit_count >= const_val->type->data.floating.bit_count) { |
| | 8126 | return true; |
| | 8127 | } |
| | 8128 | switch (other_type->data.floating.bit_count) { |
| | 8129 | case 16: |
| | 8130 | switch (const_val->type->data.floating.bit_count) { |
| | 8131 | case 32: { |
| | 8132 | float16_t tmp = zig_double_to_f16(const_val->data.x_f32); |
| | 8133 | float orig = zig_f16_to_double(tmp); |
| | 8134 | if (const_val->data.x_f32 == orig) { |
| | 8135 | return true; |
| | 8136 | } |
| | 8137 | break; |
| | 8138 | } |
| | 8139 | case 64: { |
| | 8140 | float16_t tmp = zig_double_to_f16(const_val->data.x_f64); |
| | 8141 | double orig = zig_f16_to_double(tmp); |
| | 8142 | if (const_val->data.x_f64 == orig) { |
| | 8143 | return true; |
| | 8144 | } |
| | 8145 | break; |
| | 8146 | } |
| | 8147 | case 80: |
| | 8148 | zig_panic("TODO"); |
| | 8149 | case 128: { |
| | 8150 | float16_t tmp = f128M_to_f16(&const_val->data.x_f128); |
| | 8151 | float128_t orig; |
| | 8152 | f16_to_f128M(tmp, &orig); |
| | 8153 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| | 8154 | return true; |
| | 8155 | } |
| | 8156 | break; |
| | 8157 | } |
| | 8158 | default: |
| | 8159 | zig_unreachable(); |
| | 8160 | } |
| | 8161 | break; |
| | 8162 | case 32: |
| | 8163 | switch (const_val->type->data.floating.bit_count) { |
| | 8164 | case 64: { |
| | 8165 | float tmp = const_val->data.x_f64; |
| | 8166 | double orig = tmp; |
| | 8167 | if (const_val->data.x_f64 == orig) { |
| | 8168 | return true; |
| | 8169 | } |
| | 8170 | break; |
| | 8171 | } |
| | 8172 | case 80: |
| | 8173 | zig_panic("TODO"); |
| | 8174 | case 128: { |
| | 8175 | float32_t tmp = f128M_to_f32(&const_val->data.x_f128); |
| | 8176 | float128_t orig; |
| | 8177 | f32_to_f128M(tmp, &orig); |
| | 8178 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| | 8179 | return true; |
| | 8180 | } |
| | 8181 | break; |
| | 8182 | } |
| | 8183 | default: |
| | 8184 | zig_unreachable(); |
| | 8185 | } |
| | 8186 | break; |
| | 8187 | case 64: |
| | 8188 | switch (const_val->type->data.floating.bit_count) { |
| | 8189 | case 80: |
| | 8190 | zig_panic("TODO"); |
| | 8191 | case 128: { |
| | 8192 | float64_t tmp = f128M_to_f64(&const_val->data.x_f128); |
| | 8193 | float128_t orig; |
| | 8194 | f64_to_f128M(tmp, &orig); |
| | 8195 | if (f128M_eq(&orig, &const_val->data.x_f128)) { |
| | 8196 | return true; |
| | 8197 | } |
| | 8198 | break; |
| | 8199 | } |
| | 8200 | default: |
| | 8201 | zig_unreachable(); |
| | 8202 | } |
| | 8203 | break; |
| | 8204 | case 80: |
| | 8205 | assert(const_val->type->data.floating.bit_count == 128); |
| | 8206 | zig_panic("TODO"); |
| | 8207 | case 128: |
| | 8208 | return true; |
| | 8209 | default: |
| | 8210 | zig_unreachable(); |
| | 8211 | } |
| | 8212 | Buf *val_buf = buf_alloc(); |
| | 8213 | float_append_buf(val_buf, const_val); |
| | 8214 | ir_add_error(ira, instruction, |
| | 8215 | buf_sprintf("cast of value %s to type '%s' loses information", |
| | 8216 | buf_ptr(val_buf), |
| | 8217 | buf_ptr(&other_type->name))); |
| | 8218 | return false; |
| 8075 | } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { | 8219 | } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { |
| 8076 | if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { | 8220 | if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { |
| 8077 | Buf *val_buf = buf_alloc(); | 8221 | Buf *val_buf = buf_alloc(); |
| ... | @@ -9453,11 +9597,6 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio | ... | @@ -9453,11 +9597,6 @@ static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instructio |
| 9453 | return const_instr; | 9597 | return const_instr; |
| 9454 | } | 9598 | } |
| 9455 | | 9599 | |
| 9456 | enum UndefAllowed { | | |
| 9457 | UndefOk, | | |
| 9458 | UndefBad, | | |
| 9459 | }; | | |
| 9460 | | | |
| 9461 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { | 9600 | static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { |
| 9462 | switch (value->value.special) { | 9601 | switch (value->value.special) { |
| 9463 | case ConstValSpecialStatic: | 9602 | case ConstValSpecialStatic: |
| ... | @@ -10370,6 +10509,121 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10370,6 +10509,121 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10370 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); | 10509 | return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); |
| 10371 | } | 10510 | } |
| 10372 | | 10511 | |
| | 10512 | // cast from T to ?T |
| | 10513 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism |
| | 10514 | if (wanted_type->id == ZigTypeIdOptional) { |
| | 10515 | ZigType *wanted_child_type = wanted_type->data.maybe.child_type; |
| | 10516 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, |
| | 10517 | false).id == ConstCastResultIdOk) |
| | 10518 | { |
| | 10519 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| | 10520 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| | 10521 | actual_type->id == ZigTypeIdComptimeFloat) |
| | 10522 | { |
| | 10523 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { |
| | 10524 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); |
| | 10525 | } else { |
| | 10526 | return ira->codegen->invalid_instruction; |
| | 10527 | } |
| | 10528 | } else if ( |
| | 10529 | wanted_child_type->id == ZigTypeIdPointer && |
| | 10530 | wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && |
| | 10531 | actual_type->id == ZigTypeIdPointer && |
| | 10532 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| | 10533 | actual_type->data.pointer.child_type->id == ZigTypeIdArray) |
| | 10534 | { |
| | 10535 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| | 10536 | return ira->codegen->invalid_instruction; |
| | 10537 | if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) |
| | 10538 | return ira->codegen->invalid_instruction; |
| | 10539 | if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && |
| | 10540 | types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, |
| | 10541 | actual_type->data.pointer.child_type->data.array.child_type, source_node, |
| | 10542 | !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) |
| | 10543 | { |
| | 10544 | IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, |
| | 10545 | wanted_child_type); |
| | 10546 | if (type_is_invalid(cast1->value.type)) |
| | 10547 | return ira->codegen->invalid_instruction; |
| | 10548 | return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); |
| | 10549 | } |
| | 10550 | } |
| | 10551 | } |
| | 10552 | |
| | 10553 | // T to E!T |
| | 10554 | if (wanted_type->id == ZigTypeIdErrorUnion) { |
| | 10555 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, |
| | 10556 | source_node, false).id == ConstCastResultIdOk) |
| | 10557 | { |
| | 10558 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| | 10559 | } else if (actual_type->id == ZigTypeIdComptimeInt || |
| | 10560 | actual_type->id == ZigTypeIdComptimeFloat) |
| | 10561 | { |
| | 10562 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { |
| | 10563 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); |
| | 10564 | } else { |
| | 10565 | return ira->codegen->invalid_instruction; |
| | 10566 | } |
| | 10567 | } |
| | 10568 | } |
| | 10569 | |
| | 10570 | // cast from T to E!?T |
| | 10571 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| | 10572 | wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && |
| | 10573 | actual_type->id != ZigTypeIdOptional) |
| | 10574 | { |
| | 10575 | ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; |
| | 10576 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || |
| | 10577 | actual_type->id == ZigTypeIdNull || |
| | 10578 | actual_type->id == ZigTypeIdComptimeInt || |
| | 10579 | actual_type->id == ZigTypeIdComptimeFloat) |
| | 10580 | { |
| | 10581 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); |
| | 10582 | if (type_is_invalid(cast1->value.type)) |
| | 10583 | return ira->codegen->invalid_instruction; |
| | 10584 | |
| | 10585 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); |
| | 10586 | if (type_is_invalid(cast2->value.type)) |
| | 10587 | return ira->codegen->invalid_instruction; |
| | 10588 | |
| | 10589 | return cast2; |
| | 10590 | } |
| | 10591 | } |
| | 10592 | |
| | 10593 | |
| | 10594 | // cast from comptime-known number to another number type |
| | 10595 | if (instr_is_comptime(value) && |
| | 10596 | (actual_type->id == ZigTypeIdInt || actual_type->id == ZigTypeIdComptimeInt || |
| | 10597 | actual_type->id == ZigTypeIdFloat || actual_type->id == ZigTypeIdComptimeFloat) && |
| | 10598 | (wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt || |
| | 10599 | wanted_type->id == ZigTypeIdFloat || wanted_type->id == ZigTypeIdComptimeFloat)) |
| | 10600 | { |
| | 10601 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { |
| | 10602 | if (wanted_type->id == ZigTypeIdComptimeInt || wanted_type->id == ZigTypeIdInt) { |
| | 10603 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| | 10604 | if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { |
| | 10605 | bigint_init_bigint(&result->value.data.x_bigint, &value->value.data.x_bigint); |
| | 10606 | } else { |
| | 10607 | float_init_bigint(&result->value.data.x_bigint, &value->value); |
| | 10608 | } |
| | 10609 | return result; |
| | 10610 | } else if (wanted_type->id == ZigTypeIdComptimeFloat || wanted_type->id == ZigTypeIdFloat) { |
| | 10611 | IrInstruction *result = ir_const(ira, source_instr, wanted_type); |
| | 10612 | if (actual_type->id == ZigTypeIdComptimeInt || actual_type->id == ZigTypeIdInt) { |
| | 10613 | BigFloat bf; |
| | 10614 | bigfloat_init_bigint(&bf, &value->value.data.x_bigint); |
| | 10615 | float_init_bigfloat(&result->value, &bf); |
| | 10616 | } else { |
| | 10617 | float_init_float(&result->value, &value->value); |
| | 10618 | } |
| | 10619 | return result; |
| | 10620 | } |
| | 10621 | zig_unreachable(); |
| | 10622 | } else { |
| | 10623 | return ira->codegen->invalid_instruction; |
| | 10624 | } |
| | 10625 | } |
| | 10626 | |
| 10373 | // widening conversion | 10627 | // widening conversion |
| 10374 | if (wanted_type->id == ZigTypeIdInt && | 10628 | if (wanted_type->id == ZigTypeIdInt && |
| 10375 | actual_type->id == ZigTypeIdInt && | 10629 | actual_type->id == ZigTypeIdInt && |
| ... | @@ -10472,47 +10726,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10472,47 +10726,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10472 | } | 10726 | } |
| 10473 | | 10727 | |
| 10474 | | 10728 | |
| 10475 | // cast from T to ?T | | |
| 10476 | // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism | | |
| 10477 | if (wanted_type->id == ZigTypeIdOptional) { | | |
| 10478 | ZigType *wanted_child_type = wanted_type->data.maybe.child_type; | | |
| 10479 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, | | |
| 10480 | false).id == ConstCastResultIdOk) | | |
| 10481 | { | | |
| 10482 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); | | |
| 10483 | } else if (actual_type->id == ZigTypeIdComptimeInt || | | |
| 10484 | actual_type->id == ZigTypeIdComptimeFloat) | | |
| 10485 | { | | |
| 10486 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { | | |
| 10487 | return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); | | |
| 10488 | } else { | | |
| 10489 | return ira->codegen->invalid_instruction; | | |
| 10490 | } | | |
| 10491 | } else if ( | | |
| 10492 | wanted_child_type->id == ZigTypeIdPointer && | | |
| 10493 | wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && | | |
| 10494 | actual_type->id == ZigTypeIdPointer && | | |
| 10495 | actual_type->data.pointer.ptr_len == PtrLenSingle && | | |
| 10496 | actual_type->data.pointer.child_type->id == ZigTypeIdArray) | | |
| 10497 | { | | |
| 10498 | if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) | | |
| 10499 | return ira->codegen->invalid_instruction; | | |
| 10500 | if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) | | |
| 10501 | return ira->codegen->invalid_instruction; | | |
| 10502 | if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && | | |
| 10503 | types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, | | |
| 10504 | actual_type->data.pointer.child_type->data.array.child_type, source_node, | | |
| 10505 | !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) | | |
| 10506 | { | | |
| 10507 | IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, | | |
| 10508 | wanted_child_type); | | |
| 10509 | if (type_is_invalid(cast1->value.type)) | | |
| 10510 | return ira->codegen->invalid_instruction; | | |
| 10511 | return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); | | |
| 10512 | } | | |
| 10513 | } | | |
| 10514 | } | | |
| 10515 | | | |
| 10516 | // cast from null literal to maybe type | 10729 | // cast from null literal to maybe type |
| 10517 | if (wanted_type->id == ZigTypeIdOptional && | 10730 | if (wanted_type->id == ZigTypeIdOptional && |
| 10518 | actual_type->id == ZigTypeIdNull) | 10731 | actual_type->id == ZigTypeIdNull) |
| ... | @@ -10520,23 +10733,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10520,23 +10733,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10520 | return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); | 10733 | return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); |
| 10521 | } | 10734 | } |
| 10522 | | 10735 | |
| 10523 | // cast from child type of error type to error type | | |
| 10524 | if (wanted_type->id == ZigTypeIdErrorUnion) { | | |
| 10525 | if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, | | |
| 10526 | source_node, false).id == ConstCastResultIdOk) | | |
| 10527 | { | | |
| 10528 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); | | |
| 10529 | } else if (actual_type->id == ZigTypeIdComptimeInt || | | |
| 10530 | actual_type->id == ZigTypeIdComptimeFloat) | | |
| 10531 | { | | |
| 10532 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { | | |
| 10533 | return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); | | |
| 10534 | } else { | | |
| 10535 | return ira->codegen->invalid_instruction; | | |
| 10536 | } | | |
| 10537 | } | | |
| 10538 | } | | |
| 10539 | | | |
| 10540 | // cast from [N]T to E![]const T | 10736 | // cast from [N]T to E![]const T |
| 10541 | if (wanted_type->id == ZigTypeIdErrorUnion && | 10737 | if (wanted_type->id == ZigTypeIdErrorUnion && |
| 10542 | is_slice(wanted_type->data.error_union.payload_type) && | 10738 | is_slice(wanted_type->data.error_union.payload_type) && |
| ... | @@ -10568,54 +10764,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -10568,54 +10764,6 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 10568 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); | 10764 | return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); |
| 10569 | } | 10765 | } |
| 10570 | | 10766 | |
| 10571 | // cast from T to E!?T | | |
| 10572 | if (wanted_type->id == ZigTypeIdErrorUnion && | | |
| 10573 | wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && | | |
| 10574 | actual_type->id != ZigTypeIdOptional) | | |
| 10575 | { | | |
| 10576 | ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; | | |
| 10577 | if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || | | |
| 10578 | actual_type->id == ZigTypeIdNull || | | |
| 10579 | actual_type->id == ZigTypeIdComptimeInt || | | |
| 10580 | actual_type->id == ZigTypeIdComptimeFloat) | | |
| 10581 | { | | |
| 10582 | IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); | | |
| 10583 | if (type_is_invalid(cast1->value.type)) | | |
| 10584 | return ira->codegen->invalid_instruction; | | |
| 10585 | | | |
| 10586 | IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); | | |
| 10587 | if (type_is_invalid(cast2->value.type)) | | |
| 10588 | return ira->codegen->invalid_instruction; | | |
| 10589 | | | |
| 10590 | return cast2; | | |
| 10591 | } | | |
| 10592 | } | | |
| 10593 | | | |
| 10594 | // cast from number literal to another type | | |
| 10595 | if (actual_type->id == ZigTypeIdComptimeFloat || | | |
| 10596 | actual_type->id == ZigTypeIdComptimeInt) | | |
| 10597 | { | | |
| 10598 | if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { | | |
| 10599 | CastOp op; | | |
| 10600 | if ((actual_type->id == ZigTypeIdComptimeFloat && | | |
| 10601 | wanted_type->id == ZigTypeIdFloat) || | | |
| 10602 | (actual_type->id == ZigTypeIdComptimeInt && | | |
| 10603 | wanted_type->id == ZigTypeIdInt)) | | |
| 10604 | { | | |
| 10605 | op = CastOpNumLitToConcrete; | | |
| 10606 | } else if (wanted_type->id == ZigTypeIdInt) { | | |
| 10607 | op = CastOpFloatToInt; | | |
| 10608 | } else if (wanted_type->id == ZigTypeIdFloat) { | | |
| 10609 | op = CastOpIntToFloat; | | |
| 10610 | } else { | | |
| 10611 | zig_unreachable(); | | |
| 10612 | } | | |
| 10613 | return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false); | | |
| 10614 | } else { | | |
| 10615 | return ira->codegen->invalid_instruction; | | |
| 10616 | } | | |
| 10617 | } | | |
| 10618 | | | |
| 10619 | // cast from typed number to integer or float literal. | 10767 | // cast from typed number to integer or float literal. |
| 10620 | // works when the number is known at compile time | 10768 | // works when the number is known at compile time |
| 10621 | if (instr_is_comptime(value) && | 10769 | if (instr_is_comptime(value) && |
| ... | @@ -17878,7 +18026,7 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct | ... | @@ -17878,7 +18026,7 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct |
| 17878 | if (type_is_invalid(dest_type)) | 18026 | if (type_is_invalid(dest_type)) |
| 17879 | return ira->codegen->invalid_instruction; | 18027 | return ira->codegen->invalid_instruction; |
| 17880 | | 18028 | |
| 17881 | if (dest_type->id != ZigTypeIdInt) { | 18029 | if (dest_type->id != ZigTypeIdInt && dest_type->id != ZigTypeIdComptimeInt) { |
| 17882 | ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); | 18030 | ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); |
| 17883 | return ira->codegen->invalid_instruction; | 18031 | return ira->codegen->invalid_instruction; |
| 17884 | } | 18032 | } |
| ... | @@ -17887,20 +18035,22 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct | ... | @@ -17887,20 +18035,22 @@ static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstruct |
| 17887 | if (type_is_invalid(target->value.type)) | 18035 | if (type_is_invalid(target->value.type)) |
| 17888 | return ira->codegen->invalid_instruction; | 18036 | return ira->codegen->invalid_instruction; |
| 17889 | | 18037 | |
| 17890 | if (target->value.type->id == ZigTypeIdComptimeInt) { | 18038 | if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { |
| 17891 | if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { | | |
| 17892 | return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpNumLitToConcrete, false); | | |
| 17893 | } else { | | |
| 17894 | return ira->codegen->invalid_instruction; | | |
| 17895 | } | | |
| 17896 | } | | |
| 17897 | | | |
| 17898 | if (target->value.type->id != ZigTypeIdInt) { | | |
| 17899 | ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", | 18039 | ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", |
| 17900 | buf_ptr(&target->value.type->name))); | 18040 | buf_ptr(&target->value.type->name))); |
| 17901 | return ira->codegen->invalid_instruction; | 18041 | return ira->codegen->invalid_instruction; |
| 17902 | } | 18042 | } |
| 17903 | | 18043 | |
| | 18044 | if (instr_is_comptime(target)) { |
| | 18045 | return ir_implicit_cast(ira, target, dest_type); |
| | 18046 | } |
| | 18047 | |
| | 18048 | if (dest_type->id == ZigTypeIdComptimeInt) { |
| | 18049 | ir_add_error(ira, instruction->target, buf_sprintf("attempt to cast runtime value to '%s'", |
| | 18050 | buf_ptr(&dest_type->name))); |
| | 18051 | return ira->codegen->invalid_instruction; |
| | 18052 | } |
| | 18053 | |
| 17904 | return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); | 18054 | return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); |
| 17905 | } | 18055 | } |
| 17906 | | 18056 | |