diff --git a/src/all_types.hpp b/src/all_types.hpp index 7eaef38d4..8042248f7 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -80,6 +80,7 @@ struct ConstArrayValue { ConstExprValue *elements; // This will be the same as `len` from the type, but we duplicate the information // in the constant value so that pointers pointing to arrays can see this size. + // TODO now that ConstExprValue has the type field we can use that instead of this. size_t size; // If the data for this array is supposed to be contained in a different constant // value, we link to the parent here. This way getting a pointer to this constant diff --git a/src/analyze.cpp b/src/analyze.cpp index d773efdd8..f1f294fdd 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3190,6 +3190,27 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_ } +void init_const_undefined(ConstExprValue *const_val) { + TypeTableEntry *canon_wanted_type = get_underlying_type(const_val->type); + if (canon_wanted_type->id == TypeTableEntryIdArray) { + const_val->special = ConstValSpecialStatic; + size_t elem_count = canon_wanted_type->data.array.len; + const_val->data.x_array.elements = allocate(elem_count); + const_val->data.x_array.size = elem_count; + for (size_t i = 0; i < elem_count; i += 1) { + ConstExprValue *element_val = &const_val->data.x_array.elements[i]; + element_val->type = canon_wanted_type->data.array.child_type; + init_const_undefined(element_val); + if (get_underlying_type(element_val->type)->id == TypeTableEntryIdArray) { + element_val->data.x_array.parent_array = const_val; + element_val->data.x_array.parent_array_index = i; + } + } + } else { + const_val->special = ConstValSpecialUndef; + } +} + void ensure_complete_type(CodeGen *g, TypeTableEntry *type_entry) { if (type_entry->id == TypeTableEntryIdStruct) { if (!type_entry->data.structure.complete) diff --git a/src/analyze.hpp b/src/analyze.hpp index b74f91a04..2af001055 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -136,4 +136,6 @@ ConstExprValue *create_const_slice(CodeGen *g, ConstExprValue *array_val, size_t void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_index_start, size_t arg_index_end); ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end); +void init_const_undefined(ConstExprValue *const_val); + #endif diff --git a/src/ir.cpp b/src/ir.cpp index 8b2b58fea..f5604194d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6347,6 +6347,15 @@ static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *sour return result; } +static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, + IrInstruction *target, TypeTableEntry *wanted_type) +{ + IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, + source_instr->source_node, wanted_type, target->value.depends_on_compile_var); + init_const_undefined(&result->value); + return result; +} + static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, TypeTableEntry *wanted_type) { @@ -6671,7 +6680,7 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst // explicit cast from undefined to anything if (actual_type->id == TypeTableEntryIdUndefLit) { - return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); + return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); } // explicit cast from something to const pointer of it diff --git a/test/cases/eval.zig b/test/cases/eval.zig index 629fb6366..0e5c0b37f 100644 --- a/test/cases/eval.zig +++ b/test/cases/eval.zig @@ -252,3 +252,29 @@ fn comptimeIterateOverFnPtrList() { assert(performFn('o', 0) == 1); assert(performFn('w', 99) == 99); } + + +fn initStaticArray() -> [10]i32 { + var array: [10]i32 = undefined; + array[0] = 1; + array[4] = 2; + array[7] = 3; + array[9] = 4; + return array; +} +const static_array = initStaticArray(); +fn initStaticArrayToUndefined() { + @setFnTest(this); + + assert(static_array[0] == 1); + assert(static_array[4] == 2); + assert(static_array[7] == 3); + assert(static_array[9] == 4); + + comptime { + assert(static_array[0] == 1); + assert(static_array[4] == 2); + assert(static_array[7] == 3); + assert(static_array[9] == 4); + } +}