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 {
5858 /// a unit of concurrency has been assigned to the returned task.
5959 ///
6060 /// Thread-safe.
61 async: *const fn (
61 async: @Restricted(*const fn (
6262 /// Corresponds to `Io.userdata`.
6363 userdata: ?*anyopaque,
6464 /// The pointer of this slice is an "eager" result value.
......@@ -69,10 +69,10 @@ pub const VTable = struct {
6969 /// Copied and then passed to `start`.
7070 context: []const u8,
7171 context_alignment: std.mem.Alignment,
72 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
73 ) ?*AnyFuture,
72 start: AnyFuture.Start,
73 ) ?*AnyFuture),
7474 /// Thread-safe.
75 concurrent: *const fn (
75 concurrent: @Restricted(*const fn (
7676 /// Corresponds to `Io.userdata`.
7777 userdata: ?*anyopaque,
7878 result_len: usize,
......@@ -80,12 +80,12 @@ pub const VTable = struct {
8080 /// Copied and then passed to `start`.
8181 context: []const u8,
8282 context_alignment: std.mem.Alignment,
83 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
84 ) ConcurrentError!*AnyFuture,
83 start: AnyFuture.Start,
84 ) ConcurrentError!*AnyFuture),
8585 /// This function is only called when `async` returns a non-null value.
8686 ///
8787 /// Thread-safe.
88 await: *const fn (
88 await: @Restricted(*const fn (
8989 /// Corresponds to `Io.userdata`.
9090 userdata: ?*anyopaque,
9191 /// The same value that was returned from `async`.
......@@ -94,13 +94,13 @@ pub const VTable = struct {
9494 /// The length is equal to size in bytes of result type.
9595 result: []u8,
9696 result_alignment: std.mem.Alignment,
97 ) void,
97 ) void),
9898 /// Equivalent to `await` but initiates cancel request.
9999 ///
100100 /// This function is only called when `async` returns a non-null value.
101101 ///
102102 /// Thread-safe.
103 cancel: *const fn (
103 cancel: @Restricted(*const fn (
104104 /// Corresponds to `Io.userdata`.
105105 userdata: ?*anyopaque,
106106 /// The same value that was returned from `async`.
......@@ -109,14 +109,14 @@ pub const VTable = struct {
109109 /// The length is equal to size in bytes of result type.
110110 result: []u8,
111111 result_alignment: std.mem.Alignment,
112 ) void,
112 ) void),
113113
114114 /// When this function returns, implementation guarantees that `start` has
115115 /// either already been called, or a unit of concurrency has been assigned
116116 /// to the task of calling the function.
117117 ///
118118 /// Thread-safe.
119 groupAsync: *const fn (
119 groupAsync: @Restricted(*const fn (
120120 /// Corresponds to `Io.userdata`.
121121 userdata: ?*anyopaque,
122122 /// Owner of the spawned async task.
......@@ -124,10 +124,10 @@ pub const VTable = struct {
124124 /// Copied and then passed to `start`.
125125 context: []const u8,
126126 context_alignment: std.mem.Alignment,
127 start: *const fn (context: *const anyopaque) void,
128 ) void,
127 start: Group.Start,
128 ) void),
129129 /// Thread-safe.
130 groupConcurrent: *const fn (
130 groupConcurrent: @Restricted(*const fn (
131131 /// Corresponds to `Io.userdata`.
132132 userdata: ?*anyopaque,
133133 /// Owner of the spawned async task.
......@@ -135,124 +135,124 @@ pub const VTable = struct {
135135 /// Copied and then passed to `start`.
136136 context: []const u8,
137137 context_alignment: std.mem.Alignment,
138 start: *const fn (context: *const anyopaque) void,
139 ) ConcurrentError!void,
140 groupAwait: *const fn (?*anyopaque, *Group, token: *anyopaque) Cancelable!void,
141 groupCancel: *const fn (?*anyopaque, *Group, token: *anyopaque) void,
142
143 recancel: *const fn (?*anyopaque) void,
144 swapCancelProtection: *const fn (?*anyopaque, new: CancelProtection) CancelProtection,
145 checkCancel: *const fn (?*anyopaque) Cancelable!void,
146
147 futexWait: *const fn (?*anyopaque, ptr: *const u32, expected: u32, Timeout) Cancelable!void,
148 futexWaitUncancelable: *const fn (?*anyopaque, ptr: *const u32, expected: u32) void,
149 futexWake: *const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void,
150
151 operate: *const fn (?*anyopaque, Operation) Cancelable!Operation.Result,
152 batchAwaitAsync: *const fn (?*anyopaque, *Batch) Cancelable!void,
153 batchAwaitConcurrent: *const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void,
154 batchCancel: *const fn (?*anyopaque, *Batch) void,
155
156 dirCreateDir: *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,
158 dirCreateDirPathOpen: *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,
160 dirStat: *const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat,
161 dirStatFile: *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,
163 dirCreateFile: *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,
165 dirOpenFile: *const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File,
166 dirClose: *const fn (?*anyopaque, []const Dir) void,
167 dirRead: *const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize,
168 dirRealPath: *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,
170 dirDeleteFile: *const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void,
171 dirDeleteDir: *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,
173 dirRenamePreserve: *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,
175 dirReadLink: *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,
177 dirSetFileOwner: *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,
179 dirSetFilePermissions: *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,
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,
182
183 fileStat: *const fn (?*anyopaque, File) File.StatError!File.Stat,
184 fileLength: *const fn (?*anyopaque, File) File.LengthError!u64,
185 fileClose: *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,
187 fileWriteFileStreaming: *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,
138 start: Group.Start,
139 ) ConcurrentError!void),
140 groupAwait: @Restricted(*const fn (?*anyopaque, *Group, token: *anyopaque) Cancelable!void),
141 groupCancel: @Restricted(*const fn (?*anyopaque, *Group, token: *anyopaque) void),
142
143 recancel: @Restricted(*const fn (?*anyopaque) void),
144 swapCancelProtection: @Restricted(*const fn (?*anyopaque, new: CancelProtection) CancelProtection),
145 checkCancel: @Restricted(*const fn (?*anyopaque) Cancelable!void),
146
147 futexWait: @Restricted(*const fn (?*anyopaque, ptr: *const u32, expected: u32, Timeout) Cancelable!void),
148 futexWaitUncancelable: @Restricted(*const fn (?*anyopaque, ptr: *const u32, expected: u32) void),
149 futexWake: @Restricted(*const fn (?*anyopaque, ptr: *const u32, max_waiters: u32) void),
150
151 operate: @Restricted(*const fn (?*anyopaque, Operation) Cancelable!Operation.Result),
152 batchAwaitAsync: @Restricted(*const fn (?*anyopaque, *Batch) Cancelable!void),
153 batchAwaitConcurrent: @Restricted(*const fn (?*anyopaque, *Batch, Timeout) Batch.AwaitConcurrentError!void),
154 batchCancel: @Restricted(*const fn (?*anyopaque, *Batch) void),
155
156 dirCreateDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirError!void),
157 dirCreateDirPath: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions) Dir.CreateDirPathError!Dir.CreatePathStatus),
158 dirCreateDirPathOpen: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.Permissions, Dir.OpenOptions) Dir.CreateDirPathOpenError!Dir),
159 dirOpenDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.OpenOptions) Dir.OpenError!Dir),
160 dirStat: @Restricted(*const fn (?*anyopaque, Dir) Dir.StatError!Dir.Stat),
161 dirStatFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.StatFileOptions) Dir.StatFileError!File.Stat),
162 dirAccess: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.AccessOptions) Dir.AccessError!void),
163 dirCreateFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileOptions) File.OpenError!File),
164 dirCreateFileAtomic: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.CreateFileAtomicOptions) Dir.CreateFileAtomicError!File.Atomic),
165 dirOpenFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.OpenFileOptions) File.OpenError!File),
166 dirClose: @Restricted(*const fn (?*anyopaque, []const Dir) void),
167 dirRead: @Restricted(*const fn (?*anyopaque, *Dir.Reader, []Dir.Entry) Dir.Reader.Error!usize),
168 dirRealPath: @Restricted(*const fn (?*anyopaque, Dir, out_buffer: []u8) Dir.RealPathError!usize),
169 dirRealPathFile: @Restricted(*const fn (?*anyopaque, Dir, path_name: []const u8, out_buffer: []u8) Dir.RealPathFileError!usize),
170 dirDeleteFile: @Restricted(*const fn (?*anyopaque, Dir, []const u8) Dir.DeleteFileError!void),
171 dirDeleteDir: @Restricted(*const fn (?*anyopaque, Dir, []const u8) Dir.DeleteDirError!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: @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: @Restricted(*const fn (?*anyopaque, Dir, target_path: []const u8, sym_link_path: []const u8, Dir.SymLinkFlags) Dir.SymLinkError!void),
175 dirReadLink: @Restricted(*const fn (?*anyopaque, Dir, sub_path: []const u8, buffer: []u8) Dir.ReadLinkError!usize),
176 dirSetOwner: @Restricted(*const fn (?*anyopaque, Dir, ?File.Uid, ?File.Gid) Dir.SetOwnerError!void),
177 dirSetFileOwner: @Restricted(*const fn (?*anyopaque, Dir, []const u8, ?File.Uid, ?File.Gid, Dir.SetFileOwnerOptions) Dir.SetFileOwnerError!void),
178 dirSetPermissions: @Restricted(*const fn (?*anyopaque, Dir, Dir.Permissions) Dir.SetPermissionsError!void),
179 dirSetFilePermissions: @Restricted(*const fn (?*anyopaque, Dir, []const u8, File.Permissions, Dir.SetFilePermissionsOptions) Dir.SetFilePermissionsError!void),
180 dirSetTimestamps: @Restricted(*const fn (?*anyopaque, Dir, []const u8, Dir.SetTimestampsOptions) Dir.SetTimestampsError!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),
182
183 fileStat: @Restricted(*const fn (?*anyopaque, File) File.StatError!File.Stat),
184 fileLength: @Restricted(*const fn (?*anyopaque, File) File.LengthError!u64),
185 fileClose: @Restricted(*const fn (?*anyopaque, []const File) void),
186 fileWritePositional: @Restricted(*const fn (?*anyopaque, File, header: []const u8, data: []const []const u8, splat: usize, offset: u64) File.WritePositionalError!usize),
187 fileWriteFileStreaming: @Restricted(*const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit) File.Writer.WriteFileError!usize),
188 fileWriteFilePositional: @Restricted(*const fn (?*anyopaque, File, header: []const u8, *Io.File.Reader, Io.Limit, offset: u64) File.WriteFilePositionalError!usize),
189189 /// Returns 0 if reading at or past the end.
190 fileReadPositional: *const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize,
191 fileSeekBy: *const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void,
192 fileSeekTo: *const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void,
193 fileSync: *const fn (?*anyopaque, File) File.SyncError!void,
194 fileIsTty: *const fn (?*anyopaque, File) Cancelable!bool,
195 fileEnableAnsiEscapeCodes: *const fn (?*anyopaque, File) File.EnableAnsiEscapeCodesError!void,
196 fileSupportsAnsiEscapeCodes: *const fn (?*anyopaque, File) Cancelable!bool,
197 fileSetLength: *const fn (?*anyopaque, File, u64) File.SetLengthError!void,
198 fileSetOwner: *const fn (?*anyopaque, File, ?File.Uid, ?File.Gid) File.SetOwnerError!void,
199 fileSetPermissions: *const fn (?*anyopaque, File, File.Permissions) File.SetPermissionsError!void,
200 fileSetTimestamps: *const fn (?*anyopaque, File, File.SetTimestampsOptions) File.SetTimestampsError!void,
201 fileLock: *const fn (?*anyopaque, File, File.Lock) File.LockError!void,
202 fileTryLock: *const fn (?*anyopaque, File, File.Lock) File.LockError!bool,
203 fileUnlock: *const fn (?*anyopaque, File) void,
204 fileDowngradeLock: *const fn (?*anyopaque, File) File.DowngradeLockError!void,
205 fileRealPath: *const fn (?*anyopaque, File, out_buffer: []u8) File.RealPathError!usize,
206 fileHardLink: *const fn (?*anyopaque, File, Dir, []const u8, File.HardLinkOptions) File.HardLinkError!void,
207
208 fileMemoryMapCreate: *const fn (?*anyopaque, File, File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap,
209 fileMemoryMapDestroy: *const fn (?*anyopaque, *File.MemoryMap) void,
210 fileMemoryMapSetLength: *const fn (?*anyopaque, *File.MemoryMap, usize) File.MemoryMap.SetLengthError!void,
211 fileMemoryMapRead: *const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void,
212 fileMemoryMapWrite: *const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void,
213
214 processExecutableOpen: *const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File,
215 processExecutablePath: *const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize,
216 lockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr,
217 tryLockStderr: *const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr,
218 unlockStderr: *const fn (?*anyopaque) void,
219 processCurrentPath: *const fn (?*anyopaque, buffer: []u8) std.process.CurrentPathError!usize,
220 processSetCurrentDir: *const fn (?*anyopaque, Dir) std.process.SetCurrentDirError!void,
221 processSetCurrentPath: *const fn (?*anyopaque, []const u8) std.process.SetCurrentPathError!void,
222 processReplace: *const fn (?*anyopaque, std.process.ReplaceOptions) std.process.ReplaceError,
223 processReplacePath: *const fn (?*anyopaque, Dir, std.process.ReplaceOptions) std.process.ReplaceError,
224 processSpawn: *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,
226 childWait: *const fn (?*anyopaque, *std.process.Child) std.process.Child.WaitError!std.process.Child.Term,
227 childKill: *const fn (?*anyopaque, *std.process.Child) void,
228
229 progressParentFile: *const fn (?*anyopaque) std.Progress.ParentFileError!File,
230
231 now: *const fn (?*anyopaque, Clock) Timestamp,
232 clockResolution: *const fn (?*anyopaque, Clock) Clock.ResolutionError!Duration,
233 sleep: *const fn (?*anyopaque, Timeout) Cancelable!void,
234
235 random: *const fn (?*anyopaque, buffer: []u8) void,
236 randomSecure: *const fn (?*anyopaque, buffer: []u8) RandomSecureError!void,
237
238 netListenIp: *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,
240 netBindIp: *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,
242 netListenUnix: *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,
244 netSocketCreatePair: *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 },
246 netWrite: *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,
248 netClose: *const fn (?*anyopaque, handle: []const net.Socket.Handle) void,
249 netShutdown: *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,
251 netInterfaceName: *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,
190 fileReadPositional: @Restricted(*const fn (?*anyopaque, File, data: []const []u8, offset: u64) File.ReadPositionalError!usize),
191 fileSeekBy: @Restricted(*const fn (?*anyopaque, File, relative_offset: i64) File.SeekError!void),
192 fileSeekTo: @Restricted(*const fn (?*anyopaque, File, absolute_offset: u64) File.SeekError!void),
193 fileSync: @Restricted(*const fn (?*anyopaque, File) File.SyncError!void),
194 fileIsTty: @Restricted(*const fn (?*anyopaque, File) Cancelable!bool),
195 fileEnableAnsiEscapeCodes: @Restricted(*const fn (?*anyopaque, File) File.EnableAnsiEscapeCodesError!void),
196 fileSupportsAnsiEscapeCodes: @Restricted(*const fn (?*anyopaque, File) Cancelable!bool),
197 fileSetLength: @Restricted(*const fn (?*anyopaque, File, u64) File.SetLengthError!void),
198 fileSetOwner: @Restricted(*const fn (?*anyopaque, File, ?File.Uid, ?File.Gid) File.SetOwnerError!void),
199 fileSetPermissions: @Restricted(*const fn (?*anyopaque, File, File.Permissions) File.SetPermissionsError!void),
200 fileSetTimestamps: @Restricted(*const fn (?*anyopaque, File, File.SetTimestampsOptions) File.SetTimestampsError!void),
201 fileLock: @Restricted(*const fn (?*anyopaque, File, File.Lock) File.LockError!void),
202 fileTryLock: @Restricted(*const fn (?*anyopaque, File, File.Lock) File.LockError!bool),
203 fileUnlock: @Restricted(*const fn (?*anyopaque, File) void),
204 fileDowngradeLock: @Restricted(*const fn (?*anyopaque, File) File.DowngradeLockError!void),
205 fileRealPath: @Restricted(*const fn (?*anyopaque, File, out_buffer: []u8) File.RealPathError!usize),
206 fileHardLink: @Restricted(*const fn (?*anyopaque, File, Dir, []const u8, File.HardLinkOptions) File.HardLinkError!void),
207
208 fileMemoryMapCreate: @Restricted(*const fn (?*anyopaque, File, File.MemoryMap.CreateOptions) File.MemoryMap.CreateError!File.MemoryMap),
209 fileMemoryMapDestroy: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) void),
210 fileMemoryMapSetLength: @Restricted(*const fn (?*anyopaque, *File.MemoryMap, usize) File.MemoryMap.SetLengthError!void),
211 fileMemoryMapRead: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) File.ReadPositionalError!void),
212 fileMemoryMapWrite: @Restricted(*const fn (?*anyopaque, *File.MemoryMap) File.WritePositionalError!void),
213
214 processExecutableOpen: @Restricted(*const fn (?*anyopaque, Dir.OpenFileOptions) std.process.OpenExecutableError!File),
215 processExecutablePath: @Restricted(*const fn (?*anyopaque, buffer: []u8) std.process.ExecutablePathError!usize),
216 lockStderr: @Restricted(*const fn (?*anyopaque, ?Terminal.Mode) Cancelable!LockedStderr),
217 tryLockStderr: @Restricted(*const fn (?*anyopaque, ?Terminal.Mode) Cancelable!?LockedStderr),
218 unlockStderr: @Restricted(*const fn (?*anyopaque) void),
219 processCurrentPath: @Restricted(*const fn (?*anyopaque, buffer: []u8) std.process.CurrentPathError!usize),
220 processSetCurrentDir: @Restricted(*const fn (?*anyopaque, Dir) std.process.SetCurrentDirError!void),
221 processSetCurrentPath: @Restricted(*const fn (?*anyopaque, []const u8) std.process.SetCurrentPathError!void),
222 processReplace: @Restricted(*const fn (?*anyopaque, std.process.ReplaceOptions) std.process.ReplaceError),
223 processReplacePath: @Restricted(*const fn (?*anyopaque, Dir, std.process.ReplaceOptions) std.process.ReplaceError),
224 processSpawn: @Restricted(*const fn (?*anyopaque, 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: @Restricted(*const fn (?*anyopaque, *std.process.Child) std.process.Child.WaitError!std.process.Child.Term),
227 childKill: @Restricted(*const fn (?*anyopaque, *std.process.Child) void),
228
229 progressParentFile: @Restricted(*const fn (?*anyopaque) std.Progress.ParentFileError!File),
230
231 now: @Restricted(*const fn (?*anyopaque, Clock) Timestamp),
232 clockResolution: @Restricted(*const fn (?*anyopaque, Clock) Clock.ResolutionError!Duration),
233 sleep: @Restricted(*const fn (?*anyopaque, Timeout) Cancelable!void),
234
235 random: @Restricted(*const fn (?*anyopaque, buffer: []u8) void),
236 randomSecure: @Restricted(*const fn (?*anyopaque, buffer: []u8) RandomSecureError!void),
237
238 netListenIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, net.IpAddress.ListenOptions) net.IpAddress.ListenError!net.Socket),
239 netAccept: @Restricted(*const fn (?*anyopaque, server: net.Socket.Handle, options: net.Server.AcceptOptions) net.Server.AcceptError!net.Socket),
240 netBindIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.BindOptions) net.IpAddress.BindError!net.Socket),
241 netConnectIp: @Restricted(*const fn (?*anyopaque, address: *const net.IpAddress, options: net.IpAddress.ConnectOptions) net.IpAddress.ConnectError!net.Socket),
242 netListenUnix: @Restricted(*const fn (?*anyopaque, *const net.UnixAddress, net.UnixAddress.ListenOptions) net.UnixAddress.ListenError!net.Socket.Handle),
243 netConnectUnix: @Restricted(*const fn (?*anyopaque, *const net.UnixAddress) net.UnixAddress.ConnectError!net.Socket.Handle),
244 netSocketCreatePair: @Restricted(*const fn (?*anyopaque, net.Socket.CreatePairOptions) net.Socket.CreatePairError![2]net.Socket),
245 netSend: @Restricted(*const fn (?*anyopaque, net.Socket.Handle, []net.OutgoingMessage, net.SendFlags) struct { ?net.Socket.SendError, 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: @Restricted(*const fn (?*anyopaque, net.Socket.Handle, header: []const u8, *Io.File.Reader, Io.Limit) net.Stream.Writer.WriteFileError!usize),
248 netClose: @Restricted(*const fn (?*anyopaque, handle: []const net.Socket.Handle) void),
249 netShutdown: @Restricted(*const fn (?*anyopaque, handle: net.Socket.Handle, how: net.ShutdownHow) net.ShutdownError!void),
250 netInterfaceNameResolve: @Restricted(*const fn (?*anyopaque, *const net.Interface.Name) net.Interface.Name.ResolveError!net.Interface),
251 netInterfaceName: @Restricted(*const fn (?*anyopaque, net.Interface) net.Interface.NameError!net.Interface.Name),
252 netLookup: @Restricted(*const fn (?*anyopaque, net.HostName, *Queue(net.HostName.LookupResult), net.HostName.LookupOptions) net.HostName.LookupError!void),
253253};
254254
255pub const Operation = union(enum) {
255pub const Operation = union(@Restricted(Tag)) {
256256 file_read_streaming: FileReadStreaming,
257257 file_write_streaming: FileWriteStreaming,
258258 /// On Windows this is NtDeviceIoControlFile. On POSIX this is ioctl. On
......@@ -261,7 +261,13 @@ pub const Operation = union(enum) {
261261 net_receive: NetReceive,
262262 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
266272 /// May return 0 reads which is different than `error.EndOfStream`.
267273 pub const FileReadStreaming = struct {
......@@ -1187,7 +1193,9 @@ pub const Timeout = union(enum) {
11871193 }
11881194};
11891195
1190pub const AnyFuture = opaque {};
1196pub const AnyFuture = opaque {
1197 pub const Start = @Restricted(*const fn (context: *const anyopaque, result: *anyopaque) void);
1198};
11911199
11921200pub fn Future(Result: type) type {
11931201 return struct {
......@@ -1243,6 +1251,8 @@ pub const Group = struct {
12431251
12441252 pub const init: Group = .{ .token = .init(null), .state = 0 };
12451253
1254 pub const Start = @Restricted(*const fn (context: *const anyopaque) void);
1255
12461256 /// Equivalent to `Io.async`, except the task is spawned in this `Group`
12471257 /// instead of becoming associated with a `Future`.
12481258 ///
......@@ -2711,7 +2721,7 @@ pub fn noCrashHandler(userdata: ?*anyopaque) void {
27112721 _ = userdata;
27122722}
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 {
27152725 _ = userdata;
27162726 _ = result_alignment;
27172727 _ = context_alignment;
......@@ -2725,7 +2735,7 @@ pub fn failingConcurrent(
27252735 result_alignment: std.mem.Alignment,
27262736 context: []const u8,
27272737 context_alignment: std.mem.Alignment,
2728 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
2738 start: AnyFuture.Start,
27292739) ConcurrentError!*AnyFuture {
27302740 _ = userdata;
27312741 _ = result_len;
......@@ -2767,7 +2777,7 @@ pub fn noGroupAsync(
27672777 group: *Group,
27682778 context: []const u8,
27692779 context_alignment: std.mem.Alignment,
2770 start: *const fn (context: *const anyopaque) void,
2780 start: Group.Start,
27712781) void {
27722782 _ = userdata;
27732783 _ = group;
......@@ -2780,7 +2790,7 @@ pub fn failingGroupConcurrent(
27802790 group: *Group,
27812791 context: []const u8,
27822792 context_alignment: std.mem.Alignment,
2783 start: *const fn (context: *const anyopaque) void,
2793 start: Group.Start,
27842794) ConcurrentError!void {
27852795 _ = userdata;
27862796 _ = group;
lib/std/Io/Dispatch.zig+10-10
......@@ -986,7 +986,7 @@ fn crashHandler(userdata: ?*anyopaque) void {
986986const AsyncClosure = struct {
987987 evented: *Evented,
988988 fiber: *Fiber,
989 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
989 start: Io.AnyFuture.Start,
990990 result_align: Alignment,
991991
992992 fn fromFiber(fiber: *Fiber) *AsyncClosure {
......@@ -1038,8 +1038,8 @@ fn async(
10381038 result_alignment: Alignment,
10391039 context: []const u8,
10401040 context_alignment: Alignment,
1041 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
1042) ?*std.Io.AnyFuture {
1041 start: Io.AnyFuture.Start,
1042) ?*Io.AnyFuture {
10431043 const ev: *Evented = @ptrCast(@alignCast(userdata));
10441044 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {
10451045 start(context.ptr, result.ptr);
......@@ -1053,8 +1053,8 @@ fn concurrent(
10531053 result_alignment: Alignment,
10541054 context: []const u8,
10551055 context_alignment: Alignment,
1056 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
1057) Io.ConcurrentError!*std.Io.AnyFuture {
1056 start: Io.AnyFuture.Start,
1057) Io.ConcurrentError!*Io.AnyFuture {
10581058 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
10591059 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
10601060 assert(result_len <= Fiber.max_result_size); // TODO
......@@ -1101,7 +1101,7 @@ fn concurrent(
11011101
11021102fn await(
11031103 userdata: ?*anyopaque,
1104 future: *std.Io.AnyFuture,
1104 future: *Io.AnyFuture,
11051105 result: []u8,
11061106 result_alignment: Alignment,
11071107) void {
......@@ -1115,7 +1115,7 @@ fn await(
11151115
11161116fn cancel(
11171117 userdata: ?*anyopaque,
1118 future: *std.Io.AnyFuture,
1118 future: *Io.AnyFuture,
11191119 result: []u8,
11201120 result_alignment: Alignment,
11211121) void {
......@@ -1329,7 +1329,7 @@ const Group = struct {
13291329 evented: *Evented,
13301330 group: Group,
13311331 fiber: *Fiber,
1332 start: *const fn (context: *const anyopaque) void,
1332 start: Io.Group.Start,
13331333
13341334 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {
13351335 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(
......@@ -1381,7 +1381,7 @@ fn groupAsync(
13811381 type_erased: *Io.Group,
13821382 context: []const u8,
13831383 context_alignment: Alignment,
1384 start: *const fn (context: *const anyopaque) void,
1384 start: Io.Group.Start,
13851385) void {
13861386 const ev: *Evented = @ptrCast(@alignCast(userdata));
13871387 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {
......@@ -1394,7 +1394,7 @@ fn groupConcurrent(
13941394 type_erased: *Io.Group,
13951395 context: []const u8,
13961396 context_alignment: Alignment,
1397 start: *const fn (context: *const anyopaque) void,
1397 start: Io.Group.Start,
13981398) Io.ConcurrentError!void {
13991399 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
14001400 assert(context.len <= Fiber.max_context_size); // TODO
lib/std/Io/Kqueue.zig+11-11
......@@ -3,15 +3,15 @@ const builtin = @import("builtin");
33
44const std = @import("../std.zig");
55const Io = std.Io;
6const Dir = std.Io.Dir;
7const File = std.Io.File;
8const net = std.Io.net;
6const Dir = Io.Dir;
7const File = Io.File;
8const net = Io.net;
99const assert = std.debug.assert;
1010const Allocator = std.mem.Allocator;
1111const Alignment = std.mem.Alignment;
12const IpAddress = std.Io.net.IpAddress;
13const errnoBug = std.Io.Threaded.errnoBug;
14const closeFd = std.Io.Threaded.closeFd;
12const IpAddress = Io.net.IpAddress;
13const errnoBug = Io.Threaded.errnoBug;
14const closeFd = Io.Threaded.closeFd;
1515const posix = std.posix;
1616const posixSocketModeProtocol = Io.Threaded.posixSocketModeProtocol;
1717
......@@ -577,7 +577,7 @@ fn fiberEntry() callconv(.naked) void {
577577const AsyncClosure = struct {
578578 kqueue: *Kqueue,
579579 fiber: *Fiber,
580 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
580 start: Io.AnyFuture.Start,
581581 result_align: Alignment,
582582 already_awaited: bool,
583583
......@@ -669,7 +669,7 @@ fn async(
669669 result_alignment: std.mem.Alignment,
670670 context: []const u8,
671671 context_alignment: std.mem.Alignment,
672 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
672 start: Io.AnyFuture.Start,
673673) ?*Io.AnyFuture {
674674 return concurrent(userdata, result.len, result_alignment, context, context_alignment, start) catch {
675675 start(context.ptr, result.ptr);
......@@ -683,7 +683,7 @@ fn concurrent(
683683 result_alignment: Alignment,
684684 context: []const u8,
685685 context_alignment: Alignment,
686 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
686 start: Io.AnyFuture.Start,
687687) Io.ConcurrentError!*Io.AnyFuture {
688688 const k: *Kqueue = @ptrCast(@alignCast(userdata));
689689 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
......@@ -767,7 +767,7 @@ fn groupAsync(
767767 type_erased: *Io.Group,
768768 context: []const u8,
769769 context_alignment: Alignment,
770 start: *const fn (context: *const anyopaque) void,
770 start: Io.Group.Start,
771771) void {
772772 const k: *Kqueue = @ptrCast(@alignCast(userdata));
773773 _ = k;
......@@ -783,7 +783,7 @@ fn groupConcurrent(
783783 type_erased: *Io.Group,
784784 context: []const u8,
785785 context_alignment: Alignment,
786 start: *const fn (context: *const anyopaque) void,
786 start: Io.Group.Start,
787787) Io.ConcurrentError!void {
788788 const k: *Kqueue = @ptrCast(@alignCast(userdata));
789789 _ = k;
lib/std/Io/Reader.zig+4-4
......@@ -43,7 +43,7 @@ pub const VTable = struct {
4343 /// choose to store data in `buffer`, modifying `seek` and `end`
4444 /// accordingly. Implementations are encouraged to take advantage of
4545 /// 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
4848 /// Consumes bytes from the internally tracked stream position without
4949 /// providing access to them.
......@@ -64,7 +64,7 @@ pub const VTable = struct {
6464 /// data.
6565 ///
6666 /// 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
6969 /// Returns number of bytes written to `data`.
7070 ///
......@@ -84,7 +84,7 @@ pub const VTable = struct {
8484 ///
8585 /// The default implementation calls `stream` with either `data[0]` or
8686 /// `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
8989 /// Ensures `capacity` data can be buffered without rebasing.
9090 ///
......@@ -96,7 +96,7 @@ pub const VTable = struct {
9696 ///
9797 /// The default implementation moves buffered data to the start of
9898 /// `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,
100100};
101101
102102pub const StreamError = error{
lib/std/Io/Threaded.zig+14-17
......@@ -449,7 +449,7 @@ const default_fn_align = switch (builtin.mode) {
449449
450450const Runnable = struct {
451451 node: std.SinglyLinkedList.Node,
452 startFn: *const fn (*Runnable, *Thread, *Threaded) void,
452 startFn: @Restricted(*const fn (*Runnable, *Thread, *Threaded) void),
453453};
454454
455455const Group = struct {
......@@ -484,7 +484,7 @@ const Group = struct {
484484 const Task = struct {
485485 runnable: Runnable,
486486 group: *Io.Group,
487 func: *const fn (context: *const anyopaque) void,
487 startFn: Io.Group.Start,
488488 context_alignment: Alignment,
489489 alloc_len: usize,
490490
......@@ -494,7 +494,7 @@ const Group = struct {
494494 group: Group,
495495 context: []const u8,
496496 context_alignment: Alignment,
497 func: *const fn (context: *const anyopaque) void,
497 startFn: Io.Group.Start,
498498 ) Allocator.Error!*Task {
499499 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Task);
500500 const worst_case_context_offset = context_alignment.forward(@sizeOf(Task) + max_context_misalignment);
......@@ -509,7 +509,7 @@ const Group = struct {
509509 .startFn = &start,
510510 },
511511 .group = group.ptr,
512 .func = func,
512 .startFn = startFn,
513513 .context_alignment = context_alignment,
514514 .alloc_len = alloc_len,
515515 };
......@@ -549,7 +549,7 @@ const Group = struct {
549549 }, .monotonic);
550550 }
551551
552 task.func(task.contextPointer());
552 task.startFn(task.contextPointer());
553553
554554 thread.status.store(.{ .cancelation = .none, .awaitable = .null }, .monotonic);
555555 const old_status = group.status().fetchSub(.{
......@@ -631,7 +631,7 @@ const Group = struct {
631631/// 2. result
632632const Future = struct {
633633 runnable: Runnable,
634 func: *const fn (context: *const anyopaque, result: *anyopaque) void,
634 startFn: Io.AnyFuture.Start,
635635 status: std.atomic.Value(Status),
636636 /// On completion, increment this `u32` and do a futex wake on it.
637637 awaiter: *std.atomic.Value(u32),
......@@ -666,7 +666,7 @@ const Future = struct {
666666 result_alignment: Alignment,
667667 context: []const u8,
668668 context_alignment: Alignment,
669 func: *const fn (context: *const anyopaque, result: *anyopaque) void,
669 startFn: Io.AnyFuture.Start,
670670 ) Allocator.Error!*Future {
671671 const max_context_misalignment = context_alignment.toByteUnits() -| @alignOf(Future);
672672 const worst_case_context_offset = context_alignment.forward(@sizeOf(Future) + max_context_misalignment);
......@@ -684,7 +684,7 @@ const Future = struct {
684684 .node = undefined,
685685 .startFn = &start,
686686 },
687 .func = func,
687 .startFn = startFn,
688688 .status = .init(.{
689689 .tag = .pending,
690690 .thread = .null,
......@@ -738,7 +738,7 @@ const Future = struct {
738738 }
739739 }
740740
741 future.func(future.contextPointer(), future.resultPointer());
741 future.startFn(future.contextPointer(), future.resultPointer());
742742
743743 const had_acknowledged_cancel = switch (thread.status.load(.monotonic).cancelation) {
744744 .none, .canceling => false,
......@@ -2073,7 +2073,7 @@ fn async(
20732073 result_alignment: Alignment,
20742074 context: []const u8,
20752075 context_alignment: Alignment,
2076 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
2076 start: Io.AnyFuture.Start,
20772077) ?*Io.AnyFuture {
20782078 const t: *Threaded = @ptrCast(@alignCast(userdata));
20792079 if (builtin.single_threaded) {
......@@ -2129,7 +2129,7 @@ fn concurrent(
21292129 result_alignment: Alignment,
21302130 context: []const u8,
21312131 context_alignment: Alignment,
2132 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
2132 start: Io.AnyFuture.Start,
21332133) Io.ConcurrentError!*Io.AnyFuture {
21342134 if (builtin.single_threaded) return error.ConcurrencyUnavailable;
21352135
......@@ -2174,7 +2174,7 @@ fn groupAsync(
21742174 type_erased: *Io.Group,
21752175 context: []const u8,
21762176 context_alignment: Alignment,
2177 start: *const fn (context: *const anyopaque) void,
2177 start: Io.Group.Start,
21782178) void {
21792179 const t: *Threaded = @ptrCast(@alignCast(userdata));
21802180 const g: Group = .{ .ptr = type_erased };
......@@ -2224,10 +2224,7 @@ fn groupAsync(
22242224 mutexUnlock(&t.mutex);
22252225 condSignal(&t.cond);
22262226}
2227fn groupAsyncEager(
2228 start: *const fn (context: *const anyopaque) void,
2229 context: *const anyopaque,
2230) void {
2227fn groupAsyncEager(start: Io.Group.Start, context: *const anyopaque) void {
22312228 start(context);
22322229}
22332230
......@@ -2236,7 +2233,7 @@ fn groupConcurrent(
22362233 type_erased: *Io.Group,
22372234 context: []const u8,
22382235 context_alignment: Alignment,
2239 start: *const fn (context: *const anyopaque) void,
2236 start: Io.Group.Start,
22402237) Io.ConcurrentError!void {
22412238 if (builtin.single_threaded) return error.ConcurrencyUnavailable;
22422239
lib/std/Io/Uring.zig+10-10
......@@ -1375,7 +1375,7 @@ fn crashHandler(userdata: ?*anyopaque) void {
13751375const AsyncClosure = struct {
13761376 evented: *Evented,
13771377 fiber: *Fiber,
1378 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
1378 start: Io.AnyFuture.Start,
13791379 result_align: Alignment,
13801380
13811381 fn fromFiber(fiber: *Fiber) *AsyncClosure {
......@@ -1431,8 +1431,8 @@ fn async(
14311431 result_alignment: Alignment,
14321432 context: []const u8,
14331433 context_alignment: Alignment,
1434 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
1435) ?*std.Io.AnyFuture {
1434 start: Io.AnyFuture.Start,
1435) ?*Io.AnyFuture {
14361436 const ev: *Evented = @ptrCast(@alignCast(userdata));
14371437 return concurrent(ev, result.len, result_alignment, context, context_alignment, start) catch {
14381438 start(context.ptr, result.ptr);
......@@ -1446,8 +1446,8 @@ fn concurrent(
14461446 result_alignment: Alignment,
14471447 context: []const u8,
14481448 context_alignment: Alignment,
1449 start: *const fn (context: *const anyopaque, result: *anyopaque) void,
1450) Io.ConcurrentError!*std.Io.AnyFuture {
1449 start: Io.AnyFuture.Start,
1450) Io.ConcurrentError!*Io.AnyFuture {
14511451 assert(result_alignment.compare(.lte, Fiber.max_result_align)); // TODO
14521452 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
14531453 assert(result_len <= Fiber.max_result_size); // TODO
......@@ -1510,7 +1510,7 @@ fn concurrent(
15101510
15111511fn await(
15121512 userdata: ?*anyopaque,
1513 future: *std.Io.AnyFuture,
1513 future: *Io.AnyFuture,
15141514 result: []u8,
15151515 result_alignment: Alignment,
15161516) void {
......@@ -1524,7 +1524,7 @@ fn await(
15241524
15251525fn cancel(
15261526 userdata: ?*anyopaque,
1527 future: *std.Io.AnyFuture,
1527 future: *Io.AnyFuture,
15281528 result: []u8,
15291529 result_alignment: Alignment,
15301530) void {
......@@ -1739,7 +1739,7 @@ const Group = struct {
17391739 evented: *Evented,
17401740 group: Group,
17411741 fiber: *Fiber,
1742 start: *const fn (context: *const anyopaque) void,
1742 start: Group.Start,
17431743
17441744 fn fromFiber(fiber: *Fiber) *Group.AsyncClosure {
17451745 return @ptrFromInt(Fiber.max_context_align.max(.of(Group.AsyncClosure)).backward(
......@@ -1797,7 +1797,7 @@ fn groupAsync(
17971797 type_erased: *Io.Group,
17981798 context: []const u8,
17991799 context_alignment: Alignment,
1800 start: *const fn (context: *const anyopaque) void,
1800 start: Group.Start,
18011801) void {
18021802 const ev: *Evented = @ptrCast(@alignCast(userdata));
18031803 return groupConcurrent(ev, type_erased, context, context_alignment, start) catch {
......@@ -1810,7 +1810,7 @@ fn groupConcurrent(
18101810 type_erased: *Io.Group,
18111811 context: []const u8,
18121812 context_alignment: Alignment,
1813 start: *const fn (context: *const anyopaque) void,
1813 start: Group.Start,
18141814) Io.ConcurrentError!void {
18151815 assert(context_alignment.compare(.lte, Fiber.max_context_align)); // TODO
18161816 assert(context.len <= Fiber.max_context_size); // TODO
lib/std/Io/Writer.zig+5-5
......@@ -43,7 +43,7 @@ pub const VTable = struct {
4343 /// Number of bytes returned may be zero, which does not indicate stream
4444 /// end. A subsequent call may return nonzero, or signal end of stream via
4545 /// `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
4848 /// Copies contents from an open file to the logical sink. `buffer[0..end]`
4949 /// is consumed first, followed by `limit` bytes from `file_reader`.
......@@ -60,14 +60,14 @@ pub const VTable = struct {
6060 ///
6161 /// `error.Unimplemented` indicates the callee cannot offer a more
6262 /// efficient implementation than the caller performing its own reads.
63 sendFile: *const fn (
63 sendFile: @Restricted(*const fn (
6464 w: *Writer,
6565 file_reader: *File.Reader,
6666 /// Maximum amount of bytes to read from the file. Implementations may
6767 /// assume that the file size does not exceed this amount. Data from
6868 /// `buffer` does not count towards this limit.
6969 limit: Limit,
70 ) FileError!usize = unimplementedSendFile,
70 ) FileError!usize) = unimplementedSendFile,
7171
7272 /// Consumes all remaining buffer.
7373 ///
......@@ -77,7 +77,7 @@ pub const VTable = struct {
7777 ///
7878 /// There may be subsequent calls to `drain` and `sendFile` after a `flush`
7979 /// operation.
80 flush: *const fn (w: *Writer) Error!void = defaultFlush,
80 flush: @Restricted(*const fn (w: *Writer) Error!void) = defaultFlush,
8181
8282 /// Ensures `capacity` more bytes can be buffered without rebasing.
8383 ///
......@@ -85,7 +85,7 @@ pub const VTable = struct {
8585 ///
8686 /// Only called when `capacity` bytes cannot fit into the unused capacity
8787 /// 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,
8989};
9090
9191pub const Error = error{
lib/std/http.zig+1-1
......@@ -772,7 +772,7 @@ pub const BodyWriter = struct {
772772 };
773773
774774 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;
776776 }
777777
778778 /// Sends all buffered data across `BodyWriter.http_protocol_output`.
lib/std/mem/Allocator.zig+4-4
......@@ -26,7 +26,7 @@ pub const VTable = struct {
2626 /// `ret_addr` is optionally provided as the first return address of the
2727 /// allocation call stack. If the value is `0` it means no return address
2828 /// 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
3131 /// Attempt to expand or shrink memory in place.
3232 ///
......@@ -45,7 +45,7 @@ pub const VTable = struct {
4545 /// `ret_addr` is optionally provided as the first return address of the
4646 /// allocation call stack. If the value is `0` it means no return address
4747 /// 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
5050 /// Attempt to expand or shrink memory, allowing relocation.
5151 ///
......@@ -66,7 +66,7 @@ pub const VTable = struct {
6666 /// `ret_addr` is optionally provided as the first return address of the
6767 /// allocation call stack. If the value is `0` it means no return address
6868 /// 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
7171 /// Free and invalidate a region of memory.
7272 ///
......@@ -78,7 +78,7 @@ pub const VTable = struct {
7878 /// `ret_addr` is optionally provided as the first return address of the
7979 /// allocation call stack. If the value is `0` it means no return address
8080 /// 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),
8282};
8383
8484pub fn noAlloc(