mirror of
https://github.com/ziglang/zig.git
synced 2025-12-13 09:43:09 +00:00
Allow constant struct val to reallocate its fields when resolving an inferred struct field with a comptime value.
This commit is contained in:
parent
c92957da0e
commit
debcc79d56
33
src/ir.cpp
33
src/ir.cpp
@ -18477,6 +18477,15 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
|
||||
IrInstGen *casted_ptr;
|
||||
if (isf->already_resolved) {
|
||||
field = find_struct_type_field(isf->inferred_struct_type, isf->field_name);
|
||||
|
||||
// If the value originates from another node than the original value's we overwrite the inferred struct's
|
||||
// type so that the new result can be written successfully.
|
||||
// The duplicate field will be detected and reported in 'ir_analyze_container_init_fields'
|
||||
AstNode *decl_node = value ? value->base.source_node : suspend_source_instr->source_node;
|
||||
if (decl_node != field->decl_node) {
|
||||
field->type_entry = value_type;
|
||||
field->type_val = create_const_type(ira->codegen, field->type_entry);
|
||||
}
|
||||
casted_ptr = result_loc;
|
||||
} else {
|
||||
isf->already_resolved = true;
|
||||
@ -18493,15 +18502,6 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
|
||||
field->type_val = create_const_type(ira->codegen, field->type_entry);
|
||||
field->src_index = old_field_count;
|
||||
field->decl_node = value ? value->base.source_node : suspend_source_instr->source_node;
|
||||
if (value && instr_is_comptime(value)) {
|
||||
ZigValue *val = ir_resolve_const(ira, value, UndefOk);
|
||||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
field->is_comptime = true;
|
||||
field->init_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(ira->codegen, field->init_val, val);
|
||||
return result_loc;
|
||||
}
|
||||
|
||||
ZigType *struct_ptr_type = get_pointer_to_type(ira->codegen, isf->inferred_struct_type, false);
|
||||
if (instr_is_comptime(result_loc)) {
|
||||
@ -18532,6 +18532,16 @@ static IrInstGen *ir_resolve_result(IrAnalyze *ira, IrInst *suspend_source_instr
|
||||
}
|
||||
}
|
||||
|
||||
if (value && instr_is_comptime(value)) {
|
||||
ZigValue *val = ir_resolve_const(ira, value, UndefOk);
|
||||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
field->is_comptime = true;
|
||||
field->init_val = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
copy_const_val(ira->codegen, field->init_val, val);
|
||||
return result_loc;
|
||||
}
|
||||
|
||||
result_loc = ir_analyze_struct_field_ptr(ira, suspend_source_instr, field, casted_ptr,
|
||||
isf->inferred_struct_type, true);
|
||||
result_loc_pass1->resolved_loc = result_loc;
|
||||
@ -22957,6 +22967,9 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
|
||||
first_non_const_instruction = result_loc;
|
||||
}
|
||||
}
|
||||
|
||||
heap::c_allocator.deallocate(field_assign_nodes, actual_field_count);
|
||||
|
||||
if (any_missing)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
|
||||
@ -22972,6 +22985,8 @@ static IrInstGen *ir_analyze_container_init_fields(IrAnalyze *ira, IrInst *sourc
|
||||
}
|
||||
}
|
||||
|
||||
const_ptrs.deinit();
|
||||
|
||||
IrInstGen *result = ir_get_deref(ira, source_instr, result_loc, nullptr);
|
||||
|
||||
if (is_comptime && !instr_is_comptime(result)) {
|
||||
|
||||
@ -54,3 +54,42 @@ test "tuple concatenation" {
|
||||
T.doTheTest();
|
||||
comptime T.doTheTest();
|
||||
}
|
||||
|
||||
test "tuple initialization with structure initializer and constant expression" {
|
||||
const TestStruct = struct {
|
||||
state: u8,
|
||||
};
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() void {
|
||||
const tuple_with_struct = .{ TestStruct{ .state = 42 }, 0 };
|
||||
expect(tuple_with_struct.len == 2);
|
||||
expect(tuple_with_struct[0].state == 42);
|
||||
expect(tuple_with_struct[1] == 0);
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
test "passing tuples as comptime generic parameters" {
|
||||
const S = struct {
|
||||
fn expect_len(comptime pack: var, comptime len: usize) void {
|
||||
expect(pack.len == len);
|
||||
}
|
||||
|
||||
fn expect_first_element(comptime pack: var, comptime elem: var) void {
|
||||
expect(pack[0] == elem);
|
||||
}
|
||||
|
||||
fn doTheTest() void {
|
||||
expect_len(.{}, 0);
|
||||
expect_len(.{ 0 }, 1);
|
||||
expect_first_element(.{ 0 }, 0);
|
||||
expect_len(.{ u8, 1, "literal" }, 3);
|
||||
expect_first_element(.{ u8, 1, "literal" }, u8);
|
||||
}
|
||||
};
|
||||
S.doTheTest();
|
||||
comptime S.doTheTest();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user