| author | |
| committer | |
| log | 24d78177eec4d8fc3aa8ca99dd50788e38f9f8b6 |
| tree | 14f0b5e36cb4ec2bc68717c6368afeb06a1b857e |
| parent | 0920bb087279bdfa317fc88cef877d40ece18239 |
| signature |
4 files changed, 21 insertions(+), 6 deletions(-)
BRANCH_TODO+1-1| ... | @@ -1,4 +1,3 @@ | ... | @@ -1,4 +1,3 @@ |
| 1 | * struct types as the return type of an async function. make sure it works with return result locations. | ||
| 2 | * compile error for error: expected anyframe->T, found 'anyframe' | 1 | * compile error for error: expected anyframe->T, found 'anyframe' |
| 3 | * compile error for error: expected anyframe->T, found 'i32' | 2 | * compile error for error: expected anyframe->T, found 'i32' |
| 4 | * await of a non async function | 3 | * await of a non async function |
| ... | @@ -19,3 +18,4 @@ | ... | @@ -19,3 +18,4 @@ |
| 19 | * make resuming inside a suspend block, with nothing after it, a must-tail call. | 18 | * make resuming inside a suspend block, with nothing after it, a must-tail call. |
| 20 | * make sure there are safety tests for all the new safety features (search the new PanicFnId enum values) | 19 | * make sure there are safety tests for all the new safety features (search the new PanicFnId enum values) |
| 21 | * error return tracing | 20 | * error return tracing |
| 21 | * compile error for casting a function to a non-async function pointer, but then later it gets inferred to be an async function |
src/ir.cpp+4-1| ... | @@ -14819,7 +14819,10 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst | ... | @@ -14819,7 +14819,10 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst |
| 14819 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, | 14819 | static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry, |
| 14820 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count) | 14820 | ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count) |
| 14821 | { | 14821 | { |
| 14822 | ir_assert(fn_entry != nullptr, &call_instruction->base); | 14822 | if (fn_entry == nullptr) { |
| 14823 | ir_add_error(ira, fn_ref, buf_sprintf("function is not comptime-known; @asyncCall required")); | ||
| 14824 | return ira->codegen->invalid_instruction; | ||
| 14825 | } | ||
| 14823 | 14826 | ||
| 14824 | ZigType *frame_type = get_coro_frame_type(ira->codegen, fn_entry); | 14827 | ZigType *frame_type = get_coro_frame_type(ira->codegen, fn_entry); |
| 14825 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, | 14828 | IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc, |
test/compile_errors.zig+12| ... | @@ -2,6 +2,18 @@ const tests = @import("tests.zig"); | ... | @@ -2,6 +2,18 @@ const tests = @import("tests.zig"); |
| 2 | const builtin = @import("builtin"); | 2 | const builtin = @import("builtin"); |
| 3 | 3 | ||
| 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { | 4 | pub fn addCases(cases: *tests.CompileErrorContext) void { |
| 5 | cases.add( | ||
| 6 | "runtime-known function called with async keyword", | ||
| 7 | \\export fn entry() void { | ||
| 8 | \\ var ptr = afunc; | ||
| 9 | \\ _ = async ptr(); | ||
| 10 | \\} | ||
| 11 | \\ | ||
| 12 | \\async fn afunc() void { } | ||
| 13 | , | ||
| 14 | "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required", | ||
| 15 | ); | ||
| 16 | |||
| 5 | cases.add( | 17 | cases.add( |
| 6 | "function with ccc indirectly calling async function", | 18 | "function with ccc indirectly calling async function", |
| 7 | \\export fn entry() void { | 19 | \\export fn entry() void { |
test/stage1/behavior/coroutines.zig+4-4| ... | @@ -263,15 +263,15 @@ test "async function with dot syntax" { | ... | @@ -263,15 +263,15 @@ test "async function with dot syntax" { |
| 263 | //test "async fn pointer in a struct field" { | 263 | //test "async fn pointer in a struct field" { |
| 264 | // var data: i32 = 1; | 264 | // var data: i32 = 1; |
| 265 | // const Foo = struct { | 265 | // const Foo = struct { |
| 266 | // bar: async<*std.mem.Allocator> fn (*i32) void, | 266 | // bar: async fn (*i32) void, |
| 267 | // }; | 267 | // }; |
| 268 | // var foo = Foo{ .bar = simpleAsyncFn2 }; | 268 | // var foo = Foo{ .bar = simpleAsyncFn2 }; |
| 269 | // const p = (async<allocator> foo.bar(&data)) catch unreachable; | 269 | // const p = async foo.bar(&data); |
| 270 | // expect(data == 2); | 270 | // expect(data == 2); |
| 271 | // cancel p; | 271 | // resume p; |
| 272 | // expect(data == 4); | 272 | // expect(data == 4); |
| 273 | //} | 273 | //} |
| 274 | //async<*std.mem.Allocator> fn simpleAsyncFn2(y: *i32) void { | 274 | //async fn simpleAsyncFn2(y: *i32) void { |
| 275 | // defer y.* += 2; | 275 | // defer y.* += 2; |
| 276 | // y.* += 1; | 276 | // y.* += 1; |
| 277 | // suspend; | 277 | // suspend; |