Commit be78a12d7d
Changed files (2)
src/InternPool.zig
@@ -575,9 +575,10 @@ pub const Key = union(enum) {
std.hash.autoHash(hasher, ptr.ty);
// Int-to-ptr pointers are hashed separately than decl-referencing pointers.
// This is sound due to pointer provenance rules.
+ std.hash.autoHash(hasher, @as(@typeInfo(Key.Ptr.Addr).Union.tag_type.?, ptr.addr));
switch (ptr.addr) {
+ .decl => |decl| std.hash.autoHash(hasher, decl),
.int => |int| std.hash.autoHash(hasher, int),
- .decl => @panic("TODO"),
}
},
@@ -690,19 +691,14 @@ pub const Key = union(enum) {
.ptr => |a_info| {
const b_info = b.ptr;
+ if (a_info.ty != b_info.ty) return false;
- if (a_info.ty != b_info.ty)
- return false;
+ const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?;
+ if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false;
return switch (a_info.addr) {
- .int => |a_int| switch (b_info.addr) {
- .int => |b_int| a_int == b_int,
- .decl => false,
- },
- .decl => |a_decl| switch (b_info.addr) {
- .int => false,
- .decl => |b_decl| a_decl == b_decl,
- },
+ .decl => |a_decl| a_decl == b_info.addr.decl,
+ .int => |a_int| a_int == b_info.addr.int,
};
},
@@ -1334,7 +1330,10 @@ pub const Tag = enum(u8) {
/// A value that can be represented with only an enum tag.
/// data is SimpleValue enum value.
simple_value,
- /// A pointer to an integer value.
+ /// A pointer to a decl.
+ /// data is extra index of PtrDecl, which contains the type and address.
+ ptr_decl,
+ /// A pointer with an integer value.
/// data is extra index of PtrInt, which contains the type and address.
/// Only pointer types are allowed to have this encoding. Optional types must use
/// `opt_payload` or `opt_null`.
@@ -1673,6 +1672,11 @@ pub const PackedU64 = packed struct(u64) {
}
};
+pub const PtrDecl = struct {
+ ty: Index,
+ decl: Module.Decl.Index,
+};
+
pub const PtrInt = struct {
ty: Index,
addr: Index,
@@ -1990,6 +1994,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
.val = payload_val,
} };
},
+ .ptr_decl => {
+ const info = ip.extraData(PtrDecl, data);
+ return .{ .ptr = .{
+ .ty = info.ty,
+ .addr = .{ .decl = info.decl },
+ } };
+ },
.ptr_int => {
const info = ip.extraData(PtrInt, data);
return .{ .ptr = .{
@@ -2462,7 +2473,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
.extern_func => @panic("TODO"),
.ptr => |ptr| switch (ptr.addr) {
- .decl => @panic("TODO"),
+ .decl => |decl| {
+ assert(ptr.ty != .none);
+ ip.items.appendAssumeCapacity(.{
+ .tag = .ptr_decl,
+ .data = try ip.addExtra(gpa, PtrDecl{
+ .ty = ptr.ty,
+ .decl = decl,
+ }),
+ });
+ },
.int => |int| {
assert(ptr.ty != .none);
ip.items.appendAssumeCapacity(.{
@@ -3465,6 +3485,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
.undef => 0,
.simple_type => 0,
.simple_value => 0,
+ .ptr_decl => @sizeOf(PtrDecl),
.ptr_int => @sizeOf(PtrInt),
.opt_null => 0,
.opt_payload => 0,
src/Sema.zig
@@ -29294,33 +29294,28 @@ fn analyzeDeclRef(sema: *Sema, decl_index: Decl.Index) CompileError!Air.Inst.Ref
/// decl_ref to end up in runtime code, the function body must be analyzed: `analyzeDeclRef` wraps
/// this function with `analyze_fn_body` set to true.
fn analyzeDeclRefInner(sema: *Sema, decl_index: Decl.Index, analyze_fn_body: bool) CompileError!Air.Inst.Ref {
- try sema.mod.declareDeclDependency(sema.owner_decl_index, decl_index);
+ const mod = sema.mod;
+ try mod.declareDeclDependency(sema.owner_decl_index, decl_index);
try sema.ensureDeclAnalyzed(decl_index);
- const decl = sema.mod.declPtr(decl_index);
+ const decl = mod.declPtr(decl_index);
const decl_tv = try decl.typedValue();
- if (decl_tv.val.castTag(.variable)) |payload| {
- const variable = payload.data;
- const ty = try Type.ptr(sema.arena, sema.mod, .{
- .pointee_type = decl_tv.ty,
- .mutable = variable.is_mutable,
- .@"addrspace" = decl.@"addrspace",
- .@"align" = decl.@"align",
- });
- return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl_index));
- }
+ const ptr_ty = try mod.ptrType(.{
+ .elem_type = decl_tv.ty.ip_index,
+ .alignment = InternPool.Alignment.fromByteUnits(decl.@"align"),
+ .is_const = if (decl_tv.val.castTag(.variable)) |payload|
+ !payload.data.is_mutable
+ else
+ false,
+ .address_space = decl.@"addrspace",
+ });
if (analyze_fn_body) {
try sema.maybeQueueFuncBodyAnalysis(decl_index);
}
- return sema.addConstant(
- try Type.ptr(sema.arena, sema.mod, .{
- .pointee_type = decl_tv.ty,
- .mutable = false,
- .@"addrspace" = decl.@"addrspace",
- .@"align" = decl.@"align",
- }),
- try Value.Tag.decl_ref.create(sema.arena, decl_index),
- );
+ return sema.addConstant(ptr_ty, (try mod.intern(.{ .ptr = .{
+ .ty = ptr_ty.ip_index,
+ .addr = .{ .decl = decl_index },
+ } })).toValue());
}
fn maybeQueueFuncBodyAnalysis(sema: *Sema, decl_index: Decl.Index) !void {