authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-20 17:32:04+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-20 17:32:04+02:00
log6da070c5ac1707f2f5370e2e26124a3e114e25ea
tree44f8f0a52f0089b644eccf4f3f61f6abdd45fe10
parent6511afcfe090f26345873e7e8db3ae301f8a18a7

Sema: fix crash with generic function with generic function parameter

Closes #12810

2 files changed, 23 insertions(+), 0 deletions(-)

src/Sema.zig+11
...@@ -7256,6 +7256,7 @@ fn instantiateGenericCall(...@@ -7256,6 +7256,7 @@ fn instantiateGenericCall(
7256 child_block.error_return_trace_index = error_return_trace_index;7256 child_block.error_return_trace_index = error_return_trace_index;
72577257
7258 const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body, fn_info.param_body_inst) catch |err| {7258 const new_func_inst = child_sema.resolveBody(&child_block, fn_info.param_body, fn_info.param_body_inst) catch |err| {
7259 if (err == error.GenericPoison) return error.GenericPoison;
7259 // TODO look up the compile error that happened here and attach a note to it7260 // TODO look up the compile error that happened here and attach a note to it
7260 // pointing here, at the generic instantiation callsite.7261 // pointing here, at the generic instantiation callsite.
7261 if (sema.owner_func) |owner_func| {7262 if (sema.owner_func) |owner_func| {
...@@ -8864,6 +8865,11 @@ fn zirParam(...@@ -8864,6 +8865,11 @@ fn zirParam(
8864 };8865 };
8865 switch (err) {8866 switch (err) {
8866 error.GenericPoison => {8867 error.GenericPoison => {
8868 if (sema.inst_map.get(inst)) |_| {
8869 // A generic function is about to evaluate to another generic function.
8870 // Return an error instead.
8871 return error.GenericPoison;
8872 }
8867 // The type is not available until the generic instantiation.8873 // The type is not available until the generic instantiation.
8868 // We result the param instruction with a poison value and8874 // We result the param instruction with a poison value and
8869 // insert an anytype parameter.8875 // insert an anytype parameter.
...@@ -8880,6 +8886,11 @@ fn zirParam(...@@ -8880,6 +8886,11 @@ fn zirParam(
8880 };8886 };
8881 const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) {8887 const is_comptime = sema.typeRequiresComptime(param_ty) catch |err| switch (err) {
8882 error.GenericPoison => {8888 error.GenericPoison => {
8889 if (sema.inst_map.get(inst)) |_| {
8890 // A generic function is about to evaluate to another generic function.
8891 // Return an error instead.
8892 return error.GenericPoison;
8893 }
8883 // The type is not available until the generic instantiation.8894 // The type is not available until the generic instantiation.
8884 // We result the param instruction with a poison value and8895 // We result the param instruction with a poison value and
8885 // insert an anytype parameter.8896 // insert an anytype parameter.
test/behavior/call.zig+12
...@@ -369,3 +369,15 @@ test "Enum constructed by @Type passed as generic argument" {...@@ -369,3 +369,15 @@ test "Enum constructed by @Type passed as generic argument" {
369 try S.foo(@intToEnum(S.E, i), i);369 try S.foo(@intToEnum(S.E, i), i);
370 }370 }
371}371}
372
373test "generic function with generic function parameter" {
374 const S = struct {
375 fn f(comptime a: fn (anytype) anyerror!void, b: anytype) anyerror!void {
376 try a(b);
377 }
378 fn g(a: anytype) anyerror!void {
379 try expect(a == 123);
380 }
381 };
382 try S.f(S.g, 123);
383}