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 {...@@ -884,6 +884,7 @@ pub const Struct = struct {
884 default_val: Value,884 default_val: Value,
885 /// undefined until `status` is `have_layout`.885 /// undefined until `status` is `have_layout`.
886 offset: u32,886 offset: u32,
887 /// If true then `default_val` is the comptime field value.
887 is_comptime: bool,888 is_comptime: bool,
888889
889 /// Returns the field alignment, assuming the struct is not packed.890 /// Returns the field alignment, assuming the struct is not packed.
src/Sema.zig+17
...@@ -15282,6 +15282,19 @@ fn structFieldPtrByIndex(...@@ -15282,6 +15282,19 @@ fn structFieldPtrByIndex(
15282 const target = sema.mod.getTarget();15282 const target = sema.mod.getTarget();
15283 const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);15283 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
15285 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {15298 if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
15286 return sema.addConstant(15299 return sema.addConstant(
15287 ptr_field_ty,15300 ptr_field_ty,
...@@ -15330,6 +15343,10 @@ fn structFieldVal(...@@ -15330,6 +15343,10 @@ fn structFieldVal(
15330 const field_index = @intCast(u32, field_index_usize);15343 const field_index = @intCast(u32, field_index_usize);
15331 const field = struct_obj.fields.values()[field_index];15344 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
15333 if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {15350 if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {
15334 if (struct_val.isUndef()) return sema.addConstUndef(field.ty);15351 if (struct_val.isUndef()) return sema.addConstUndef(field.ty);
15335 if ((try sema.typeHasOnePossibleValue(block, src, field.ty))) |opv| {15352 if ((try sema.typeHasOnePossibleValue(block, src, field.ty))) |opv| {
test/behavior/struct.zig+2-1
...@@ -982,7 +982,8 @@ test "tuple assigned to variable" {...@@ -982,7 +982,8 @@ test "tuple assigned to variable" {
982}982}
983983
984test "comptime struct field" {984test "comptime struct field" {
985 if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO985 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
986 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
986987
987 const T = struct {988 const T = struct {
988 a: i32,989 a: i32,