| ... | ... | @@ -14996,25 +14996,16 @@ static IrInstGen *ir_analyze_enum_literal(IrAnalyze *ira, IrInst* source_instr, |
| 14996 | 14996 | } |
| 14997 | 14997 | |
| 14998 | 14998 | static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* source_instr, |
| 14999 | | IrInstGen *struct_operand, ZigType *wanted_type) |
| 14999 | IrInstGen *struct_ptr, ZigType *actual_type, ZigType *wanted_type) |
| 15000 | 15000 | { |
| 15001 | 15001 | Error err; |
| 15002 | 15002 | |
| 15003 | | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); |
| 15004 | | if (type_is_invalid(struct_ptr->value->type)) |
| 15005 | | return ira->codegen->invalid_inst_gen; |
| 15006 | | |
| 15007 | 15003 | if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusSizeKnown))) |
| 15008 | 15004 | return ira->codegen->invalid_inst_gen; |
| 15009 | 15005 | |
| 15010 | 15006 | size_t array_len = wanted_type->data.array.len; |
| 15011 | | size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count; |
| 15012 | | |
| 15013 | | if (instr_field_count != array_len) { |
| 15014 | | ir_add_error(ira, source_instr, buf_sprintf("expected %" ZIG_PRI_usize " fields, found %" ZIG_PRI_usize, |
| 15015 | | array_len, instr_field_count)); |
| 15016 | | return ira->codegen->invalid_inst_gen; |
| 15017 | | } |
| 15007 | size_t instr_field_count = actual_type->data.structure.src_field_count; |
| 15008 | assert(array_len == instr_field_count); |
| 15018 | 15009 | |
| 15019 | 15010 | bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) |
| 15020 | 15011 | || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; |
| ... | ... | @@ -15028,10 +15019,10 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou |
| 15028 | 15019 | IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); |
| 15029 | 15020 | |
| 15030 | 15021 | for (size_t i = 0; i < array_len; i += 1) { |
| 15031 | | TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i]; |
| 15022 | TypeStructField *src_field = actual_type->data.structure.fields[i]; |
| 15032 | 15023 | |
| 15033 | 15024 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, |
| 15034 | | struct_operand->value->type, false); |
| 15025 | actual_type, false); |
| 15035 | 15026 | if (type_is_invalid(field_ptr->value->type)) |
| 15036 | 15027 | return ira->codegen->invalid_inst_gen; |
| 15037 | 15028 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| ... | ... | @@ -15087,18 +15078,14 @@ static IrInstGen *ir_analyze_struct_literal_to_array(IrAnalyze *ira, IrInst* sou |
| 15087 | 15078 | heap::c_allocator.deallocate(elem_values, array_len); |
| 15088 | 15079 | heap::c_allocator.deallocate(casted_fields, array_len); |
| 15089 | 15080 | |
| 15090 | | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 15081 | return result_loc_inst; |
| 15091 | 15082 | } |
| 15092 | 15083 | |
| 15093 | 15084 | static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* source_instr, |
| 15094 | | IrInstGen *struct_operand, ZigType *wanted_type) |
| 15085 | IrInstGen *struct_ptr, ZigType *actual_type, ZigType *wanted_type) |
| 15095 | 15086 | { |
| 15096 | 15087 | Error err; |
| 15097 | 15088 | |
| 15098 | | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, struct_operand, true, false); |
| 15099 | | if (type_is_invalid(struct_ptr->value->type)) |
| 15100 | | return ira->codegen->invalid_inst_gen; |
| 15101 | | |
| 15102 | 15089 | if (wanted_type->data.structure.resolve_status == ResolveStatusBeingInferred) { |
| 15103 | 15090 | ir_add_error(ira, source_instr, buf_sprintf("type coercion of anon struct literal to inferred struct")); |
| 15104 | 15091 | return ira->codegen->invalid_inst_gen; |
| ... | ... | @@ -15108,7 +15095,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15108 | 15095 | return ira->codegen->invalid_inst_gen; |
| 15109 | 15096 | |
| 15110 | 15097 | size_t actual_field_count = wanted_type->data.structure.src_field_count; |
| 15111 | | size_t instr_field_count = struct_operand->value->type->data.structure.src_field_count; |
| 15098 | size_t instr_field_count = actual_type->data.structure.src_field_count; |
| 15112 | 15099 | |
| 15113 | 15100 | bool need_comptime = ir_should_inline(ira->old_irb.exec, source_instr->scope) |
| 15114 | 15101 | || type_requires_comptime(ira->codegen, wanted_type) == ReqCompTimeYes; |
| ... | ... | @@ -15122,7 +15109,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15122 | 15109 | IrInstGen *const_result = ir_const(ira, source_instr, wanted_type); |
| 15123 | 15110 | |
| 15124 | 15111 | for (size_t i = 0; i < instr_field_count; i += 1) { |
| 15125 | | TypeStructField *src_field = struct_operand->value->type->data.structure.fields[i]; |
| 15112 | TypeStructField *src_field = actual_type->data.structure.fields[i]; |
| 15126 | 15113 | TypeStructField *dst_field = find_struct_type_field(wanted_type, src_field->name); |
| 15127 | 15114 | if (dst_field == nullptr) { |
| 15128 | 15115 | ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("no field named '%s' in struct '%s'", |
| ... | ... | @@ -15146,7 +15133,7 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15146 | 15133 | field_assign_nodes[dst_field->src_index] = src_field->decl_node; |
| 15147 | 15134 | |
| 15148 | 15135 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, src_field, struct_ptr, |
| 15149 | | struct_operand->value->type, false); |
| 15136 | actual_type, false); |
| 15150 | 15137 | if (type_is_invalid(field_ptr->value->type)) |
| 15151 | 15138 | return ira->codegen->invalid_inst_gen; |
| 15152 | 15139 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| ... | ... | @@ -15226,14 +15213,13 @@ static IrInstGen *ir_analyze_struct_literal_to_struct(IrAnalyze *ira, IrInst* so |
| 15226 | 15213 | heap::c_allocator.deallocate(field_values, actual_field_count); |
| 15227 | 15214 | heap::c_allocator.deallocate(casted_fields, actual_field_count); |
| 15228 | 15215 | |
| 15229 | | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 15216 | return result_loc_inst; |
| 15230 | 15217 | } |
| 15231 | 15218 | |
| 15232 | 15219 | static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* source_instr, |
| 15233 | | IrInstGen *value, ZigType *union_type) |
| 15220 | IrInstGen *struct_ptr, ZigType *struct_type, ZigType *union_type) |
| 15234 | 15221 | { |
| 15235 | 15222 | Error err; |
| 15236 | | ZigType *struct_type = value->value->type; |
| 15237 | 15223 | |
| 15238 | 15224 | assert(struct_type->id == ZigTypeIdStruct); |
| 15239 | 15225 | assert(union_type->id == ZigTypeIdUnion); |
| ... | ... | @@ -15256,7 +15242,11 @@ static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* sou |
| 15256 | 15242 | if (payload_type == nullptr) |
| 15257 | 15243 | return ira->codegen->invalid_inst_gen; |
| 15258 | 15244 | |
| 15259 | | IrInstGen *field_value = ir_analyze_struct_value_field_value(ira, source_instr, value, only_field); |
| 15245 | IrInstGen *field_ptr = ir_analyze_struct_field_ptr(ira, source_instr, only_field, struct_ptr, |
| 15246 | struct_type, false); |
| 15247 | if (type_is_invalid(field_ptr->value->type)) |
| 15248 | return ira->codegen->invalid_inst_gen; |
| 15249 | IrInstGen *field_value = ir_get_deref(ira, source_instr, field_ptr, nullptr); |
| 15260 | 15250 | if (type_is_invalid(field_value->value->type)) |
| 15261 | 15251 | return ira->codegen->invalid_inst_gen; |
| 15262 | 15252 | |
| ... | ... | @@ -15294,7 +15284,7 @@ static IrInstGen *ir_analyze_struct_literal_to_union(IrAnalyze *ira, IrInst* sou |
| 15294 | 15284 | if (type_is_invalid(store_ptr_inst->value->type)) |
| 15295 | 15285 | return ira->codegen->invalid_inst_gen; |
| 15296 | 15286 | |
| 15297 | | return ir_get_deref(ira, source_instr, result_loc_inst, nullptr); |
| 15287 | return result_loc_inst; |
| 15298 | 15288 | } |
| 15299 | 15289 | |
| 15300 | 15290 | // Add a compile error and return ErrorSemanticAnalyzeFail if the pointer alignment does not work, |
| ... | ... | @@ -15927,13 +15917,76 @@ static IrInstGen *ir_analyze_cast(IrAnalyze *ira, IrInst *source_instr, |
| 15927 | 15917 | if (wanted_type->id == ZigTypeIdArray && (is_array_init || field_count == 0) && |
| 15928 | 15918 | wanted_type->data.array.len == field_count) |
| 15929 | 15919 | { |
| 15930 | | return ir_analyze_struct_literal_to_array(ira, source_instr, value, wanted_type); |
| 15920 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15921 | if (type_is_invalid(struct_ptr->value->type)) |
| 15922 | return ira->codegen->invalid_inst_gen; |
| 15923 | |
| 15924 | IrInstGen *ptr = ir_analyze_struct_literal_to_array(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15925 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15926 | return ptr; |
| 15927 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15931 | 15928 | } else if (wanted_type->id == ZigTypeIdStruct && !is_slice(wanted_type) && |
| 15932 | 15929 | (!is_array_init || field_count == 0)) |
| 15933 | 15930 | { |
| 15934 | | return ir_analyze_struct_literal_to_struct(ira, source_instr, value, wanted_type); |
| 15931 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15932 | if (type_is_invalid(struct_ptr->value->type)) |
| 15933 | return ira->codegen->invalid_inst_gen; |
| 15934 | |
| 15935 | IrInstGen *ptr = ir_analyze_struct_literal_to_struct(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15936 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15937 | return ptr; |
| 15938 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15935 | 15939 | } else if (wanted_type->id == ZigTypeIdUnion && !is_array_init && field_count == 1) { |
| 15936 | | return ir_analyze_struct_literal_to_union(ira, source_instr, value, wanted_type); |
| 15940 | IrInstGen *struct_ptr = ir_get_ref(ira, source_instr, value, true, false); |
| 15941 | if (type_is_invalid(struct_ptr->value->type)) |
| 15942 | return ira->codegen->invalid_inst_gen; |
| 15943 | |
| 15944 | IrInstGen *ptr = ir_analyze_struct_literal_to_union(ira, source_instr, struct_ptr, actual_type, wanted_type); |
| 15945 | if (ptr->value->type->id != ZigTypeIdPointer) |
| 15946 | return ptr; |
| 15947 | return ir_get_deref(ira, source_instr, ptr, nullptr); |
| 15948 | } |
| 15949 | } |
| 15950 | |
| 15951 | // cast from pointer to inferred struct type to pointer to array, union, or struct |
| 15952 | if (actual_type->id == ZigTypeIdPointer && is_anon_container(actual_type->data.pointer.child_type)) { |
| 15953 | ZigType *anon_type = actual_type->data.pointer.child_type; |
| 15954 | const bool is_array_init = |
| 15955 | anon_type->data.structure.special == StructSpecialInferredTuple; |
| 15956 | const uint32_t field_count = anon_type->data.structure.src_field_count; |
| 15957 | |
| 15958 | if (wanted_type->id == ZigTypeIdPointer) { |
| 15959 | ZigType *wanted_child = wanted_type->data.pointer.child_type; |
| 15960 | if (wanted_child->id == ZigTypeIdArray && (is_array_init || field_count == 0) && |
| 15961 | wanted_child->data.array.len == field_count) |
| 15962 | { |
| 15963 | IrInstGen *res = ir_analyze_struct_literal_to_array(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, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile); |
| 15967 | } else if (wanted_child->id == ZigTypeIdStruct && !is_slice(wanted_type) && |
| 15968 | (!is_array_init || field_count == 0)) |
| 15969 | { |
| 15970 | IrInstGen *res = ir_analyze_struct_literal_to_struct(ira, source_instr, value, anon_type, wanted_child); |
| 15971 | if (res->value->type->id == ZigTypeIdPointer) |
| 15972 | return res; |
| 15973 | return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile); |
| 15974 | } else if (wanted_child->id == ZigTypeIdUnion && !is_array_init && field_count == 1) { |
| 15975 | IrInstGen *res = ir_analyze_struct_literal_to_union(ira, source_instr, value, anon_type, wanted_child); |
| 15976 | if (res->value->type->id == ZigTypeIdPointer) |
| 15977 | return res; |
| 15978 | return ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile); |
| 15979 | } |
| 15980 | } else if (is_slice(wanted_type) && (is_array_init || field_count == 0)) { |
| 15981 | ZigType *slice_child_type = wanted_type->data.structure.fields[slice_ptr_index]->type_entry->data.pointer.child_type; |
| 15982 | ZigType *slice_array_type = get_array_type(ira->codegen, slice_child_type, field_count, nullptr); |
| 15983 | IrInstGen *res = ir_analyze_struct_literal_to_array(ira, source_instr, value, anon_type, slice_array_type); |
| 15984 | if (type_is_invalid(res->value->type)) |
| 15985 | return ira->codegen->invalid_inst_gen; |
| 15986 | if (res->value->type->id != ZigTypeIdPointer) |
| 15987 | res = ir_get_ref(ira, source_instr, res, wanted_type->data.pointer.is_const, wanted_type->data.pointer.is_volatile); |
| 15988 | |
| 15989 | return ir_resolve_ptr_of_array_to_slice(ira, source_instr, res, wanted_type, nullptr); |
| 15937 | 15990 | } |
| 15938 | 15991 | } |
| 15939 | 15992 | |