-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
When you await
a promise
in the same stack frame or coroutine frame that you created it with async
, we can guarantee that no memory allocation occurs. With status quo Zig, I've been using async foo() catch unreachable
, but this is problematic for a few reasons:
- It's not the correct semantics. This means that the allocation may occur, but we know we have enough memory available in the allocator so that the next allocation will not fail.
catch unreachable
should stick out as a noticeable code smell. Guaranteed memory allocation elision for async calls is common, and should be used often. False positives like this harm people's respect for trying to avoidcatch unreachable
.
Proposal: use async<>
with empty angle brackets to require frame allocation elision.
async fn foo() void {
await async<> bar();
}
Using async<>
asserts that the corresponding await
or cancel
will occur in the same stack frame or coroutine frame.
Implementation details:
It's certainly possible to make a runtime safety check for this. We can make a convention that passing a null pointer as the allocator means it must be elided, and then when asked to do an allocation, if the allocator is null, call panic.
Theoretically we should be able to have a compile error for not being able to do the elision. However this depends on LLVM IR passes. So it would require inspection into the LLVM IR module post-optimization. This is inherently tricky and would require research.