Async / Await
Zynx provides a hot-start, single-runtime async/await model.
Async Functions
Declare with async fn. Calling an async function returns a Future<T> and schedules it with the runtime.
async fn add(a: i32, b: i32) -> i32 {
return a + b;
}
Await
Use await inside an async fn to suspend until a Future<T> is ready.
async fn main() {
let value = await add(20, 22);
os.write("{value}\n");
}
awaitis only valid withinasync fn.- Error propagation remains explicit:
await Future<T!>yieldsT!, requiringtryorcatch.
Cancellation
Cancellation is cooperative and applies only to error-carrying futures (Future<T!>).
async fn main() {
let fut = work();
let p = Promise<i32!> { future: fut };
_ = p.cancel(); // Request cancellation
let value = (await fut) catch 99;
}
Suspend-Safety Rules
To maintain memory safety, the following are prohibited across await points:
- Borrows: Neither mutable nor shared borrows may live across
await. - Defer:
deferblocks cannot remain live acrossawait.
Implementation Details
Async Main
An async fn main initializes the runtime, schedules the task, and runs the event loop until completion.
Lowering and Shapes
The compiler optimizes common async patterns (linear sequences, simple loops, condition trees). If a pattern isn't optimized, it uses a fallback lowering strategy and emits a compile-time warning.
To inspect shape detection:
zynx --dump-async-shape <file.zx>