authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-14 23:04:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-07-18 19:02:06-07:00
log9f61c29bfb8f9a93f737a099ed38f9e0a106d6b6
tree8cb0d38128e1e8412d5d34722982aedff784839a
parent1b70fca534c64a412270897f06938c50f0b7b39c

InternPool: unwrap func_coerced when using it as generic_owner


1 files changed, 31 insertions(+), 12 deletions(-)

src/InternPool.zig+31-12
...@@ -4729,7 +4729,9 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -4729,7 +4729,9 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
4729 .addrspace_is_generic = false,4729 .addrspace_is_generic = false,
4730 });4730 });
47314731
4732 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(arg.generic_owner)));4732 const generic_owner = unwrapCoercedFunc(ip, arg.generic_owner);
4733
4734 assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner)));
47334735
4734 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +4736 try ip.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.FuncInstance).Struct.fields.len +
4735 arg.comptime_args.len);4737 arg.comptime_args.len);
...@@ -4750,7 +4752,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -4750,7 +4752,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
4750 .owner_decl = undefined,4752 .owner_decl = undefined,
4751 .ty = func_ty,4753 .ty = func_ty,
4752 .branch_quota = 0,4754 .branch_quota = 0,
4753 .generic_owner = arg.generic_owner,4755 .generic_owner = generic_owner,
4754 });4756 });
4755 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));4757 ip.extra.appendSliceAssumeCapacity(@ptrCast(arg.comptime_args));
47564758
...@@ -4775,7 +4777,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)...@@ -4775,7 +4777,7 @@ pub fn getFuncInstance(ip: *InternPool, gpa: Allocator, arg: GetFuncInstanceKey)
4775 return finishFuncInstance(4777 return finishFuncInstance(
4776 ip,4778 ip,
4777 gpa,4779 gpa,
4778 arg.generic_owner,4780 generic_owner,
4779 func_index,4781 func_index,
4780 func_extra_index,4782 func_extra_index,
4781 arg.generation,4783 arg.generation,
...@@ -5673,7 +5675,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -5673,7 +5675,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
5673 } });5675 } });
5674 },5676 },
5675 .elems => |elems| {5677 .elems => |elems| {
5676 const elems_copy = try gpa.dupe(InternPool.Index, elems[0..new_len]);5678 const elems_copy = try gpa.dupe(Index, elems[0..new_len]);
5677 defer gpa.free(elems_copy);5679 defer gpa.free(elems_copy);
5678 return ip.get(gpa, .{ .aggregate = .{5680 return ip.get(gpa, .{ .aggregate = .{
5679 .ty = new_ty,5681 .ty = new_ty,
...@@ -5689,7 +5691,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al...@@ -5689,7 +5691,7 @@ pub fn getCoerced(ip: *InternPool, gpa: Allocator, val: Index, new_ty: Index) Al
5689 }5691 }
5690 }5692 }
5691 // Direct approach failed - we must recursively coerce elems5693 // Direct approach failed - we must recursively coerce elems
5692 const agg_elems = try gpa.alloc(InternPool.Index, new_len);5694 const agg_elems = try gpa.alloc(Index, new_len);
5693 defer gpa.free(agg_elems);5695 defer gpa.free(agg_elems);
5694 // First, fill the vector with the uncoerced elements. We do this to avoid key5696 // First, fill the vector with the uncoerced elements. We do this to avoid key
5695 // lifetime issues, since it'll allow us to avoid referencing `aggregate` after we5697 // lifetime issues, since it'll allow us to avoid referencing `aggregate` after we
...@@ -6042,7 +6044,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -6042,7 +6044,10 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
60426044
6043 .type_function => b: {6045 .type_function => b: {
6044 const info = ip.extraData(Tag.TypeFunction, data);6046 const info = ip.extraData(Tag.TypeFunction, data);
6045 break :b @sizeOf(Tag.TypeFunction) + (@sizeOf(Index) * info.params_len);6047 break :b @sizeOf(Tag.TypeFunction) +
6048 (@sizeOf(Index) * info.params_len) +
6049 (@as(u32, 4) * @intFromBool(info.flags.has_comptime_bits)) +
6050 (@as(u32, 4) * @intFromBool(info.flags.has_noalias_bits));
6046 },6051 },
60476052
6048 .undef => 0,6053 .undef => 0,
...@@ -6996,7 +7001,7 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {...@@ -6996,7 +7001,7 @@ pub fn funcZirBodyInst(ip: *const InternPool, i: Index) Zir.Inst.Index {
6996 return ip.extra.items[extra_index];7001 return ip.extra.items[extra_index];
6997}7002}
69987003
6999pub fn iesFuncIndex(ip: *const InternPool, ies_index: InternPool.Index) InternPool.Index {7004pub fn iesFuncIndex(ip: *const InternPool, ies_index: Index) Index {
7000 assert(ies_index != .none);7005 assert(ies_index != .none);
7001 const tags = ip.items.items(.tag);7006 const tags = ip.items.items(.tag);
7002 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);7007 assert(tags[@intFromEnum(ies_index)] == .type_inferred_error_set);
...@@ -7011,7 +7016,7 @@ pub fn iesFuncIndex(ip: *const InternPool, ies_index: InternPool.Index) InternPo...@@ -7011,7 +7016,7 @@ pub fn iesFuncIndex(ip: *const InternPool, ies_index: InternPool.Index) InternPo
7011/// Returns a mutable pointer to the resolved error set type of an inferred7016/// Returns a mutable pointer to the resolved error set type of an inferred
7012/// error set function. The returned pointer is invalidated when anything is7017/// error set function. The returned pointer is invalidated when anything is
7013/// added to `ip`.7018/// added to `ip`.
7014pub fn iesResolved(ip: *const InternPool, ies_index: InternPool.Index) *InternPool.Index {7019pub fn iesResolved(ip: *const InternPool, ies_index: Index) *Index {
7015 assert(ies_index != .none);7020 assert(ies_index != .none);
7016 const tags = ip.items.items(.tag);7021 const tags = ip.items.items(.tag);
7017 const datas = ip.items.items(.data);7022 const datas = ip.items.items(.data);
...@@ -7023,7 +7028,7 @@ pub fn iesResolved(ip: *const InternPool, ies_index: InternPool.Index) *InternPo...@@ -7023,7 +7028,7 @@ pub fn iesResolved(ip: *const InternPool, ies_index: InternPool.Index) *InternPo
7023/// Returns a mutable pointer to the resolved error set type of an inferred7028/// Returns a mutable pointer to the resolved error set type of an inferred
7024/// error set function. The returned pointer is invalidated when anything is7029/// error set function. The returned pointer is invalidated when anything is
7025/// added to `ip`.7030/// added to `ip`.
7026pub fn funcIesResolved(ip: *const InternPool, func_index: InternPool.Index) *InternPool.Index {7031pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
7027 const tags = ip.items.items(.tag);7032 const tags = ip.items.items(.tag);
7028 const datas = ip.items.items(.data);7033 const datas = ip.items.items(.data);
7029 assert(funcHasInferredErrorSet(ip, func_index));7034 assert(funcHasInferredErrorSet(ip, func_index));
...@@ -7036,21 +7041,35 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: InternPool.Index) *Int...@@ -7036,21 +7041,35 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: InternPool.Index) *Int
7036 return @ptrCast(&ip.extra.items[extra_index]);7041 return @ptrCast(&ip.extra.items[extra_index]);
7037}7042}
70387043
7039pub fn funcDeclInfo(ip: *const InternPool, i: InternPool.Index) Key.Func {7044pub fn funcDeclInfo(ip: *const InternPool, i: Index) Key.Func {
7040 const tags = ip.items.items(.tag);7045 const tags = ip.items.items(.tag);
7041 const datas = ip.items.items(.data);7046 const datas = ip.items.items(.data);
7042 assert(tags[@intFromEnum(i)] == .func_decl);7047 assert(tags[@intFromEnum(i)] == .func_decl);
7043 return extraFuncDecl(ip, datas[@intFromEnum(i)]);7048 return extraFuncDecl(ip, datas[@intFromEnum(i)]);
7044}7049}
70457050
7046pub fn funcDeclOwner(ip: *const InternPool, i: InternPool.Index) Module.Decl.Index {7051pub fn funcDeclOwner(ip: *const InternPool, i: Index) Module.Decl.Index {
7047 return funcDeclInfo(ip, i).owner_decl;7052 return funcDeclInfo(ip, i).owner_decl;
7048}7053}
70497054
7050pub fn funcTypeParamsLen(ip: *const InternPool, i: InternPool.Index) u32 {7055pub fn funcTypeParamsLen(ip: *const InternPool, i: Index) u32 {
7051 const tags = ip.items.items(.tag);7056 const tags = ip.items.items(.tag);
7052 const datas = ip.items.items(.data);7057 const datas = ip.items.items(.data);
7053 assert(tags[@intFromEnum(i)] == .type_function);7058 assert(tags[@intFromEnum(i)] == .type_function);
7054 const start = datas[@intFromEnum(i)];7059 const start = datas[@intFromEnum(i)];
7055 return ip.extra.items[start + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];7060 return ip.extra.items[start + std.meta.fieldIndex(Tag.TypeFunction, "params_len").?];
7056}7061}
7062
7063fn unwrapCoercedFunc(ip: *const InternPool, i: Index) Index {
7064 const tags = ip.items.items(.tag);
7065 return switch (tags[@intFromEnum(i)]) {
7066 .func_coerced => {
7067 const datas = ip.items.items(.data);
7068 return @enumFromInt(ip.extra.items[
7069 datas[@intFromEnum(i)] + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
7070 ]);
7071 },
7072 .func_instance, .func_decl => i,
7073 else => unreachable,
7074 };
7075}