Commit d4c5396646

mlugg <mlugg@mlugg.co.uk>
2025-03-16 04:13:19
Sema: fix pointers to comptime fields of comptime-known aggregate pointers
Resolves: #23190
1 parent 5ed8bd5
Changed files (2)
src
test
src/Sema.zig
@@ -28013,12 +28013,17 @@ fn structFieldPtrByIndex(
     const zcu = pt.zcu;
     const ip = &zcu.intern_pool;
 
-    if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
-        const val = try struct_ptr_val.ptrField(field_index, pt);
-        return Air.internedToRef(val.toIntern());
+    const struct_type = zcu.typeToStruct(struct_ty).?;
+    const field_is_comptime = struct_type.fieldIsComptime(ip, field_index);
+
+    // Comptime fields are handled later
+    if (!field_is_comptime) {
+        if (try sema.resolveDefinedValue(block, src, struct_ptr)) |struct_ptr_val| {
+            const val = try struct_ptr_val.ptrField(field_index, pt);
+            return Air.internedToRef(val.toIntern());
+        }
     }
 
-    const struct_type = zcu.typeToStruct(struct_ty).?;
     const field_ty = struct_type.field_types.get(ip)[field_index];
     const struct_ptr_ty = sema.typeOf(struct_ptr);
     const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(zcu);
@@ -28038,6 +28043,7 @@ fn structFieldPtrByIndex(
         try Type.fromInterned(struct_ptr_ty_info.child).abiAlignmentSema(pt);
 
     if (struct_type.layout == .@"packed") {
+        assert(!field_is_comptime);
         switch (struct_ty.packedStructFieldPtrInfo(struct_ptr_ty, field_index, pt)) {
             .bit_ptr => |packed_offset| {
                 ptr_ty_data.flags.alignment = parent_align;
@@ -28048,6 +28054,7 @@ fn structFieldPtrByIndex(
             },
         }
     } else if (struct_type.layout == .@"extern") {
+        assert(!field_is_comptime);
         // For extern structs, field alignment might be bigger than type's
         // natural alignment. Eg, in `extern struct { x: u32, y: u16 }` the
         // second field is aligned as u32.
@@ -28071,7 +28078,7 @@ fn structFieldPtrByIndex(
 
     const ptr_field_ty = try pt.ptrTypeSema(ptr_ty_data);
 
-    if (struct_type.fieldIsComptime(ip, field_index)) {
+    if (field_is_comptime) {
         try struct_ty.resolveStructFieldInits(pt);
         const val = try pt.intern(.{ .ptr = .{
             .ty = ptr_field_ty.toIntern(),
test/cases/compile_errors/runtime_store_to_comptime_field.zig
@@ -0,0 +1,19 @@
+const init: u32 = 1;
+fn rt() u32 {
+    return 3;
+}
+
+var tuple_val = .{init};
+export fn tuple_field() void {
+    tuple_val[0] = rt();
+}
+
+var struct_val = .{ .x = init };
+export fn struct_field() void {
+    struct_val.x = rt();
+}
+
+// error
+//
+// :8:14: error: cannot store runtime value in compile time variable
+// :13:15: error: cannot store runtime value in compile time variable