| ... | @@ -18777,6 +18777,18 @@ fn structInitAnon( | ... | @@ -18777,6 +18777,18 @@ fn structInitAnon( |
| 18777 | break :rs runtime_index; | 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 | // We treat anonymous struct types as reified types, because there are similarities: they have | 18792 | // We treat anonymous struct types as reified types, because there are similarities: they have |
| 18781 | // no captures, and instead use a form of structural equivalence which we can easy represent by | 18793 | // no captures, and instead use a form of structural equivalence which we can easy represent by |
| 18782 | // hashing the field names/types/values. They also perform layout resolution immediately. These | 18794 | // hashing the field names/types/values. They also perform layout resolution immediately. These |
| ... | @@ -18785,7 +18797,7 @@ fn structInitAnon( | ... | @@ -18785,7 +18797,7 @@ fn structInitAnon( |
| 18785 | const type_hash: u64 = hash: { | 18797 | const type_hash: u64 = hash: { |
| 18786 | var hasher = std.hash.Wyhash.init(0); | 18798 | var hasher = std.hash.Wyhash.init(0); |
| 18787 | hasher.update(std.mem.sliceAsBytes(types)); | 18799 | hasher.update(std.mem.sliceAsBytes(types)); |
| 18788 | hasher.update(std.mem.sliceAsBytes(values)); | 18800 | hasher.update(std.mem.sliceAsBytes(values_no_comptime)); |
| 18789 | hasher.update(std.mem.sliceAsBytes(names)); | 18801 | hasher.update(std.mem.sliceAsBytes(names)); |
| 18790 | break :hash hasher.final(); | 18802 | break :hash hasher.final(); |
| 18791 | }; | 18803 | }; |
| ... | @@ -18809,9 +18821,9 @@ fn structInitAnon( | ... | @@ -18809,9 +18821,9 @@ fn structInitAnon( |
| 18809 | @memcpy(wip.field_names.get(ip), names); | 18821 | @memcpy(wip.field_names.get(ip), names); |
| 18810 | @memcpy(wip.field_types.get(ip), types); | 18822 | @memcpy(wip.field_types.get(ip), types); |
| 18811 | if (any_values) { | 18823 | if (any_values) { |
| 18812 | @memcpy(wip.field_values.get(ip), values); | 18824 | @memcpy(wip.field_values.get(ip), values_no_comptime); |
| 18813 | @memset(wip.field_is_comptime_bits.getAll(ip), 0); | 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 | if (val == .none) continue; | 18827 | if (val == .none) continue; |
| 18816 | const bit_bag_index = field_index / 32; | 18828 | const bit_bag_index = field_index / 32; |
| 18817 | const mask = @as(u32, 1) << @intCast(field_index % 32); | 18829 | const mask = @as(u32, 1) << @intCast(field_index % 32); |
| ... | @@ -18839,6 +18851,15 @@ fn structInitAnon( | ... | @@ -18839,6 +18851,15 @@ fn structInitAnon( |
| 18839 | return sema.addConstantMaybeRef(struct_val, is_ref); | 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 | if (is_ref) { | 18863 | if (is_ref) { |
| 18843 | const target = zcu.getTarget(); | 18864 | const target = zcu.getTarget(); |
| 18844 | const alloc_ty = try pt.ptrType(.{ | 18865 | const alloc_ty = try pt.ptrType(.{ |
| ... | @@ -19095,13 +19116,11 @@ fn arrayInitAnon( | ... | @@ -19095,13 +19116,11 @@ fn arrayInitAnon( |
| 19095 | .values = values_no_comptime, | 19116 | .values = values_no_comptime, |
| 19096 | })); | 19117 | })); |
| 19097 | | 19118 | |
| 19098 | const runtime_src = opt_runtime_src orelse { | 19119 | _ = opt_runtime_src orelse { |
| 19099 | const tuple_val = try pt.aggregateValue(tuple_ty, values); | 19120 | const tuple_val = try pt.aggregateValue(tuple_ty, values); |
| 19100 | return sema.addConstantMaybeRef(tuple_val, is_ref); | 19121 | return sema.addConstantMaybeRef(tuple_val, is_ref); |
| 19101 | }; | 19122 | }; |
| 19102 | | 19123 | |
| 19103 | try sema.requireRuntimeBlock(block, src, runtime_src); | | |
| 19104 | | | |
| 19105 | for (operands, 0..) |operand, i| { | 19124 | for (operands, 0..) |operand, i| { |
| 19106 | const operand_src = block.src(.{ .init_elem = .{ | 19125 | const operand_src = block.src(.{ .init_elem = .{ |
| 19107 | .init_node_offset = src.offset.node_offset.x, | 19126 | .init_node_offset = src.offset.node_offset.x, |