| author | |
| committer | |
| log | f205d23e650019dd66120cf122ffb449267f619b |
| tree | 1d7ab12881bcf381ab46dfdf21653fc690ee44fc |
| parent | 69b587c1d389808e55846cadd8eec5b9fd4bc64a |
| signature | Commit is signed but in an unrecognized format. |
this removes the last usage of var args in zig std lib9 files changed, 57 insertions(+), 29 deletions(-)
doc/langref.html.in+3| ... | @@ -6880,6 +6880,9 @@ pub const CallOptions = struct { | ... | @@ -6880,6 +6880,9 @@ pub const CallOptions = struct { |
| 6880 | /// Equivalent to function call syntax. | 6880 | /// Equivalent to function call syntax. |
| 6881 | auto, | 6881 | auto, |
| 6882 | 6882 | ||
| 6883 | /// Equivalent to async keyword used with function call syntax. | ||
| 6884 | async_kw, | ||
| 6885 | |||
| 6883 | /// Prevents tail call optimization. This guarantees that the return | 6886 | /// Prevents tail call optimization. This guarantees that the return |
| 6884 | /// address will point to the callsite, as opposed to the callsite's | 6887 | /// address will point to the callsite, as opposed to the callsite's |
| 6885 | /// callsite. If the call is otherwise required to be tail-called | 6888 | /// callsite. If the call is otherwise required to be tail-called |
lib/std/builtin.zig+3| ... | @@ -382,6 +382,9 @@ pub const CallOptions = struct { | ... | @@ -382,6 +382,9 @@ pub const CallOptions = struct { |
| 382 | /// Equivalent to function call syntax. | 382 | /// Equivalent to function call syntax. |
| 383 | auto, | 383 | auto, |
| 384 | 384 | ||
| 385 | /// Equivalent to async keyword used with function call syntax. | ||
| 386 | async_kw, | ||
| 387 | |||
| 385 | /// Prevents tail call optimization. This guarantees that the return | 388 | /// Prevents tail call optimization. This guarantees that the return |
| 386 | /// address will point to the callsite, as opposed to the callsite's | 389 | /// address will point to the callsite, as opposed to the callsite's |
| 387 | /// callsite. If the call is otherwise required to be tail-called | 390 | /// callsite. If the call is otherwise required to be tail-called |
lib/std/event/group.zig+6-3| ... | @@ -60,16 +60,19 @@ pub fn Group(comptime ReturnType: type) type { | ... | @@ -60,16 +60,19 @@ pub fn Group(comptime ReturnType: type) type { |
| 60 | /// allocated by the group and freed by `wait`. | 60 | /// allocated by the group and freed by `wait`. |
| 61 | /// `func` must be async and have return type `ReturnType`. | 61 | /// `func` must be async and have return type `ReturnType`. |
| 62 | /// Thread-safe. | 62 | /// Thread-safe. |
| 63 | pub fn call(self: *Self, comptime func: var, args: ...) error{OutOfMemory}!void { | 63 | pub fn call(self: *Self, comptime func: var, args: var) error{OutOfMemory}!void { |
| 64 | var frame = try self.allocator.create(@Frame(func)); | 64 | var frame = try self.allocator.create(@typeOf(@call(.{ .modifier = .async_kw }, func, args))); |
| 65 | errdefer self.allocator.destroy(frame); | ||
| 65 | const node = try self.allocator.create(AllocStack.Node); | 66 | const node = try self.allocator.create(AllocStack.Node); |
| 67 | errdefer self.allocator.destroy(node); | ||
| 66 | node.* = AllocStack.Node{ | 68 | node.* = AllocStack.Node{ |
| 67 | .next = undefined, | 69 | .next = undefined, |
| 68 | .data = Node{ | 70 | .data = Node{ |
| 69 | .handle = @asyncCall(frame, {}, func, args), | 71 | .handle = frame, |
| 70 | .bytes = std.mem.asBytes(frame), | 72 | .bytes = std.mem.asBytes(frame), |
| 71 | }, | 73 | }, |
| 72 | }; | 74 | }; |
| 75 | frame.* = @call(.{ .modifier = .async_kw }, func, args); | ||
| 73 | self.alloc_stack.push(node); | 76 | self.alloc_stack.push(node); |
| 74 | } | 77 | } |
| 75 | 78 |
src-self-hosted/compilation.zig+11-11| ... | @@ -778,7 +778,7 @@ pub const Compilation = struct { | ... | @@ -778,7 +778,7 @@ pub const Compilation = struct { |
| 778 | continue; | 778 | continue; |
| 779 | }; | 779 | }; |
| 780 | const root_scope = ev.data; | 780 | const root_scope = ev.data; |
| 781 | group.call(rebuildFile, self, root_scope) catch |err| { | 781 | group.call(rebuildFile, .{ self, root_scope }) catch |err| { |
| 782 | build_result = err; | 782 | build_result = err; |
| 783 | continue; | 783 | continue; |
| 784 | }; | 784 | }; |
| ... | @@ -787,7 +787,7 @@ pub const Compilation = struct { | ... | @@ -787,7 +787,7 @@ pub const Compilation = struct { |
| 787 | while (self.fs_watch.channel.getOrNull()) |ev_or_err| { | 787 | while (self.fs_watch.channel.getOrNull()) |ev_or_err| { |
| 788 | if (ev_or_err) |ev| { | 788 | if (ev_or_err) |ev| { |
| 789 | const root_scope = ev.data; | 789 | const root_scope = ev.data; |
| 790 | group.call(rebuildFile, self, root_scope) catch |err| { | 790 | group.call(rebuildFile, .{ self, root_scope }) catch |err| { |
| 791 | build_result = err; | 791 | build_result = err; |
| 792 | continue; | 792 | continue; |
| 793 | }; | 793 | }; |
| ... | @@ -868,7 +868,7 @@ pub const Compilation = struct { | ... | @@ -868,7 +868,7 @@ pub const Compilation = struct { |
| 868 | 868 | ||
| 869 | // TODO connect existing comptime decls to updated source files | 869 | // TODO connect existing comptime decls to updated source files |
| 870 | 870 | ||
| 871 | try self.prelink_group.call(addCompTimeBlock, self, tree_scope, &decl_scope.base, comptime_node); | 871 | try self.prelink_group.call(addCompTimeBlock, .{ self, tree_scope, &decl_scope.base, comptime_node }); |
| 872 | }, | 872 | }, |
| 873 | .VarDecl => @panic("TODO"), | 873 | .VarDecl => @panic("TODO"), |
| 874 | .FnProto => { | 874 | .FnProto => { |
| ... | @@ -921,7 +921,7 @@ pub const Compilation = struct { | ... | @@ -921,7 +921,7 @@ pub const Compilation = struct { |
| 921 | tree_scope.base.ref(); | 921 | tree_scope.base.ref(); |
| 922 | errdefer self.gpa().destroy(fn_decl); | 922 | errdefer self.gpa().destroy(fn_decl); |
| 923 | 923 | ||
| 924 | try group.call(addTopLevelDecl, self, &fn_decl.base, locked_table); | 924 | try group.call(addTopLevelDecl, .{ self, &fn_decl.base, locked_table }); |
| 925 | } | 925 | } |
| 926 | }, | 926 | }, |
| 927 | .TestDecl => @panic("TODO"), | 927 | .TestDecl => @panic("TODO"), |
| ... | @@ -1042,8 +1042,8 @@ pub const Compilation = struct { | ... | @@ -1042,8 +1042,8 @@ pub const Compilation = struct { |
| 1042 | const is_export = decl.isExported(decl.tree_scope.tree); | 1042 | const is_export = decl.isExported(decl.tree_scope.tree); |
| 1043 | 1043 | ||
| 1044 | if (is_export) { | 1044 | if (is_export) { |
| 1045 | try self.prelink_group.call(verifyUniqueSymbol, self, decl); | 1045 | try self.prelink_group.call(verifyUniqueSymbol, .{ self, decl }); |
| 1046 | try self.prelink_group.call(resolveDecl, self, decl); | 1046 | try self.prelink_group.call(resolveDecl, .{ self, decl }); |
| 1047 | } | 1047 | } |
| 1048 | 1048 | ||
| 1049 | const gop = try locked_table.getOrPut(decl.name); | 1049 | const gop = try locked_table.getOrPut(decl.name); |
| ... | @@ -1062,7 +1062,7 @@ pub const Compilation = struct { | ... | @@ -1062,7 +1062,7 @@ pub const Compilation = struct { |
| 1062 | const msg = try Msg.createFromScope(self, tree_scope, span, text); | 1062 | const msg = try Msg.createFromScope(self, tree_scope, span, text); |
| 1063 | errdefer msg.destroy(); | 1063 | errdefer msg.destroy(); |
| 1064 | 1064 | ||
| 1065 | try self.prelink_group.call(addCompileErrorAsync, self, msg); | 1065 | try self.prelink_group.call(addCompileErrorAsync, .{ self, msg }); |
| 1066 | } | 1066 | } |
| 1067 | 1067 | ||
| 1068 | fn addCompileErrorCli(self: *Compilation, realpath: []const u8, comptime fmt: []const u8, args: var) !void { | 1068 | fn addCompileErrorCli(self: *Compilation, realpath: []const u8, comptime fmt: []const u8, args: var) !void { |
| ... | @@ -1072,7 +1072,7 @@ pub const Compilation = struct { | ... | @@ -1072,7 +1072,7 @@ pub const Compilation = struct { |
| 1072 | const msg = try Msg.createFromCli(self, realpath, text); | 1072 | const msg = try Msg.createFromCli(self, realpath, text); |
| 1073 | errdefer msg.destroy(); | 1073 | errdefer msg.destroy(); |
| 1074 | 1074 | ||
| 1075 | try self.prelink_group.call(addCompileErrorAsync, self, msg); | 1075 | try self.prelink_group.call(addCompileErrorAsync, .{ self, msg }); |
| 1076 | } | 1076 | } |
| 1077 | 1077 | ||
| 1078 | async fn addCompileErrorAsync( | 1078 | async fn addCompileErrorAsync( |
| ... | @@ -1131,7 +1131,7 @@ pub const Compilation = struct { | ... | @@ -1131,7 +1131,7 @@ pub const Compilation = struct { |
| 1131 | 1131 | ||
| 1132 | // get a head start on looking for the native libc | 1132 | // get a head start on looking for the native libc |
| 1133 | if (self.target == Target.Native and self.override_libc == null) { | 1133 | if (self.target == Target.Native and self.override_libc == null) { |
| 1134 | try self.deinit_group.call(startFindingNativeLibC, self); | 1134 | try self.deinit_group.call(startFindingNativeLibC, .{self}); |
| 1135 | } | 1135 | } |
| 1136 | } | 1136 | } |
| 1137 | return link_lib; | 1137 | return link_lib; |
| ... | @@ -1339,8 +1339,8 @@ fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { | ... | @@ -1339,8 +1339,8 @@ fn generateDeclFn(comp: *Compilation, fn_decl: *Decl.Fn) !void { |
| 1339 | 1339 | ||
| 1340 | // Kick off rendering to LLVM module, but it doesn't block the fn decl | 1340 | // Kick off rendering to LLVM module, but it doesn't block the fn decl |
| 1341 | // analysis from being complete. | 1341 | // analysis from being complete. |
| 1342 | try comp.prelink_group.call(codegen.renderToLlvm, comp, fn_val, analyzed_code); | 1342 | try comp.prelink_group.call(codegen.renderToLlvm, .{ comp, fn_val, analyzed_code }); |
| 1343 | try comp.prelink_group.call(addFnToLinkSet, comp, fn_val); | 1343 | try comp.prelink_group.call(addFnToLinkSet, .{ comp, fn_val }); |
| 1344 | } | 1344 | } |
| 1345 | 1345 | ||
| 1346 | async fn addFnToLinkSet(comp: *Compilation, fn_val: *Value.Fn) Compilation.BuildError!void { | 1346 | async fn addFnToLinkSet(comp: *Compilation, fn_val: *Value.Fn) Compilation.BuildError!void { |
src-self-hosted/libc_installation.zig+8-8| ... | @@ -158,9 +158,9 @@ pub const LibCInstallation = struct { | ... | @@ -158,9 +158,9 @@ pub const LibCInstallation = struct { |
| 158 | if (sdk.msvc_lib_dir_ptr != 0) { | 158 | if (sdk.msvc_lib_dir_ptr != 0) { |
| 159 | self.msvc_lib_dir = try std.mem.dupe(allocator, u8, sdk.msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]); | 159 | self.msvc_lib_dir = try std.mem.dupe(allocator, u8, sdk.msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]); |
| 160 | } | 160 | } |
| 161 | try group.call(findNativeKernel32LibDir, allocator, self, sdk); | 161 | try group.call(findNativeKernel32LibDir, .{ allocator, self, sdk }); |
| 162 | try group.call(findNativeIncludeDirWindows, self, allocator, sdk); | 162 | try group.call(findNativeIncludeDirWindows, .{ self, allocator, sdk }); |
| 163 | try group.call(findNativeLibDirWindows, self, allocator, sdk); | 163 | try group.call(findNativeLibDirWindows, .{ self, allocator, sdk }); |
| 164 | }, | 164 | }, |
| 165 | c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, | 165 | c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, |
| 166 | c.ZigFindWindowsSdkError.NotFound => return error.NotFound, | 166 | c.ZigFindWindowsSdkError.NotFound => return error.NotFound, |
| ... | @@ -168,10 +168,10 @@ pub const LibCInstallation = struct { | ... | @@ -168,10 +168,10 @@ pub const LibCInstallation = struct { |
| 168 | } | 168 | } |
| 169 | }, | 169 | }, |
| 170 | .linux => { | 170 | .linux => { |
| 171 | try group.call(findNativeIncludeDirLinux, self, allocator); | 171 | try group.call(findNativeIncludeDirLinux, .{ self, allocator }); |
| 172 | try group.call(findNativeLibDirLinux, self, allocator); | 172 | try group.call(findNativeLibDirLinux, .{ self, allocator }); |
| 173 | try group.call(findNativeStaticLibDir, self, allocator); | 173 | try group.call(findNativeStaticLibDir, .{ self, allocator }); |
| 174 | try group.call(findNativeDynamicLinker, self, allocator); | 174 | try group.call(findNativeDynamicLinker, .{ self, allocator }); |
| 175 | }, | 175 | }, |
| 176 | .macosx, .freebsd, .netbsd => { | 176 | .macosx, .freebsd, .netbsd => { |
| 177 | self.include_dir = try std.mem.dupe(allocator, u8, "/usr/include"); | 177 | self.include_dir = try std.mem.dupe(allocator, u8, "/usr/include"); |
| ... | @@ -322,7 +322,7 @@ pub const LibCInstallation = struct { | ... | @@ -322,7 +322,7 @@ pub const LibCInstallation = struct { |
| 322 | var group = event.Group(FindError!void).init(allocator); | 322 | var group = event.Group(FindError!void).init(allocator); |
| 323 | errdefer group.wait() catch {}; | 323 | errdefer group.wait() catch {}; |
| 324 | for (dyn_tests) |*dyn_test| { | 324 | for (dyn_tests) |*dyn_test| { |
| 325 | try group.call(testNativeDynamicLinker, self, allocator, dyn_test); | 325 | try group.call(testNativeDynamicLinker, .{ self, allocator, dyn_test }); |
| 326 | } | 326 | } |
| 327 | try group.wait(); | 327 | try group.wait(); |
| 328 | for (dyn_tests) |*dyn_test| { | 328 | for (dyn_tests) |*dyn_test| { |
src-self-hosted/main.zig+2-2| ... | @@ -654,7 +654,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { | ... | @@ -654,7 +654,7 @@ fn cmdFmt(allocator: *Allocator, args: []const []const u8) !void { |
| 654 | 654 | ||
| 655 | var group = event.Group(FmtError!void).init(allocator); | 655 | var group = event.Group(FmtError!void).init(allocator); |
| 656 | for (flags.positionals.toSliceConst()) |file_path| { | 656 | for (flags.positionals.toSliceConst()) |file_path| { |
| 657 | try group.call(fmtPath, &fmt, file_path, check_mode); | 657 | try group.call(fmtPath, .{ &fmt, file_path, check_mode }); |
| 658 | } | 658 | } |
| 659 | try group.wait(); | 659 | try group.wait(); |
| 660 | if (fmt.any_error) { | 660 | if (fmt.any_error) { |
| ... | @@ -710,7 +710,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro | ... | @@ -710,7 +710,7 @@ async fn fmtPath(fmt: *Fmt, file_path_ref: []const u8, check_mode: bool) FmtErro |
| 710 | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { | 710 | if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) { |
| 711 | const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); | 711 | const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name }); |
| 712 | @panic("TODO https://github.com/ziglang/zig/issues/3777"); | 712 | @panic("TODO https://github.com/ziglang/zig/issues/3777"); |
| 713 | // try group.call(fmtPath, fmt, full_path, check_mode); | 713 | // try group.call(fmtPath, .{fmt, full_path, check_mode}); |
| 714 | } | 714 | } |
| 715 | } | 715 | } |
| 716 | return group.wait(); | 716 | return group.wait(); |
src/all_types.hpp+1-1| ... | @@ -782,6 +782,7 @@ struct AstNodeUnwrapOptional { | ... | @@ -782,6 +782,7 @@ struct AstNodeUnwrapOptional { |
| 782 | // Must be synchronized with std.builtin.CallOptions.Modifier | 782 | // Must be synchronized with std.builtin.CallOptions.Modifier |
| 783 | enum CallModifier { | 783 | enum CallModifier { |
| 784 | CallModifierNone, | 784 | CallModifierNone, |
| 785 | CallModifierAsync, | ||
| 785 | CallModifierNeverTail, | 786 | CallModifierNeverTail, |
| 786 | CallModifierNeverInline, | 787 | CallModifierNeverInline, |
| 787 | CallModifierNoAsync, | 788 | CallModifierNoAsync, |
| ... | @@ -791,7 +792,6 @@ enum CallModifier { | ... | @@ -791,7 +792,6 @@ enum CallModifier { |
| 791 | 792 | ||
| 792 | // These are additional tags in the compiler, but not exposed in the std lib. | 793 | // These are additional tags in the compiler, but not exposed in the std lib. |
| 793 | CallModifierBuiltin, | 794 | CallModifierBuiltin, |
| 794 | CallModifierAsync, | ||
| 795 | }; | 795 | }; |
| 796 | 796 | ||
| 797 | struct AstNodeFnCallExpr { | 797 | struct AstNodeFnCallExpr { |
src/ir.cpp+1-4| ... | @@ -18330,10 +18330,7 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc | ... | @@ -18330,10 +18330,7 @@ static IrInstruction *ir_analyze_call_extra(IrAnalyze *ira, IrInstruction *sourc |
| 18330 | if (modifier_val == nullptr) | 18330 | if (modifier_val == nullptr) |
| 18331 | return ira->codegen->invalid_instruction; | 18331 | return ira->codegen->invalid_instruction; |
| 18332 | CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); | 18332 | CallModifier modifier = (CallModifier)bigint_as_u32(&modifier_val->data.x_enum_tag); |
| 18333 | if (modifier == CallModifierAsync) { | 18333 | |
| 18334 | ir_add_error(ira, source_instr, buf_sprintf("TODO: @call with async modifier")); | ||
| 18335 | return ira->codegen->invalid_instruction; | ||
| 18336 | } | ||
| 18337 | if (ir_should_inline(ira->new_irb.exec, source_instr->scope)) { | 18334 | if (ir_should_inline(ira->new_irb.exec, source_instr->scope)) { |
| 18338 | switch (modifier) { | 18335 | switch (modifier) { |
| 18339 | case CallModifierBuiltin: | 18336 | case CallModifierBuiltin: |
test/stage1/behavior/async_fn.zig+22| ... | @@ -1271,3 +1271,25 @@ test "spill target expr in a for loop, with a var decl in the loop body" { | ... | @@ -1271,3 +1271,25 @@ test "spill target expr in a for loop, with a var decl in the loop body" { |
| 1271 | resume S.global_frame; | 1271 | resume S.global_frame; |
| 1272 | resume S.global_frame; | 1272 | resume S.global_frame; |
| 1273 | } | 1273 | } |
| 1274 | |||
| 1275 | test "async call with @call" { | ||
| 1276 | const S = struct { | ||
| 1277 | var global_frame: anyframe = undefined; | ||
| 1278 | fn doTheTest() void { | ||
| 1279 | _ = @call(.{ .modifier = .async_kw }, atest, .{}); | ||
| 1280 | resume global_frame; | ||
| 1281 | } | ||
| 1282 | fn atest() void { | ||
| 1283 | var frame = @call(.{ .modifier = .async_kw }, afoo, .{}); | ||
| 1284 | const res = await frame; | ||
| 1285 | expect(res == 42); | ||
| 1286 | } | ||
| 1287 | fn afoo() i32 { | ||
| 1288 | suspend { | ||
| 1289 | global_frame = @frame(); | ||
| 1290 | } | ||
| 1291 | return 42; | ||
| 1292 | } | ||
| 1293 | }; | ||
| 1294 | S.doTheTest(); | ||
| 1295 | } |