diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-12-20 17:32:04 +0200 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-12-20 17:32:04 +0200 |
| commit | 6da070c5ac1707f2f5370e2e26124a3e114e25ea (patch) | |
| tree | 44f8f0a52f0089b644eccf4f3f61f6abdd45fe10 | |
| parent | 6511afcfe090f26345873e7e8db3ae301f8a18a7 (diff) | |
| download | zig-6da070c5ac1707f2f5370e2e26124a3e114e25ea.tar.gz zig-6da070c5ac1707f2f5370e2e26124a3e114e25ea.zip | |
Sema: fix crash with generic function with generic function parameter
Closes #12810
| -rw-r--r-- | src/Sema.zig | 11 | ||||
| -rw-r--r-- | test/behavior/call.zig | 12 |
2 files changed, 23 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index f068018ddb..9de6945fc5 100644 --- 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 index a8d0d40751..4addd93227 100644 --- 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); +} |
