Commit 24d78177ee

Andrew Kelley <andrew@ziglang.org>
2019-08-03 07:06:14
add compile error for async call of function pointer
1 parent 0920bb0
Changed files (4)
src/ir.cpp
@@ -14819,7 +14819,10 @@ static IrInstruction *ir_analyze_instruction_reset_result(IrAnalyze *ira, IrInst
 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc *call_instruction, ZigFn *fn_entry,
         ZigType *fn_type, IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count)
 {
-    ir_assert(fn_entry != nullptr, &call_instruction->base);
+    if (fn_entry == nullptr) {
+        ir_add_error(ira, fn_ref, buf_sprintf("function is not comptime-known; @asyncCall required"));
+        return ira->codegen->invalid_instruction;
+    }
 
     ZigType *frame_type = get_coro_frame_type(ira->codegen, fn_entry);
     IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
test/stage1/behavior/coroutines.zig
@@ -263,15 +263,15 @@ test "async function with dot syntax" {
 //test "async fn pointer in a struct field" {
 //    var data: i32 = 1;
 //    const Foo = struct {
-//        bar: async<*std.mem.Allocator> fn (*i32) void,
+//        bar: async fn (*i32) void,
 //    };
 //    var foo = Foo{ .bar = simpleAsyncFn2 };
-//    const p = (async<allocator> foo.bar(&data)) catch unreachable;
+//    const p = async foo.bar(&data);
 //    expect(data == 2);
-//    cancel p;
+//    resume p;
 //    expect(data == 4);
 //}
-//async<*std.mem.Allocator> fn simpleAsyncFn2(y: *i32) void {
+//async fn simpleAsyncFn2(y: *i32) void {
 //    defer y.* += 2;
 //    y.* += 1;
 //    suspend;
test/compile_errors.zig
@@ -2,6 +2,18 @@ const tests = @import("tests.zig");
 const builtin = @import("builtin");
 
 pub fn addCases(cases: *tests.CompileErrorContext) void {
+    cases.add(
+        "runtime-known function called with async keyword",
+        \\export fn entry() void {
+        \\    var ptr = afunc;
+        \\    _ = async ptr();
+        \\}
+        \\
+        \\async fn afunc() void { }
+    ,
+        "tmp.zig:3:15: error: function is not comptime-known; @asyncCall required",
+    );
+
     cases.add(
         "function with ccc indirectly calling async function",
         \\export fn entry() void {
BRANCH_TODO
@@ -1,4 +1,3 @@
- * struct types as the return type of an async function. make sure it works with return result locations.
  * compile error for error: expected anyframe->T, found 'anyframe'
  * compile error for error: expected anyframe->T, found 'i32'
  * await of a non async function
@@ -19,3 +18,4 @@
  * make resuming inside a suspend block, with nothing after it, a must-tail call.
  * make sure there are safety tests for all the new safety features (search the new PanicFnId enum values)
  * error return tracing
+ * compile error for casting a function to a non-async function pointer, but then later it gets inferred to be an async function