Yes. But there was also a non-snapshot cycle.
Normally a cellloop / streamloop is constructing a forward reference to the actual
output. But in your case your feeding the
new_output stream back into
output which is defined in terms of
Conceptually you have:
output = output.filter(...).filter(...)...
For the expression
a.snapshot(b,...) the snapshot protects you for a cycle through
b, because it is just calling
b internally during transactions. But does not protect you for a cycle through
So here is the devil in the original code:
let new_output = output.snapshot(&output_cell_loop.cell(),
That's where the cycle occurred. "CYCLE HERE".snapshot("NOT HERE",...).
Using defer can be kind of magic, you can change new into old.
new_output = output.filter(...)
Defer is like an old function (the stream before current transaction) "old(new_output) is output" --> "defer(new_output) is output".