Skip to content

syntax for guaranteed coroutine frame allocation elision #1260

@andrewrk

Description

@andrewrk

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 avoid catch 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    proposalThis issue suggests modifications. If it also has the "accepted" label then it is planned.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions