Commit eefcd04462

Alexandros Naskos <alex_naskos@hotmail.com>
2020-06-24 15:56:24
Small fixes, fixed tests, added test for argument tuple type
1 parent 50b70bd
Changed files (3)
src
test
src/ir.cpp
@@ -6260,7 +6260,7 @@ static IrInstSrc *ir_gen_async_call(IrBuilderSrc *irb, Scope *scope, AstNode *aw
     if (args == irb->codegen->invalid_inst_src)
         return args;
 
-    IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, bytes, ret_ptr, args, result_loc);
+    IrInstSrc *call = ir_build_async_call_extra(irb, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc);
     return ir_lval_wrap(irb, scope, call, lval, result_loc);
 }
 
@@ -20277,7 +20277,7 @@ static IrInstGen *ir_analyze_fn_call(IrAnalyze *ira, IrInst* source_instr,
         // Fork a scope of the function with known values for the parameters.
         Scope *parent_scope = fn_entry->fndef_scope->base.parent;
         ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node);
-        
+        impl_fn->param_source_nodes = heap::c_allocator.allocate<AstNode *>(new_fn_arg_count);
         buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name);
         impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn);
         impl_fn->child_scope = &impl_fn->fndef_scope->base;
@@ -20772,11 +20772,17 @@ static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_ins
             return ira->codegen->invalid_inst_gen;
     }
 
+    IrInstGen *first_arg_ptr = nullptr;
+    IrInst *first_arg_ptr_src = nullptr;
     ZigFn *fn = nullptr;
     if (instr_is_comptime(fn_ref)) {
         if (fn_ref->value->type->id == ZigTypeIdBoundFn) {
             assert(fn_ref->value->special == ConstValSpecialStatic);
             fn = fn_ref->value->data.x_bound_fn.fn;
+            first_arg_ptr = fn_ref->value->data.x_bound_fn.first_arg;
+            first_arg_ptr_src = fn_ref->value->data.x_bound_fn.first_arg_src;
+            if (type_is_invalid(first_arg_ptr->value->type))
+                return ira->codegen->invalid_inst_gen;
         } else {
             fn = ir_resolve_fn(ira, fn_ref);
         }
@@ -20795,9 +20801,8 @@ static IrInstGen *ir_analyze_async_call_extra(IrAnalyze *ira, IrInst* source_ins
     if (casted_new_stack != nullptr && type_is_invalid(casted_new_stack->value->type))
         return ira->codegen->invalid_inst_gen;
 
-    IrInstGen *result =  ir_analyze_async_call(ira, source_instr, fn, fn_type, fn_ref, args_ptr, args_len,
-        casted_new_stack, true, ret_ptr_uncasted, result_loc);
-    return ir_finish_anal(ira, result);
+    return ir_analyze_fn_call(ira, source_instr, fn, fn_type, fn_ref, first_arg_ptr, first_arg_ptr_src,
+        modifier, casted_new_stack, &new_stack->base, true, args_ptr, args_len, ret_ptr_uncasted, result_loc);
 }
 
 static bool ir_extract_tuple_call_args(IrAnalyze *ira, IrInst *source_instr, IrInstGen *args, IrInstGen ***args_ptr, size_t *args_len) {
test/stage1/behavior/async_fn.zig
@@ -282,7 +282,7 @@ test "async fn pointer in a struct field" {
     };
     var foo = Foo{ .bar = simpleAsyncFn2 };
     var bytes: [64]u8 align(16) = undefined;
-    const f = @asyncCall(&bytes, {}, foo.bar, &data);
+    const f = @asyncCall(&bytes, {}, foo.bar, .{&data});
     comptime expect(@TypeOf(f) == anyframe->void);
     expect(data == 2);
     resume f;
@@ -318,7 +318,7 @@ test "@asyncCall with return type" {
     var foo = Foo{ .bar = Foo.middle };
     var bytes: [150]u8 align(16) = undefined;
     var aresult: i32 = 0;
-    _ = @asyncCall(&bytes, &aresult, foo.bar);
+    _ = @asyncCall(&bytes, &aresult, foo.bar, .{});
     expect(aresult == 0);
     resume Foo.global_frame;
     expect(aresult == 1234);
@@ -332,7 +332,7 @@ test "async fn with inferred error set" {
             var frame: [1]@Frame(middle) = undefined;
             var fn_ptr = middle;
             var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;
-            _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr);
+            _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr, .{});
             resume global_frame;
             std.testing.expectError(error.Fail, result);
         }
@@ -827,7 +827,7 @@ test "cast fn to async fn when it is inferred to be async" {
             ptr = func;
             var buf: [100]u8 align(16) = undefined;
             var result: i32 = undefined;
-            const f = @asyncCall(&buf, &result, ptr);
+            const f = @asyncCall(&buf, &result, ptr, .{});
             _ = await f;
             expect(result == 1234);
             ok = true;
@@ -855,7 +855,7 @@ test "cast fn to async fn when it is inferred to be async, awaited directly" {
             ptr = func;
             var buf: [100]u8 align(16) = undefined;
             var result: i32 = undefined;
-            _ = await @asyncCall(&buf, &result, ptr);
+            _ = await @asyncCall(&buf, &result, ptr, .{});
             expect(result == 1234);
             ok = true;
         }
@@ -951,7 +951,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
         fn doTheTest() void {
             var frame: [1]@Frame(middle) = undefined;
             var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;
-            _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle);
+            _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle, .{});
             resume global_frame;
             std.testing.expectError(error.Fail, result);
         }
