| ... | @@ -575,9 +575,10 @@ pub const Key = union(enum) { | ... | @@ -575,9 +575,10 @@ pub const Key = union(enum) { |
| 575 | std.hash.autoHash(hasher, ptr.ty); | 575 | std.hash.autoHash(hasher, ptr.ty); |
| 576 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. | 576 | // Int-to-ptr pointers are hashed separately than decl-referencing pointers. |
| 577 | // This is sound due to pointer provenance rules. | 577 | // This is sound due to pointer provenance rules. |
| | 578 | std.hash.autoHash(hasher, @as(@typeInfo(Key.Ptr.Addr).Union.tag_type.?, ptr.addr)); |
| 578 | switch (ptr.addr) { | 579 | switch (ptr.addr) { |
| | 580 | .decl => |decl| std.hash.autoHash(hasher, decl), |
| 579 | .int => |int| std.hash.autoHash(hasher, int), | 581 | .int => |int| std.hash.autoHash(hasher, int), |
| 580 | .decl => @panic("TODO"), | | |
| 581 | } | 582 | } |
| 582 | }, | 583 | }, |
| 583 | | 584 | |
| ... | @@ -690,19 +691,14 @@ pub const Key = union(enum) { | ... | @@ -690,19 +691,14 @@ pub const Key = union(enum) { |
| 690 | | 691 | |
| 691 | .ptr => |a_info| { | 692 | .ptr => |a_info| { |
| 692 | const b_info = b.ptr; | 693 | const b_info = b.ptr; |
| | 694 | if (a_info.ty != b_info.ty) return false; |
| 693 | | 695 | |
| 694 | if (a_info.ty != b_info.ty) | 696 | const AddrTag = @typeInfo(Key.Ptr.Addr).Union.tag_type.?; |
| 695 | return false; | 697 | if (@as(AddrTag, a_info.addr) != @as(AddrTag, b_info.addr)) return false; |
| 696 | | 698 | |
| 697 | return switch (a_info.addr) { | 699 | return switch (a_info.addr) { |
| 698 | .int => |a_int| switch (b_info.addr) { | 700 | .decl => |a_decl| a_decl == b_info.addr.decl, |
| 699 | .int => |b_int| a_int == b_int, | 701 | .int => |a_int| a_int == b_info.addr.int, |
| 700 | .decl => false, | | |
| 701 | }, | | |
| 702 | .decl => |a_decl| switch (b_info.addr) { | | |
| 703 | .int => false, | | |
| 704 | .decl => |b_decl| a_decl == b_decl, | | |
| 705 | }, | | |
| 706 | }; | 702 | }; |
| 707 | }, | 703 | }, |
| 708 | | 704 | |
| ... | @@ -1334,7 +1330,10 @@ pub const Tag = enum(u8) { | ... | @@ -1334,7 +1330,10 @@ pub const Tag = enum(u8) { |
| 1334 | /// A value that can be represented with only an enum tag. | 1330 | /// A value that can be represented with only an enum tag. |
| 1335 | /// data is SimpleValue enum value. | 1331 | /// data is SimpleValue enum value. |
| 1336 | simple_value, | 1332 | simple_value, |
| 1337 | /// A pointer to an integer value. | 1333 | /// A pointer to a decl. |
| | 1334 | /// data is extra index of PtrDecl, which contains the type and address. |
| | 1335 | ptr_decl, |
| | 1336 | /// A pointer with an integer value. |
| 1338 | /// data is extra index of PtrInt, which contains the type and address. | 1337 | /// data is extra index of PtrInt, which contains the type and address. |
| 1339 | /// Only pointer types are allowed to have this encoding. Optional types must use | 1338 | /// Only pointer types are allowed to have this encoding. Optional types must use |
| 1340 | /// `opt_payload` or `opt_null`. | 1339 | /// `opt_payload` or `opt_null`. |
| ... | @@ -1673,6 +1672,11 @@ pub const PackedU64 = packed struct(u64) { | ... | @@ -1673,6 +1672,11 @@ pub const PackedU64 = packed struct(u64) { |
| 1673 | } | 1672 | } |
| 1674 | }; | 1673 | }; |
| 1675 | | 1674 | |
| | 1675 | pub const PtrDecl = struct { |
| | 1676 | ty: Index, |
| | 1677 | decl: Module.Decl.Index, |
| | 1678 | }; |
| | 1679 | |
| 1676 | pub const PtrInt = struct { | 1680 | pub const PtrInt = struct { |
| 1677 | ty: Index, | 1681 | ty: Index, |
| 1678 | addr: Index, | 1682 | addr: Index, |
| ... | @@ -1990,6 +1994,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { | ... | @@ -1990,6 +1994,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { |
| 1990 | .val = payload_val, | 1994 | .val = payload_val, |
| 1991 | } }; | 1995 | } }; |
| 1992 | }, | 1996 | }, |
| | 1997 | .ptr_decl => { |
| | 1998 | const info = ip.extraData(PtrDecl, data); |
| | 1999 | return .{ .ptr = .{ |
| | 2000 | .ty = info.ty, |
| | 2001 | .addr = .{ .decl = info.decl }, |
| | 2002 | } }; |
| | 2003 | }, |
| 1993 | .ptr_int => { | 2004 | .ptr_int => { |
| 1994 | const info = ip.extraData(PtrInt, data); | 2005 | const info = ip.extraData(PtrInt, data); |
| 1995 | return .{ .ptr = .{ | 2006 | return .{ .ptr = .{ |
| ... | @@ -2462,7 +2473,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { | ... | @@ -2462,7 +2473,16 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { |
| 2462 | .extern_func => @panic("TODO"), | 2473 | .extern_func => @panic("TODO"), |
| 2463 | | 2474 | |
| 2464 | .ptr => |ptr| switch (ptr.addr) { | 2475 | .ptr => |ptr| switch (ptr.addr) { |
| 2465 | .decl => @panic("TODO"), | 2476 | .decl => |decl| { |
| | 2477 | assert(ptr.ty != .none); |
| | 2478 | ip.items.appendAssumeCapacity(.{ |
| | 2479 | .tag = .ptr_decl, |
| | 2480 | .data = try ip.addExtra(gpa, PtrDecl{ |
| | 2481 | .ty = ptr.ty, |
| | 2482 | .decl = decl, |
| | 2483 | }), |
| | 2484 | }); |
| | 2485 | }, |
| 2466 | .int => |int| { | 2486 | .int => |int| { |
| 2467 | assert(ptr.ty != .none); | 2487 | assert(ptr.ty != .none); |
| 2468 | ip.items.appendAssumeCapacity(.{ | 2488 | ip.items.appendAssumeCapacity(.{ |
| ... | @@ -3465,6 +3485,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { | ... | @@ -3465,6 +3485,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void { |
| 3465 | .undef => 0, | 3485 | .undef => 0, |
| 3466 | .simple_type => 0, | 3486 | .simple_type => 0, |
| 3467 | .simple_value => 0, | 3487 | .simple_value => 0, |
| | 3488 | .ptr_decl => @sizeOf(PtrDecl), |
| 3468 | .ptr_int => @sizeOf(PtrInt), | 3489 | .ptr_int => @sizeOf(PtrInt), |
| 3469 | .opt_null => 0, | 3490 | .opt_null => 0, |
| 3470 | .opt_payload => 0, | 3491 | .opt_payload => 0, |