Why this fires¶
fn* child() -> int { yield 1 }
fn* parent() -> int { yield ... child() }The child must come from a checked generator declaration, a factory with a proved returned producer, an owned standard iterator adapter, or a canonical Iterator and Cleanup witness. An Iter annotation, Any value, or similarly named next/close methods does not establish its ownership and cleanup contract.
The child is acquired once when execution reaches the delegation. Each parent pull requests one child item. Finishing or closing the parent closes the live child and drains cleanup before acknowledging closure.
Use a checked factory or supported owned adapter. Keep await in an async function: delegation does not change TE224 for fn*.
Canonical Iterator and Cleanup methods must satisfy their declared pure trait contracts. A newly constructed nominal child, including a checked factory tail returning it, can carry those witnesses; a borrowed parameter cannot. Non-generic self-only callbacks are supported by the current executable binder. JavaScript and standalone wasm-aot reject delegation explicitly because they do not provide the authenticated close lifecycle; ordinary generators retain their existing backend behavior.
Delegation consumes a linear child. Its actual next/body and cleanup effects remain part of the enclosing generator's effect contract. A readonly presentation is available only for the unchanged owning node that was checked.