authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-02-17 03:34:47+00:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-03-06 21:26:37+00:00
log8ec6f730eff1f6008b7eba1c749824a4a5734e5f
tree34cf9c0ef9ab1d5ee6338984440deb1db1d7ec2e
parent975b859377dee450418ae9ed572ec9d3c0b77312
signaturelock-open Commit is signed but in an unrecognized format.

compiler: represent captures directly in InternPool

These were previously associated with the type's namespace, but we need to store them directly in the InternPool for #18816.

4 files changed, 356 insertions(+), 132 deletions(-)

src/InternPool.zig+320-79
...@@ -501,6 +501,42 @@ pub const OptionalNullTerminatedString = enum(u32) {...@@ -501,6 +501,42 @@ pub const OptionalNullTerminatedString = enum(u32) {
501 }501 }
502};502};
503503
504/// A single value captured in the closure of a namespace type. This is not a plain
505/// `Index` because we must differentiate between runtime-known values (where we
506/// store the type) and comptime-known values (where we store the value).
507pub const CaptureValue = packed struct(u32) {
508 tag: enum { @"comptime", runtime },
509 idx: u31,
510
511 pub fn wrap(val: Unwrapped) CaptureValue {
512 return switch (val) {
513 .@"comptime" => |i| .{ .tag = .@"comptime", .idx = @intCast(@intFromEnum(i)) },
514 .runtime => |i| .{ .tag = .runtime, .idx = @intCast(@intFromEnum(i)) },
515 };
516 }
517 pub fn unwrap(val: CaptureValue) Unwrapped {
518 return switch (val.tag) {
519 .@"comptime" => .{ .@"comptime" = @enumFromInt(val.idx) },
520 .runtime => .{ .runtime = @enumFromInt(val.idx) },
521 };
522 }
523
524 pub const Unwrapped = union(enum) {
525 /// Index refers to the value.
526 @"comptime": Index,
527 /// Index refers to the type.
528 runtime: Index,
529 };
530
531 pub const Slice = struct {
532 start: u32,
533 len: u32,
534 pub fn get(slice: Slice, ip: *const InternPool) []CaptureValue {
535 return @ptrCast(ip.extra.items[slice.start..][0..slice.len]);
536 }
537 };
538};
539
504pub const Key = union(enum) {540pub const Key = union(enum) {
505 int_type: IntType,541 int_type: IntType,
506 ptr_type: PtrType,542 ptr_type: PtrType,
...@@ -707,6 +743,7 @@ pub const Key = union(enum) {...@@ -707,6 +743,7 @@ pub const Key = union(enum) {
707 /// This may be updated via `setTagType` later.743 /// This may be updated via `setTagType` later.
708 tag_ty: Index = .none,744 tag_ty: Index = .none,
709 zir_index: TrackedInst.Index.Optional,745 zir_index: TrackedInst.Index.Optional,
746 captures: []const CaptureValue,
710747
711 pub fn toEnumType(self: @This()) LoadedEnumType {748 pub fn toEnumType(self: @This()) LoadedEnumType {
712 if (true) @compileError("AHHHH");749 if (true) @compileError("AHHHH");
...@@ -1660,6 +1697,7 @@ pub const LoadedUnionType = struct {...@@ -1660,6 +1697,7 @@ pub const LoadedUnionType = struct {
1660 field_aligns: Alignment.Slice,1697 field_aligns: Alignment.Slice,
1661 /// Index of the union_decl ZIR instruction.1698 /// Index of the union_decl ZIR instruction.
1662 zir_index: TrackedInst.Index.Optional,1699 zir_index: TrackedInst.Index.Optional,
1700 captures: CaptureValue.Slice,
16631701
1664 pub const RuntimeTag = enum(u2) {1702 pub const RuntimeTag = enum(u2) {
1665 none,1703 none,
...@@ -1791,24 +1829,47 @@ pub const LoadedUnionType = struct {...@@ -1791,24 +1829,47 @@ pub const LoadedUnionType = struct {
1791};1829};
17921830
1793pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {1831pub fn loadUnionType(ip: *const InternPool, index: Index) LoadedUnionType {
1794 const extra_index = ip.items.items(.data)[@intFromEnum(index)];1832 const data = ip.items.items(.data)[@intFromEnum(index)];
1795 const type_union = ip.extraDataTrail(Tag.TypeUnion, extra_index);1833 const type_union = ip.extraDataTrail(Tag.TypeUnion, data);
1796 const fields_len = type_union.data.fields_len;1834 const fields_len = type_union.data.fields_len;
17971835
1836 var extra_index = type_union.end;
1837 const captures_len = if (type_union.data.flags.any_captures) c: {
1838 const len = ip.extra.items[extra_index];
1839 extra_index += 1;
1840 break :c len;
1841 } else 0;
1842
1843 const captures: CaptureValue.Slice = .{
1844 .start = extra_index,
1845 .len = captures_len,
1846 };
1847 extra_index += captures_len;
1848
1849 const field_types: Index.Slice = .{
1850 .start = extra_index,
1851 .len = fields_len,
1852 };
1853 extra_index += fields_len;
1854
1855 const field_aligns: Alignment.Slice = if (type_union.data.flags.any_aligned_fields) a: {
1856 const a: Alignment.Slice = .{
1857 .start = extra_index,
1858 .len = fields_len,
1859 };
1860 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
1861 break :a a;
1862 } else .{ .start = 0, .len = 0 };
1863
1798 return .{1864 return .{
1799 .extra_index = extra_index,1865 .extra_index = data,
1800 .decl = type_union.data.decl,1866 .decl = type_union.data.decl,
1801 .namespace = type_union.data.namespace,1867 .namespace = type_union.data.namespace,
1802 .enum_tag_ty = type_union.data.tag_ty,1868 .enum_tag_ty = type_union.data.tag_ty,
1803 .field_types = .{1869 .field_types = field_types,
1804 .start = type_union.end,1870 .field_aligns = field_aligns,
1805 .len = fields_len,
1806 },
1807 .field_aligns = .{
1808 .start = type_union.end + fields_len,
1809 .len = if (type_union.data.flags.any_aligned_fields) fields_len else 0,
1810 },
1811 .zir_index = type_union.data.zir_index,1871 .zir_index = type_union.data.zir_index,
1872 .captures = captures,
1812 };1873 };
1813}1874}
18141875
...@@ -1830,6 +1891,7 @@ pub const LoadedStructType = struct {...@@ -1830,6 +1891,7 @@ pub const LoadedStructType = struct {
1830 comptime_bits: ComptimeBits,1891 comptime_bits: ComptimeBits,
1831 offsets: Offsets,1892 offsets: Offsets,
1832 names_map: OptionalMapIndex,1893 names_map: OptionalMapIndex,
1894 captures: CaptureValue.Slice,
18331895
1834 pub const ComptimeBits = struct {1896 pub const ComptimeBits = struct {
1835 start: u32,1897 start: u32,
...@@ -2162,10 +2224,26 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2162,10 +2224,26 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2162 .comptime_bits = .{ .start = 0, .len = 0 },2224 .comptime_bits = .{ .start = 0, .len = 0 },
2163 .offsets = .{ .start = 0, .len = 0 },2225 .offsets = .{ .start = 0, .len = 0 },
2164 .names_map = .none,2226 .names_map = .none,
2227 .captures = .{ .start = 0, .len = 0 },
2165 };2228 };
2166 const extra = ip.extraDataTrail(Tag.TypeStruct, item.data);2229 const extra = ip.extraDataTrail(Tag.TypeStruct, item.data);
2167 const fields_len = extra.data.fields_len;2230 const fields_len = extra.data.fields_len;
2168 var extra_index = extra.end + fields_len; // skip field types2231 var extra_index = extra.end;
2232 const captures_len = if (extra.data.flags.any_captures) c: {
2233 const len = ip.extra.items[extra_index];
2234 extra_index += 1;
2235 break :c len;
2236 } else 0;
2237 const captures: CaptureValue.Slice = .{
2238 .start = extra_index,
2239 .len = captures_len,
2240 };
2241 extra_index += captures_len;
2242 const field_types: Index.Slice = .{
2243 .start = extra_index,
2244 .len = fields_len,
2245 };
2246 extra_index += fields_len;
2169 const names_map: OptionalMapIndex, const names: NullTerminatedString.Slice = if (!extra.data.flags.is_tuple) n: {2247 const names_map: OptionalMapIndex, const names: NullTerminatedString.Slice = if (!extra.data.flags.is_tuple) n: {
2170 const names_map: OptionalMapIndex = @enumFromInt(ip.extra.items[extra_index]);2248 const names_map: OptionalMapIndex = @enumFromInt(ip.extra.items[extra_index]);
2171 extra_index += 1;2249 extra_index += 1;
...@@ -2211,42 +2289,64 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2211,42 +2289,64 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2211 .zir_index = extra.data.zir_index,2289 .zir_index = extra.data.zir_index,
2212 .layout = if (extra.data.flags.is_extern) .Extern else .Auto,2290 .layout = if (extra.data.flags.is_extern) .Extern else .Auto,
2213 .field_names = names,2291 .field_names = names,
2214 .field_types = .{ .start = extra.end, .len = fields_len },2292 .field_types = field_types,
2215 .field_inits = inits,2293 .field_inits = inits,
2216 .field_aligns = aligns,2294 .field_aligns = aligns,
2217 .runtime_order = runtime_order,2295 .runtime_order = runtime_order,
2218 .comptime_bits = comptime_bits,2296 .comptime_bits = comptime_bits,
2219 .offsets = offsets,2297 .offsets = offsets,
2220 .names_map = names_map,2298 .names_map = names_map,
2299 .captures = captures,
2221 };2300 };
2222 },2301 },
2223 .type_struct_packed, .type_struct_packed_inits => {2302 .type_struct_packed, .type_struct_packed_inits => {
2224 const extra = ip.extraDataTrail(Tag.TypeStructPacked, item.data);2303 const extra = ip.extraDataTrail(Tag.TypeStructPacked, item.data);
2225 const has_inits = item.tag == .type_struct_packed_inits;2304 const has_inits = item.tag == .type_struct_packed_inits;
2226 const fields_len = extra.data.fields_len;2305 const fields_len = extra.data.fields_len;
2306 var extra_index = extra.end;
2307 const captures_len = if (extra.data.flags.any_captures) c: {
2308 const len = ip.extra.items[extra_index];
2309 extra_index += 1;
2310 break :c len;
2311 } else 0;
2312 const captures: CaptureValue.Slice = .{
2313 .start = extra_index,
2314 .len = captures_len,
2315 };
2316 extra_index += captures_len;
2317 const field_types: Index.Slice = .{
2318 .start = extra_index,
2319 .len = fields_len,
2320 };
2321 extra_index += fields_len;
2322 const field_names: NullTerminatedString.Slice = .{
2323 .start = extra_index,
2324 .len = fields_len,
2325 };
2326 extra_index += fields_len;
2327 const field_inits: Index.Slice = if (has_inits) inits: {
2328 const i: Index.Slice = .{
2329 .start = extra_index,
2330 .len = fields_len,
2331 };
2332 extra_index += fields_len;
2333 break :inits i;
2334 } else .{ .start = 0, .len = 0 };
2227 return .{2335 return .{
2228 .extra_index = item.data,2336 .extra_index = item.data,
2229 .decl = extra.data.decl.toOptional(),2337 .decl = extra.data.decl.toOptional(),
2230 .namespace = extra.data.namespace,2338 .namespace = extra.data.namespace,
2231 .zir_index = extra.data.zir_index,2339 .zir_index = extra.data.zir_index,
2232 .layout = .Packed,2340 .layout = .Packed,
2233 .field_names = .{2341 .field_names = field_names,
2234 .start = extra.end + fields_len,2342 .field_types = field_types,
2235 .len = fields_len,2343 .field_inits = field_inits,
2236 },
2237 .field_types = .{
2238 .start = extra.end,
2239 .len = fields_len,
2240 },
2241 .field_inits = if (has_inits) .{
2242 .start = extra.end + 2 * fields_len,
2243 .len = fields_len,
2244 } else .{ .start = 0, .len = 0 },
2245 .field_aligns = .{ .start = 0, .len = 0 },2344 .field_aligns = .{ .start = 0, .len = 0 },
2246 .runtime_order = .{ .start = 0, .len = 0 },2345 .runtime_order = .{ .start = 0, .len = 0 },
2247 .comptime_bits = .{ .start = 0, .len = 0 },2346 .comptime_bits = .{ .start = 0, .len = 0 },
2248 .offsets = .{ .start = 0, .len = 0 },2347 .offsets = .{ .start = 0, .len = 0 },
2249 .names_map = extra.data.names_map.toOptional(),2348 .names_map = extra.data.names_map.toOptional(),
2349 .captures = captures,
2250 };2350 };
2251 },2351 },
2252 else => unreachable,2352 else => unreachable,
...@@ -2273,6 +2373,7 @@ const LoadedEnumType = struct {...@@ -2273,6 +2373,7 @@ const LoadedEnumType = struct {
2273 /// This is guaranteed to not be `.none` if explicit values are provided.2373 /// This is guaranteed to not be `.none` if explicit values are provided.
2274 values_map: OptionalMapIndex,2374 values_map: OptionalMapIndex,
2275 zir_index: TrackedInst.Index.Optional,2375 zir_index: TrackedInst.Index.Optional,
2376 captures: CaptureValue.Slice,
22762377
2277 pub const TagMode = enum {2378 pub const TagMode = enum {
2278 /// The integer tag type was auto-numbered by zig.2379 /// The integer tag type was auto-numbered by zig.
...@@ -2332,7 +2433,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2332,7 +2433,7 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2332 .namespace = extra.data.namespace,2433 .namespace = extra.data.namespace,
2333 .tag_ty = extra.data.int_tag_type,2434 .tag_ty = extra.data.int_tag_type,
2334 .names = .{2435 .names = .{
2335 .start = @intCast(extra.end),2436 .start = @intCast(extra.end + extra.data.captures_len),
2336 .len = extra.data.fields_len,2437 .len = extra.data.fields_len,
2337 },2438 },
2338 .values = .{ .start = 0, .len = 0 },2439 .values = .{ .start = 0, .len = 0 },
...@@ -2340,6 +2441,10 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2340,6 +2441,10 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2340 .names_map = extra.data.names_map,2441 .names_map = extra.data.names_map,
2341 .values_map = .none,2442 .values_map = .none,
2342 .zir_index = extra.data.zir_index,2443 .zir_index = extra.data.zir_index,
2444 .captures = .{
2445 .start = @intCast(extra.end),
2446 .len = extra.data.captures_len,
2447 },
2343 };2448 };
2344 },2449 },
2345 .type_enum_explicit, .type_enum_nonexhaustive => {2450 .type_enum_explicit, .type_enum_nonexhaustive => {
...@@ -2349,11 +2454,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2349,11 +2454,11 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2349 .namespace = extra.data.namespace,2454 .namespace = extra.data.namespace,
2350 .tag_ty = extra.data.int_tag_type,2455 .tag_ty = extra.data.int_tag_type,
2351 .names = .{2456 .names = .{
2352 .start = @intCast(extra.end),2457 .start = @intCast(extra.end + extra.data.captures_len),
2353 .len = extra.data.fields_len,2458 .len = extra.data.fields_len,
2354 },2459 },
2355 .values = .{2460 .values = .{
2356 .start = @intCast(extra.end + extra.data.fields_len),2461 .start = @intCast(extra.end + extra.data.captures_len + extra.data.fields_len),
2357 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,2462 .len = if (extra.data.values_map != .none) extra.data.fields_len else 0,
2358 },2463 },
2359 .tag_mode = switch (item.tag) {2464 .tag_mode = switch (item.tag) {
...@@ -2364,6 +2469,10 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {...@@ -2364,6 +2469,10 @@ pub fn loadEnumType(ip: *const InternPool, index: Index) LoadedEnumType {
2364 .names_map = extra.data.names_map,2469 .names_map = extra.data.names_map,
2365 .values_map = extra.data.values_map,2470 .values_map = extra.data.values_map,
2366 .zir_index = extra.data.zir_index,2471 .zir_index = extra.data.zir_index,
2472 .captures = .{
2473 .start = @intCast(extra.end),
2474 .len = extra.data.captures_len,
2475 },
2367 };2476 };
2368 },2477 },
2369 else => unreachable,2478 else => unreachable,
...@@ -2378,12 +2487,22 @@ pub const LoadedOpaqueType = struct {...@@ -2378,12 +2487,22 @@ pub const LoadedOpaqueType = struct {
2378 namespace: NamespaceIndex,2487 namespace: NamespaceIndex,
2379 /// The index of the `opaque_decl` instruction.2488 /// The index of the `opaque_decl` instruction.
2380 zir_index: TrackedInst.Index.Optional,2489 zir_index: TrackedInst.Index.Optional,
2490 captures: CaptureValue.Slice,
2381};2491};
23822492
2383pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {2493pub fn loadOpaqueType(ip: *const InternPool, index: Index) LoadedOpaqueType {
2384 assert(ip.items.items(.tag)[@intFromEnum(index)] == .type_opaque);2494 assert(ip.items.items(.tag)[@intFromEnum(index)] == .type_opaque);
2385 const extra_index = ip.items.items(.data)[@intFromEnum(index)];2495 const extra_index = ip.items.items(.data)[@intFromEnum(index)];
2386 return ip.extraData(LoadedOpaqueType, extra_index);2496 const extra = ip.extraDataTrail(Tag.TypeOpaque, extra_index);
2497 return .{
2498 .decl = extra.data.decl,
2499 .namespace = extra.data.namespace,
2500 .zir_index = extra.data.zir_index,
2501 .captures = .{
2502 .start = extra.end,
2503 .len = extra.data.captures_len,
2504 },
2505 };
2387}2506}
23882507
2389pub const Item = struct {2508pub const Item = struct {
...@@ -2601,7 +2720,7 @@ pub const Index = enum(u32) {...@@ -2601,7 +2720,7 @@ pub const Index = enum(u32) {
2601 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,2720 type_enum_explicit: DataIsExtraIndexOfEnumExplicit,
2602 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,2721 type_enum_nonexhaustive: DataIsExtraIndexOfEnumExplicit,
2603 simple_type: struct { data: SimpleType },2722 simple_type: struct { data: SimpleType },
2604 type_opaque: struct { data: *Key.OpaqueType },2723 type_opaque: struct { data: *Tag.TypeOpaque },
2605 type_struct: struct { data: *Tag.TypeStruct },2724 type_struct: struct { data: *Tag.TypeStruct },
2606 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,2725 type_struct_anon: DataIsExtraIndexOfTypeStructAnon,
2607 type_struct_packed: struct { data: *Tag.TypeStructPacked },2726 type_struct_packed: struct { data: *Tag.TypeStructPacked },
...@@ -3036,7 +3155,7 @@ pub const Tag = enum(u8) {...@@ -3036,7 +3155,7 @@ pub const Tag = enum(u8) {
3036 /// data is SimpleType enum value.3155 /// data is SimpleType enum value.
3037 simple_type,3156 simple_type,
3038 /// An opaque type.3157 /// An opaque type.
3039 /// data is index of Key.OpaqueType in extra.3158 /// data is index of Tag.TypeOpaque in extra.
3040 type_opaque,3159 type_opaque,
3041 /// A non-packed struct type.3160 /// A non-packed struct type.
3042 /// data is 0 or extra index of `TypeStruct`.3161 /// data is 0 or extra index of `TypeStruct`.
...@@ -3239,7 +3358,6 @@ pub const Tag = enum(u8) {...@@ -3239,7 +3358,6 @@ pub const Tag = enum(u8) {
3239 memoized_call,3358 memoized_call,
32403359
3241 const ErrorUnionType = Key.ErrorUnionType;3360 const ErrorUnionType = Key.ErrorUnionType;
3242 const OpaqueType = LoadedOpaqueType;
3243 const TypeValue = Key.TypeValue;3361 const TypeValue = Key.TypeValue;
3244 const Error = Key.Error;3362 const Error = Key.Error;
3245 const EnumTag = Key.EnumTag;3363 const EnumTag = Key.EnumTag;
...@@ -3266,7 +3384,7 @@ pub const Tag = enum(u8) {...@@ -3266,7 +3384,7 @@ pub const Tag = enum(u8) {
3266 .type_enum_explicit => EnumExplicit,3384 .type_enum_explicit => EnumExplicit,
3267 .type_enum_nonexhaustive => EnumExplicit,3385 .type_enum_nonexhaustive => EnumExplicit,
3268 .simple_type => unreachable,3386 .simple_type => unreachable,
3269 .type_opaque => OpaqueType,3387 .type_opaque => TypeOpaque,
3270 .type_struct => TypeStruct,3388 .type_struct => TypeStruct,
3271 .type_struct_anon => TypeStructAnon,3389 .type_struct_anon => TypeStructAnon,
3272 .type_struct_packed, .type_struct_packed_inits => TypeStructPacked,3390 .type_struct_packed, .type_struct_packed_inits => TypeStructPacked,
...@@ -3424,8 +3542,10 @@ pub const Tag = enum(u8) {...@@ -3424,8 +3542,10 @@ pub const Tag = enum(u8) {
3424 };3542 };
34253543
3426 /// Trailing:3544 /// Trailing:
3427 /// 0. field type: Index for each field; declaration order3545 /// 0. captures_len: u32 // if `any_captures`
3428 /// 1. field align: Alignment for each field; declaration order3546 /// 1. capture: CaptureValue // for each `captures_len`
3547 /// 2. field type: Index for each field; declaration order
3548 /// 3. field align: Alignment for each field; declaration order
3429 pub const TypeUnion = struct {3549 pub const TypeUnion = struct {
3430 flags: Flags,3550 flags: Flags,
3431 /// This could be provided through the tag type, but it is more convenient3551 /// This could be provided through the tag type, but it is more convenient
...@@ -3443,6 +3563,7 @@ pub const Tag = enum(u8) {...@@ -3443,6 +3563,7 @@ pub const Tag = enum(u8) {
3443 zir_index: TrackedInst.Index.Optional,3563 zir_index: TrackedInst.Index.Optional,
34443564
3445 pub const Flags = packed struct(u32) {3565 pub const Flags = packed struct(u32) {
3566 any_captures: bool,
3446 runtime_tag: LoadedUnionType.RuntimeTag,3567 runtime_tag: LoadedUnionType.RuntimeTag,
3447 /// If false, the field alignment trailing data is omitted.3568 /// If false, the field alignment trailing data is omitted.
3448 any_aligned_fields: bool,3569 any_aligned_fields: bool,
...@@ -3452,14 +3573,16 @@ pub const Tag = enum(u8) {...@@ -3452,14 +3573,16 @@ pub const Tag = enum(u8) {
3452 assumed_runtime_bits: bool,3573 assumed_runtime_bits: bool,
3453 assumed_pointer_aligned: bool,3574 assumed_pointer_aligned: bool,
3454 alignment: Alignment,3575 alignment: Alignment,
3455 _: u14 = 0,3576 _: u13 = 0,
3456 };3577 };
3457 };3578 };
34583579
3459 /// Trailing:3580 /// Trailing:
3460 /// 0. type: Index for each fields_len3581 /// 0. captures_len: u32 // if `any_captures`
3461 /// 1. name: NullTerminatedString for each fields_len3582 /// 1. capture: CaptureValue // for each `captures_len`
3462 /// 2. init: Index for each fields_len // if tag is type_struct_packed_inits3583 /// 2. type: Index for each fields_len
3584 /// 3. name: NullTerminatedString for each fields_len
3585 /// 4. init: Index for each fields_len // if tag is type_struct_packed_inits
3463 pub const TypeStructPacked = struct {3586 pub const TypeStructPacked = struct {
3464 decl: DeclIndex,3587 decl: DeclIndex,
3465 zir_index: TrackedInst.Index.Optional,3588 zir_index: TrackedInst.Index.Optional,
...@@ -3470,10 +3593,11 @@ pub const Tag = enum(u8) {...@@ -3470,10 +3593,11 @@ pub const Tag = enum(u8) {
3470 flags: Flags,3593 flags: Flags,
34713594
3472 pub const Flags = packed struct(u32) {3595 pub const Flags = packed struct(u32) {
3596 any_captures: bool,
3473 /// Dependency loop detection when resolving field inits.3597 /// Dependency loop detection when resolving field inits.
3474 field_inits_wip: bool,3598 field_inits_wip: bool,
3475 inits_resolved: bool,3599 inits_resolved: bool,
3476 _: u30 = 0,3600 _: u29 = 0,
3477 };3601 };
3478 };3602 };
34793603
...@@ -3492,21 +3616,23 @@ pub const Tag = enum(u8) {...@@ -3492,21 +3616,23 @@ pub const Tag = enum(u8) {
3492 /// than coming up with some other scheme for the data.3616 /// than coming up with some other scheme for the data.
3493 ///3617 ///
3494 /// Trailing:3618 /// Trailing:
3495 /// 0. type: Index for each field in declared order3619 /// 0. captures_len: u32 // if `any_captures`
3496 /// 1. if not is_tuple:3620 /// 1. capture: CaptureValue // for each `captures_len`
3621 /// 2. type: Index for each field in declared order
3622 /// 3. if not is_tuple:
3497 /// names_map: MapIndex,3623 /// names_map: MapIndex,
3498 /// name: NullTerminatedString // for each field in declared order3624 /// name: NullTerminatedString // for each field in declared order
3499 /// 2. if any_default_inits:3625 /// 4. if any_default_inits:
3500 /// init: Index // for each field in declared order3626 /// init: Index // for each field in declared order
3501 /// 3. if has_namespace:3627 /// 5. if has_namespace:
3502 /// namespace: NamespaceIndex3628 /// namespace: NamespaceIndex
3503 /// 4. if any_aligned_fields:3629 /// 6. if any_aligned_fields:
3504 /// align: Alignment // for each field in declared order3630 /// align: Alignment // for each field in declared order
3505 /// 5. if any_comptime_fields:3631 /// 7. if any_comptime_fields:
3506 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 03632 /// field_is_comptime_bits: u32 // minimal number of u32s needed, LSB is field 0
3507 /// 6. if not is_extern:3633 /// 8. if not is_extern:
3508 /// field_index: RuntimeOrder // for each field in runtime order3634 /// field_index: RuntimeOrder // for each field in runtime order
3509 /// 7. field_offset: u32 // for each field in declared order, undef until layout_resolved3635 /// 9. field_offset: u32 // for each field in declared order, undef until layout_resolved
3510 pub const TypeStruct = struct {3636 pub const TypeStruct = struct {
3511 decl: DeclIndex,3637 decl: DeclIndex,
3512 zir_index: TrackedInst.Index.Optional,3638 zir_index: TrackedInst.Index.Optional,
...@@ -3515,6 +3641,7 @@ pub const Tag = enum(u8) {...@@ -3515,6 +3641,7 @@ pub const Tag = enum(u8) {
3515 size: u32,3641 size: u32,
35163642
3517 pub const Flags = packed struct(u32) {3643 pub const Flags = packed struct(u32) {
3644 any_captures: bool,
3518 is_extern: bool,3645 is_extern: bool,
3519 known_non_opv: bool,3646 known_non_opv: bool,
3520 requires_comptime: RequiresComptime,3647 requires_comptime: RequiresComptime,
...@@ -3544,9 +3671,21 @@ pub const Tag = enum(u8) {...@@ -3544,9 +3671,21 @@ pub const Tag = enum(u8) {
3544 // which `layout_resolved` does not ensure.3671 // which `layout_resolved` does not ensure.
3545 fully_resolved: bool,3672 fully_resolved: bool,
35463673
3547 _: u8 = 0,3674 _: u7 = 0,
3548 };3675 };
3549 };3676 };
3677
3678 /// Trailing:
3679 /// 0. capture: CaptureValue // for each `captures_len`
3680 pub const TypeOpaque = struct {
3681 /// The opaque's owner Decl.
3682 decl: DeclIndex,
3683 /// Contains the declarations inside this opaque.
3684 namespace: NamespaceIndex,
3685 /// The index of the `opaque_decl` instruction.
3686 zir_index: TrackedInst.Index.Optional,
3687 captures_len: u32,
3688 };
3550};3689};
35513690
3552/// State that is mutable during semantic analysis. This data is not used for3691/// State that is mutable during semantic analysis. This data is not used for
...@@ -3853,11 +3992,13 @@ pub const Array = struct {...@@ -3853,11 +3992,13 @@ pub const Array = struct {
3853};3992};
38543993
3855/// Trailing:3994/// Trailing:
3856/// 0. field name: NullTerminatedString for each fields_len; declaration order3995/// 0. capture: CaptureValue // for each `captures_len`
3857/// 1. tag value: Index for each fields_len; declaration order3996/// 1. field name: NullTerminatedString for each fields_len; declaration order
3997/// 2. tag value: Index for each fields_len; declaration order
3858pub const EnumExplicit = struct {3998pub const EnumExplicit = struct {
3859 /// The Decl that corresponds to the enum itself.3999 /// The Decl that corresponds to the enum itself.
3860 decl: DeclIndex,4000 decl: DeclIndex,
4001 captures_len: u32,
3861 /// This may be `none` if there are no declarations.4002 /// This may be `none` if there are no declarations.
3862 namespace: OptionalNamespaceIndex,4003 namespace: OptionalNamespaceIndex,
3863 /// An integer type which is used for the numerical value of the enum, which4004 /// An integer type which is used for the numerical value of the enum, which
...@@ -3874,10 +4015,12 @@ pub const EnumExplicit = struct {...@@ -3874,10 +4015,12 @@ pub const EnumExplicit = struct {
3874};4015};
38754016
3876/// Trailing:4017/// Trailing:
3877/// 0. field name: NullTerminatedString for each fields_len; declaration order4018/// 0. capture: CaptureValue // for each `captures_len`
4019/// 1. field name: NullTerminatedString for each fields_len; declaration order
3878pub const EnumAuto = struct {4020pub const EnumAuto = struct {
3879 /// The Decl that corresponds to the enum itself.4021 /// The Decl that corresponds to the enum itself.
3880 decl: DeclIndex,4022 decl: DeclIndex,
4023 captures_len: u32,
3881 /// This may be `none` if there are no declarations.4024 /// This may be `none` if there are no declarations.
3882 namespace: OptionalNamespaceIndex,4025 namespace: OptionalNamespaceIndex,
3883 /// An integer type which is used for the numerical value of the enum, which4026 /// An integer type which is used for the numerical value of the enum, which
...@@ -4187,7 +4330,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -4187,7 +4330,9 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
4187 .inferred_error_set_type = @enumFromInt(data),4330 .inferred_error_set_type = @enumFromInt(data),
4188 },4331 },
41894332
4190 .type_opaque => .{ .opaque_type = ip.extraData(Key.OpaqueType, data) },4333 .type_opaque => .{ .opaque_type = .{
4334 .decl = ip.extraData(Tag.TypeOpaque, data).decl,
4335 } },
41914336
4192 .type_struct => .{ .struct_type = if (data == 0) .{4337 .type_struct => .{ .struct_type = if (data == 0) .{
4193 .decl = .none,4338 .decl = .none,
...@@ -5497,7 +5642,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -5497,7 +5642,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
5497}5642}
54985643
5499pub const UnionTypeInit = struct {5644pub const UnionTypeInit = struct {
5500 flags: Tag.TypeUnion.Flags,5645 flags: packed struct {
5646 runtime_tag: LoadedUnionType.RuntimeTag,
5647 any_aligned_fields: bool,
5648 layout: std.builtin.Type.ContainerLayout,
5649 status: LoadedUnionType.Status,
5650 requires_comptime: RequiresComptime,
5651 assumed_runtime_bits: bool,
5652 assumed_pointer_aligned: bool,
5653 alignment: Alignment,
5654 },
5501 decl: DeclIndex,5655 decl: DeclIndex,
5502 namespace: NamespaceIndex,5656 namespace: NamespaceIndex,
5503 zir_index: TrackedInst.Index.Optional,5657 zir_index: TrackedInst.Index.Optional,
...@@ -5509,6 +5663,7 @@ pub const UnionTypeInit = struct {...@@ -5509,6 +5663,7 @@ pub const UnionTypeInit = struct {
5509 /// The logic for `any_aligned_fields` is asserted to have been done before5663 /// The logic for `any_aligned_fields` is asserted to have been done before
5510 /// calling this function.5664 /// calling this function.
5511 field_aligns: []const Alignment,5665 field_aligns: []const Alignment,
5666 captures: []const CaptureValue,
5512};5667};
55135668
5514pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocator.Error!Index {5669pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocator.Error!Index {
...@@ -5516,12 +5671,24 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -5516,12 +5671,24 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
5516 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;5671 const align_elements_len = if (ini.flags.any_aligned_fields) (ini.fields_len + 3) / 4 else 0;
5517 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);5672 const align_element: u32 = @bitCast([1]u8{@intFromEnum(Alignment.none)} ** 4);
5518 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +5673 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeUnion).Struct.fields.len +
5674 @intFromBool(ini.captures.len != 0) + // captures_len
5675 ini.captures.len + // captures
5519 ini.fields_len + // field types5676 ini.fields_len + // field types
5520 align_elements_len);5677 align_elements_len);
5521 try ip.items.ensureUnusedCapacity(gpa, 1);5678 try ip.items.ensureUnusedCapacity(gpa, 1);
55225679
5523 const union_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{5680 const union_type_extra_index = ip.addExtraAssumeCapacity(Tag.TypeUnion{
5524 .flags = ini.flags,5681 .flags = .{
5682 .any_captures = ini.captures.len != 0,
5683 .runtime_tag = ini.flags.runtime_tag,
5684 .any_aligned_fields = ini.flags.any_aligned_fields,
5685 .layout = ini.flags.layout,
5686 .status = ini.flags.status,
5687 .requires_comptime = ini.flags.requires_comptime,
5688 .assumed_runtime_bits = ini.flags.assumed_runtime_bits,
5689 .assumed_pointer_aligned = ini.flags.assumed_pointer_aligned,
5690 .alignment = ini.flags.alignment,
5691 },
5525 .fields_len = ini.fields_len,5692 .fields_len = ini.fields_len,
5526 .size = std.math.maxInt(u32),5693 .size = std.math.maxInt(u32),
5527 .padding = std.math.maxInt(u32),5694 .padding = std.math.maxInt(u32),
...@@ -5531,6 +5698,11 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat...@@ -5531,6 +5698,11 @@ pub fn getUnionType(ip: *InternPool, gpa: Allocator, ini: UnionTypeInit) Allocat
5531 .zir_index = ini.zir_index,5698 .zir_index = ini.zir_index,
5532 });5699 });
55335700
5701 if (ini.captures.len != 0) {
5702 ip.extra.appendAssumeCapacity(@intCast(ini.captures.len));
5703 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
5704 }
5705
5534 // field types5706 // field types
5535 if (ini.field_types.len > 0) {5707 if (ini.field_types.len > 0) {
5536 assert(ini.field_types.len == ini.fields_len);5708 assert(ini.field_types.len == ini.fields_len);
...@@ -5582,6 +5754,7 @@ pub const StructTypeInit = struct {...@@ -5582,6 +5754,7 @@ pub const StructTypeInit = struct {
5582 any_default_inits: bool,5754 any_default_inits: bool,
5583 inits_resolved: bool,5755 inits_resolved: bool,
5584 any_aligned_fields: bool,5756 any_aligned_fields: bool,
5757 captures: []const CaptureValue,
5585};5758};
55865759
5587pub fn getStructType(5760pub fn getStructType(
...@@ -5605,6 +5778,8 @@ pub fn getStructType(...@@ -5605,6 +5778,8 @@ pub fn getStructType(
5605 .Extern => true,5778 .Extern => true,
5606 .Packed => {5779 .Packed => {
5607 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len +5780 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStructPacked).Struct.fields.len +
5781 @intFromBool(ini.captures.len != 0) + // captures_len
5782 ini.captures.len + // captures
5608 ini.fields_len + // types5783 ini.fields_len + // types
5609 ini.fields_len + // names5784 ini.fields_len + // names
5610 ini.fields_len); // inits5785 ini.fields_len); // inits
...@@ -5618,11 +5793,16 @@ pub fn getStructType(...@@ -5618,11 +5793,16 @@ pub fn getStructType(
5618 .backing_int_ty = .none,5793 .backing_int_ty = .none,
5619 .names_map = names_map,5794 .names_map = names_map,
5620 .flags = .{5795 .flags = .{
5796 .any_captures = ini.captures.len != 0,
5621 .field_inits_wip = false,5797 .field_inits_wip = false,
5622 .inits_resolved = ini.inits_resolved,5798 .inits_resolved = ini.inits_resolved,
5623 },5799 },
5624 }),5800 }),
5625 });5801 });
5802 if (ini.captures.len != 0) {
5803 ip.extra.appendAssumeCapacity(@intCast(ini.captures.len));
5804 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
5805 }
5626 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);5806 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
5627 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);5807 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(OptionalNullTerminatedString.none), ini.fields_len);
5628 if (ini.any_default_inits) {5808 if (ini.any_default_inits) {
...@@ -5637,6 +5817,8 @@ pub fn getStructType(...@@ -5637,6 +5817,8 @@ pub fn getStructType(
5637 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;5817 const comptime_elements_len = if (ini.any_comptime_fields) (ini.fields_len + 31) / 32 else 0;
56385818
5639 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStruct).Struct.fields.len +5819 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.TypeStruct).Struct.fields.len +
5820 @intFromBool(ini.captures.len != 0) + // captures_len
5821 ini.captures.len + // captures
5640 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets5822 (ini.fields_len * 5) + // types, names, inits, runtime order, offsets
5641 align_elements_len + comptime_elements_len +5823 align_elements_len + comptime_elements_len +
5642 2); // names_map + namespace5824 2); // names_map + namespace
...@@ -5648,6 +5830,7 @@ pub fn getStructType(...@@ -5648,6 +5830,7 @@ pub fn getStructType(
5648 .fields_len = ini.fields_len,5830 .fields_len = ini.fields_len,
5649 .size = std.math.maxInt(u32),5831 .size = std.math.maxInt(u32),
5650 .flags = .{5832 .flags = .{
5833 .any_captures = ini.captures.len != 0,
5651 .is_extern = is_extern,5834 .is_extern = is_extern,
5652 .known_non_opv = ini.known_non_opv,5835 .known_non_opv = ini.known_non_opv,
5653 .requires_comptime = ini.requires_comptime,5836 .requires_comptime = ini.requires_comptime,
...@@ -5669,6 +5852,10 @@ pub fn getStructType(...@@ -5669,6 +5852,10 @@ pub fn getStructType(
5669 },5852 },
5670 }),5853 }),
5671 });5854 });
5855 if (ini.captures.len != 0) {
5856 ip.extra.appendAssumeCapacity(@intCast(ini.captures.len));
5857 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
5858 }
5672 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);5859 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), ini.fields_len);
5673 if (!ini.is_tuple) {5860 if (!ini.is_tuple) {
5674 ip.extra.appendAssumeCapacity(@intFromEnum(names_map));5861 ip.extra.appendAssumeCapacity(@intFromEnum(names_map));
...@@ -6405,11 +6592,12 @@ fn getIncompleteEnumAuto(...@@ -6405,11 +6592,12 @@ fn getIncompleteEnumAuto(
6405 const names_map = try ip.addMap(gpa, enum_type.fields_len);6592 const names_map = try ip.addMap(gpa, enum_type.fields_len);
64066593
6407 const extra_fields_len: u32 = @typeInfo(EnumAuto).Struct.fields.len;6594 const extra_fields_len: u32 = @typeInfo(EnumAuto).Struct.fields.len;
6408 try ip.extra.ensureUnusedCapacity(gpa, extra_fields_len + enum_type.fields_len);6595 try ip.extra.ensureUnusedCapacity(gpa, extra_fields_len + enum_type.captures.len + enum_type.fields_len);
6409 try ip.items.ensureUnusedCapacity(gpa, 1);6596 try ip.items.ensureUnusedCapacity(gpa, 1);
64106597
6411 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{6598 const extra_index = ip.addExtraAssumeCapacity(EnumAuto{
6412 .decl = enum_type.decl,6599 .decl = enum_type.decl,
6600 .captures_len = @intCast(enum_type.captures.len),
6413 .namespace = enum_type.namespace,6601 .namespace = enum_type.namespace,
6414 .int_tag_type = int_tag_type,6602 .int_tag_type = int_tag_type,
6415 .names_map = names_map,6603 .names_map = names_map,
...@@ -6421,6 +6609,7 @@ fn getIncompleteEnumAuto(...@@ -6421,6 +6609,7 @@ fn getIncompleteEnumAuto(
6421 .tag = .type_enum_auto,6609 .tag = .type_enum_auto,
6422 .data = extra_index,6610 .data = extra_index,
6423 });6611 });
6612 ip.extra.appendSliceAssumeCapacity(@ptrCast(enum_type.captures));
6424 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), enum_type.fields_len);6613 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), enum_type.fields_len);
6425 return .{6614 return .{
6426 .index = @enumFromInt(ip.items.len - 1),6615 .index = @enumFromInt(ip.items.len - 1),
...@@ -6455,11 +6644,12 @@ fn getIncompleteEnumExplicit(...@@ -6455,11 +6644,12 @@ fn getIncompleteEnumExplicit(
6455 if (enum_type.has_values) enum_type.fields_len else 0;6644 if (enum_type.has_values) enum_type.fields_len else 0;
64566645
6457 const extra_fields_len: u32 = @typeInfo(EnumExplicit).Struct.fields.len;6646 const extra_fields_len: u32 = @typeInfo(EnumExplicit).Struct.fields.len;
6458 try ip.extra.ensureUnusedCapacity(gpa, extra_fields_len + reserved_len);6647 try ip.extra.ensureUnusedCapacity(gpa, extra_fields_len + enum_type.captures.len + reserved_len);
6459 try ip.items.ensureUnusedCapacity(gpa, 1);6648 try ip.items.ensureUnusedCapacity(gpa, 1);
64606649
6461 const extra_index = ip.addExtraAssumeCapacity(EnumExplicit{6650 const extra_index = ip.addExtraAssumeCapacity(EnumExplicit{
6462 .decl = enum_type.decl,6651 .decl = enum_type.decl,
6652 .captures_len = @intCast(enum_type.captures.len),
6463 .namespace = enum_type.namespace,6653 .namespace = enum_type.namespace,
6464 .int_tag_type = enum_type.tag_ty,6654 .int_tag_type = enum_type.tag_ty,
6465 .fields_len = enum_type.fields_len,6655 .fields_len = enum_type.fields_len,
...@@ -6472,6 +6662,7 @@ fn getIncompleteEnumExplicit(...@@ -6472,6 +6662,7 @@ fn getIncompleteEnumExplicit(
6472 .tag = tag,6662 .tag = tag,
6473 .data = extra_index,6663 .data = extra_index,
6474 });6664 });
6665 ip.extra.appendSliceAssumeCapacity(@ptrCast(enum_type.captures));
6475 // This is both fields and values (if present).6666 // This is both fields and values (if present).
6476 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), reserved_len);6667 ip.extra.appendNTimesAssumeCapacity(@intFromEnum(Index.none), reserved_len);
6477 return .{6668 return .{
...@@ -6492,6 +6683,7 @@ pub const GetEnumInit = struct {...@@ -6492,6 +6683,7 @@ pub const GetEnumInit = struct {
6492 values: []const Index,6683 values: []const Index,
6493 tag_mode: LoadedEnumType.TagMode,6684 tag_mode: LoadedEnumType.TagMode,
6494 zir_index: TrackedInst.Index.Optional,6685 zir_index: TrackedInst.Index.Optional,
6686 captures: []const CaptureValue,
6495};6687};
64966688
6497pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Error!Index {6689pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Error!Index {
...@@ -6513,11 +6705,12 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro...@@ -6513,11 +6705,12 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro
65136705
6514 const fields_len: u32 = @intCast(ini.names.len);6706 const fields_len: u32 = @intCast(ini.names.len);
6515 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +6707 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumAuto).Struct.fields.len +
6516 fields_len);6708 ini.captures.len + fields_len);
6517 ip.items.appendAssumeCapacity(.{6709 ip.items.appendAssumeCapacity(.{
6518 .tag = .type_enum_auto,6710 .tag = .type_enum_auto,
6519 .data = ip.addExtraAssumeCapacity(EnumAuto{6711 .data = ip.addExtraAssumeCapacity(EnumAuto{
6520 .decl = ini.decl,6712 .decl = ini.decl,
6713 .captures_len = @intCast(ini.captures.len),
6521 .namespace = ini.namespace,6714 .namespace = ini.namespace,
6522 .int_tag_type = ini.tag_ty,6715 .int_tag_type = ini.tag_ty,
6523 .names_map = names_map,6716 .names_map = names_map,
...@@ -6525,6 +6718,7 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro...@@ -6525,6 +6718,7 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro
6525 .zir_index = ini.zir_index,6718 .zir_index = ini.zir_index,
6526 }),6719 }),
6527 });6720 });
6721 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
6528 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));6722 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
6529 return @enumFromInt(ip.items.len - 1);6723 return @enumFromInt(ip.items.len - 1);
6530 },6724 },
...@@ -6533,7 +6727,7 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro...@@ -6533,7 +6727,7 @@ pub fn getEnum(ip: *InternPool, gpa: Allocator, ini: GetEnumInit) Allocator.Erro
6533 }6727 }
6534}6728}
65356729
6536pub fn finishGetEnum(6730fn finishGetEnum(
6537 ip: *InternPool,6731 ip: *InternPool,
6538 gpa: Allocator,6732 gpa: Allocator,
6539 ini: GetEnumInit,6733 ini: GetEnumInit,
...@@ -6549,11 +6743,12 @@ pub fn finishGetEnum(...@@ -6549,11 +6743,12 @@ pub fn finishGetEnum(
6549 };6743 };
6550 const fields_len: u32 = @intCast(ini.names.len);6744 const fields_len: u32 = @intCast(ini.names.len);
6551 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +6745 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(EnumExplicit).Struct.fields.len +
6552 fields_len);6746 ini.captures.len + fields_len);
6553 ip.items.appendAssumeCapacity(.{6747 ip.items.appendAssumeCapacity(.{
6554 .tag = tag,6748 .tag = tag,
6555 .data = ip.addExtraAssumeCapacity(EnumExplicit{6749 .data = ip.addExtraAssumeCapacity(EnumExplicit{
6556 .decl = ini.decl,6750 .decl = ini.decl,
6751 .captures_len = @intCast(ini.captures.len),
6557 .namespace = ini.namespace,6752 .namespace = ini.namespace,
6558 .int_tag_type = ini.tag_ty,6753 .int_tag_type = ini.tag_ty,
6559 .fields_len = fields_len,6754 .fields_len = fields_len,
...@@ -6562,23 +6757,37 @@ pub fn finishGetEnum(...@@ -6562,23 +6757,37 @@ pub fn finishGetEnum(
6562 .zir_index = ini.zir_index,6757 .zir_index = ini.zir_index,
6563 }),6758 }),
6564 });6759 });
6760 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
6565 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));6761 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.names));
6566 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));6762 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.values));
6567 return @enumFromInt(ip.items.len - 1);6763 return @enumFromInt(ip.items.len - 1);
6568}6764}
65696765
6570pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, key: LoadedOpaqueType) Allocator.Error!Index {6766pub const OpaqueTypeIni = struct {
6767 decl: DeclIndex,
6768 namespace: NamespaceIndex,
6769 zir_index: TrackedInst.Index.Optional,
6770 captures: []const CaptureValue,
6771};
6772
6773pub fn getOpaqueType(ip: *InternPool, gpa: Allocator, ini: OpaqueTypeIni) Allocator.Error!Index {
6571 const adapter: KeyAdapter = .{ .intern_pool = ip };6774 const adapter: KeyAdapter = .{ .intern_pool = ip };
6572 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(LoadedOpaqueType).Struct.fields.len);6775 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(LoadedOpaqueType).Struct.fields.len + ini.captures.len);
6573 try ip.items.ensureUnusedCapacity(gpa, 1);6776 try ip.items.ensureUnusedCapacity(gpa, 1);
6574 const gop = try ip.map.getOrPutAdapted(gpa, Key{6777 const gop = try ip.map.getOrPutAdapted(gpa, Key{
6575 .opaque_type = .{ .decl = key.decl },6778 .opaque_type = .{ .decl = ini.decl },
6576 }, adapter);6779 }, adapter);
6577 if (gop.found_existing) return @enumFromInt(gop.index);6780 if (gop.found_existing) return @enumFromInt(gop.index);
6578 ip.items.appendAssumeCapacity(.{6781 ip.items.appendAssumeCapacity(.{
6579 .tag = .type_opaque,6782 .tag = .type_opaque,
6580 .data = ip.addExtraAssumeCapacity(key),6783 .data = ip.addExtraAssumeCapacity(Tag.TypeOpaque{
6784 .decl = ini.decl,
6785 .namespace = ini.namespace,
6786 .zir_index = ini.zir_index,
6787 .captures_len = @intCast(ini.captures.len),
6788 }),
6581 });6789 });
6790 ip.extra.appendSliceAssumeCapacity(@ptrCast(ini.captures));
6582 return @enumFromInt(gop.index);6791 return @enumFromInt(gop.index);
6583}6792}
65846793
...@@ -7442,12 +7651,31 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -7442,12 +7651,31 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
7442 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);7651 break :b @sizeOf(Tag.ErrorSet) + (@sizeOf(u32) * info.names_len);
7443 },7652 },
7444 .type_inferred_error_set => 0,7653 .type_inferred_error_set => 0,
7445 .type_enum_explicit, .type_enum_nonexhaustive => @sizeOf(EnumExplicit),7654 .type_enum_explicit, .type_enum_nonexhaustive => b: {
7446 .type_enum_auto => @sizeOf(EnumAuto),7655 const info = ip.extraData(EnumExplicit, data);
7447 .type_opaque => @sizeOf(Key.OpaqueType),7656 var ints = @typeInfo(EnumExplicit).Struct.fields.len + info.captures_len + info.fields_len;
7657 if (info.values_map != .none) ints += info.fields_len;
7658 break :b @sizeOf(u32) * ints;
7659 },
7660 .type_enum_auto => b: {
7661 const info = ip.extraData(EnumAuto, data);
7662 const ints = @typeInfo(EnumAuto).Struct.fields.len + info.captures_len + info.fields_len;
7663 break :b @sizeOf(u32) * ints;
7664 },
7665 .type_opaque => b: {
7666 const info = ip.extraData(Tag.TypeOpaque, data);
7667 const ints = @typeInfo(Tag.TypeOpaque).Struct.fields.len + info.captures_len;
7668 break :b @sizeOf(u32) * ints;
7669 },
7448 .type_struct => b: {7670 .type_struct => b: {
7449 const info = ip.extraData(Tag.TypeStruct, data);7671 if (data == 0) break :b 0;
7672 const extra = ip.extraDataTrail(Tag.TypeStruct, data);
7673 const info = extra.data;
7450 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;7674 var ints: usize = @typeInfo(Tag.TypeStruct).Struct.fields.len;
7675 if (info.flags.any_captures) {
7676 const captures_len = ip.extra.items[extra.end];
7677 ints += 1 + captures_len;
7678 }
7451 ints += info.fields_len; // types7679 ints += info.fields_len; // types
7452 if (!info.flags.is_tuple) {7680 if (!info.flags.is_tuple) {
7453 ints += 1; // names_map7681 ints += 1; // names_map
...@@ -7470,14 +7698,24 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -7470,14 +7698,24 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
7470 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);7698 break :b @sizeOf(TypeStructAnon) + (@sizeOf(u32) * 3 * info.fields_len);
7471 },7699 },
7472 .type_struct_packed => b: {7700 .type_struct_packed => b: {
7473 const info = ip.extraData(Tag.TypeStructPacked, data);7701 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
7702 const captures_len = if (extra.data.flags.any_captures)
7703 ip.extra.items[extra.end]
7704 else
7705 0;
7474 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +7706 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
7475 info.fields_len + info.fields_len);7707 @intFromBool(extra.data.flags.any_captures) + captures_len +
7708 extra.data.fields_len * 2);
7476 },7709 },
7477 .type_struct_packed_inits => b: {7710 .type_struct_packed_inits => b: {
7478 const info = ip.extraData(Tag.TypeStructPacked, data);7711 const extra = ip.extraDataTrail(Tag.TypeStructPacked, data);
7712 const captures_len = if (extra.data.flags.any_captures)
7713 ip.extra.items[extra.end]
7714 else
7715 0;
7479 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +7716 break :b @sizeOf(u32) * (@typeInfo(Tag.TypeStructPacked).Struct.fields.len +
7480 info.fields_len + info.fields_len + info.fields_len);7717 @intFromBool(extra.data.flags.any_captures) + captures_len +
7718 extra.data.fields_len * 3);
7481 },7719 },
7482 .type_tuple_anon => b: {7720 .type_tuple_anon => b: {
7483 const info = ip.extraData(TypeStructAnon, data);7721 const info = ip.extraData(TypeStructAnon, data);
...@@ -7485,16 +7723,20 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -7485,16 +7723,20 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
7485 },7723 },
74867724
7487 .type_union => b: {7725 .type_union => b: {
7488 const info = ip.extraData(Tag.TypeUnion, data);7726 const extra = ip.extraDataTrail(Tag.TypeUnion, data);
7489 const enum_info = ip.loadEnumType(info.tag_ty);7727 const captures_len = if (extra.data.flags.any_captures)
7490 const fields_len: u32 = @intCast(enum_info.names.len);7728 ip.extra.items[extra.end]
7729 else
7730 0;
7491 const per_field = @sizeOf(u32); // field type7731 const per_field = @sizeOf(u32); // field type
7492 // 1 byte per field for alignment, rounded up to the nearest 4 bytes7732 // 1 byte per field for alignment, rounded up to the nearest 4 bytes
7493 const alignments = if (info.flags.any_aligned_fields)7733 const alignments = if (extra.data.flags.any_aligned_fields)
7494 ((fields_len + 3) / 4) * 47734 ((extra.data.fields_len + 3) / 4) * 4
7495 else7735 else
7496 0;7736 0;
7497 break :b @sizeOf(Tag.TypeUnion) + (fields_len * per_field) + alignments;7737 break :b @sizeOf(Tag.TypeUnion) +
7738 4 * (@intFromBool(extra.data.flags.any_captures) + captures_len) +
7739 (extra.data.fields_len * per_field) + alignments;
7498 },7740 },
74997741
7500 .type_function => b: {7742 .type_function => b: {
...@@ -7802,7 +8044,6 @@ pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex)...@@ -7802,7 +8044,6 @@ pub fn destroyNamespace(ip: *InternPool, gpa: Allocator, index: NamespaceIndex)
7802 .parent = undefined,8044 .parent = undefined,
7803 .file_scope = undefined,8045 .file_scope = undefined,
7804 .decl_index = undefined,8046 .decl_index = undefined,
7805 .captures = undefined,
7806 };8047 };
7807 ip.namespaces_free_list.append(gpa, index) catch {8048 ip.namespaces_free_list.append(gpa, index) catch {
7808 // In order to keep `destroyNamespace` a non-fallible function, we ignore memory8049 // In order to keep `destroyNamespace` a non-fallible function, we ignore memory
src/Module.zig-33
...@@ -761,37 +761,6 @@ pub const Namespace = struct {...@@ -761,37 +761,6 @@ pub const Namespace = struct {
761 /// the Decl Value has to be resolved as a Type which has a Namespace.761 /// the Decl Value has to be resolved as a Type which has a Namespace.
762 /// Value is whether the usingnamespace decl is marked `pub`.762 /// Value is whether the usingnamespace decl is marked `pub`.
763 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},763 usingnamespace_set: std.AutoHashMapUnmanaged(Decl.Index, bool) = .{},
764 /// Allocated into `gpa`.
765 /// The ordered set of values captured in this type's closure.
766 /// `closure_get` instructions look up values in this list.
767 captures: []CaptureValue,
768
769 /// A single value captured in a container's closure. This is not an
770 /// `InternPool.Index` so we can differentiate between runtime-known values
771 /// (where only the type is comptime-known) and comptime-known values.
772 pub const CaptureValue = enum(u32) {
773 _,
774 pub const Unwrapped = union(enum) {
775 /// Index refers to the value.
776 @"comptime": InternPool.Index,
777 /// Index refers to the type.
778 runtime: InternPool.Index,
779 };
780 pub fn wrap(val: Unwrapped) CaptureValue {
781 return switch (val) {
782 .@"comptime" => |i| @enumFromInt(@intFromEnum(i)),
783 .runtime => |i| @enumFromInt((1 << 31) | @intFromEnum(i)),
784 };
785 }
786 pub fn unwrap(val: CaptureValue) Unwrapped {
787 const tag: u1 = @intCast(@intFromEnum(val) >> 31);
788 const raw = @intFromEnum(val);
789 return switch (tag) {
790 0 => .{ .@"comptime" = @enumFromInt(raw) },
791 1 => .{ .runtime = @enumFromInt(@as(u31, @truncate(raw))) },
792 };
793 }
794 };
795764
796 const Index = InternPool.NamespaceIndex;765 const Index = InternPool.NamespaceIndex;
797 const OptionalIndex = InternPool.OptionalNamespaceIndex;766 const OptionalIndex = InternPool.OptionalNamespaceIndex;
...@@ -2130,7 +2099,6 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2130,7 +2099,6 @@ pub fn deinit(zcu: *Zcu) void {
2130 while (it.next()) |namespace| {2099 while (it.next()) |namespace| {
2131 namespace.decls.deinit(gpa);2100 namespace.decls.deinit(gpa);
2132 namespace.usingnamespace_set.deinit(gpa);2101 namespace.usingnamespace_set.deinit(gpa);
2133 gpa.free(namespace.captures);
2134 }2102 }
2135 }2103 }
21362104
...@@ -3354,7 +3322,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3354,7 +3322,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3354 .parent = .none,3322 .parent = .none,
3355 .decl_index = undefined,3323 .decl_index = undefined,
3356 .file_scope = file,3324 .file_scope = file,
3357 .captures = &.{},
3358 });3325 });
3359 const new_namespace = mod.namespacePtr(new_namespace_index);3326 const new_namespace = mod.namespacePtr(new_namespace_index);
3360 errdefer mod.destroyNamespace(new_namespace_index);3327 errdefer mod.destroyNamespace(new_namespace_index);
src/Sema.zig+24-20
...@@ -2670,28 +2670,27 @@ fn analyzeAsInt(...@@ -2670,28 +2670,27 @@ fn analyzeAsInt(
2670}2670}
26712671
2672/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,2672/// Given a ZIR extra index which points to a list of `Zir.Inst.Capture`,
2673/// resolves this into a list of `Namespace.CaptureValue` allocated by `gpa`.2673/// resolves this into a list of `InternPool.CaptureValue` allocated by `arena`.
2674/// Caller owns returned memory.2674fn getCaptures(sema: *Sema, parent_namespace: ?InternPool.NamespaceIndex, extra_index: usize, captures_len: u32) ![]InternPool.CaptureValue {
2675fn getCaptures(sema: *Sema, parent_namespace: ?InternPool.NamespaceIndex, extra_index: usize, captures_len: u32) ![]Namespace.CaptureValue {2675 const zcu = sema.mod;
2676 const gpa = sema.gpa;2676 const ip = &zcu.intern_pool;
2677 const parent_captures: []const Namespace.CaptureValue = if (parent_namespace) |p| parent: {2677 const parent_captures: InternPool.CaptureValue.Slice = if (parent_namespace) |p| parent: {
2678 break :parent sema.mod.namespacePtr(p).captures;2678 break :parent zcu.namespacePtr(p).ty.getCaptures(zcu);
2679 } else &.{};2679 } else undefined; // never used so `undefined` is safe
26802680
2681 const captures = try gpa.alloc(Namespace.CaptureValue, captures_len);2681 const captures = try sema.arena.alloc(InternPool.CaptureValue, captures_len);
2682 errdefer gpa.free(captures);
26832682
2684 for (sema.code.extra[extra_index..][0..captures_len], captures) |raw, *capture| {2683 for (sema.code.extra[extra_index..][0..captures_len], captures) |raw, *capture| {
2685 const zir_capture: Zir.Inst.Capture = @enumFromInt(raw);2684 const zir_capture: Zir.Inst.Capture = @enumFromInt(raw);
2686 capture.* = switch (zir_capture.unwrap()) {2685 capture.* = switch (zir_capture.unwrap()) {
2687 .inst => |inst| Namespace.CaptureValue.wrap(capture: {2686 .inst => |inst| InternPool.CaptureValue.wrap(capture: {
2688 const air_ref = try sema.resolveInst(inst.toRef());2687 const air_ref = try sema.resolveInst(inst.toRef());
2689 if (try sema.resolveValue(air_ref)) |val| {2688 if (try sema.resolveValue(air_ref)) |val| {
2690 break :capture .{ .@"comptime" = val.toIntern() };2689 break :capture .{ .@"comptime" = val.toIntern() };
2691 }2690 }
2692 break :capture .{ .runtime = sema.typeOf(air_ref).toIntern() };2691 break :capture .{ .runtime = sema.typeOf(air_ref).toIntern() };
2693 }),2692 }),
2694 .nested => |parent_idx| parent_captures[parent_idx],2693 .nested => |parent_idx| parent_captures.get(ip)[parent_idx],
2695 };2694 };
2696 }2695 }
26972696
...@@ -2731,7 +2730,7 @@ pub fn getStructType(...@@ -2731,7 +2730,7 @@ pub fn getStructType(
2731 break :blk decls_len;2730 break :blk decls_len;
2732 } else 0;2731 } else 0;
27332732
2734 mod.namespacePtr(namespace).captures = try sema.getCaptures(parent_namespace, extra_index, captures_len);2733 const captures = try sema.getCaptures(parent_namespace, extra_index, captures_len);
2735 extra_index += captures_len;2734 extra_index += captures_len;
27362735
2737 if (small.has_backing_int) {2736 if (small.has_backing_int) {
...@@ -2761,6 +2760,7 @@ pub fn getStructType(...@@ -2761,6 +2760,7 @@ pub fn getStructType(
2761 .any_comptime_fields = small.any_comptime_fields,2760 .any_comptime_fields = small.any_comptime_fields,
2762 .inits_resolved = false,2761 .inits_resolved = false,
2763 .any_aligned_fields = small.any_aligned_fields,2762 .any_aligned_fields = small.any_aligned_fields,
2763 .captures = captures,
2764 });2764 });
27652765
2766 return ty;2766 return ty;
...@@ -2801,7 +2801,6 @@ fn zirStructDecl(...@@ -2801,7 +2801,6 @@ fn zirStructDecl(
2801 .parent = block.namespace.toOptional(),2801 .parent = block.namespace.toOptional(),
2802 .decl_index = new_decl_index,2802 .decl_index = new_decl_index,
2803 .file_scope = block.getFileScope(mod),2803 .file_scope = block.getFileScope(mod),
2804 .captures = &.{}, // Will be set by `getStructType`
2805 });2804 });
2806 errdefer mod.destroyNamespace(new_namespace_index);2805 errdefer mod.destroyNamespace(new_namespace_index);
28072806
...@@ -2997,7 +2996,6 @@ fn zirEnumDecl(...@@ -2997,7 +2996,6 @@ fn zirEnumDecl(
2997 .parent = block.namespace.toOptional(),2996 .parent = block.namespace.toOptional(),
2998 .decl_index = new_decl_index,2997 .decl_index = new_decl_index,
2999 .file_scope = block.getFileScope(mod),2998 .file_scope = block.getFileScope(mod),
3000 .captures = captures,
3001 });2999 });
3002 errdefer if (!done) mod.destroyNamespace(new_namespace_index);3000 errdefer if (!done) mod.destroyNamespace(new_namespace_index);
30033001
...@@ -3029,6 +3027,7 @@ fn zirEnumDecl(...@@ -3029,6 +3027,7 @@ fn zirEnumDecl(
3029 else3027 else
3030 .explicit,3028 .explicit,
3031 .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),3029 .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),
3030 .captures = captures,
3032 });3031 });
3033 if (sema.builtin_type_target_index != .none) {3032 if (sema.builtin_type_target_index != .none) {
3034 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, incomplete_enum.index);3033 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, incomplete_enum.index);
...@@ -3261,7 +3260,6 @@ fn zirUnionDecl(...@@ -3261,7 +3260,6 @@ fn zirUnionDecl(
3261 .parent = block.namespace.toOptional(),3260 .parent = block.namespace.toOptional(),
3262 .decl_index = new_decl_index,3261 .decl_index = new_decl_index,
3263 .file_scope = block.getFileScope(mod),3262 .file_scope = block.getFileScope(mod),
3264 .captures = captures,
3265 });3263 });
3266 errdefer mod.destroyNamespace(new_namespace_index);3264 errdefer mod.destroyNamespace(new_namespace_index);
32673265
...@@ -3291,6 +3289,7 @@ fn zirUnionDecl(...@@ -3291,6 +3289,7 @@ fn zirUnionDecl(
3291 .enum_tag_ty = .none,3289 .enum_tag_ty = .none,
3292 .field_types = &.{},3290 .field_types = &.{},
3293 .field_aligns = &.{},3291 .field_aligns = &.{},
3292 .captures = captures,
3294 });3293 });
3295 if (sema.builtin_type_target_index != .none) {3294 if (sema.builtin_type_target_index != .none) {
3296 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty);3295 mod.intern_pool.resolveBuiltinType(sema.builtin_type_target_index, ty);
...@@ -3367,7 +3366,6 @@ fn zirOpaqueDecl(...@@ -3367,7 +3366,6 @@ fn zirOpaqueDecl(
3367 .parent = block.namespace.toOptional(),3366 .parent = block.namespace.toOptional(),
3368 .decl_index = new_decl_index,3367 .decl_index = new_decl_index,
3369 .file_scope = block.getFileScope(mod),3368 .file_scope = block.getFileScope(mod),
3370 .captures = captures,
3371 });3369 });
3372 errdefer mod.destroyNamespace(new_namespace_index);3370 errdefer mod.destroyNamespace(new_namespace_index);
33733371
...@@ -3375,6 +3373,7 @@ fn zirOpaqueDecl(...@@ -3375,6 +3373,7 @@ fn zirOpaqueDecl(
3375 .decl = new_decl_index,3373 .decl = new_decl_index,
3376 .namespace = new_namespace_index,3374 .namespace = new_namespace_index,
3377 .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),3375 .zir_index = (try mod.intern_pool.trackZir(sema.gpa, block.getFileScope(mod), inst)).toOptional(),
3376 .captures = captures,
3378 });3377 });
3379 // TODO: figure out InternPool removals for incremental compilation3378 // TODO: figure out InternPool removals for incremental compilation
3380 //errdefer mod.intern_pool.remove(opaque_ty);3379 //errdefer mod.intern_pool.remove(opaque_ty);
...@@ -17287,12 +17286,13 @@ fn zirThis(...@@ -17287,12 +17286,13 @@ fn zirThis(
1728717286
17288fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {17287fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
17289 const mod = sema.mod;17288 const mod = sema.mod;
17290 const captures = mod.namespacePtr(block.namespace).captures;17289 const ip = &mod.intern_pool;
17290 const captures = mod.namespacePtr(block.namespace).ty.getCaptures(mod);
1729117291
17292 const src_node: i32 = @bitCast(extended.operand);17292 const src_node: i32 = @bitCast(extended.operand);
17293 const src = LazySrcLoc.nodeOffset(src_node);17293 const src = LazySrcLoc.nodeOffset(src_node);
1729417294
17295 const capture_ty = switch (captures[extended.small].unwrap()) {17295 const capture_ty = switch (captures.get(ip)[extended.small].unwrap()) {
17296 .@"comptime" => |index| return Air.internedToRef(index),17296 .@"comptime" => |index| return Air.internedToRef(index),
17297 .runtime => |index| index,17297 .runtime => |index| index,
17298 };17298 };
...@@ -21360,6 +21360,7 @@ fn zirReify(...@@ -21360,6 +21360,7 @@ fn zirReify(
21360 .explicit,21360 .explicit,
21361 .tag_ty = int_tag_ty.toIntern(),21361 .tag_ty = int_tag_ty.toIntern(),
21362 .zir_index = .none,21362 .zir_index = .none,
21363 .captures = &.{},
21363 });21364 });
21364 // TODO: figure out InternPool removals for incremental compilation21365 // TODO: figure out InternPool removals for incremental compilation
21365 //errdefer ip.remove(incomplete_enum.index);21366 //errdefer ip.remove(incomplete_enum.index);
...@@ -21450,7 +21451,6 @@ fn zirReify(...@@ -21450,7 +21451,6 @@ fn zirReify(
21450 .parent = block.namespace.toOptional(),21451 .parent = block.namespace.toOptional(),
21451 .decl_index = new_decl_index,21452 .decl_index = new_decl_index,
21452 .file_scope = block.getFileScope(mod),21453 .file_scope = block.getFileScope(mod),
21453 .captures = &.{},
21454 });21454 });
21455 errdefer mod.destroyNamespace(new_namespace_index);21455 errdefer mod.destroyNamespace(new_namespace_index);
2145621456
...@@ -21458,6 +21458,7 @@ fn zirReify(...@@ -21458,6 +21458,7 @@ fn zirReify(
21458 .decl = new_decl_index,21458 .decl = new_decl_index,
21459 .namespace = new_namespace_index,21459 .namespace = new_namespace_index,
21460 .zir_index = .none,21460 .zir_index = .none,
21461 .captures = &.{},
21461 });21462 });
21462 // TODO: figure out InternPool removals for incremental compilation21463 // TODO: figure out InternPool removals for incremental compilation
21463 //errdefer ip.remove(opaque_ty);21464 //errdefer ip.remove(opaque_ty);
...@@ -21659,7 +21660,6 @@ fn zirReify(...@@ -21659,7 +21660,6 @@ fn zirReify(
21659 .parent = block.namespace.toOptional(),21660 .parent = block.namespace.toOptional(),
21660 .decl_index = new_decl_index,21661 .decl_index = new_decl_index,
21661 .file_scope = block.getFileScope(mod),21662 .file_scope = block.getFileScope(mod),
21662 .captures = &.{},
21663 });21663 });
21664 errdefer mod.destroyNamespace(new_namespace_index);21664 errdefer mod.destroyNamespace(new_namespace_index);
2166521665
...@@ -21688,6 +21688,7 @@ fn zirReify(...@@ -21688,6 +21688,7 @@ fn zirReify(
21688 },21688 },
21689 .field_types = union_fields.items(.type),21689 .field_types = union_fields.items(.type),
21690 .field_aligns = if (any_aligned_fields) union_fields.items(.alignment) else &.{},21690 .field_aligns = if (any_aligned_fields) union_fields.items(.alignment) else &.{},
21691 .captures = &.{},
21691 });21692 });
2169221693
21693 new_decl.ty = Type.type;21694 new_decl.ty = Type.type;
...@@ -21849,6 +21850,7 @@ fn reifyStruct(...@@ -21849,6 +21850,7 @@ fn reifyStruct(
21849 .any_default_inits = true,21850 .any_default_inits = true,
21850 .inits_resolved = true,21851 .inits_resolved = true,
21851 .any_aligned_fields = true,21852 .any_aligned_fields = true,
21853 .captures = &.{},
21852 });21854 });
21853 // TODO: figure out InternPool removals for incremental compilation21855 // TODO: figure out InternPool removals for incremental compilation
21854 //errdefer ip.remove(ty);21856 //errdefer ip.remove(ty);
...@@ -37404,6 +37406,7 @@ fn generateUnionTagTypeNumbered(...@@ -37404,6 +37406,7 @@ fn generateUnionTagTypeNumbered(
37404 .values = enum_field_vals,37406 .values = enum_field_vals,
37405 .tag_mode = .explicit,37407 .tag_mode = .explicit,
37406 .zir_index = .none,37408 .zir_index = .none,
37409 .captures = &.{},
37407 });37410 });
3740837411
37409 new_decl.ty = Type.type;37412 new_decl.ty = Type.type;
...@@ -37455,6 +37458,7 @@ fn generateUnionTagTypeSimple(...@@ -37455,6 +37458,7 @@ fn generateUnionTagTypeSimple(
37455 .values = &.{},37458 .values = &.{},
37456 .tag_mode = .auto,37459 .tag_mode = .auto,
37457 .zir_index = .none,37460 .zir_index = .none,
37461 .captures = &.{},
37458 });37462 });
3745937463
37460 const new_decl = mod.declPtr(new_decl_index);37464 const new_decl = mod.declPtr(new_decl_index);
src/type.zig+12
...@@ -3294,6 +3294,18 @@ pub const Type = struct {...@@ -3294,6 +3294,18 @@ pub const Type = struct {
3294 };3294 };
3295 }3295 }
32963296
3297 /// Given a namespace type, returns its list of caotured values.
3298 pub fn getCaptures(ty: Type, zcu: *const Zcu) InternPool.CaptureValue.Slice {
3299 const ip = &zcu.intern_pool;
3300 return switch (ip.indexToKey(ty.toIntern())) {
3301 .struct_type => ip.loadStructType(ty.toIntern()).captures,
3302 .union_type => ip.loadUnionType(ty.toIntern()).captures,
3303 .enum_type => ip.loadEnumType(ty.toIntern()).captures,
3304 .opaque_type => ip.loadOpaqueType(ty.toIntern()).captures,
3305 else => unreachable,
3306 };
3307 }
3308
3297 pub const @"u1": Type = .{ .ip_index = .u1_type };3309 pub const @"u1": Type = .{ .ip_index = .u1_type };
3298 pub const @"u8": Type = .{ .ip_index = .u8_type };3310 pub const @"u8": Type = .{ .ip_index = .u8_type };
3299 pub const @"u16": Type = .{ .ip_index = .u16_type };3311 pub const @"u16": Type = .{ .ip_index = .u16_type };