| ... | ... | @@ -18777,6 +18777,18 @@ fn structInitAnon( |
| 18777 | 18777 | break :rs runtime_index; |
| 18778 | 18778 | }; |
| 18779 | 18779 | |
| 18780 | // A field can't be `comptime` if it references a `comptime var` but the aggregate can still be comptime-known. |
| 18781 | // Replace these fields with `.none` only for generating the type. |
| 18782 | const values_no_comptime = if (!any_values) values else blk: { |
| 18783 | const new_values = try sema.arena.alloc(InternPool.Index, types.len); |
| 18784 | for (values, new_values) |val, *new_val| { |
| 18785 | if (val != .none and Value.fromInterned(val).canMutateComptimeVarState(zcu)) { |
| 18786 | new_val.* = .none; |
| 18787 | } else new_val.* = val; |
| 18788 | } |
| 18789 | break :blk new_values; |
| 18790 | }; |
| 18791 | |
| 18780 | 18792 | // We treat anonymous struct types as reified types, because there are similarities: they have |
| 18781 | 18793 | // no captures, and instead use a form of structural equivalence which we can easy represent by |
| 18782 | 18794 | // hashing the field names/types/values. They also perform layout resolution immediately. These |
| ... | ... | @@ -18785,7 +18797,7 @@ fn structInitAnon( |
| 18785 | 18797 | const type_hash: u64 = hash: { |
| 18786 | 18798 | var hasher = std.hash.Wyhash.init(0); |
| 18787 | 18799 | hasher.update(std.mem.sliceAsBytes(types)); |
| 18788 | | hasher.update(std.mem.sliceAsBytes(values)); |
| 18800 | hasher.update(std.mem.sliceAsBytes(values_no_comptime)); |
| 18789 | 18801 | hasher.update(std.mem.sliceAsBytes(names)); |
| 18790 | 18802 | break :hash hasher.final(); |
| 18791 | 18803 | }; |
| ... | ... | @@ -18809,9 +18821,9 @@ fn structInitAnon( |
| 18809 | 18821 | @memcpy(wip.field_names.get(ip), names); |
| 18810 | 18822 | @memcpy(wip.field_types.get(ip), types); |
| 18811 | 18823 | if (any_values) { |
| 18812 | | @memcpy(wip.field_values.get(ip), values); |
| 18824 | @memcpy(wip.field_values.get(ip), values_no_comptime); |
| 18813 | 18825 | @memset(wip.field_is_comptime_bits.getAll(ip), 0); |
| 18814 | | for (values, 0..) |val, field_index| { |
| 18826 | for (values_no_comptime, 0..) |val, field_index| { |
| 18815 | 18827 | if (val == .none) continue; |
| 18816 | 18828 | const bit_bag_index = field_index / 32; |
| 18817 | 18829 | const mask = @as(u32, 1) << @intCast(field_index % 32); |
| ... | ... | @@ -18839,6 +18851,15 @@ fn structInitAnon( |
| 18839 | 18851 | return sema.addConstantMaybeRef(struct_val, is_ref); |
| 18840 | 18852 | }; |
| 18841 | 18853 | |
| 18854 | for (values, 0..) |field_val, i| { |
| 18855 | if (field_val == .none) continue; // runtime-known |
| 18856 | const field_src = block.src(.{ .init_elem = .{ |
| 18857 | .init_node_offset = src.offset.node_offset.x, |
| 18858 | .elem_index = @intCast(i), |
| 18859 | } }); |
| 18860 | try sema.validateRuntimeValue(block, field_src, .fromIntern(field_val)); |
| 18861 | } |
| 18862 | |
| 18842 | 18863 | if (is_ref) { |
| 18843 | 18864 | const target = zcu.getTarget(); |
| 18844 | 18865 | const alloc_ty = try pt.ptrType(.{ |