aboutsummaryrefslogtreecommitdiff
path: root/src/InternPool.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2024-03-05 07:22:47 +0000
committermlugg <mlugg@mlugg.co.uk>2024-03-06 21:26:38 +0000
commit2c4ac44f25743f5b7ae9db6bc570ab71f15fd83b (patch)
tree5936a2c47c13ea1fcd5bd37ce523754517be38cf /src/InternPool.zig
parentd0c022f7347b5cda34751a986a535aee3b1f45dc (diff)
downloadzig-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.zig17
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 {