authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-14 06:31:13-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-04-24 11:48:37-04:00
log79cc29e23886c7996cdc5fb0036f2cdec163d9b6
tree91e87ed551387fe279516a7f4860e77ceb8e443c
parent221fb30b3c961f81e99bfe9b25db8460e6231824

std: experiment with using restricted function pointers in vtables


9 files changed, 204 insertions(+), 197 deletions(-)

lib/std/Io.zig+145-135
...@@ -58,7 +58,7 @@ pub const VTable = struct {...@@ -58,7 +58,7 @@ pub const VTable = struct {
58 /// a unit of concurrency has been assigned to the returned task.58 /// a unit of concurrency has been assigned to the returned task.
59 ///59 ///
60 /// Thread-safe.60 /// Thread-safe.
61 async: *const fn (61 async: @Restricted(*const fn (
62 /// Corresponds to `Io.userdata`.62 /// Corresponds to `Io.userdata`.
63 userdata: ?*anyopaque,63 userdata: ?*anyopaque,
64 /// The pointer of this slice is an "eager" result value.64 /// The pointer of this slice is an "eager" result value.
...@@ -69,10 +69,10 @@ pub const VTable = struct {...@@ -69,10 +69,10 @@ pub const VTable = struct {
69 /// Copied and then passed to `start`.69 /// Copied and then passed to `start`.
70 context: []const u8,70 context: []const u8,
71 context_alignment: std.mem.Alignment,71 context_alignment: std.mem.Alignment,
72 start: *const fn (context: *const anyopaque, result: *anyopaque) void,72 start: AnyFuture.Start,
73 ) ?*AnyFuture,73 ) ?*AnyFuture),
74 /// Thread-safe.74 /// Thread-safe.
75 concurrent: *const fn (75 concurrent: @Restricted(*const fn (
76 /// Corresponds to `Io.userdata`.76 /// Corresponds to `Io.userdata`.
77 userdata: ?*anyopaque,77 userdata: ?*anyopaque,
78 result_len: usize,78 result_len: usize,
...@@ -80,12 +80,12 @@ pub const VTable = struct {...@@ -80,12 +80,12 @@ pub const VTable = struct {
80 /// Copied and then passed to `start`.80 /// Copied and then passed to `start`.
81 context: []const u8,81 context: []const u8,
82 context_alignment: std.mem.Alignment,82 context_alignment: std.mem.Alignment,
83 start: *const fn (context: *const anyopaque, result: *anyopaque) void,83 start: AnyFuture.Start,
84 ) ConcurrentError!*AnyFuture,84 ) ConcurrentError!*AnyFuture),
85 /// This function is only called when `async` returns a non-null value.85 /// This function is only called when `async` returns a non-null value.
86 ///86 ///
87 /// Thread-safe.87 /// Thread-safe.
88 await: *const fn (88 await: @Restricted(*const fn (
89 /// Corresponds to `Io.userdata`.89 /// Corresponds to `Io.userdata`.
90 userdata: ?*anyopaque,90 userdata: ?*anyopaque,
91 /// The same value that was returned from `async`.91 /// The same value that was returned from `async`.
...@@ -94,13 +94,13 @@ pub const VTable = struct {...@@ -94,13 +94,13 @@ pub const VTable = struct {
94 /// The length is equal to size in bytes of result type.94 /// The length is equal to size in bytes of result type.
95 result: []u8,95 result: []u8,
96 result_alignment: std.mem.Alignment,96 result_alignment: std.mem.Alignment,
97 ) void,97 ) void),
98 /// Equivalent to `await` but initiates cancel request.98 /// Equivalent to `await` but initiates cancel request.
99 ///99 ///
100 /// This function is only called when `async` returns a non-null value.100 /// This function is only called when `async` returns a non-null value.
101 ///101 ///
102 /// Thread-safe.102 /// Thread-safe.
103 cancel: *const fn (103 cancel: @Restricted(*const fn (
104 /// Corresponds to `Io.userdata`.104 /// Corresponds to `Io.userdata`.
105 userdata: ?*anyopaque,105 userdata: ?*anyopaque,
106 /// The same value that was returned from `async`.106 /// The same value that was returned from `async`.
...@@ -109,14 +109,14 @@ pub const VTable = struct {...@@ -109,14 +109,14 @@ pub const VTable = struct {
109 /// The length is equal to size in bytes of result type.109 /// The length is equal to size in bytes of result type.
110 result: []u8,110 result: []u8,
111 result_alignment: std.mem.Alignment,111 result_alignment: std.mem.Alignment,
112 ) void,112 ) void),
113113
114 /// When this function returns, implementation guarantees that `start` has114 /// When this function returns, implementation guarantees that `start` has
115 /// either already been called, or a unit of concurrency has been assigned115 /// either already been called, or a unit of concurrency has been assigned
116 /// to the task of calling the function.116 /// to the task of calling the function.
117 ///117 ///
118 /// Thread-safe.118 /// Thread-safe.
119 groupAsync: *const fn (119 groupAsync: @Restricted(*const fn (
120 /// Corresponds to `Io.userdata`.120 /// Corresponds to `Io.userdata`.
121 userdata: ?*anyopaque,121 userdata: ?*anyopaque,
122 /// Owner of the spawned async task.122 /// Owner of the spawned async task.
...@@ -124,10 +124,10 @@ pub const VTable = struct {...@@ -124,10 +124,10 @@ pub const VTable = struct {
124 /// Copied and then passed to `start`.124 /// Copied and then passed to `start`.
125 context: []const u8,125 context: []const u8,
126 context_alignment: std.mem.Alignment,126 context_alignment: std.mem.Alignment,
127 start: *const fn (context: *const anyopaque) void,127 start: Group.Start,
128 ) void,128 ) void),
129 /// Thread-safe.129 /// Thread-safe.
130 groupConcurrent: *const fn (130 groupConcurrent: @Restricted(*const fn (
131 /// Corresponds to `Io.userdata`.131 /// Corresponds to `Io.userdata`.
132 userdata: ?*anyopaque,132 userdata: ?*anyopaque,
133 /// Owner of the spawned async task.133 /// Owner of the spawned async task.
...@@ -135,124 +135,124 @@ pub const VTable = struct {...@@ -135,124 +135,124 @@ pub const VTable = struct {
135 /// Copied and then passed to `start`.135 /// Copied and then passed to `start`.
136 context: []const u8,136 context: []const u8,
137 context_alignment: std.mem.Alignment,137 context_alignment: std.mem.Alignment,
138 start: *const fn (context: *const anyopaque) void,138 start: Group.Start,
139 ) ConcurrentError!void,139 ) ConcurrentError!void),
140 groupAwait: *const fn (?*anyopaque, *Group, token: *anyopaque) Cancelable!void,140 groupAwait: @Restricted(*const fn (?*anyopaque, *Group, token: *anyopaque) Cancelable!void),
141 groupCancel: *const fn (?*anyopaque, *Group, token: *anyopaque) void,141 groupCancel: @Restricted(*const fn (?*anyopaque, *Group, token: *anyopaque) void),
142142
143 recancel: *const fn (?*anyopaque) void,143 recancel: @Restricted(*const fn (?*anyopaque) void),
144 swapCancelProtection: *const fn (?*anyopaque, new: CancelProtection) CancelProtection,144 swapCancelProtection: @Restricted(*const fn (?*anyopaque, new: CancelProtection) CancelProtection),
145 checkCancel: *const fn (?*anyopaque) Cancelable!void,145 checkCancel: @Restricted(*const fn (?*anyopaque) Cancelable!void),
146146
147 futexWait: *const fn (?*anyopaque, ptr: *const u32, expected: u32, Timeout) Cancelable!void,147 futexWait: @Restricted(*const fn (?*anyopaque, ptr: *const u32, expected: u32, Timeout) Cancelable!void),
148 futexWaitUncancelable: *const fn (?*anyopaque, ptr: *const u32, expected: u32) void,148 futexWaitUncancelable: @Restricted(*const fn (?*anyopaque, ptr: *const u32, expected: u32) void),
149 futexWake: *const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void,149 futexWake: @Restricted(*const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void),
150150
151 operate: *const fn (?*anyopaque, Operation) Cancelable!Operation.Result,151 operate: @Restricted(*const fn (?*anyopaque, Operation) Cancelable!Operation.Result),
152 batchAwaitAsync: *const fn (?*anyopaque, *Batch) Cancelable!void,152 batchAwaitAsync: @Restricted(*const fn (?*anyopaque, *Batch) Cancelable!void),
153 batchAwaitConcurrent: *const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void,153 batchAwaitConcurrent: @Restricted(*const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void),
154 batchCancel: *const fn (?*anyopaque, *Batch) void,154 batchCancel: @Restricted(*const fn (?*anyopaque, *Batch) void),
155155
156 dirCreateDir: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirError!void,156 dirCreateDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirError!void),
157 dirCreateDirPath: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirPathError!Dir.CreatePathStatus,157 dirCreateDirPath: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirPathError!Dir.CreatePathStatus),
158 dirCreateDirPathOpen: *const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir,158 dirCreateDirPathOpen: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir),
159 dirOpenDir: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir,159 dirOpenDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir),
160 dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat,160 dirStat: @Restricted(*const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat),
161 dirStatFile: *const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat,161 dirStatFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat),
162 dirAccess: *const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void,162 dirAccess: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void),
163 dirCreateFile: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileOptions) File.OpenError!File,163 dirCreateFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileOptions) File.OpenError!File),
164 dirCreateFileAtomic: *const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic,164 dirCreateFileAtomic: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic),
165 dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File,165 dirOpenFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File),
166 dirClose: *const fn (?*anyopaque, []const Dir) void,166 dirClose: @Restricted(*const fn (?*anyopaque, []const Dir) void),
167 dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize,167 dirRead: @Restricted(*const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize),
168 dirRealPath: *const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize,168 dirRealPath: @Restricted(*const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize),
169 dirRealPathFile: *const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize,169 dirRealPathFile: @Restricted(*const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize),
170 dirDeleteFile: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void,170 dirDeleteFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void),
171 dirDeleteDir: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteDirError!void,171 dirDeleteDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8) Dir.DeleteDirError!void),
172 dirRename: *const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenameError!void,172 dirRename: @Restricted(*const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenameError!void),
173 dirRenamePreserve: *const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenamePreserveError!void,173 dirRenamePreserve: @Restricted(*const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8) Dir.RenamePreserveError!void),
174 dirSymLink: *const fn (?*anyopaque, Dir, target_path: []const u8, sym_link_path: []const u8, Dir.SymLinkFlags) Dir.SymLinkError!void,174 dirSymLink: @Restricted(*const fn (?*anyopaque, Dir, target_path: []const u8, sym_link_path: []const u8, Dir.SymLinkFlags) Dir.SymLinkError!void),
175 dirReadLink: *const fn (?*anyopaque, Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize,175 dirReadLink: @Restricted(*const fn (?*anyopaque, Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize),
176 dirSetOwner: *const fn (?*anyopaque, Dir, ?File.Uid, ?File.Gid) Dir.SetOwnerError!void,176 dirSetOwner: @Restricted(*const fn (?*anyopaque, Dir, ?File.Uid, ?File.Gid) Dir.SetOwnerError!void),
177 dirSetFileOwner: *const fn (?*anyopaque, Dir, []const u8, ?File.Uid, ?File.Gid, Dir.SetFileOwnerOptions) Dir.SetFileOwnerError!void,177 dirSetFileOwner: @Restricted(*const fn (?*anyopaque, Dir, []const u8, ?File.Uid, ?File.Gid, Dir.SetFileOwnerOptions) Dir.SetFileOwnerError!void),
178 dirSetPermissions: *const fn (?*anyopaque, Dir, Dir.Permissions) Dir.SetPermissionsError!void,178 dirSetPermissions: @Restricted(*const fn (?*anyopaque, Dir, Dir.Permissions) Dir.SetPermissionsError!void),
179 dirSetFilePermissions: *const fn (?*anyopaque, Dir, []const u8, File.Permissions, Dir.SetFilePermissionsOptions) Dir.SetFilePermissionsError!void,179 dirSetFilePermissions: @Restricted(*const fn (?*anyopaque, Dir, []const u8, File.Permissions, Dir.SetFilePermissionsOptions) Dir.SetFilePermissionsError!void),
180 dirSetTimestamps: *const fn (?*anyopaque, Dir, []const u8, Dir.SetTimestampsOptions) Dir.SetTimestampsError!void,180 dirSetTimestamps: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.SetTimestampsOptions) Dir.SetTimestampsError!void),
181 dirHardLink: *const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8, Dir.HardLinkOptions) Dir.HardLinkError!void,181 dirHardLink: @Restricted(*const fn (?*anyopaque, old_dir: Dir, old_sub_path: []const u8, new_dir: Dir, new_sub_path: []const u8, Dir.HardLinkOptions) Dir.HardLinkError!void),
182182
183 fileStat: *const fn (?*anyopaque, File) File.StatError!File.Stat,183 fileStat: @Restricted(*const fn (?*anyopaque, File) File.StatError!File.Stat),
184 fileLength: *const fn (?*anyopaque, File) File.LengthError!u64,184 fileLength: @Restricted(*const fn (?*anyopaque, File) File.LengthError!u64),
185 fileClose: *const fn (?*anyopaque, []const File) void,185 fileClose: @Restricted(*const fn (?*anyopaque, []const File) void),
186 fileWritePositional: *const fn (?*anyopaque, File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize,186 fileWritePositional: @Restricted(*const fn (?*anyopaque, File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize),
187 fileWriteFileStreaming: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit) File.Writer.WriteFileError!usize,187 fileWriteFileStreaming: @Restricted(*const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit) File.Writer.WriteFileError!usize),
188 fileWriteFilePositional: *const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit, offset: u64) File.WriteFilePositionalError!usize,188 fileWriteFilePositional: @Restricted(*const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit, offset: u64) File.WriteFilePositionalError!usize),
189 /// Returns 0 if reading at or past the end.189 /// Returns 0 if reading at or past the end.
190 fileReadPositional: *const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize,190 fileReadPositional: @Restricted(*const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize),
191 fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void,191 fileSeekBy: @Restricted(*const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void),
192 fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void,192 fileSeekTo: @Restricted(*const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void),
193 fileSync: *const fn (?*anyopaque, File) File.SyncError!void,193 fileSync: @Restricted(*const fn (?*anyopaque, File) File.SyncError!void),
194 fileIsTty: *const fn (?*anyopaque, File) Cancelable!bool,194 fileIsTty: @Restricted(*const fn (?*anyopaque, File) Cancelable!bool),
195 fileEnableAnsiEscapeCodes: *const fn (?*anyopaque, File) File.EnableAnsiEscapeCodesError!void,195 fileEnableAnsiEscapeCodes: @Restricted(*const fn (?*anyopaque, File) File.EnableAnsiEscapeCodesError!void),
196 fileSupportsAnsiEscapeCodes: *const fn (?*anyopaque, File) Cancelable!bool,196 fileSupportsAnsiEscapeCodes: @Restricted(*const fn (?*anyopaque, File) Cancelable!bool),
197 fileSetLength: *const fn (?*anyopaque, File, u64) File.SetLengthError!void,197 fileSetLength: @Restricted(*const fn (?*anyopaque, File, u64) File.SetLengthError!void),
198 fileSetOwner: *const fn (?*anyopaque, File, ?File.Uid, ?File.Gid) File.SetOwnerError!void,198 fileSetOwner: @Restricted(*const fn (?*anyopaque, File, ?File.Uid, ?File.Gid) File.SetOwnerError!void),
199 fileSetPermissions: *const fn (?*anyopaque, File, File.Permissions) File.SetPermissionsError!void,199 fileSetPermissions: @Restricted(*const fn (?*anyopaque, File, File.Permissions) File.SetPermissionsError!void),
200 fileSetTimestamps: *const fn (?*anyopaque, File, File.SetTimestampsOptions) File.SetTimestampsError!void,200 fileSetTimestamps: @Restricted(*const fn (?*anyopaque, File, File.SetTimestampsOptions) File.SetTimestampsError!void),
201 fileLock: *const fn (?*anyopaque, File, File.Lock) File.LockError!void,201 fileLock: @Restricted(*const fn (?*anyopaque, File, File.Lock) File.LockError!void),
202 fileTryLock: *const fn (?*anyopaque, File, File.Lock) File.LockError!bool,202 fileTryLock: @Restricted(*const fn (?*anyopaque, File, File.Lock) File.LockError!bool),
203 fileUnlock: *const fn (?*anyopaque, File) void,203 fileUnlock: @Restricted(*const fn (?*anyopaque, File) void),
204 fileDowngradeLock: *const fn (?*anyopaque, File) File.DowngradeLockError!void,204 fileDowngradeLock: @Restricted(*const fn (?*anyopaque, File) File.DowngradeLockError!void),
205 fileRealPath: *const fn (?*anyopaque, File, out_buffer: []u8) File.RealPathError!usize,205 fileRealPath: @Restricted(*const fn (?*anyopaque, File, out_buffer: []u8) File.RealPathError!usize),
206 fileHardLink: *const fn (?*anyopaque, File, Dir, []const u8, File.HardLinkOptions) File.HardLinkError!void,206 fileHardLink: @Restricted(*const fn (?*anyopaque, File, Dir, []const u8, File.HardLinkOptions) File.HardLinkError!void),
207207
208 fileMemoryMapCreate: *const fn (?*anyopaque, File, File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap,208 fileMemoryMapCreate: @Restricted(*const fn (?*anyopaque, File, File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap),
209 fileMemoryMapDestroy: *const fn (?*anyopaque, *File.MemoryMap) void,209 fileMemoryMapDestroy: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) void),
210 fileMemoryMapSetLength: *const fn (?*anyopaque, *File.MemoryMap, usize) File.MemoryMap.SetLengthError!void,210 fileMemoryMapSetLength: @Restricted(*const fn (?*anyopaque, *File.MemoryMap, usize) File.MemoryMap.SetLengthError!void),
211 fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void,211 fileMemoryMapRead: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void),
212 fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void,212 fileMemoryMapWrite: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void),
213213
214 processExecutableOpen: *const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File,214 processExecutableOpen: @Restricted(*const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File),
215 processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize,215 processExecutablePath: @Restricted(*const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize),
216 lockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr,216 lockStderr: @Restricted(*const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr),
217 tryLockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr,217 tryLockStderr: @Restricted(*const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr),
218 unlockStderr: *const fn (?*anyopaque) void,218 unlockStderr: @Restricted(*const fn (?*anyopaque) void),
219 processCurrentPath: *const fn (?*anyopaque, buffer: []u8) std.process.CurrentPathError!usize,219 processCurrentPath: @Restricted(*const fn (?*anyopaque, buffer: []u8) std.process.CurrentPathError!usize),
220 processSetCurrentDir: *const fn (?*anyopaque, Dir) std.process.SetCurrentDirError!void,220 processSetCurrentDir: @Restricted(*const fn (?*anyopaque, Dir) std.process.SetCurrentDirError!void),
221 processSetCurrentPath: *const fn (?*anyopaque, []const u8) std.process.SetCurrentPathError!void,221 processSetCurrentPath: @Restricted(*const fn (?*anyopaque, []const u8) std.process.SetCurrentPathError!void),
222 processReplace: *const fn (?*anyopaque, std.process.ReplaceOptions) std.process.ReplaceError,222 processReplace: @Restricted(*const fn (?*anyopaque, std.process.ReplaceOptions) std.process.ReplaceError),
223 processReplacePath: *const fn (?*anyopaque, Dir, std.process.ReplaceOptions) std.process.ReplaceError,223 processReplacePath: @Restricted(*const fn (?*anyopaque, Dir, std.process.ReplaceOptions) std.process.ReplaceError),
224 processSpawn: *const fn (?*anyopaque, std.process.SpawnOptions) std.process.SpawnError!std.process.Child,224 processSpawn: @Restricted(*const fn (?*anyopaque, std.process.SpawnOptions) std.process.SpawnError!std.process.Child),
225 processSpawnPath: *const fn (?*anyopaque, Dir, std.process.SpawnOptions) std.process.SpawnError!std.process.Child,225 processSpawnPath: @Restricted(*const fn (?*anyopaque, Dir, std.process.SpawnOptions) std.process.SpawnError!std.process.Child),
226 childWait: *const fn (?*anyopaque, *std.process.Child) std.process.Child.WaitError!std.process.Child.Term,226 childWait: @Restricted(*const fn (?*anyopaque, *std.process.Child) std.process.Child.WaitError!std.process.Child.Term),
227 childKill: *const fn (?*anyopaque, *std.process.Child) void,227 childKill: @Restricted(*const fn (?*anyopaque, *std.process.Child) void),
228228
229 progressParentFile: *const fn (?*anyopaque) std.Progress.ParentFileError!File,229 progressParentFile: @Restricted(*const fn (?*anyopaque) std.Progress.ParentFileError!File),
230230
231 now: *const fn (?*anyopaque, Clock) Timestamp,231 now: @Restricted(*const fn (?*anyopaque, Clock) Timestamp),
232 clockResolution: *const fn (?*anyopaque, Clock) Clock.ResolutionError!Duration,232 clockResolution: @Restricted(*const fn (?*anyopaque, Clock) Clock.ResolutionError!Duration),
233 sleep: *const fn (?*anyopaque, Timeout) Cancelable!void,233 sleep: @Restricted(*const fn (?*anyopaque, Timeout) Cancelable!void),
234234
235 random: *const fn (?*anyopaque, buffer: []u8) void,235 random: @Restricted(*const fn (?*anyopaque, buffer: []u8) void),
236 randomSecure: *const fn (?*anyopaque, buffer: []u8) RandomSecureError!void,236 randomSecure: @Restricted(*const fn (?*anyopaque, buffer: []u8) RandomSecureError!void),
237237
238 netListenIp: *const fn (?*anyopaque, address: *const net.IpAddress, net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Socket,238 netListenIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Socket),
239 netAccept: *const fn (?*anyopaque, server: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket,239 netAccept: @Restricted(*const fn (?*anyopaque, server: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket),
240 netBindIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket,240 netBindIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket),
241 netConnectIp: *const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket,241 netConnectIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket),
242 netListenUnix: *const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle,242 netListenUnix: @Restricted(*const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle),
243 netConnectUnix: *const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle,243 netConnectUnix: @Restricted(*const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle),
244 netSocketCreatePair: *const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket,244 netSocketCreatePair: @Restricted(*const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket),
245 netSend: *const fn (?*anyopaque, net.Socket.Handle, []net.OutgoingMessage, net.SendFlags) struct { ?net.Socket.SendError, usize },245 netSend: @Restricted(*const fn (?*anyopaque, net.Socket.Handle, []net.OutgoingMessage, net.SendFlags) struct { ?net.Socket.SendError, usize }),
246 netWrite: *const fn (?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize,246 netWrite: @Restricted(*const fn (?*anyopaque, dest: net.Socket.Handle, header: []const u8, data: []const []const u8, splat: usize) net.Stream.Writer.Error!usize),
247 netWriteFile: *const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize,247 netWriteFile: @Restricted(*const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize),
248 netClose: *const fn (?*anyopaque, handle: []const net.Socket.Handle) void,248 netClose: @Restricted(*const fn (?*anyopaque, handle: []const net.Socket.Handle) void),
249 netShutdown: *const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void,249 netShutdown: @Restricted(*const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void),
250 netInterfaceNameResolve: *const fn (?*anyopaque, *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface,250 netInterfaceNameResolve: @Restricted(*const fn (?*anyopaque, *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface),
251 netInterfaceName: *const fn (?*anyopaque, net.Interface) net.Interface.NameError!net.Interface.Name,251 netInterfaceName: @Restricted(*const fn (?*anyopaque, net.Interface) net.Interface.NameError!net.Interface.Name),
252 netLookup: *const fn (?*anyopaque, net.HostName, *Queue(net.HostName.LookupResult), net.HostName.LookupOptions) net.HostName.LookupError!void,252 netLookup: @Restricted(*const fn (?*anyopaque, net.HostName, *Queue(net.HostName.LookupResult), net.HostName.LookupOptions) net.HostName.LookupError!void),
253};253};
254254
255pub const Operation = union(enum) {255pub const Operation = union(@Restricted(Tag)) {
256 file_read_streaming: FileReadStreaming,256 file_read_streaming: FileReadStreaming,
257 file_write_streaming: FileWriteStreaming,257 file_write_streaming: FileWriteStreaming,
258 /// On Windows this is NtDeviceIoControlFile. On POSIX this is ioctl. On258 /// On Windows this is NtDeviceIoControlFile. On POSIX this is ioctl. On
...@@ -261,7 +261,13 @@ pub const Operation = union(enum) {...@@ -261,7 +261,13 @@ pub const Operation = union(enum) {
261 net_receive: NetReceive,261 net_receive: NetReceive,
262 net_read: NetRead,262 net_read: NetRead,
263263
264 pub const Tag = @typeInfo(Operation).@"union".tag_type.?;264 pub const Tag = enum {
265 file_read_streaming,
266 file_write_streaming,
267 device_io_control,
268 net_receive,
269 net_read,
270 };
265271
266 /// May return 0 reads which is different than `error.EndOfStream`.272 /// May return 0 reads which is different than `error.EndOfStream`.
267 pub const FileReadStreaming = struct {273 pub const FileReadStreaming = struct {
...@@ -1187,7 +1193,9 @@ pub const Timeout = union(enum) {...@@ -1187,7 +1193,9 @@ pub const Timeout = union(enum) {
1187 }1193 }
1188};1194};
11891195
1190pub const AnyFuture = opaque {};1196pub const AnyFuture = opaque {
1197 pub const Start = @Restricted(*const fn (context: *const anyopaque, result: *anyopaque) void);
1198};
11911199
1192pub fn Future(Result: type) type {1200pub fn Future(Result: type) type {
1193 return struct {1201 return struct {
...@@ -1243,6 +1251,8 @@ pub const Group = struct {...@@ -1243,6 +1251,8 @@ pub const Group = struct {
12431251
1244 pub const init: Group = .{ .token = .init(null), .state = 0 };1252 pub const init: Group = .{ .token = .init(null), .state = 0 };
12451253
1254 pub const Start = @Restricted(*const fn (context: *const anyopaque) void);
1255
1246 /// Equivalent to `Io.async`, except the task is spawned in this `Group`1256 /// Equivalent to `Io.async`, except the task is spawned in this `Group`
1247 /// instead of becoming associated with a `Future`.1257 /// instead of becoming associated with a `Future`.
1248 ///1258 ///
...@@ -2711,7 +2721,7 @@ pub fn noCrashHandler(userdata: ?*anyopaque) void {...@@ -2711,7 +2721,7 @@ pub fn noCrashHandler(userdata: ?*anyopaque) void {
2711 _ = userdata;2721 _ = userdata;
2712}2722}
27132723
2714pub fn noAsync(userdata: ?*anyopaque, result: []u8, result_alignment: std.mem.Alignment, context: []const u8, context_alignment: std.mem.Alignment, start: *const fn (context: *const anyopaque, result: *anyopaque) void) ?*AnyFuture {2724pub fn noAsync(userdata: ?*anyopaque, result: []u8, result_alignment: std.mem.Alignment, context: []const u8, context_alignment: std.mem.Alignment, start: AnyFuture.Start) ?*AnyFuture {
2715 _ = userdata;2725 _ = userdata;
2716 _ = result_alignment;2726 _ = result_alignment;
2717 _ = context_alignment;2727 _ = context_alignment;
...@@ -2725,7 +2735,7 @@ pub fn failingConcurrent(...@@ -2725,7 +2735,7 @@ pub fn failingConcurrent(
2725 result_alignment: std.mem.Alignment,2735 result_alignment: std.mem.Alignment,
2726 context: []const u8,2736 context: []const u8,
2727 context_alignment: std.mem.Alignment,2737 context_alignment: std.mem.Alignment,
2728 start: *const fn (context: *const anyopaque, result: *anyopaque) void,2738 start: AnyFuture.Start,
2729) ConcurrentError!*AnyFuture {2739) ConcurrentError!*AnyFuture {
2730 _ = userdata;2740 _ = userdata;
2731 _ = result_len;2741 _ = result_len;
...@@ -2767,7 +2777,7 @@ pub fn noGroupAsync(...@@ -2767,7 +2777,7 @@ pub fn noGroupAsync(
2767 group: *Group,2777 group: *Group,
2768 context: []const u8,2778 context: []const u8,
2769 context_alignment: std.mem.Alignment,2779 context_alignment: std.mem.Alignment,
2770 start: *const fn (context: *const anyopaque) void,2780 start: Group.Start,
2771) void {2781) void {
2772 _ = userdata;2782 _ = userdata;
2773 _ = group;2783 _ = group;
...@@ -2780,7 +2790,7 @@ pub fn failingGroupConcurrent(...@@ -2780,7 +2790,7 @@ pub fn failingGroupConcurrent(
2780 group: *Group,2790 group: *Group,
2781 context: []const u8,2791 context: []const u8,
2782 context_alignment: std.mem.Alignment,2792 context_alignment: std.mem.Alignment,
2783 start: *const fn (context: *const anyopaque) void,2793 start: Group.Start,
2784) ConcurrentError!void {2794) ConcurrentError!void {
2785 _ = userdata;2795 _ = userdata;
2786 _ = group;2796 _ = group;
lib/std/Io/Dispatch.zig+10-10
...@@ -986,7 +986,7 @@ fn crashHandler(userdata: ?*anyopaque) void {...@@ -986,7 +986,7 @@ fn crashHandler(userdata: ?*anyopaque) void {
986const AsyncClosure = struct {986const AsyncClosure = struct {
987 evented: *Evented,987 evented: *Evented,
988 fiber: *Fiber,988 fiber: *Fiber,
989 start: *const fn (context: *const anyopaque, result: *anyopaque) void,989 start: Io.AnyFuture.Start,
990 result_align: Alignment,990 result_align: Alignment,
991991
992 fn fromFiber(fiber: *Fiber) *AsyncClosure {992 fn fromFiber(fiber: *Fiber) *AsyncClosure {
...@@ -1038,8 +1038,8 @@ fn async(...@@ -1038,8 +1038,8 @@ fn async(
1038 result_alignment: Alignment,1038 result_alignment: Alignment,
1039 context: []const u8,1039 context: []const u8,
1040 context_alignment: Alignment,1040 context_alignment: Alignment,
1041 start: *const fn (context: *const anyopaque, result: *anyopaque) void,1041 start: Io.AnyFuture.Start,
1042) ?*std.Io.AnyFuture {1042) ?*Io.AnyFuture {
1043 const ev: *Evented = @ptrCast(@alignCast(userdata));1043 const ev: *Evented = @ptrCast(@alignCast(userdata));
1044 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {1044 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {
1045 start(context.ptr, result.ptr);1045 start(context.ptr, result.ptr);
...@@ -1053,8 +1053,8 @@ fn concurrent(...@@ -1053,8 +1053,8 @@ fn concurrent(
1053 result_alignment: Alignment,1053 result_alignment: Alignment,
1054 context: []const u8,1054 context: []const u8,
1055 context_alignment: Alignment,1055 context_alignment: Alignment,
1056 start: *const fn (context: *const anyopaque, result: *anyopaque) void,1056 start: Io.AnyFuture.Start,
1057) Io.ConcurrentError!*std.Io.AnyFuture {1057) Io.ConcurrentError!*Io.AnyFuture {
1058 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO1058 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
1059 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO1059 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
1060 assert(result_len <= Fiber.max_result_size); // TODO1060 assert(result_len <= Fiber.max_result_size); // TODO
...@@ -1101,7 +1101,7 @@ fn concurrent(...@@ -1101,7 +1101,7 @@ fn concurrent(
11011101
1102fn await(1102fn await(
1103 userdata: ?*anyopaque,1103 userdata: ?*anyopaque,
1104 future: *std.Io.AnyFuture,1104 future: *Io.AnyFuture,
1105 result: []u8,1105 result: []u8,
1106 result_alignment: Alignment,1106 result_alignment: Alignment,
1107) void {1107) void {
...@@ -1115,7 +1115,7 @@ fn await(...@@ -1115,7 +1115,7 @@ fn await(
11151115
1116fn cancel(1116fn cancel(
1117 userdata: ?*anyopaque,1117 userdata: ?*anyopaque,
1118 future: *std.Io.AnyFuture,1118 future: *Io.AnyFuture,
1119 result: []u8,1119 result: []u8,
1120 result_alignment: Alignment,1120 result_alignment: Alignment,
1121) void {1121) void {
...@@ -1329,7 +1329,7 @@ const Group = struct {...@@ -1329,7 +1329,7 @@ const Group = struct {
1329 evented: *Evented,1329 evented: *Evented,
1330 group: Group,1330 group: Group,
1331 fiber: *Fiber,1331 fiber: *Fiber,
1332 start: *const fn (context: *const anyopaque) void,1332 start: Io.Group.Start,
13331333
1334 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {1334 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {
1335 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(1335 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(
...@@ -1381,7 +1381,7 @@ fn groupAsync(...@@ -1381,7 +1381,7 @@ fn groupAsync(
1381 type_erased: *Io.Group,1381 type_erased: *Io.Group,
1382 context: []const u8,1382 context: []const u8,
1383 context_alignment: Alignment,1383 context_alignment: Alignment,
1384 start: *const fn (context: *const anyopaque) void,1384 start: Io.Group.Start,
1385) void {1385) void {
1386 const ev: *Evented = @ptrCast(@alignCast(userdata));1386 const ev: *Evented = @ptrCast(@alignCast(userdata));
1387 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {1387 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {
...@@ -1394,7 +1394,7 @@ fn groupConcurrent(...@@ -1394,7 +1394,7 @@ fn groupConcurrent(
1394 type_erased: *Io.Group,1394 type_erased: *Io.Group,
1395 context: []const u8,1395 context: []const u8,
1396 context_alignment: Alignment,1396 context_alignment: Alignment,
1397 start: *const fn (context: *const anyopaque) void,1397 start: Io.Group.Start,
1398) Io.ConcurrentError!void {1398) Io.ConcurrentError!void {
1399 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO1399 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
1400 assert(context.len <= Fiber.max_context_size); // TODO1400 assert(context.len <= Fiber.max_context_size); // TODO
lib/std/Io/Kqueue.zig+11-11
...@@ -3,15 +3,15 @@ const builtin = @import("builtin");...@@ -3,15 +3,15 @@ const builtin = @import("builtin");
33
4const std = @import("../std.zig");4const std = @import("../std.zig");
5const Io = std.Io;5const Io = std.Io;
6const Dir = std.Io.Dir;6const Dir = Io.Dir;
7const File = std.Io.File;7const File = Io.File;
8const net = std.Io.net;8const net = Io.net;
9const assert = std.debug.assert;9const assert = std.debug.assert;
10const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
11const Alignment = std.mem.Alignment;11const Alignment = std.mem.Alignment;
12const IpAddress = std.Io.net.IpAddress;12const IpAddress = Io.net.IpAddress;
13const errnoBug = std.Io.Threaded.errnoBug;13const errnoBug = Io.Threaded.errnoBug;
14const closeFd = std.Io.Threaded.closeFd;14const closeFd = Io.Threaded.closeFd;
15const posix = std.posix;15const posix = std.posix;
16const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;16const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
1717
...@@ -577,7 +577,7 @@ fn fiberEntry() callconv(.naked) void {...@@ -577,7 +577,7 @@ fn fiberEntry() callconv(.naked) void {
577const AsyncClosure = struct {577const AsyncClosure = struct {
578 kqueue: *Kqueue,578 kqueue: *Kqueue,
579 fiber: *Fiber,579 fiber: *Fiber,
580 start: *const fn (context: *const anyopaque, result: *anyopaque) void,580 start: Io.AnyFuture.Start,
581 result_align: Alignment,581 result_align: Alignment,
582 already_awaited: bool,582 already_awaited: bool,
583583
...@@ -669,7 +669,7 @@ fn async(...@@ -669,7 +669,7 @@ fn async(
669 result_alignment: std.mem.Alignment,669 result_alignment: std.mem.Alignment,
670 context: []const u8,670 context: []const u8,
671 context_alignment: std.mem.Alignment,671 context_alignment: std.mem.Alignment,
672 start: *const fn (context: *const anyopaque, result: *anyopaque) void,672 start: Io.AnyFuture.Start,
673) ?*Io.AnyFuture {673) ?*Io.AnyFuture {
674 return concurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {674 return concurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {
675 start(context.ptr, result.ptr);675 start(context.ptr, result.ptr);
...@@ -683,7 +683,7 @@ fn concurrent(...@@ -683,7 +683,7 @@ fn concurrent(
683 result_alignment: Alignment,683 result_alignment: Alignment,
684 context: []const u8,684 context: []const u8,
685 context_alignment: Alignment,685 context_alignment: Alignment,
686 start: *const fn (context: *const anyopaque, result: *anyopaque) void,686 start: Io.AnyFuture.Start,
687) Io.ConcurrentError!*Io.AnyFuture {687) Io.ConcurrentError!*Io.AnyFuture {
688 const k: *Kqueue = @ptrCast(@alignCast(userdata));688 const k: *Kqueue = @ptrCast(@alignCast(userdata));
689 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO689 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
...@@ -767,7 +767,7 @@ fn groupAsync(...@@ -767,7 +767,7 @@ fn groupAsync(
767 type_erased: *Io.Group,767 type_erased: *Io.Group,
768 context: []const u8,768 context: []const u8,
769 context_alignment: Alignment,769 context_alignment: Alignment,
770 start: *const fn (context: *const anyopaque) void,770 start: Io.Group.Start,
771) void {771) void {
772 const k: *Kqueue = @ptrCast(@alignCast(userdata));772 const k: *Kqueue = @ptrCast(@alignCast(userdata));
773 _ = k;773 _ = k;
...@@ -783,7 +783,7 @@ fn groupConcurrent(...@@ -783,7 +783,7 @@ fn groupConcurrent(
783 type_erased: *Io.Group,783 type_erased: *Io.Group,
784 context: []const u8,784 context: []const u8,
785 context_alignment: Alignment,785 context_alignment: Alignment,
786 start: *const fn (context: *const anyopaque) void,786 start: Io.Group.Start,
787) Io.ConcurrentError!void {787) Io.ConcurrentError!void {
788 const k: *Kqueue = @ptrCast(@alignCast(userdata));788 const k: *Kqueue = @ptrCast(@alignCast(userdata));
789 _ = k;789 _ = k;
lib/std/Io/Reader.zig+4-4
...@@ -43,7 +43,7 @@ pub const VTable = struct {...@@ -43,7 +43,7 @@ pub const VTable = struct {
43 /// choose to store data in `buffer`, modifying `seek` and `end`43 /// choose to store data in `buffer`, modifying `seek` and `end`
44 /// accordingly. Implementations are encouraged to take advantage of44 /// accordingly. Implementations are encouraged to take advantage of
45 /// this if it simplifies the logic.45 /// this if it simplifies the logic.
46 stream: *const fn (r: *Reader, w: *Writer, limit: Limit) StreamError!usize,46 stream: @Restricted(*const fn (r: *Reader, w: *Writer, limit: Limit) StreamError!usize),
4747
48 /// Consumes bytes from the internally tracked stream position without48 /// Consumes bytes from the internally tracked stream position without
49 /// providing access to them.49 /// providing access to them.
...@@ -64,7 +64,7 @@ pub const VTable = struct {...@@ -64,7 +64,7 @@ pub const VTable = struct {
64 /// data.64 /// data.
65 ///65 ///
66 /// This function is only called when `buffer` is empty.66 /// This function is only called when `buffer` is empty.
67 discard: *const fn (r: *Reader, limit: Limit) Error!usize = defaultDiscard,67 discard: @Restricted(*const fn (r: *Reader, limit: Limit) Error!usize) = defaultDiscard,
6868
69 /// Returns number of bytes written to `data`.69 /// Returns number of bytes written to `data`.
70 ///70 ///
...@@ -84,7 +84,7 @@ pub const VTable = struct {...@@ -84,7 +84,7 @@ pub const VTable = struct {
84 ///84 ///
85 /// The default implementation calls `stream` with either `data[0]` or85 /// The default implementation calls `stream` with either `data[0]` or
86 /// `Reader.buffer`, whichever is bigger.86 /// `Reader.buffer`, whichever is bigger.
87 readVec: *const fn (r: *Reader, data: [][]u8) Error!usize = defaultReadVec,87 readVec: @Restricted(*const fn (r: *Reader, data: [][]u8) Error!usize) = defaultReadVec,
8888
89 /// Ensures `capacity` data can be buffered without rebasing.89 /// Ensures `capacity` data can be buffered without rebasing.
90 ///90 ///
...@@ -96,7 +96,7 @@ pub const VTable = struct {...@@ -96,7 +96,7 @@ pub const VTable = struct {
96 ///96 ///
97 /// The default implementation moves buffered data to the start of97 /// The default implementation moves buffered data to the start of
98 /// `buffer`, setting `seek` to zero, and cannot fail.98 /// `buffer`, setting `seek` to zero, and cannot fail.
99 rebase: *const fn (r: *Reader, capacity: usize) RebaseError!void = defaultRebase,99 rebase: @Restricted(*const fn (r: *Reader, capacity: usize) RebaseError!void) = defaultRebase,
100};100};
101101
102pub const StreamError = error{102pub const StreamError = error{
lib/std/Io/Threaded.zig+14-17
...@@ -449,7 +449,7 @@ const default_fn_align = switch (builtin.mode) {...@@ -449,7 +449,7 @@ const default_fn_align = switch (builtin.mode) {
449449
450const Runnable = struct {450const Runnable = struct {
451 node: std.SinglyLinkedList.Node,451 node: std.SinglyLinkedList.Node,
452 startFn: *const fn (*Runnable, *Thread, *Threaded) void,452 startFn: @Restricted(*const fn (*Runnable, *Thread, *Threaded) void),
453};453};
454454
455const Group = struct {455const Group = struct {
...@@ -484,7 +484,7 @@ const Group = struct {...@@ -484,7 +484,7 @@ const Group = struct {
484 const Task = struct {484 const Task = struct {
485 runnable: Runnable,485 runnable: Runnable,
486 group: *Io.Group,486 group: *Io.Group,
487 func: *const fn (context: *const anyopaque) void,487 startFn: Io.Group.Start,
488 context_alignment: Alignment,488 context_alignment: Alignment,
489 alloc_len: usize,489 alloc_len: usize,
490490
...@@ -494,7 +494,7 @@ const Group = struct {...@@ -494,7 +494,7 @@ const Group = struct {
494 group: Group,494 group: Group,
495 context: []const u8,495 context: []const u8,
496 context_alignment: Alignment,496 context_alignment: Alignment,
497 func: *const fn (context: *const anyopaque) void,497 startFn: Io.Group.Start,
498 ) Allocator.Error!*Task {498 ) Allocator.Error!*Task {
499 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Task);499 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Task);
500 const worst_case_context_offset = context_alignment.forward(@sizeOf(Task) + max_context_misalignment);500 const worst_case_context_offset = context_alignment.forward(@sizeOf(Task) + max_context_misalignment);
...@@ -509,7 +509,7 @@ const Group = struct {...@@ -509,7 +509,7 @@ const Group = struct {
509 .startFn = &start,509 .startFn = &start,
510 },510 },
511 .group = group.ptr,511 .group = group.ptr,
512 .func = func,512 .startFn = startFn,
513 .context_alignment = context_alignment,513 .context_alignment = context_alignment,
514 .alloc_len = alloc_len,514 .alloc_len = alloc_len,
515 };515 };
...@@ -549,7 +549,7 @@ const Group = struct {...@@ -549,7 +549,7 @@ const Group = struct {
549 }, .monotonic);549 }, .monotonic);
550 }550 }
551551
552 task.func(task.contextPointer());552 task.startFn(task.contextPointer());
553553
554 thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic);554 thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic);
555 const old_status = group.status().fetchSub(.{555 const old_status = group.status().fetchSub(.{
...@@ -631,7 +631,7 @@ const Group = struct {...@@ -631,7 +631,7 @@ const Group = struct {
631/// 2. result631/// 2. result
632const Future = struct {632const Future = struct {
633 runnable: Runnable,633 runnable: Runnable,
634 func: *const fn (context: *const anyopaque, result: *anyopaque) void,634 startFn: Io.AnyFuture.Start,
635 status: std.atomic.Value(Status),635 status: std.atomic.Value(Status),
636 /// On completion, increment this `u32` and do a futex wake on it.636 /// On completion, increment this `u32` and do a futex wake on it.
637 awaiter: *std.atomic.Value(u32),637 awaiter: *std.atomic.Value(u32),
...@@ -666,7 +666,7 @@ const Future = struct {...@@ -666,7 +666,7 @@ const Future = struct {
666 result_alignment: Alignment,666 result_alignment: Alignment,
667 context: []const u8,667 context: []const u8,
668 context_alignment: Alignment,668 context_alignment: Alignment,
669 func: *const fn (context: *const anyopaque, result: *anyopaque) void,669 startFn: Io.AnyFuture.Start,
670 ) Allocator.Error!*Future {670 ) Allocator.Error!*Future {
671 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Future);671 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Future);
672 const worst_case_context_offset = context_alignment.forward(@sizeOf(Future) + max_context_misalignment);672 const worst_case_context_offset = context_alignment.forward(@sizeOf(Future) + max_context_misalignment);
...@@ -684,7 +684,7 @@ const Future = struct {...@@ -684,7 +684,7 @@ const Future = struct {
684 .node = undefined,684 .node = undefined,
685 .startFn = &start,685 .startFn = &start,
686 },686 },
687 .func = func,687 .startFn = startFn,
688 .status = .init(.{688 .status = .init(.{
689 .tag = .pending,689 .tag = .pending,
690 .thread = .null,690 .thread = .null,
...@@ -738,7 +738,7 @@ const Future = struct {...@@ -738,7 +738,7 @@ const Future = struct {
738 }738 }
739 }739 }
740740
741 future.func(future.contextPointer(), future.resultPointer());741 future.startFn(future.contextPointer(), future.resultPointer());
742742
743 const had_acknowledged_cancel = switch (thread.status.load(.monotonic).cancelation) {743 const had_acknowledged_cancel = switch (thread.status.load(.monotonic).cancelation) {
744 .none, .canceling => false,744 .none, .canceling => false,
...@@ -2073,7 +2073,7 @@ fn async(...@@ -2073,7 +2073,7 @@ fn async(
2073 result_alignment: Alignment,2073 result_alignment: Alignment,
2074 context: []const u8,2074 context: []const u8,
2075 context_alignment: Alignment,2075 context_alignment: Alignment,
2076 start: *const fn (context: *const anyopaque, result: *anyopaque) void,2076 start: Io.AnyFuture.Start,
2077) ?*Io.AnyFuture {2077) ?*Io.AnyFuture {
2078 const t: *Threaded = @ptrCast(@alignCast(userdata));2078 const t: *Threaded = @ptrCast(@alignCast(userdata));
2079 if (builtin.single_threaded) {2079 if (builtin.single_threaded) {
...@@ -2129,7 +2129,7 @@ fn concurrent(...@@ -2129,7 +2129,7 @@ fn concurrent(
2129 result_alignment: Alignment,2129 result_alignment: Alignment,
2130 context: []const u8,2130 context: []const u8,
2131 context_alignment: Alignment,2131 context_alignment: Alignment,
2132 start: *const fn (context: *const anyopaque, result: *anyopaque) void,2132 start: Io.AnyFuture.Start,
2133) Io.ConcurrentError!*Io.AnyFuture {2133) Io.ConcurrentError!*Io.AnyFuture {
2134 if (builtin.single_threaded) return error.ConcurrencyUnavailable;2134 if (builtin.single_threaded) return error.ConcurrencyUnavailable;
21352135
...@@ -2174,7 +2174,7 @@ fn groupAsync(...@@ -2174,7 +2174,7 @@ fn groupAsync(
2174 type_erased: *Io.Group,2174 type_erased: *Io.Group,
2175 context: []const u8,2175 context: []const u8,
2176 context_alignment: Alignment,2176 context_alignment: Alignment,
2177 start: *const fn (context: *const anyopaque) void,2177 start: Io.Group.Start,
2178) void {2178) void {
2179 const t: *Threaded = @ptrCast(@alignCast(userdata));2179 const t: *Threaded = @ptrCast(@alignCast(userdata));
2180 const g: Group = .{ .ptr = type_erased };2180 const g: Group = .{ .ptr = type_erased };
...@@ -2224,10 +2224,7 @@ fn groupAsync(...@@ -2224,10 +2224,7 @@ fn groupAsync(
2224 mutexUnlock(&t.mutex);2224 mutexUnlock(&t.mutex);
2225 condSignal(&t.cond);2225 condSignal(&t.cond);
2226}2226}
2227fn groupAsyncEager(2227fn groupAsyncEager(start: Io.Group.Start, context: *const anyopaque) void {
2228 start: *const fn (context: *const anyopaque) void,
2229 context: *const anyopaque,
2230) void {
2231 start(context);2228 start(context);
2232}2229}
22332230
...@@ -2236,7 +2233,7 @@ fn groupConcurrent(...@@ -2236,7 +2233,7 @@ fn groupConcurrent(
2236 type_erased: *Io.Group,2233 type_erased: *Io.Group,
2237 context: []const u8,2234 context: []const u8,
2238 context_alignment: Alignment,2235 context_alignment: Alignment,
2239 start: *const fn (context: *const anyopaque) void,2236 start: Io.Group.Start,
2240) Io.ConcurrentError!void {2237) Io.ConcurrentError!void {
2241 if (builtin.single_threaded) return error.ConcurrencyUnavailable;2238 if (builtin.single_threaded) return error.ConcurrencyUnavailable;
22422239
lib/std/Io/Uring.zig+10-10
...@@ -1375,7 +1375,7 @@ fn crashHandler(userdata: ?*anyopaque) void {...@@ -1375,7 +1375,7 @@ fn crashHandler(userdata: ?*anyopaque) void {
1375const AsyncClosure = struct {1375const AsyncClosure = struct {
1376 evented: *Evented,1376 evented: *Evented,
1377 fiber: *Fiber,1377 fiber: *Fiber,
1378 start: *const fn (context: *const anyopaque, result: *anyopaque) void,1378 start: Io.AnyFuture.Start,
1379 result_align: Alignment,1379 result_align: Alignment,
13801380
1381 fn fromFiber(fiber: *Fiber) *AsyncClosure {1381 fn fromFiber(fiber: *Fiber) *AsyncClosure {
...@@ -1431,8 +1431,8 @@ fn async(...@@ -1431,8 +1431,8 @@ fn async(
1431 result_alignment: Alignment,1431 result_alignment: Alignment,
1432 context: []const u8,1432 context: []const u8,
1433 context_alignment: Alignment,1433 context_alignment: Alignment,
1434 start: *const fn (context: *const anyopaque, result: *anyopaque) void,1434 start: Io.AnyFuture.Start,
1435) ?*std.Io.AnyFuture {1435) ?*Io.AnyFuture {
1436 const ev: *Evented = @ptrCast(@alignCast(userdata));1436 const ev: *Evented = @ptrCast(@alignCast(userdata));
1437 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {1437 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {
1438 start(context.ptr, result.ptr);1438 start(context.ptr, result.ptr);
...@@ -1446,8 +1446,8 @@ fn concurrent(...@@ -1446,8 +1446,8 @@ fn concurrent(
1446 result_alignment: Alignment,1446 result_alignment: Alignment,
1447 context: []const u8,1447 context: []const u8,
1448 context_alignment: Alignment,1448 context_alignment: Alignment,
1449 start: *const fn (context: *const anyopaque, result: *anyopaque) void,1449 start: Io.AnyFuture.Start,
1450) Io.ConcurrentError!*std.Io.AnyFuture {1450) Io.ConcurrentError!*Io.AnyFuture {
1451 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO1451 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
1452 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO1452 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
1453 assert(result_len <= Fiber.max_result_size); // TODO1453 assert(result_len <= Fiber.max_result_size); // TODO
...@@ -1510,7 +1510,7 @@ fn concurrent(...@@ -1510,7 +1510,7 @@ fn concurrent(
15101510
1511fn await(1511fn await(
1512 userdata: ?*anyopaque,1512 userdata: ?*anyopaque,
1513 future: *std.Io.AnyFuture,1513 future: *Io.AnyFuture,
1514 result: []u8,1514 result: []u8,
1515 result_alignment: Alignment,1515 result_alignment: Alignment,
1516) void {1516) void {
...@@ -1524,7 +1524,7 @@ fn await(...@@ -1524,7 +1524,7 @@ fn await(
15241524
1525fn cancel(1525fn cancel(
1526 userdata: ?*anyopaque,1526 userdata: ?*anyopaque,
1527 future: *std.Io.AnyFuture,1527 future: *Io.AnyFuture,
1528 result: []u8,1528 result: []u8,
1529 result_alignment: Alignment,1529 result_alignment: Alignment,
1530) void {1530) void {
...@@ -1739,7 +1739,7 @@ const Group = struct {...@@ -1739,7 +1739,7 @@ const Group = struct {
1739 evented: *Evented,1739 evented: *Evented,
1740 group: Group,1740 group: Group,
1741 fiber: *Fiber,1741 fiber: *Fiber,
1742 start: *const fn (context: *const anyopaque) void,1742 start: Group.Start,
17431743
1744 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {1744 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {
1745 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(1745 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(
...@@ -1797,7 +1797,7 @@ fn groupAsync(...@@ -1797,7 +1797,7 @@ fn groupAsync(
1797 type_erased: *Io.Group,1797 type_erased: *Io.Group,
1798 context: []const u8,1798 context: []const u8,
1799 context_alignment: Alignment,1799 context_alignment: Alignment,
1800 start: *const fn (context: *const anyopaque) void,1800 start: Group.Start,
1801) void {1801) void {
1802 const ev: *Evented = @ptrCast(@alignCast(userdata));1802 const ev: *Evented = @ptrCast(@alignCast(userdata));
1803 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {1803 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {
...@@ -1810,7 +1810,7 @@ fn groupConcurrent(...@@ -1810,7 +1810,7 @@ fn groupConcurrent(
1810 type_erased: *Io.Group,1810 type_erased: *Io.Group,
1811 context: []const u8,1811 context: []const u8,
1812 context_alignment: Alignment,1812 context_alignment: Alignment,
1813 start: *const fn (context: *const anyopaque) void,1813 start: Group.Start,
1814) Io.ConcurrentError!void {1814) Io.ConcurrentError!void {
1815 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO1815 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
1816 assert(context.len <= Fiber.max_context_size); // TODO1816 assert(context.len <= Fiber.max_context_size); // TODO
lib/std/Io/Writer.zig+5-5
...@@ -43,7 +43,7 @@ pub const VTable = struct {...@@ -43,7 +43,7 @@ pub const VTable = struct {
43 /// Number of bytes returned may be zero, which does not indicate stream43 /// Number of bytes returned may be zero, which does not indicate stream
44 /// end. A subsequent call may return nonzero, or signal end of stream via44 /// end. A subsequent call may return nonzero, or signal end of stream via
45 /// `error.WriteFailed`.45 /// `error.WriteFailed`.
46 drain: *const fn (w: *Writer, data: []const []const u8, splat: usize) Error!usize,46 drain: @Restricted(*const fn (w: *Writer, data: []const []const u8, splat: usize) Error!usize),
4747
48 /// Copies contents from an open file to the logical sink. `buffer[0..end]`48 /// Copies contents from an open file to the logical sink. `buffer[0..end]`
49 /// is consumed first, followed by `limit` bytes from `file_reader`.49 /// is consumed first, followed by `limit` bytes from `file_reader`.
...@@ -60,14 +60,14 @@ pub const VTable = struct {...@@ -60,14 +60,14 @@ pub const VTable = struct {
60 ///60 ///
61 /// `error.Unimplemented` indicates the callee cannot offer a more61 /// `error.Unimplemented` indicates the callee cannot offer a more
62 /// efficient implementation than the caller performing its own reads.62 /// efficient implementation than the caller performing its own reads.
63 sendFile: *const fn (63 sendFile: @Restricted(*const fn (
64 w: *Writer,64 w: *Writer,
65 file_reader: *File.Reader,65 file_reader: *File.Reader,
66 /// Maximum amount of bytes to read from the file. Implementations may66 /// Maximum amount of bytes to read from the file. Implementations may
67 /// assume that the file size does not exceed this amount. Data from67 /// assume that the file size does not exceed this amount. Data from
68 /// `buffer` does not count towards this limit.68 /// `buffer` does not count towards this limit.
69 limit: Limit,69 limit: Limit,
70 ) FileError!usize = unimplementedSendFile,70 ) FileError!usize) = unimplementedSendFile,
7171
72 /// Consumes all remaining buffer.72 /// Consumes all remaining buffer.
73 ///73 ///
...@@ -77,7 +77,7 @@ pub const VTable = struct {...@@ -77,7 +77,7 @@ pub const VTable = struct {
77 ///77 ///
78 /// There may be subsequent calls to `drain` and `sendFile` after a `flush`78 /// There may be subsequent calls to `drain` and `sendFile` after a `flush`
79 /// operation.79 /// operation.
80 flush: *const fn (w: *Writer) Error!void = defaultFlush,80 flush: @Restricted(*const fn (w: *Writer) Error!void) = defaultFlush,
8181
82 /// Ensures `capacity` more bytes can be buffered without rebasing.82 /// Ensures `capacity` more bytes can be buffered without rebasing.
83 ///83 ///
...@@ -85,7 +85,7 @@ pub const VTable = struct {...@@ -85,7 +85,7 @@ pub const VTable = struct {
85 ///85 ///
86 /// Only called when `capacity` bytes cannot fit into the unused capacity86 /// Only called when `capacity` bytes cannot fit into the unused capacity
87 /// of `buffer`.87 /// of `buffer`.
88 rebase: *const fn (w: *Writer, preserve: usize, capacity: usize) Error!void = defaultRebase,88 rebase: @Restricted(*const fn (w: *Writer, preserve: usize, capacity: usize) Error!void) = defaultRebase,
89};89};
9090
91pub const Error = error{91pub const Error = error{
lib/std/http.zig+1-1
...@@ -772,7 +772,7 @@ pub const BodyWriter = struct {...@@ -772,7 +772,7 @@ pub const BodyWriter = struct {
772 };772 };
773773
774 pub fn isEliding(w: *const BodyWriter) bool {774 pub fn isEliding(w: *const BodyWriter) bool {
775 return w.writer.vtable.drain == elidingDrain;775 return @as(*const fn (*Writer, []const []const u8, usize) Writer.Error!usize, w.writer.vtable.drain) == elidingDrain;
776 }776 }
777777
778 /// Sends all buffered data across `BodyWriter.http_protocol_output`.778 /// Sends all buffered data across `BodyWriter.http_protocol_output`.
lib/std/mem/Allocator.zig+4-4
...@@ -26,7 +26,7 @@ pub const VTable = struct {...@@ -26,7 +26,7 @@ pub const VTable = struct {
26 /// `ret_addr` is optionally provided as the first return address of the26 /// `ret_addr` is optionally provided as the first return address of the
27 /// allocation call stack. If the value is `0` it means no return address27 /// allocation call stack. If the value is `0` it means no return address
28 /// has been provided.28 /// has been provided.
29 alloc: *const fn (*anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8,29 alloc: @Restricted(*const fn (*anyopaque, len: usize, alignment: Alignment, ret_addr: usize) ?[*]u8),
3030
31 /// Attempt to expand or shrink memory in place.31 /// Attempt to expand or shrink memory in place.
32 ///32 ///
...@@ -45,7 +45,7 @@ pub const VTable = struct {...@@ -45,7 +45,7 @@ pub const VTable = struct {
45 /// `ret_addr` is optionally provided as the first return address of the45 /// `ret_addr` is optionally provided as the first return address of the
46 /// allocation call stack. If the value is `0` it means no return address46 /// allocation call stack. If the value is `0` it means no return address
47 /// has been provided.47 /// has been provided.
48 resize: *const fn (*anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool,48 resize: @Restricted(*const fn (*anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) bool),
4949
50 /// Attempt to expand or shrink memory, allowing relocation.50 /// Attempt to expand or shrink memory, allowing relocation.
51 ///51 ///
...@@ -66,7 +66,7 @@ pub const VTable = struct {...@@ -66,7 +66,7 @@ pub const VTable = struct {
66 /// `ret_addr` is optionally provided as the first return address of the66 /// `ret_addr` is optionally provided as the first return address of the
67 /// allocation call stack. If the value is `0` it means no return address67 /// allocation call stack. If the value is `0` it means no return address
68 /// has been provided.68 /// has been provided.
69 remap: *const fn (*anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8,69 remap: @Restricted(*const fn (*anyopaque, memory: []u8, alignment: Alignment, new_len: usize, ret_addr: usize) ?[*]u8),
7070
71 /// Free and invalidate a region of memory.71 /// Free and invalidate a region of memory.
72 ///72 ///
...@@ -78,7 +78,7 @@ pub const VTable = struct {...@@ -78,7 +78,7 @@ pub const VTable = struct {
78 /// `ret_addr` is optionally provided as the first return address of the78 /// `ret_addr` is optionally provided as the first return address of the
79 /// allocation call stack. If the value is `0` it means no return address79 /// allocation call stack. If the value is `0` it means no return address
80 /// has been provided.80 /// has been provided.
81 free: *const fn (*anyopaque, memory: []u8, alignment: Alignment, ret_addr: usize) void,81 free: @Restricted(*const fn (*anyopaque, memory: []u8, alignment: Alignment, ret_addr: usize) void),
82};82};
8383
84pub fn noAlloc(84pub fn noAlloc(