| ... | ... | @@ -108,6 +108,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, |
| 108 | 108 | static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); |
| 109 | 109 | static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); |
| 110 | 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 | 113 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 113 | 114 | assert(const_val->type->id == TypeTableEntryIdPointer); |
| ... | ... | @@ -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 | 8055 | // implicit [N]T to ?[]const T |
| 8028 | 8056 | if (expected_type->id == TypeTableEntryIdMaybe && |
| 8029 | 8057 | is_slice(expected_type->data.maybe.child_type) && |
| ... | ... | @@ -8699,6 +8727,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op, |
| 8699 | 8727 | zig_unreachable(); |
| 8700 | 8728 | case CastOpErrSet: |
| 8701 | 8729 | case CastOpBitCast: |
| 8730 | case CastOpPtrOfArrayToSlice: |
| 8702 | 8731 | zig_panic("TODO"); |
| 8703 | 8732 | case CastOpNoop: |
| 8704 | 8733 | { |
| ... | ... | @@ -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 | 8875 | static bool is_container(TypeTableEntry *type) { |
| 8790 | 8876 | return type->id == TypeTableEntryIdStruct || |
| 8791 | 8877 | type->id == TypeTableEntryIdEnum || |
| ... | ... | @@ -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 | 10055 | // explicit cast from child type of maybe type to maybe type |
| 9941 | 10056 | if (wanted_type->id == TypeTableEntryIdMaybe) { |
| 9942 | 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 | 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 | 13275 | static TypeTableEntry *adjust_ptr_len(CodeGen *g, TypeTableEntry *ptr_type, PtrLen ptr_len) { |
| 13154 | 13276 | assert(ptr_type->id == TypeTableEntryIdPointer); |
| 13155 | 13277 | return get_pointer_to_type_extra(g, |