Commit 1afbb53661

Andrew Kelley <andrew@ziglang.org>
2019-08-07 01:07:25
fix awaiting when result type is a struct
1 parent 966c9ea
Changed files (5)
src/codegen.cpp
@@ -2300,9 +2300,8 @@ static LLVMValueRef ir_render_return_begin(CodeGen *g, IrExecutable *executable,
 static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrInstructionReturn *instruction) {
     if (fn_is_async(g->cur_fn)) {
         LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type;
-        bool ret_type_has_bits = instruction->operand != nullptr &&
-            type_has_bits(instruction->operand->value.type);
-        ZigType *ret_type = ret_type_has_bits ? instruction->operand->value.type : nullptr;
+        ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type;
+        bool ret_type_has_bits = type_has_bits(ret_type);
 
         if (ir_want_runtime_safety(g, &instruction->base)) {
             LLVMValueRef new_resume_index = LLVMConstAllOnes(usize_type_ref);
test/stage1/behavior/cancel.zig
@@ -1,86 +1,86 @@
 const std = @import("std");
 
-var defer_f1: bool = false;
-var defer_f2: bool = false;
-var defer_f3: bool = false;
-
-test "cancel forwards" {
-    const p = async<std.heap.direct_allocator> f1() catch unreachable;
-    cancel p;
-    std.testing.expect(defer_f1);
-    std.testing.expect(defer_f2);
-    std.testing.expect(defer_f3);
-}
-
-async fn f1() void {
-    defer {
-        defer_f1 = true;
-    }
-    await (async f2() catch unreachable);
-}
-
-async fn f2() void {
-    defer {
-        defer_f2 = true;
-    }
-    await (async f3() catch unreachable);
-}
-
-async fn f3() void {
-    defer {
-        defer_f3 = true;
-    }
-    suspend;
-}
-
-var defer_b1: bool = false;
-var defer_b2: bool = false;
-var defer_b3: bool = false;
-var defer_b4: bool = false;
-
-test "cancel backwards" {
-    const p = async<std.heap.direct_allocator> b1() catch unreachable;
-    cancel p;
-    std.testing.expect(defer_b1);
-    std.testing.expect(defer_b2);
-    std.testing.expect(defer_b3);
-    std.testing.expect(defer_b4);
-}
-
-async fn b1() void {
-    defer {
-        defer_b1 = true;
-    }
-    await (async b2() catch unreachable);
-}
-
-var b4_handle: promise = undefined;
-
-async fn b2() void {
-    const b3_handle = async b3() catch unreachable;
-    resume b4_handle;
-    cancel b4_handle;
-    defer {
-        defer_b2 = true;
-    }
-    const value = await b3_handle;
-    @panic("unreachable");
-}
-
-async fn b3() i32 {
-    defer {
-        defer_b3 = true;
-    }
-    await (async b4() catch unreachable);
-    return 1234;
-}
-
-async fn b4() void {
-    defer {
-        defer_b4 = true;
-    }
-    suspend {
-        b4_handle = @handle();
-    }
-    suspend;
-}
+//var defer_f1: bool = false;
+//var defer_f2: bool = false;
+//var defer_f3: bool = false;
+//
+//test "cancel forwards" {
+//    const p = async<std.heap.direct_allocator> f1() catch unreachable;
+//    cancel p;
+//    std.testing.expect(defer_f1);
+//    std.testing.expect(defer_f2);
+//    std.testing.expect(defer_f3);
+//}
+//
+//async fn f1() void {
+//    defer {
+//        defer_f1 = true;
+//    }
+//    await (async f2() catch unreachable);
+//}
+//
+//async fn f2() void {
+//    defer {
+//        defer_f2 = true;
+//    }
+//    await (async f3() catch unreachable);
+//}
+//
+//async fn f3() void {
+//    defer {
+//        defer_f3 = true;
+//    }
+//    suspend;
+//}
+//
+//var defer_b1: bool = false;
+//var defer_b2: bool = false;
+//var defer_b3: bool = false;
+//var defer_b4: bool = false;
+//
+//test "cancel backwards" {
+//    const p = async<std.heap.direct_allocator> b1() catch unreachable;
+//    cancel p;
+//    std.testing.expect(defer_b1);
+//    std.testing.expect(defer_b2);
+//    std.testing.expect(defer_b3);
+//    std.testing.expect(defer_b4);
+//}
+//
+//async fn b1() void {
+//    defer {
+//        defer_b1 = true;
+//    }
+//    await (async b2() catch unreachable);
+//}
+//
+//var b4_handle: promise = undefined;
+//
+//async fn b2() void {
+//    const b3_handle = async b3() catch unreachable;
+//    resume b4_handle;
+//    cancel b4_handle;
+//    defer {
+//        defer_b2 = true;
+//    }
+//    const value = await b3_handle;
+//    @panic("unreachable");
+//}
+//
+//async fn b3() i32 {
+//    defer {
+//        defer_b3 = true;
+//    }
+//    await (async b4() catch unreachable);
+//    return 1234;
+//}
+//
+//async fn b4() void {
+//    defer {
+//        defer_b4 = true;
+//    }
+//    suspend {
+//        b4_handle = @handle();
+//    }
+//    suspend;
+//}
test/stage1/behavior/coroutines.zig
@@ -474,3 +474,36 @@ test "suspension points inside branching control flow" {
     };
     S.doTheTest();
 }
+
+test "call async function which has struct return type" {
+    const S = struct {
+        var frame: anyframe = undefined;
+
+        fn doTheTest() void {
+            _ = async atest();
+            resume frame;
+        }
+
+        fn atest() void {
+            const result = func();
+            expect(result.x == 5);
+            expect(result.y == 6);
+        }
+
+        const Point = struct {
+            x: usize,
+            y: usize,
+        };
+
+        fn func() Point {
+            suspend {
+                frame = @frame();
+            }
+            return Point{
+                .x = 5,
+                .y = 6,
+            };
+        }
+    };
+    S.doTheTest();
+}
test/stage1/behavior.zig
@@ -39,10 +39,10 @@ comptime {
     _ = @import("behavior/bugs/828.zig");
     _ = @import("behavior/bugs/920.zig");
     _ = @import("behavior/byval_arg_var.zig");
-    //_ = @import("behavior/cancel.zig");
+    _ = @import("behavior/cancel.zig");
     _ = @import("behavior/cast.zig");
     _ = @import("behavior/const_slice_child.zig");
-    //_ = @import("behavior/coroutine_await_struct.zig");
+    _ = @import("behavior/coroutine_await_struct.zig");
     _ = @import("behavior/coroutines.zig");
     _ = @import("behavior/defer.zig");
     _ = @import("behavior/enum.zig");
BRANCH_TODO
@@ -1,5 +1,4 @@
- * error return tracing - handle `await` and function calls
- * go over the commented out tests
+ * go over the commented out tests in cancel.zig
  * compile error for error: expected anyframe->T, found 'anyframe'
  * compile error for error: expected anyframe->T, found 'i32'
  * await of a non async function