authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-20 19:47:54+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-07-23 15:40:12+03:00
log585c160c2022d71197a3ce1399818372371c23a4
treef282b28e83133112c1289974bdb1484d78a946e9
parent9465906775620a0832b19370b42ef2b193b96356

Sema: handle store to comptime field when `ResultLoc == .none`


2 files changed, 52 insertions(+), 3 deletions(-)

src/Sema.zig+21-3
......@@ -14515,6 +14515,16 @@ fn zirStructInit(
1451514515 }
1451614516 found_fields[field_index] = item.data.field_type;
1451714517 field_inits[field_index] = try sema.resolveInst(item.data.init);
14518 if (resolved_ty.structFieldValueComptime(field_index)) |default_value| {
14519 const init_val = (try sema.resolveMaybeUndefVal(block, field_src, field_inits[field_index])) orelse {
14520 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime known");
14521 };
14522
14523 if (!init_val.eql(default_value, resolved_ty.structFieldType(field_index), sema.mod)) {
14524 // TODO add note showing where default value is provided
14525 return sema.fail(block, field_src, "value stored in comptime field does not match the default value of the field", .{});
14526 }
14527 }
1451814528 }
1451914529
1452014530 return sema.finishStructInit(block, src, src, field_inits, resolved_ty, is_ref);
......@@ -23688,6 +23698,7 @@ fn coerceTupleToStruct(
2368823698 const struct_ty = try sema.resolveTypeFields(block, dest_ty_src, dest_ty);
2368923699
2369023700 if (struct_ty.isTupleOrAnonStruct()) {
23701 // NOTE remember to handle comptime fields
2369123702 return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to tuples", .{});
2369223703 }
2369323704
......@@ -23708,12 +23719,19 @@ fn coerceTupleToStruct(
2370823719 try std.fmt.allocPrint(sema.arena, "{d}", .{i});
2370923720 const field_index = try sema.structFieldIndex(block, struct_ty, field_name, field_src);
2371023721 const field = fields.values()[field_index];
23711 if (field.is_comptime) {
23712 return sema.fail(block, dest_ty_src, "TODO: implement coercion from tuples to structs when one of the destination struct fields is comptime", .{});
23713 }
2371423722 const elem_ref = try tupleField(sema, block, inst_src, inst, field_src, i);
2371523723 const coerced = try sema.coerce(block, field.ty, elem_ref, field_src);
2371623724 field_refs[field_index] = coerced;
23725 if (field.is_comptime) {
23726 const init_val = (try sema.resolveMaybeUndefVal(block, field_src, coerced)) orelse {
23727 return sema.failWithNeededComptime(block, field_src, "value stored in comptime field must be comptime known");
23728 };
23729
23730 if (!init_val.eql(field.default_val, field.ty, sema.mod)) {
23731 // TODO add note showing where default value is provided
23732 return sema.fail(block, field_src, "value stored in comptime field does not match the default value of the field", .{});
23733 }
23734 }
2371723735 if (runtime_src == null) {
2371823736 if (try sema.resolveMaybeUndefVal(block, field_src, coerced)) |field_val| {
2371923737 field_vals[field_index] = field_val;
test/cases/compile_errors/invalid_store_to_comptime_field.zig+31
......@@ -20,6 +20,35 @@ pub export fn entry2() void {
2020 _ = list2;
2121 _ = list3;
2222}
23pub export fn entry3() void {
24 const U = struct {
25 comptime foo: u32 = 1,
26 bar: u32,
27 fn foo(x: @This()) void {
28 _ = x;
29 }
30 };
31 _ = U.foo(U{ .foo = 2, .bar = 2 });
32}
33pub export fn entry4() void {
34 const U = struct {
35 comptime foo: u32 = 1,
36 bar: u32,
37 fn foo(x: @This()) void {
38 _ = x;
39 }
40 };
41 _ = U.foo(.{ .foo = 2, .bar = 2 });
42}
43// pub export fn entry5() void {
44// var x: u32 = 15;
45// const T = @TypeOf(.{ @as(i32, -1234), @as(u32, 5678), x });
46// const S = struct {
47// fn foo(_: T) void {}
48// };
49// _ = S.foo(.{ -1234, 5679, x });
50// }
51
2352
2453// error
2554// target=native
......@@ -28,3 +57,5 @@ pub export fn entry2() void {
2857// :6:19: error: value stored in comptime field does not match the default value of the field
2958// :14:19: error: value stored in comptime field does not match the default value of the field
3059// :19:38: error: value stored in comptime field does not match the default value of the field
60// :31:19: error: value stored in comptime field does not match the default value of the field
61// :41:14: error: value stored in comptime field does not match the default value of the field