fix(Sema): patch segfault in finishStructInit
This commit is contained in:
committed by
Veikka Tuominen
parent
cad65307b7
commit
28383d4d98
20
src/Sema.zig
20
src/Sema.zig
@@ -20345,7 +20345,12 @@ fn structInitEmpty(
|
||||
defer gpa.free(field_inits);
|
||||
@memset(field_inits, .none);
|
||||
|
||||
return sema.finishStructInit(block, init_src, dest_src, field_inits, struct_ty, struct_ty, false);
|
||||
// Maps field index in the struct declaration to the field index in the initialization expression.
|
||||
const field_assign_idxs = try gpa.alloc(?usize, struct_ty.structFieldCount(zcu));
|
||||
defer gpa.free(field_assign_idxs);
|
||||
@memset(field_assign_idxs, null);
|
||||
|
||||
return sema.finishStructInit(block, init_src, dest_src, field_inits, field_assign_idxs, struct_ty, struct_ty, false);
|
||||
}
|
||||
|
||||
fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref {
|
||||
@@ -20456,6 +20461,11 @@ fn zirStructInit(
|
||||
defer gpa.free(field_inits);
|
||||
@memset(field_inits, .none);
|
||||
|
||||
// Maps field index in the struct declaration to the field index in the initialization expression.
|
||||
const field_assign_idxs = try gpa.alloc(?usize, resolved_ty.structFieldCount(zcu));
|
||||
defer gpa.free(field_assign_idxs);
|
||||
@memset(field_assign_idxs, null);
|
||||
|
||||
var field_i: u32 = 0;
|
||||
var extra_index = extra.end;
|
||||
|
||||
@@ -20478,6 +20488,7 @@ fn zirStructInit(
|
||||
else
|
||||
try sema.structFieldIndex(block, resolved_ty, field_name, field_src);
|
||||
assert(field_inits[field_index] == .none);
|
||||
field_assign_idxs[field_index] = field_i;
|
||||
found_fields[field_index] = item.data.field_type;
|
||||
const uncoerced_init = try sema.resolveInst(item.data.init);
|
||||
const field_ty = resolved_ty.fieldType(field_index, zcu);
|
||||
@@ -20498,7 +20509,7 @@ fn zirStructInit(
|
||||
}
|
||||
}
|
||||
|
||||
return sema.finishStructInit(block, src, src, field_inits, resolved_ty, result_ty, is_ref);
|
||||
return sema.finishStructInit(block, src, src, field_inits, field_assign_idxs, resolved_ty, result_ty, is_ref);
|
||||
} else if (resolved_ty.zigTypeTag(zcu) == .@"union") {
|
||||
if (extra.data.fields_len != 1) {
|
||||
return sema.fail(block, src, "union initialization expects exactly one field", .{});
|
||||
@@ -20583,6 +20594,7 @@ fn finishStructInit(
|
||||
init_src: LazySrcLoc,
|
||||
dest_src: LazySrcLoc,
|
||||
field_inits: []Air.Inst.Ref,
|
||||
field_assign_idxs: []?usize,
|
||||
struct_ty: Type,
|
||||
result_ty: Type,
|
||||
is_ref: bool,
|
||||
@@ -20684,9 +20696,9 @@ fn finishStructInit(
|
||||
}
|
||||
|
||||
// Find which field forces the expression to be runtime, if any.
|
||||
const opt_runtime_index = for (field_inits, 0..) |field_init, i| {
|
||||
const opt_runtime_index = for (field_inits, field_assign_idxs) |field_init, field_assign| {
|
||||
if (!(try sema.isComptimeKnown(field_init))) {
|
||||
break i;
|
||||
break field_assign;
|
||||
}
|
||||
} else null;
|
||||
|
||||
|
||||
19
test/cases/compile_errors/compile_time_struct_field.zig
Normal file
19
test/cases/compile_errors/compile_time_struct_field.zig
Normal file
@@ -0,0 +1,19 @@
|
||||
const S = struct {
|
||||
comptime_field: comptime_int = 2,
|
||||
normal_ptr: *u32,
|
||||
};
|
||||
|
||||
export fn a() void {
|
||||
var value: u32 = 3;
|
||||
const comptimeStruct = S {
|
||||
.normal_ptr = &value,
|
||||
};
|
||||
_ = comptimeStruct;
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// 9:6: error: unable to resolve comptime value
|
||||
// 9:6: note: initializer of comptime only struct must be comptime-known
|
||||
Reference in New Issue
Block a user