Commit 6f560c9909

Andrew Kelley <andrew@ziglang.org>
2022-03-09 04:52:38
Sema: implement comptime struct fields
1 parent a917532
Changed files (3)
src/Module.zig
@@ -884,6 +884,7 @@ pub const Struct = struct {
         default_val: Value,
         /// undefined until `status` is `have_layout`.
         offset: u32,
+        /// If true then `default_val` is the comptime field value.
         is_comptime: bool,
 
         /// Returns the field alignment, assuming the struct is not packed.
src/Sema.zig
@@ -15282,6 +15282,19 @@ fn structFieldPtrByIndex(
     const target = sema.mod.getTarget();
     const ptr_field_ty = try Type.ptr(sema.arena, target, ptr_ty_data);
 
+    if (field.is_comptime) {
+        var anon_decl = try block.startAnonDecl(field_src);
+        defer anon_decl.deinit();
+        const decl = try anon_decl.finish(
+            try field.ty.copy(anon_decl.arena()),
+            try field.default_val.copy(anon_decl.arena()),
+        );
+        if (ptr_ty_data.@"align" != 0) {
+            decl.align_val = field.abi_align;
+        }
+        return sema.analyzeDeclRef(decl);
+    }
+
     if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
         return sema.addConstant(
             ptr_field_ty,
@@ -15330,6 +15343,10 @@ fn structFieldVal(
             const field_index = @intCast(u32, field_index_usize);
             const field = struct_obj.fields.values()[field_index];
 
+            if (field.is_comptime) {
+                return sema.addConstant(field.ty, field.default_val);
+            }
+
             if (try sema.resolveMaybeUndefVal(block, src, struct_byval)) |struct_val| {
                 if (struct_val.isUndef()) return sema.addConstUndef(field.ty);
                 if ((try sema.typeHasOnePossibleValue(block, src, field.ty))) |opv| {
test/behavior/struct.zig
@@ -982,7 +982,8 @@ test "tuple assigned to variable" {
 }
 
 test "comptime struct field" {
-    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
 
     const T = struct {
         a: i32,