McpScope
Receiver of a cross-tick iterator { ... } snippet — scope and iterator in one object, as the stdlib's SequenceBuilderIterator is. Replaces the stdlib builder for three reasons:
yield renders what it is handed. The lane drives the iterator to exhaustion and discards every element, so under the stdlib builder
iterator { ...; yield(answer) }reported"(no output)"— the one snippet shape that could not answer, silently. Rendering must happen at the yield, not at the driver: by then the value is a bareObject, and a runtime type is no substitute (listOf(1, 2)reads asjava.util.Arrays$ArrayList). Only areifiedparameter, resolved per call site, keepskotlin.collections.List<kotlin.Int>— and a reifiedyieldmust beinline, which rules out overriding the stdlib'sabstractone.RestrictsSuspension carries its weight. It is what makes yield the only suspension point in the body, so a step always resumes on the thread that called hasNext. Without it a snippet can
kotlinx.coroutines.delay(..)— on the game loader here — and wake on a foreign thread while the lane still believes it owns the tick. The annotation is public, so we keep that guard without extendingSequenceScope.A suspended body can be ended. The stdlib only ever resumes its body with success, so one left at a
yieldnever runs itsfinallyblocks — and an eval that ends early leaves its body exactly there. unwind resumes it with a throw instead, and the body releases what it holds on its way out.
No yieldAll: its only remaining meaning would be "yield in bulk, silently", which is the opposite of the point. for (v in xs) yield(v) is one line and reports each element.
Types
Five states: the stdlib's six, less the two that go with yieldAll's delegate-pull, plus the split of its single Failed — see Resuming.
Functions
The same ValueRender.line a single-tick result goes through, so the two cannot report differently.
Rethrow so a throw surfaces out of the hasNext that resumed it — the lane's guard turns it into partial output plus a stack. State FIRST: getOrThrow does not return on a failure, so setting it after would strand Step.Resuming and misreport the next entry as a suspension that never happened.
End a suspended body: throw out of the yield it stopped at, so its finally blocks and use {} closes run. The body runs on the calling thread, as under hasNext, so call this where a step would run. One not yet started throws before its first line — right, since it opened nothing.
The suspension itself — everything yield does apart from rendering. @PublishedApi for the inline call.