InternPool: add func_coerced handling to funcIesResolved

This commit is contained in:
Andrew Kelley 2023-07-23 17:46:50 -07:00
parent a7f3c2eab4
commit cc6964c5dc
2 changed files with 31 additions and 0 deletions

View File

@ -7069,6 +7069,17 @@ pub fn funcIesResolved(ip: *const InternPool, func_index: Index) *Index {
const extra_index = switch (tags[@intFromEnum(func_index)]) {
.func_decl => func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,
.func_instance => func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,
.func_coerced => i: {
const uncoerced_func_index: Index = @enumFromInt(ip.extra.items[
func_start + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
]);
const uncoerced_func_start = datas[@intFromEnum(uncoerced_func_index)];
break :i switch (tags[@intFromEnum(uncoerced_func_index)]) {
.func_decl => uncoerced_func_start + @typeInfo(Tag.FuncDecl).Struct.fields.len,
.func_instance => uncoerced_func_start + @typeInfo(Tag.FuncInstance).Struct.fields.len,
else => unreachable,
};
},
else => unreachable,
};
return @ptrCast(&ip.extra.items[extra_index]);

View File

@ -456,3 +456,23 @@ test "return type of generic function is function pointer" {
try expect(null == S.b(void));
}
test "coerced function body has inequal value with its uncoerced body" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
const S = struct {
const A = B(i32, c);
fn c() !i32 {
return 1234;
}
fn B(comptime T: type, comptime d: ?fn () anyerror!T) type {
return struct {
fn do() T {
return d.?() catch @panic("fail");
}
};
}
};
try expect(S.A.do() == 1234);
}