| author | |
| committer | |
| log | 9b5851f0019c6cf2b5a54ffa54acd7f13b941a07 |
| tree | 915cd5bce518687f907df71b6b44eff22952bece |
| parent | 1581601ffa1fe36f579c81fb5c774f99dbc20942 |
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/232352 files changed, 18 insertions(+), 2 deletions(-)
src/InternPool.zig+2-2| ... | ... | @@ -10165,8 +10165,8 @@ pub fn getCoerced( |
| 10165 | 10165 | val_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").? |
| 10166 | 10166 | ]); |
| 10167 | 10167 | switch (func.unwrap(ip).getTag(ip)) { |
| 10168 | .func_decl => return getCoercedFuncDecl(ip, gpa, io, tid, val, new_ty), | |
| 10169 | .func_instance => return getCoercedFuncInstance(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, func, new_ty), | |
| 10170 | 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 | 3153 | |
| 3154 | 3154 | try expect(result == .foo); |
| 3155 | 3155 | } |
| 3156 | ||
| 3157 | test "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 | } |