| ... | @@ -108,6 +108,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, | ... | @@ -108,6 +108,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 108 | static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); | 108 | static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); |
| 109 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); | 109 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); |
| 110 | static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align); | 110 | static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, uint32_t new_align); |
| | 111 | static TypeTableEntry *adjust_slice_align(CodeGen *g, TypeTableEntry *slice_type, uint32_t new_align); |
| 111 | | 112 | |
| 112 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { | 113 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 113 | assert(const_val->type->id == TypeTableEntryIdPointer); | 114 | assert(const_val->type->id == TypeTableEntryIdPointer); |
| ... | @@ -8024,6 +8025,33 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, | ... | @@ -8024,6 +8025,33 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, |
| 8024 | } | 8025 | } |
| 8025 | } | 8026 | } |
| 8026 | | 8027 | |
| | 8028 | // implicit *[N]T to [*]T |
| | 8029 | if (expected_type->id == TypeTableEntryIdPointer && |
| | 8030 | expected_type->data.pointer.ptr_len == PtrLenUnknown && |
| | 8031 | actual_type->id == TypeTableEntryIdPointer && |
| | 8032 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| | 8033 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray && |
| | 8034 | types_match_const_cast_only(ira, expected_type->data.pointer.child_type, |
| | 8035 | actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| | 8036 | { |
| | 8037 | return ImplicitCastMatchResultYes; |
| | 8038 | } |
| | 8039 | |
| | 8040 | // implicit *[N]T to []T |
| | 8041 | if (is_slice(expected_type) && |
| | 8042 | actual_type->id == TypeTableEntryIdPointer && |
| | 8043 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| | 8044 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray) |
| | 8045 | { |
| | 8046 | TypeTableEntry *slice_ptr_type = expected_type->data.structure.fields[slice_ptr_index].type_entry; |
| | 8047 | assert(slice_ptr_type->id == TypeTableEntryIdPointer); |
| | 8048 | if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, |
| | 8049 | actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| | 8050 | { |
| | 8051 | return ImplicitCastMatchResultYes; |
| | 8052 | } |
| | 8053 | } |
| | 8054 | |
| 8027 | // implicit [N]T to ?[]const T | 8055 | // implicit [N]T to ?[]const T |
| 8028 | if (expected_type->id == TypeTableEntryIdMaybe && | 8056 | if (expected_type->id == TypeTableEntryIdMaybe && |
| 8029 | is_slice(expected_type->data.maybe.child_type) && | 8057 | is_slice(expected_type->data.maybe.child_type) && |
| ... | @@ -8699,6 +8727,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, | ... | @@ -8699,6 +8727,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 8699 | zig_unreachable(); | 8727 | zig_unreachable(); |
| 8700 | case CastOpErrSet: | 8728 | case CastOpErrSet: |
| 8701 | case CastOpBitCast: | 8729 | case CastOpBitCast: |
| | 8730 | case CastOpPtrOfArrayToSlice: |
| 8702 | zig_panic("TODO"); | 8731 | zig_panic("TODO"); |
| 8703 | case CastOpNoop: | 8732 | case CastOpNoop: |
| 8704 | { | 8733 | { |
| ... | @@ -8786,6 +8815,63 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -8786,6 +8815,63 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 8786 | } | 8815 | } |
| 8787 | } | 8816 | } |
| 8788 | | 8817 | |
| | 8818 | static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| | 8819 | IrInstruction *value, TypeTableEntry *wanted_type) |
| | 8820 | { |
| | 8821 | assert(value->value.type->id == TypeTableEntryIdPointer); |
| | 8822 | wanted_type = adjust_ptr_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); |
| | 8823 | |
| | 8824 | if (instr_is_comptime(value)) { |
| | 8825 | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| | 8826 | if (pointee->special != ConstValSpecialRuntime) { |
| | 8827 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| | 8828 | source_instr->source_node, wanted_type); |
| | 8829 | result->value.type = wanted_type; |
| | 8830 | result->value.data.x_ptr.special = ConstPtrSpecialBaseArray; |
| | 8831 | result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; |
| | 8832 | result->value.data.x_ptr.data.base_array.array_val = pointee; |
| | 8833 | result->value.data.x_ptr.data.base_array.elem_index = 0; |
| | 8834 | result->value.data.x_ptr.data.base_array.is_cstr = false; |
| | 8835 | return result; |
| | 8836 | } |
| | 8837 | } |
| | 8838 | |
| | 8839 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| | 8840 | wanted_type, value, CastOpBitCast); |
| | 8841 | result->value.type = wanted_type; |
| | 8842 | return result; |
| | 8843 | } |
| | 8844 | |
| | 8845 | static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, |
| | 8846 | IrInstruction *value, TypeTableEntry *wanted_type) |
| | 8847 | { |
| | 8848 | wanted_type = adjust_slice_align(ira->codegen, wanted_type, value->value.type->data.pointer.alignment); |
| | 8849 | |
| | 8850 | if (instr_is_comptime(value)) { |
| | 8851 | ConstExprValue *pointee = const_ptr_pointee(ira->codegen, &value->value); |
| | 8852 | if (pointee->special != ConstValSpecialRuntime) { |
| | 8853 | assert(value->value.type->id == TypeTableEntryIdPointer); |
| | 8854 | TypeTableEntry *array_type = value->value.type->data.pointer.child_type; |
| | 8855 | assert(is_slice(wanted_type)); |
| | 8856 | bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; |
| | 8857 | |
| | 8858 | IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, |
| | 8859 | source_instr->source_node, wanted_type); |
| | 8860 | init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); |
| | 8861 | result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = |
| | 8862 | value->value.data.x_ptr.mut; |
| | 8863 | result->value.type = wanted_type; |
| | 8864 | return result; |
| | 8865 | } |
| | 8866 | } |
| | 8867 | |
| | 8868 | IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, |
| | 8869 | wanted_type, value, CastOpPtrOfArrayToSlice); |
| | 8870 | result->value.type = wanted_type; |
| | 8871 | ir_add_alloca(ira, result, wanted_type); |
| | 8872 | return result; |
| | 8873 | } |
| | 8874 | |
| 8789 | static bool is_container(TypeTableEntry *type) { | 8875 | static bool is_container(TypeTableEntry *type) { |
| 8790 | return type->id == TypeTableEntryIdStruct || | 8876 | return type->id == TypeTableEntryIdStruct || |
| 8791 | type->id == TypeTableEntryIdEnum || | 8877 | type->id == TypeTableEntryIdEnum || |
| ... | @@ -9937,6 +10023,35 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst | ... | @@ -9937,6 +10023,35 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst |
| 9937 | } | 10023 | } |
| 9938 | } | 10024 | } |
| 9939 | | 10025 | |
| | 10026 | // explicit *[N]T to [*]T |
| | 10027 | if (wanted_type->id == TypeTableEntryIdPointer && |
| | 10028 | wanted_type->data.pointer.ptr_len == PtrLenUnknown && |
| | 10029 | actual_type->id == TypeTableEntryIdPointer && |
| | 10030 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| | 10031 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray && |
| | 10032 | actual_type->data.pointer.alignment >= wanted_type->data.pointer.alignment && |
| | 10033 | types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, |
| | 10034 | actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| | 10035 | { |
| | 10036 | return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); |
| | 10037 | } |
| | 10038 | |
| | 10039 | // explicit *[N]T to []T |
| | 10040 | if (is_slice(wanted_type) && |
| | 10041 | actual_type->id == TypeTableEntryIdPointer && |
| | 10042 | actual_type->data.pointer.ptr_len == PtrLenSingle && |
| | 10043 | actual_type->data.pointer.child_type->id == TypeTableEntryIdArray) |
| | 10044 | { |
| | 10045 | TypeTableEntry *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; |
| | 10046 | assert(slice_ptr_type->id == TypeTableEntryIdPointer); |
| | 10047 | if (types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, |
| | 10048 | actual_type->data.pointer.child_type->data.array.child_type, source_node).id == ConstCastResultIdOk) |
| | 10049 | { |
| | 10050 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); |
| | 10051 | } |
| | 10052 | } |
| | 10053 | |
| | 10054 | |
| 9940 | // explicit cast from child type of maybe type to maybe type | 10055 | // explicit cast from child type of maybe type to maybe type |
| 9941 | if (wanted_type->id == TypeTableEntryIdMaybe) { | 10056 | if (wanted_type->id == TypeTableEntryIdMaybe) { |
| 9942 | TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type; | 10057 | TypeTableEntry *wanted_child_type = wanted_type->data.maybe.child_type; |
| ... | @@ -13150,6 +13265,13 @@ static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, ui | ... | @@ -13150,6 +13265,13 @@ static TypeTableEntry *adjust_ptr_align(CodeGen *g, TypeTableEntry *ptr_type, ui |
| 13150 | ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); | 13265 | ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count); |
| 13151 | } | 13266 | } |
| 13152 | | 13267 | |
| | 13268 | static TypeTableEntry *adjust_slice_align(CodeGen *g, TypeTableEntry *slice_type, uint32_t new_align) { |
| | 13269 | assert(is_slice(slice_type)); |
| | 13270 | TypeTableEntry *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, |
| | 13271 | new_align); |
| | 13272 | return get_slice_type(g, ptr_type); |
| | 13273 | } |
| | 13274 | |
| 13153 | static TypeTableEntry *adjust_ptr_len(CodeGen *g, TypeTableEntry *ptr_type, PtrLen ptr_len) { | 13275 | static TypeTableEntry *adjust_ptr_len(CodeGen *g, TypeTableEntry *ptr_type, PtrLen ptr_len) { |
| 13154 | assert(ptr_type->id == TypeTableEntryIdPointer); | 13276 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 13155 | return get_pointer_to_type_extra(g, | 13277 | return get_pointer_to_type_extra(g, |