@@ -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,
0 commit comments