@@ -982,7 +982,7 @@ test "@asyncCall with actual frame instead of byte buffer" {
     };
     var frame: @Frame(S.func) = undefined;
     var result: i32 = undefined;
-    const ptr = @asyncCall(&frame, &result, S.func);
+    const ptr = @asyncCall(&frame, &result, S.func, .{});
     resume ptr;
     expect(result == 1234);
 }
@@ -1005,7 +1005,7 @@ test "@asyncCall using the result location inside the frame" {
     };
     var foo = Foo{ .bar = S.simple2 };
     var bytes: [64]u8 align(16) = undefined;
-    const f = @asyncCall(&bytes, {}, foo.bar, &data);
+    const f = @asyncCall(&bytes, {}, foo.bar, .{&data});
     comptime expect(@TypeOf(f) == anyframe->i32);
     expect(data == 2);
     resume f;
@@ -1042,7 +1042,7 @@ test "using @TypeOf on a generic function call" {
             }
             const F = @TypeOf(async amain(x - 1));
             const frame = @intToPtr(*F, @ptrToInt(&buf));
-            return await @asyncCall(frame, {}, amain, x - 1);
+            return await @asyncCall(frame, {}, amain, .{x - 1});
         }
     };
     _ = async S.amain(@as(u32, 1));
@@ -1067,7 +1067,7 @@ test "recursive call of await @asyncCall with struct return type" {
             }
             const F = @TypeOf(async amain(x - 1));
             const frame = @intToPtr(*F, @ptrToInt(&buf));
-            return await @asyncCall(frame, {}, amain, x - 1);
+            return await @asyncCall(frame, {}, amain, .{x - 1});
         }
 
         const Foo = struct {
@@ -1078,7 +1078,7 @@ test "recursive call of await @asyncCall with struct return type" {
     };
     var res: S.Foo = undefined;
     var frame: @TypeOf(async S.amain(@as(u32, 1))) = undefined;
-    _ = @asyncCall(&frame, &res, S.amain, @as(u32, 1));
+    _ = @asyncCall(&frame, &res, S.amain, .{@as(u32, 1)});
     resume S.global_frame;
     expect(S.global_ok);
     expect(res.x == 1);
@@ -1377,7 +1377,7 @@ test "async function call resolves target fn frame, comptime func" {
         fn foo() anyerror!void {
             const stack_size = 1000;
             var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;
-            return await @asyncCall(&stack_frame, {}, bar);
+            return await @asyncCall(&stack_frame, {}, bar, .{});
         }
 
         fn bar() anyerror!void {
@@ -1400,7 +1400,7 @@ test "async function call resolves target fn frame, runtime func" {
             const stack_size = 1000;
             var stack_frame: [stack_size]u8 align(std.Target.stack_align) = undefined;
             var func: fn () callconv(.Async) anyerror!void = bar;
-            return await @asyncCall(&stack_frame, {}, func);
+            return await @asyncCall(&stack_frame, {}, func, .{});
         }
 
         fn bar() anyerror!void {
test/compile_errors.zig
@@ -1144,13 +1144,26 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         "tmp.zig:2:15: error: @Type not available for 'TypeInfo.Struct'",
     });
 
+    cases.add("wrong type for argument tuple to @asyncCall",
+        \\export fn entry1() void {
+        \\    var frame: @Frame(foo) = undefined;
+        \\    @asyncCall(&frame, {}, foo, {});
+        \\}
+        \\
+        \\fn foo() i32 {
+        \\    return 0;
+        \\}
+    , &[_][]const u8{
+        "tmp.zig:3:33: error: expected tuple or struct, found 'void'",
+    });
+
     cases.add("wrong type for result ptr to @asyncCall",
         \\export fn entry() void {
         \\    _ = async amain();
         \\}
         \\fn amain() i32 {
         \\    var frame: @Frame(foo) = undefined;
-        \\    return await @asyncCall(&frame, false, foo);
+        \\    return await @asyncCall(&frame, false, foo, .{});
         \\}
         \\fn foo() i32 {
         \\    return 1234;
@@ -1291,7 +1304,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\export fn entry() void {
         \\    var ptr: fn () callconv(.Async) void = func;
         \\    var bytes: [64]u8 = undefined;
-        \\    _ = @asyncCall(&bytes, {}, ptr);
+        \\    _ = @asyncCall(&bytes, {}, ptr, .{});
         \\}
         \\fn func() callconv(.Async) void {}
     , &[_][]const u8{
@@ -1467,7 +1480,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
         \\export fn entry() void {
         \\    var ptr = afunc;
         \\    var bytes: [100]u8 align(16) = undefined;
-        \\    _ = @asyncCall(&bytes, {}, ptr);
+        \\    _ = @asyncCall(&bytes, {}, ptr, .{});
         \\}
         \\fn afunc() void { }
     , &[_][]const u8{