authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-03 01:06:14-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-03 01:06:14-04:00
log24d78177eec4d8fc3aa8ca99dd50788e38f9f8b6
tree14f0b5e36cb4ec2bc68717c6368afeb06a1b857e
parent0920bb087279bdfa317fc88cef877d40ece18239
signature Commit is signed but in an unrecognized format.

add compile error for async call of function pointer


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 function3 * 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 tracing20 * 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
14819static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,14819static 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 }
1482314826
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");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub 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;