| ... | ... | @@ -14981,21 +14981,96 @@ static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, |
| 14981 | 14981 | } |
| 14982 | 14982 | |
| 14983 | 14983 | static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, |
| 14984 | | IrInstGen *value, ZigType *wanted_type) |
| 14984 | IrInstGen *struct_ptr, ZigType *actual_type, ZigType *wanted_type) |
| 14985 | 14985 | { |
| 14986 | | ir_add_error(ira, source_instr, buf_sprintf("TODO: type coercion of anon list literal to array")); |
| 14987 | | return ira->codegen->invalid_inst_gen; |
| 14986 | Error err; |
| 14987 | |
| 14988 | if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) |
| 14989 | return ira->codegen->invalid_inst_gen; |
| 14990 | |
| 14991 | size_t array_len = wanted_type->data.array.len; |
| 14992 | size_t instr_field_count = actual_type->data.structure.src_field_count; |
| 14993 | assert(array_len == instr_field_count); |
| 14994 | |
| 14995 | bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) |
| 14996 | || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; |
| 14997 | bool is_comptime = true; |
| 14998 | |
| 14999 | ZigType *elem_type = wanted_type->data.array.child_type; |
| 15000 | |
| 15001 | // Determine if the struct_operand will be comptime. |
| 15002 | ZigValue *elem_values = heap::c_allocator.allocate<ZigValue>(array_len); |
| 15003 | IrInstGen **casted_fields = heap::c_allocator.allocate<IrInstGen *>(array_len); |
| 15004 | IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); |
| 15005 | |
| 15006 | for (size_t i = 0; i < array_len; i += 1) { |
| 15007 | TypeStructField *src_field = actual_type->data.structure.fields[i]; |
| 15008 | |
| 15009 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, |
| 15010 | actual_type, false); |
| 15011 | if (type_is_invalid(field_ptr->value->type)) |
| 15012 | return ira->codegen->invalid_inst_gen; |
| 15013 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| 15014 | if (type_is_invalid(field_value->value->type)) |
| 15015 | return ira->codegen->invalid_inst_gen; |
| 15016 | IrInstGen *casted_value = ir_implicit_cast(ira, field_value, elem_type); |
| 15017 | if (type_is_invalid(casted_value->value->type)) |
| 15018 | return ira->codegen->invalid_inst_gen; |
| 15019 | |
| 15020 | casted_fields[i] = casted_value; |
| 15021 | if (need_comptime || instr_is_comptime(casted_value)) { |
| 15022 | ZigValue *field_val = ir_resolve_const(ira, casted_value, UndefOk); |
| 15023 | if (field_val == nullptr) |
| 15024 | return ira->codegen->invalid_inst_gen; |
| 15025 | |
| 15026 | field_val->parent.id = ConstParentIdArray; |
| 15027 | field_val->parent.data.p_array.array_val = const_result->value; |
| 15028 | field_val->parent.data.p_array.elem_index = i; |
| 15029 | elem_values[i] = *field_val; |
| 15030 | if (field_val->type->id == ZigTypeIdUndefined) { |
| 15031 | elem_values[i].special = ConstValSpecialUndef; |
| 15032 | } |
| 15033 | } else { |
| 15034 | is_comptime = false; |
| 15035 | } |
| 15036 | } |
| 15037 | |
| 15038 | if (is_comptime) { |
| 15039 | IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); |
| 15040 | const_result->value->data.x_array.special = ConstArraySpecialNone; |
| 15041 | const_result->value->data.x_array.data.s_none.elements = elem_values; |
| 15042 | return const_result; |
| 15043 | } |
| 15044 | |
| 15045 | IrInstGen *result_loc_inst = ir_resolve_result(ira, source_instr, no_result_loc(), |
| 15046 | wanted_type, nullptr, true, true); |
| 15047 | if (type_is_invalid(result_loc_inst->value->type) || result_loc_inst->value->type->id == ZigTypeIdUnreachable) { |
| 15048 | return ira->codegen->invalid_inst_gen; |
| 15049 | } |
| 15050 | |
| 15051 | ZigType *elem_type_ptr = get_pointer_to_type(ira->codegen, elem_type, false); |
| 15052 | for (size_t i = 0; i < array_len; i += 1) { |
| 15053 | IrInstGen *index_val = ir_const(ira, source_instr, ira->codegen->builtin_types.entry_usize); |
| 15054 | bigint_init_unsigned(&index_val->value->data.x_bigint, i); |
| 15055 | |
| 15056 | IrInstGen *elem_ptr = ir_build_elem_ptr_gen(ira, source_instr->scope, source_instr->source_node, |
| 15057 | result_loc_inst, index_val, false, elem_type_ptr); |
| 15058 | IrInstGen *store_ptr_inst = ir_analyze_store_ptr(ira, source_instr, elem_ptr, casted_fields[i], true); |
| 15059 | if (type_is_invalid(store_ptr_inst->value->type)) |
| 15060 | return ira->codegen->invalid_inst_gen; |
| 15061 | } |
| 15062 | |
| 15063 | heap::c_allocator.deallocate(elem_values, array_len); |
| 15064 | heap::c_allocator.deallocate(casted_fields, array_len); |
| 15065 | |
| 15066 | return result_loc_inst; |
| 14988 | 15067 | } |
| 14989 | 15068 | |
| 14990 | 15069 | static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, |
| 14991 | | IrInstGen *struct_operand, ZigType *wanted_type) |
| 15070 | IrInstGen *struct_ptr, ZigType *actual_type, ZigType *wanted_type) |
| 14992 | 15071 | { |
| 14993 | 15072 | Error err; |
| 14994 | 15073 | |
| 14995 | | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); |
| 14996 | | if (type_is_invalid(struct_ptr->value->type)) |
| 14997 | | return ira->codegen->invalid_inst_gen; |
| 14998 | | |
| 14999 | 15074 | if (wanted_type->data.structure.resolve_status == ResolveStatusBeingInferred) { |
| 15000 | 15075 | ir_add_error(ira, source_instr, buf_sprintf("type coercion of anon struct literal to inferred struct")); |
| 15001 | 15076 | return ira->codegen->invalid_inst_gen; |
| ... | ... | @@ -15005,7 +15080,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15005 | 15080 | return ira->codegen->invalid_inst_gen; |
| 15006 | 15081 | |
| 15007 | 15082 | size_t actual_field_count = wanted_type->data.structure.src_field_count; |
| 15008 | | size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count; |
| 15083 | size_t instr_field_count = actual_type->data.structure.src_field_count; |
| 15009 | 15084 | |
| 15010 | 15085 | bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) |
| 15011 | 15086 | || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; |
| ... | ... | @@ -15019,7 +15094,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15019 | 15094 | IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); |
| 15020 | 15095 | |
| 15021 | 15096 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 15022 | | TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i]; |
| 15097 | TypeStructField *src_field = actual_type->data.structure.fields[i]; |
| 15023 | 15098 | TypeStructField *dst_field = find_struct_type_field(wanted_type, src_field->name); |
| 15024 | 15099 | if (dst_field == nullptr) { |
| 15025 | 15100 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("no field named '%s' in struct '%s'", |
| ... | ... | @@ -15043,7 +15118,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15043 | 15118 | field_assign_nodes[dst_field->src_index] = src_field->decl_node; |
| 15044 | 15119 | |
| 15045 | 15120 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, |
| 15046 | | struct_operand->value->type, false); |
| 15121 | actual_type, false); |
| 15047 | 15122 | if (type_is_invalid(field_ptr->value->type)) |
| 15048 | 15123 | return ira->codegen->invalid_inst_gen; |
| 15049 | 15124 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| ... | ... | @@ -15123,14 +15198,13 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15123 | 15198 | heap::c_allocator.deallocate(field_values, actual_field_count); |
| 15124 | 15199 | heap::c_allocator.deallocate(casted_fields, actual_field_count); |
| 15125 | 15200 | |
| 15126 | | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 15201 | return result_loc_inst; |
| 15127 | 15202 | } |
| 15128 | 15203 | |
| 15129 | 15204 | static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, |
| 15130 | | IrInstGen *value, ZigType *union_type) |
| 15205 | IrInstGen *struct_ptr, ZigType *struct_type, ZigType *union_type) |
| 15131 | 15206 | { |
| 15132 | 15207 | Error err; |
| 15133 | | ZigType *struct_type = value->value->type; |
| 15134 | 15208 | |
| 15135 | 15209 | assert(struct_type->id == ZigTypeIdStruct); |
| 15136 | 15210 | assert(union_type->id == ZigTypeIdUnion); |
| ... | ... | @@ -15153,7 +15227,11 @@ static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* sou |
| 15153 | 15227 | if (payload_type == nullptr) |
| 15154 | 15228 | return ira->codegen->invalid_inst_gen; |
| 15155 | 15229 | |
| 15156 | | IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, value, only_field); |
| 15230 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, only_field, struct_ptr, |
| 15231 | struct_type, false); |
| 15232 | if (type_is_invalid(field_ptr->value->type)) |
| 15233 | return ira->codegen->invalid_inst_gen; |
| 15234 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| 15157 | 15235 | if (type_is_invalid(field_value->value->type)) |
| 15158 | 15236 | return ira->codegen->invalid_inst_gen; |
| 15159 | 15237 | |
| ... | ... | @@ -15191,7 +15269,7 @@ static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* sou |
| 15191 | 15269 | if (type_is_invalid(store_ptr_inst->value->type)) |
| 15192 | 15270 | return ira->codegen->invalid_inst_gen; |
| 15193 | 15271 | |
| 15194 | | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 15272 | return result_loc_inst; |
| 15195 | 15273 | } |
| 15196 | 15274 | |
| 15197 | 15275 | // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, |
| ... | ... | @@ -15824,13 +15902,84 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, |
| 15824 | 15902 | if (wanted_type->id == ZigTypeIdArray && (is_array_init || field_count == 0) && |
| 15825 | 15903 | wanted_type->data.array.len == field_count) |
| 15826 | 15904 | { |
| 15827 | | return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); |
| 15905 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15906 | if (type_is_invalid(struct_ptr->value->type)) |
| 15907 | return ira->codegen->invalid_inst_gen; |
| 15908 | |
| 15909 | IrInstGen *ptr = ir_analyze_struct_literal_to_array(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15910 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15911 | return ptr; |
| 15912 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15828 | 15913 | } else if (wanted_type->id == ZigTypeIdStruct && !is_slice(wanted_type) && |
| 15829 | 15914 | (!is_array_init || field_count == 0)) |
| 15830 | 15915 | { |
| 15831 | | return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); |
| 15916 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15917 | if (type_is_invalid(struct_ptr->value->type)) |
| 15918 | return ira->codegen->invalid_inst_gen; |
| 15919 | |
| 15920 | IrInstGen *ptr = ir_analyze_struct_literal_to_struct(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15921 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15922 | return ptr; |
| 15923 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15832 | 15924 | } else if (wanted_type->id == ZigTypeIdUnion && !is_array_init && field_count == 1) { |
| 15833 | | return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); |
| 15925 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15926 | if (type_is_invalid(struct_ptr->value->type)) |
| 15927 | return ira->codegen->invalid_inst_gen; |
| 15928 | |
| 15929 | IrInstGen *ptr = ir_analyze_struct_literal_to_union(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15930 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15931 | return ptr; |
| 15932 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15933 | } |
| 15934 | } |
| 15935 | |
| 15936 | // cast from pointer to inferred struct type to pointer to array, union, or struct |
| 15937 | if (actual_type->id == ZigTypeIdPointer && is_anon_container(actual_type->data.pointer.child_type)) { |
| 15938 | ZigType *anon_type = actual_type->data.pointer.child_type; |
| 15939 | const bool is_array_init = |
| 15940 | anon_type->data.structure.special == StructSpecialInferredTuple; |
| 15941 | const uint32_t field_count = anon_type->data.structure.src_field_count; |
| 15942 | |
| 15943 | if (wanted_type->id == ZigTypeIdPointer && |
| 15944 | (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile)) |
| 15945 | { |
| 15946 | ZigType *wanted_child = wanted_type->data.pointer.child_type; |
| 15947 | bool const_ok = (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const); |
| 15948 | if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) && |
| 15949 | wanted_child->data.array.len == field_count && (const_ok || field_count == 0)) |
| 15950 | { |
| 15951 | IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, wanted_child); |
| 15952 | if (res->value->type->id == ZigTypeIdPointer) |
| 15953 | return res; |
| 15954 | return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile); |
| 15955 | } else if (wanted_child->id == ZigTypeIdStruct && !is_slice(wanted_type) && |
| 15956 | (!is_array_init || field_count == 0) && const_ok) |
| 15957 | { |
| 15958 | IrInstGen *res = ir_analyze_struct_literal_to_struct(ira, source_instr, value, anon_type, wanted_child); |
| 15959 | if (res->value->type->id == ZigTypeIdPointer) |
| 15960 | return res; |
| 15961 | return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile); |
| 15962 | } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1 && const_ok) { |
| 15963 | IrInstGen *res = ir_analyze_struct_literal_to_union(ira, source_instr, value, anon_type, wanted_child); |
| 15964 | if (res->value->type->id == ZigTypeIdPointer) |
| 15965 | return res; |
| 15966 | return ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile); |
| 15967 | } |
| 15968 | } else if (is_slice(wanted_type) && (is_array_init || field_count == 0)) { |
| 15969 | ZigType *slice_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry; |
| 15970 | if ((!actual_type->data.pointer.is_const || slice_type->data.pointer.is_const || field_count == 0) && |
| 15971 | (!actual_type->data.pointer.is_volatile || slice_type->data.pointer.is_volatile)) |
| 15972 | { |
| 15973 | ZigType *slice_child_type = slice_type->data.pointer.child_type; |
| 15974 | ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr); |
| 15975 | IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type); |
| 15976 | if (type_is_invalid(res->value->type)) |
| 15977 | return ira->codegen->invalid_inst_gen; |
| 15978 | if (res->value->type->id != ZigTypeIdPointer) |
| 15979 | res = ir_get_ref(ira, source_instr, res, actual_type->data.pointer.is_const, actual_type->data.pointer.is_volatile); |
| 15980 | |
| 15981 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr); |
| 15982 | } |
| 15834 | 15983 | } |
| 15835 | 15984 | } |
| 15836 | 15985 | |