From d4c539664661a93fe193a9559688e7c6c3955e0d Mon Sep 17 00:00:00 2001 From: mlugg Date: Sun, 16 Mar 2025 03:13:19 +0000 Subject: [PATCH] Sema: fix pointers to comptime fields of comptime-known aggregate pointers Resolves: #23190 --- src/Sema.zig | 17 ++++++++++++----- .../runtime_store_to_comptime_field.zig | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 test/cases/compile_errors/runtime_store_to_comptime_field.zig diff --git a/src/Sema.zig b/src/Sema.zig index 5c084cd4b6..788f8ba057 100644 --- a/src/Sema.zig +++ b/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(), diff --git a/test/cases/compile_errors/runtime_store_to_comptime_field.zig b/test/cases/compile_errors/runtime_store_to_comptime_field.zig new file mode 100644 index 0000000000..0c5d6a7ad3 --- /dev/null +++ b/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