zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit 6da070c5ac1707f2f5370e2e26124a3e114e25ea (tree)
parent 6511afcfe090f26345873e7e8db3ae301f8a18a7
Author: Veikka Tuominen <git@vexu.eu>
Date:   Tue, 20 Dec 2022 17:32:04 +0200

Sema: fix crash with generic function with generic function parameter

Closes #12810

Diffstat:
Msrc/Sema.zig | 11+++++++++++
Mtest/behavior/call.zig | 12++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/src/Sema.zig b/src/Sema.zig @@ -7256,6 +7256,7 @@ fn instantiateGenericCall( child_block.error_return_trace_index = error_return_trace_index; const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body, fn_info.param_body_inst) catch |err| { + if (err == error.GenericPoison) return error.GenericPoison; // TODO look up the compile error that happened here and attach a note to it // pointing here, at the generic instantiation callsite. if (sema.owner_func) |owner_func| { @@ -8864,6 +8865,11 @@ fn zirParam( }; switch (err) { error.GenericPoison => { + if (sema.inst_map.get(inst)) |_| { + // A generic function is about to evaluate to another generic function. + // Return an error instead. + return error.GenericPoison; + } // The type is not available until the generic instantiation. // We result the param instruction with a poison value and // insert an anytype parameter. @@ -8880,6 +8886,11 @@ fn zirParam( }; const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) { error.GenericPoison => { + if (sema.inst_map.get(inst)) |_| { + // A generic function is about to evaluate to another generic function. + // Return an error instead. + return error.GenericPoison; + } // The type is not available until the generic instantiation. // We result the param instruction with a poison value and // insert an anytype parameter. diff --git a/test/behavior/call.zig b/test/behavior/call.zig @@ -369,3 +369,15 @@ test "Enum constructed by @Type passed as generic argument" { try S.foo(@intToEnum(S.E, i), i); } } + +test "generic function with generic function parameter" { + const S = struct { + fn f(comptime a: fn (anytype) anyerror!void, b: anytype) anyerror!void { + try a(b); + } + fn g(a: anytype) anyerror!void { + try expect(a == 123); + } + }; + try S.f(S.g, 123); +}