diff options
| author | mlugg <mlugg@mlugg.co.uk> | 2024-03-05 07:22:47 +0000 |
|---|---|---|
| committer | mlugg <mlugg@mlugg.co.uk> | 2024-03-06 21:26:38 +0000 |
| commit | 2c4ac44f25743f5b7ae9db6bc570ab71f15fd83b (patch) | |
| tree | 5936a2c47c13ea1fcd5bd37ce523754517be38cf /src/InternPool.zig | |
| parent | d0c022f7347b5cda34751a986a535aee3b1f45dc (diff) | |
| download | zig-2c4ac44f25743f5b7ae9db6bc570ab71f15fd83b.tar.gz zig-2c4ac44f25743f5b7ae9db6bc570ab71f15fd83b.zip | |
compiler: treat decl_val/decl_ref of potentially generic decls as captures
This fixes an issue with the implementation of #18816. Consider the
following code:
```zig
pub fn Wrap(comptime T: type) type {
return struct {
pub const T1 = T;
inner: struct { x: T1 },
};
}
```
Previously, the type of `inner` was not considered to be "capturing" any
value, as `T1` is a decl. However, since it is declared within a generic
function, this decl reference depends on the context, and thus should be
treated as a capture.
AstGen has been augmented to tunnel references to decls through closure
when the decl was declared in a potentially-generic context (i.e. within
a function).
Diffstat (limited to 'src/InternPool.zig')
| -rw-r--r-- | src/InternPool.zig | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/InternPool.zig b/src/InternPool.zig index 36311100da..6639603cb5 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -503,22 +503,29 @@ pub const OptionalNullTerminatedString = enum(u32) { }; /// A single value captured in the closure of a namespace type. This is not a plain -/// `Index` because we must differentiate between runtime-known values (where we -/// store the type) and comptime-known values (where we store the value). +/// `Index` because we must differentiate between the following cases: +/// * runtime-known value (where we store the type) +/// * comptime-known value (where we store the value) +/// * decl val (so that we can analyze the value lazily) +/// * decl ref (so that we can analyze the reference lazily) pub const CaptureValue = packed struct(u32) { - tag: enum { @"comptime", runtime }, - idx: u31, + tag: enum { @"comptime", runtime, decl_val, decl_ref }, + idx: u30, pub fn wrap(val: Unwrapped) CaptureValue { return switch (val) { .@"comptime" => |i| .{ .tag = .@"comptime", .idx = @intCast(@intFromEnum(i)) }, .runtime => |i| .{ .tag = .runtime, .idx = @intCast(@intFromEnum(i)) }, + .decl_val => |i| .{ .tag = .decl_val, .idx = @intCast(@intFromEnum(i)) }, + .decl_ref => |i| .{ .tag = .decl_ref, .idx = @intCast(@intFromEnum(i)) }, }; } pub fn unwrap(val: CaptureValue) Unwrapped { return switch (val.tag) { .@"comptime" => .{ .@"comptime" = @enumFromInt(val.idx) }, .runtime => .{ .runtime = @enumFromInt(val.idx) }, + .decl_val => .{ .decl_val = @enumFromInt(val.idx) }, + .decl_ref => .{ .decl_ref = @enumFromInt(val.idx) }, }; } @@ -527,6 +534,8 @@ pub const CaptureValue = packed struct(u32) { @"comptime": Index, /// Index refers to the type. runtime: Index, + decl_val: DeclIndex, + decl_ref: DeclIndex, }; pub const Slice = struct { |
