aboutsummaryrefslogtreecommitdiff
path: root/src/Type.zig
diff options
context:
space:
mode:
authorxdBronch <51252236+xdBronch@users.noreply.github.com>2025-10-04 00:12:26 -0400
committerMatthew Lugg <mlugg@mlugg.co.uk>2025-10-08 18:04:25 +0100
commit60be67d3c0ba6ae15fa7115596734ab1e74fbcd3 (patch)
tree4679e250207c5215d5df51d79a307d41443fd4eb /src/Type.zig
parent60a332406c10be922568e11dcc5144bb0f2d7a85 (diff)
downloadzig-60be67d3c0ba6ae15fa7115596734ab1e74fbcd3.tar.gz
zig-60be67d3c0ba6ae15fa7115596734ab1e74fbcd3.zip
don't make OPV tuple fields `comptime`
Diffstat (limited to 'src/Type.zig')
-rw-r--r--src/Type.zig63
1 files changed, 38 insertions, 25 deletions
diff --git a/src/Type.zig b/src/Type.zig
index cdce964356..c57d0df506 100644
--- a/src/Type.zig
+++ b/src/Type.zig
@@ -2581,15 +2581,30 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
},
.tuple_type => |tuple| {
- for (tuple.values.get(ip)) |val| {
- if (val == .none) return null;
+ if (tuple.types.len == 0) {
+ return try pt.aggregateValue(ty, &.{});
}
- // In this case the struct has all comptime-known fields and
- // therefore has one possible value.
- // TODO: write something like getCoercedInts to avoid needing to dupe
- const duped_values = try zcu.gpa.dupe(InternPool.Index, tuple.values.get(ip));
- defer zcu.gpa.free(duped_values);
- return try pt.aggregateValue(ty, duped_values);
+
+ const field_vals = try zcu.gpa.alloc(
+ InternPool.Index,
+ tuple.types.len,
+ );
+ defer zcu.gpa.free(field_vals);
+ for (
+ field_vals,
+ tuple.types.get(ip),
+ tuple.values.get(ip),
+ ) |*field_val, field_ty, field_comptime_val| {
+ if (field_comptime_val != .none) {
+ field_val.* = field_comptime_val;
+ continue;
+ }
+ if (try Type.fromInterned(field_ty).onePossibleValue(pt)) |opv| {
+ field_val.* = opv.toIntern();
+ } else return null;
+ }
+
+ return try pt.aggregateValue(ty, field_vals);
},
.union_type => {
@@ -2630,24 +2645,22 @@ pub fn onePossibleValue(starting_type: Type, pt: Zcu.PerThread) !?Value {
.auto, .explicit => {
if (Type.fromInterned(enum_type.tag_ty).hasRuntimeBits(zcu)) return null;
- switch (enum_type.names.len) {
- 0 => {
- const only = try pt.intern(.{ .empty_enum_value = ty.toIntern() });
- return Value.fromInterned(only);
- },
- 1 => {
- if (enum_type.values.len == 0) {
- const only = try pt.intern(.{ .enum_tag = .{
- .ty = ty.toIntern(),
- .int = (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern(),
- } });
- return Value.fromInterned(only);
- } else {
- return Value.fromInterned(enum_type.values.get(ip)[0]);
- }
- },
+ return Value.fromInterned(switch (enum_type.names.len) {
+ 0 => try pt.intern(.{ .empty_enum_value = ty.toIntern() }),
+ 1 => try pt.intern(.{ .enum_tag = .{
+ .ty = ty.toIntern(),
+ .int = if (enum_type.values.len == 0)
+ (try pt.intValue(.fromInterned(enum_type.tag_ty), 0)).toIntern()
+ else
+ try ip.getCoercedInts(
+ zcu.gpa,
+ pt.tid,
+ ip.indexToKey(enum_type.values.get(ip)[0]).int,
+ enum_type.tag_ty,
+ ),
+ } }),
else => return null,
- }
+ });
},
}
},