From eefcd044628ea080d8fe3346ae4d01e8ed4008e6 Mon Sep 17 00:00:00 2001 From: Alexandros Naskos Date: Wed, 24 Jun 2020 16:56:24 +0300 Subject: [PATCH] Small fixes, fixed tests, added test for argument tuple type --- src/ir.cpp | 15 ++++++++++----- test/compile_errors.zig | 19 ++++++++++++++++--- test/stage1/behavior/async_fn.zig | 26 +++++++++++++------------- 3 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/ir.cpp b/src/ir.cpp index b765ea09f..5f44e5306 100644 --- a/src/ir.cpp +++ b/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(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) { diff --git a/test/compile_errors.zig b/test/compile_errors.zig index e8b7e610e..90c970c84 100644 --- a/test/compile_errors.zig +++ b/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{ diff --git a/test/stage1/behavior/async_fn.zig b/test/stage1/behavior/async_fn.zig index 30df7f64a..4214ed84d 100644 --- a/test/stage1/behavior/async_fn.zig +++ b/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 {