authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-08 20:52:38-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-08 20:52:38-07:00
log6f560c99094eec2210f2d76a2449b5f60191e11b
tree7576694e5db2ef0ae63190fbb9fe20710920703f
parenta91753219df5d0b51f55dcad3e2ef96044efdd62

Sema: implement comptime struct fields


3 files changed, 20 insertions(+), 1 deletions(-)

src/Module.zig+1
......@@ -884,6 +884,7 @@ pub const Struct = struct {
884884 default_val: Value,
885885 /// undefined until `status` is `have_layout`.
886886 offset: u32,
887 /// If true then `default_val` is the comptime field value.
887888 is_comptime: bool,
888889
889890 /// Returns the field alignment, assuming the struct is not packed.
src/Sema.zig+17
......@@ -15282,6 +15282,19 @@ fn structFieldPtrByIndex(
1528215282 const target = sema.mod.getTarget();
1528315283 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
1528415284
15285 if (field.is_comptime) {
15286 var anon_decl = try block.startAnonDecl(field_src);
15287 defer anon_decl.deinit();
15288 const decl = try anon_decl.finish(
15289 try field.ty.copy(anon_decl.arena()),
15290 try field.default_val.copy(anon_decl.arena()),
15291 );
15292 if (ptr_ty_data.@"align" != 0) {
15293 decl.align_val = field.abi_align;
15294 }
15295 return sema.analyzeDeclRef(decl);
15296 }
15297
1528515298 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
1528615299 return sema.addConstant(
1528715300 ptr_field_ty,
......@@ -15330,6 +15343,10 @@ fn structFieldVal(
1533015343 const field_index = @intCast(u32, field_index_usize);
1533115344 const field = struct_obj.fields.values()[field_index];
1533215345
15346 if (field.is_comptime) {
15347 return sema.addConstant(field.ty, field.default_val);
15348 }
15349
1533315350 if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {
1533415351 if (struct_val.isUndef()) return sema.addConstUndef(field.ty);
1533515352 if ((try sema.typeHasOnePossibleValue(block, src, field.ty))) |opv| {
test/behavior/struct.zig+2-1
......@@ -982,7 +982,8 @@ test "tuple assigned to variable" {
982982}
983983
984984test "comptime struct field" {
985 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
985 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
986 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
986987
987988 const T = struct {
988989 a: i32,