| ... | @@ -204,6 +204,8 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de | ... | @@ -204,6 +204,8 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de |
| 204 | ResultLoc *parent_result_loc); | 204 | ResultLoc *parent_result_loc); |
| 205 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, | 205 | static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr, |
| 206 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); | 206 | TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing); |
| | 207 | static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name, |
| | 208 | IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); |
| 207 | | 209 | |
| 208 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { | 210 | static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { |
| 209 | assert(get_src_ptr_type(const_val->type) != nullptr); | 211 | assert(get_src_ptr_type(const_val->type) != nullptr); |
| ... | @@ -16329,16 +16331,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -16329,16 +16331,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 16329 | uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; | 16331 | uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count; |
| 16330 | uint32_t new_field_count = old_field_count + 1; | 16332 | uint32_t new_field_count = old_field_count + 1; |
| 16331 | isf->inferred_struct_type->data.structure.src_field_count = new_field_count; | 16333 | isf->inferred_struct_type->data.structure.src_field_count = new_field_count; |
| 16332 | // This thing with max(x, 16) is a hack to allow this functionality to work without | 16334 | if (new_field_count > 16) { |
| 16333 | // modifying the ConstExprValue layout of structs. That reworking needs to be | 16335 | // This thing with 16 is a hack to allow this functionality to work without |
| 16334 | // done, but this hack lets us do it separately, in the future. | 16336 | // modifying the ConstExprValue layout of structs. That reworking needs to be |
| 16335 | TypeStructField *prev_ptr = isf->inferred_struct_type->data.structure.fields; | 16337 | // done, but this hack lets us do it separately, in the future. |
| 16336 | isf->inferred_struct_type->data.structure.fields = reallocate( | 16338 | zig_panic("TODO need to rework the layout of ZigTypeStruct. This realloc would have caused invalid pointer references"); |
| 16337 | isf->inferred_struct_type->data.structure.fields, | 16339 | } |
| 16338 | (old_field_count == 0) ? 0 : max(old_field_count, 16u), | 16340 | if (isf->inferred_struct_type->data.structure.fields == nullptr) { |
| 16339 | max(new_field_count, 16u)); | 16341 | isf->inferred_struct_type->data.structure.fields = allocate<TypeStructField>(16); |
| 16340 | if (prev_ptr != nullptr && prev_ptr != isf->inferred_struct_type->data.structure.fields) { | | |
| 16341 | zig_panic("TODO need to rework the layout of ZigTypeStruct. this realloc would have caused invalid pointer references"); | | |
| 16342 | } | 16342 | } |
| 16343 | | 16343 | |
| 16344 | // This reference can't live long, don't keep it around outside this block. | 16344 | // This reference can't live long, don't keep it around outside this block. |
| ... | @@ -16368,15 +16368,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source | ... | @@ -16368,15 +16368,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source |
| 16368 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, | 16368 | ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val, |
| 16369 | source_instr->source_node); | 16369 | source_instr->source_node); |
| 16370 | struct_val->special = ConstValSpecialStatic; | 16370 | struct_val->special = ConstValSpecialStatic; |
| 16371 | ConstExprValue *prev_ptr = struct_val->data.x_struct.fields; | 16371 | if (new_field_count > 16) { |
| 16372 | // This thing with max(x, 16) is a hack to allow this functionality to work without | 16372 | // This thing with 16 is a hack to allow this functionality to work without |
| 16373 | // modifying the ConstExprValue layout of structs. That reworking needs to be | 16373 | // modifying the ConstExprValue layout of structs. That reworking needs to be |
| 16374 | // done, but this hack lets us do it separately, in the future. | 16374 | // done, but this hack lets us do it separately, in the future. |
| 16375 | struct_val->data.x_struct.fields = realloc_const_vals(struct_val->data.x_struct.fields, | 16375 | zig_panic("TODO need to rework the layout of ConstExprValue for structs. This realloc would have caused invalid pointer references"); |
| 16376 | (old_field_count == 0) ? 0 : max(old_field_count, 16u), | 16376 | } |
| 16377 | max(new_field_count, 16u)); | 16377 | if (struct_val->data.x_struct.fields == nullptr) { |
| 16378 | if (prev_ptr != nullptr && prev_ptr != struct_val->data.x_struct.fields) { | 16378 | struct_val->data.x_struct.fields = create_const_vals(16); |
| 16379 | zig_panic("TODO need to rework the layout of ConstExprValue for structs. this realloc would have caused invalid pointer references"); | | |
| 16380 | } | 16379 | } |
| 16381 | | 16380 | |
| 16382 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count]; | 16381 | ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count]; |
| ... | @@ -17893,6 +17892,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct | ... | @@ -17893,6 +17892,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct |
| 17893 | } else if (array_type->id == ZigTypeIdVector) { | 17892 | } else if (array_type->id == ZigTypeIdVector) { |
| 17894 | // This depends on whether the element index is comptime, so it is computed later. | 17893 | // This depends on whether the element index is comptime, so it is computed later. |
| 17895 | return_type = nullptr; | 17894 | return_type = nullptr; |
| | 17895 | } else if (elem_ptr_instruction->init_array_type_source_node != nullptr && |
| | 17896 | array_type->id == ZigTypeIdStruct && |
| | 17897 | array_type->data.structure.resolve_status == ResolveStatusBeingInferred) |
| | 17898 | { |
| | 17899 | ZigType *usize = ira->codegen->builtin_types.entry_usize; |
| | 17900 | IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); |
| | 17901 | if (casted_elem_index == ira->codegen->invalid_instruction) |
| | 17902 | return ira->codegen->invalid_instruction; |
| | 17903 | ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base); |
| | 17904 | Buf *field_name = buf_alloc(); |
| | 17905 | bigint_append_buf(field_name, &casted_elem_index->value.data.x_bigint, 10); |
| | 17906 | return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base, |
| | 17907 | array_ptr, array_type); |
| 17896 | } else { | 17908 | } else { |
| 17897 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, | 17909 | ir_add_error_node(ira, elem_ptr_instruction->base.source_node, |
| 17898 | buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); | 17910 | buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); |
| ... | @@ -20246,8 +20258,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc | ... | @@ -20246,8 +20258,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc |
| 20246 | TypeStructField *field = &container_type->data.structure.fields[i]; | 20258 | TypeStructField *field = &container_type->data.structure.fields[i]; |
| 20247 | if (field->init_val == nullptr) { | 20259 | if (field->init_val == nullptr) { |
| 20248 | // it's not memoized. time to go analyze it | 20260 | // it's not memoized. time to go analyze it |
| 20249 | assert(field->decl_node->type == NodeTypeStructField); | 20261 | AstNode *init_node; |
| 20250 | AstNode *init_node = field->decl_node->data.struct_field.value; | 20262 | if (field->decl_node->type == NodeTypeStructField) { |
| | 20263 | init_node = field->decl_node->data.struct_field.value; |
| | 20264 | } else { |
| | 20265 | init_node = nullptr; |
| | 20266 | } |
| 20251 | if (init_node == nullptr) { | 20267 | if (init_node == nullptr) { |
| 20252 | ir_add_error_node(ira, instruction->source_node, | 20268 | ir_add_error_node(ira, instruction->source_node, |
| 20253 | buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); | 20269 | buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); |
| ... | @@ -20337,23 +20353,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, | ... | @@ -20337,23 +20353,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, |
| 20337 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); | 20353 | return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc); |
| 20338 | } | 20354 | } |
| 20339 | | 20355 | |
| 20340 | if (container_type->id != ZigTypeIdArray) { | 20356 | if (container_type->id == ZigTypeIdArray) { |
| | 20357 | ZigType *child_type = container_type->data.array.child_type; |
| | 20358 | if (container_type->data.array.len != elem_count) { |
| | 20359 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); |
| | 20360 | |
| | 20361 | ir_add_error(ira, &instruction->base, |
| | 20362 | buf_sprintf("expected %s literal, found %s literal", |
| | 20363 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); |
| | 20364 | return ira->codegen->invalid_instruction; |
| | 20365 | } |
| | 20366 | } else if (container_type->id == ZigTypeIdStruct && |
| | 20367 | container_type->data.structure.resolve_status == ResolveStatusBeingInferred) |
| | 20368 | { |
| | 20369 | // We're now done inferring the type. |
| | 20370 | container_type->data.structure.resolve_status = ResolveStatusUnstarted; |
| | 20371 | } else { |
| 20341 | ir_add_error_node(ira, instruction->base.source_node, | 20372 | ir_add_error_node(ira, instruction->base.source_node, |
| 20342 | buf_sprintf("type '%s' does not support array initialization", | 20373 | buf_sprintf("type '%s' does not support array initialization", |
| 20343 | buf_ptr(&container_type->name))); | 20374 | buf_ptr(&container_type->name))); |
| 20344 | return ira->codegen->invalid_instruction; | 20375 | return ira->codegen->invalid_instruction; |
| 20345 | } | 20376 | } |
| 20346 | | 20377 | |
| 20347 | ZigType *child_type = container_type->data.array.child_type; | | |
| 20348 | if (container_type->data.array.len != elem_count) { | | |
| 20349 | ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); | | |
| 20350 | | | |
| 20351 | ir_add_error(ira, &instruction->base, | | |
| 20352 | buf_sprintf("expected %s literal, found %s literal", | | |
| 20353 | buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); | | |
| 20354 | return ira->codegen->invalid_instruction; | | |
| 20355 | } | | |
| 20356 | | | |
| 20357 | switch (type_has_one_possible_value(ira->codegen, container_type)) { | 20378 | switch (type_has_one_possible_value(ira->codegen, container_type)) { |
| 20358 | case OnePossibleValueInvalid: | 20379 | case OnePossibleValueInvalid: |
| 20359 | return ira->codegen->invalid_instruction; | 20380 | return ira->codegen->invalid_instruction; |