authorgravatar for rmehri01@tutamail.comRyan Mehri <rmehri01@tutamail.com> 2026-06-25 17:55:22-04:00
committergravatar for justusk@noreply.codeberg.orgJustus Klausecker <justusk@noreply.codeberg.org> 2026-06-27 10:57:03+02:00
log9b5851f0019c6cf2b5a54ffa54acd7f13b941a07
tree915cd5bce518687f907df71b6b44eff22952bece
parent1581601ffa1fe36f579c81fb5c774f99dbc20942

InternPool: fix incorrect coercion of `func_coerced`

When trying to coerce a `func_coerced` value to another type, `getCoerced` checks the tag but passes the whole `func_coerced` value instead of the `func_decl` or `func_instance` which eventually leads to a panic in `extraFuncCoerced`. Instead, we should pass the uncoerced value to be coerced again. Closes https://github.com/ziglang/zig/issues/23235

2 files changed, 18 insertions(+), 2 deletions(-)

src/InternPool.zig+2-2
...@@ -10165,8 +10165,8 @@ pub fn getCoerced(...@@ -10165,8 +10165,8 @@ pub fn getCoerced(
10165 val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?10165 val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").?
10166 ]);10166 ]);
10167 switch (func.unwrap(ip).getTag(ip)) {10167 switch (func.unwrap(ip).getTag(ip)) {
10168 .func_decl => return getCoercedFuncDecl(ip, gpa, io, tid, val, new_ty),10168 .func_decl => return getCoercedFuncDecl(ip, gpa, io, tid, func, new_ty),
10169 .func_instance => return getCoercedFuncInstance(ip, gpa, io, tid, val, new_ty),10169 .func_instance => return getCoercedFuncInstance(ip, gpa, io, tid, func, new_ty),
10170 else => unreachable,10170 else => unreachable,
10171 }10171 }
10172 },10172 },
test/behavior/cast.zig+16
...@@ -3153,3 +3153,19 @@ test "coerce enum to union with zero-bit fields through local variables" {...@@ -3153,3 +3153,19 @@ test "coerce enum to union with zero-bit fields through local variables" {
31533153
3154 try expect(result == .foo);3154 try expect(result == .foo);
3155}3155}
3156
3157test "coercing a coerced function" {
3158 const S = struct {
3159 fn doTheTest() !void {
3160 const bar: fn (anytype, anytype) void = foo;
3161 higherOrder(1, bar);
3162 }
3163
3164 fn foo(_: anytype, _: void) void {}
3165
3166 fn higherOrder(x: anytype, f: fn (@TypeOf(x), void) void) void {
3167 _ = f(x, {});
3168 }
3169 };
3170 try S.doTheTest();
3171}