@@ -108,6 +108,7 @@ static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction,
108108static TypeTableEntry *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op);
109109static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval);
110110static 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);
111112
112113ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) {
113114 assert(const_val->type->id == TypeTableEntryIdPointer);
@@ -8024,6 +8025,33 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
80248025 }
80258026 }
80268027
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+
80278055 // implicit [N]T to ?[]const T
80288056 if (expected_type->id == TypeTableEntryIdMaybe &&
80298057 is_slice(expected_type->data.maybe.child_type) &&
@@ -8699,6 +8727,7 @@ static void eval_const_expr_implicit_cast(CastOp cast_op,
86998727 zig_unreachable();
87008728 case CastOpErrSet:
87018729 case CastOpBitCast:
8730+ case CastOpPtrOfArrayToSlice:
87028731 zig_panic("TODO");
87038732 case CastOpNoop:
87048733 {
@@ -8786,6 +8815,63 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
87868815 }
87878816}
87888817
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+
87898875static bool is_container(TypeTableEntry *type) {
87908876 return type->id == TypeTableEntryIdStruct ||
87918877 type->id == TypeTableEntryIdEnum ||
@@ -9937,6 +10023,35 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst
993710023 }
993810024 }
993910025
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+
994010055 // explicit cast from child type of maybe type to maybe type
994110056 if (wanted_type->id == TypeTableEntryIdMaybe) {
994210057 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
1315013265 ptr_type->data.pointer.bit_offset, ptr_type->data.pointer.unaligned_bit_count);
1315113266}
1315213267
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+
1315313275static TypeTableEntry *adjust_ptr_len(CodeGen *g, TypeTableEntry *ptr_type, PtrLen ptr_len) {
1315413276 assert(ptr_type->id == TypeTableEntryIdPointer);
1315513277 return get_pointer_to_type_extra(g,
0 commit comments