Commit 28383d4d98
Changed files (2)
src
test
cases
compile_errors
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;
test/cases/compile_errors/compile_time_struct_field.zig
@@ -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