Skip to content

Fix GH-15375: nested "yield from" skips items after valid()/next() - #22640

Closed
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/gh-15375-nested-yield-from
Closed

Fix GH-15375: nested "yield from" skips items after valid()/next()#22640
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/gh-15375-nested-yield-from

Conversation

@iliaal

@iliaal iliaal commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Nested yield from drops the inner generator's current value on the second and later delegations when it was primed via valid()/next(). The ZEND_GENERATOR_DO_INIT guard in zend_generator_resume() reads the flag on orig_generator, but in a nested chain the fresh delegation is established by the middle generator, whose flag it never checks. Track and check the delegating generator instead.

Fixes #15375

The DO_INIT guard in zend_generator_resume() that avoids re-advancing an
already-primed delegate read the flag on orig_generator, but in a nested
"yield from" chain the fresh delegation is established by a middle generator
rather than the outermost consumer. Track the delegating generator through
the resume loop and check its DO_INIT, so a primed inner generator reached
through two "yield from" levels yields its current value once instead of
skipping it.

Fixes phpGH-15375

@arnaud-lb arnaud-lb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks right to me!

@iliaal iliaal closed this in 0ccff76 Aug 12, 2026
@kocsismate

Copy link
Copy Markdown
Member

Is it possible that this commit broke the symfony demo app? if you have a look at the nightly benchmark logs (https://github.com/php/php-src/actions/runs/31758646923/job/94639986302#step:16:20969), it will be visible that the end of the HTML is duplicated for some reason:

aws_instance.host (remote-exec):                 <!-- Page rendered on August 14, 2026 at 1:00:17 AM UTC -->
aws_instance.host (remote-exec):     </body>
aws_instance.host (remote-exec): </html>
aws_instance.host (remote-exec):  -->
aws_instance.host (remote-exec):     </body>
aws_instance.host (remote-exec): </html>

even though the template properly has them: https://github.com/symfony/demo/blob/v2.8.0/templates/base.html.twig#L140

I "bisected" the PHP commits one by one and this was the first commit where the benchmark broke.

@iliaal

iliaal commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

Yes. Same as #23301: Twig's trailing yield from [] re-emits the last chunk ( --> / </html>). #23302.

@kocsismate

Copy link
Copy Markdown
Member

Is it possible to revert this change until the fix is merged?

@LamentXU123

Copy link
Copy Markdown
Member

If there is a real-world impact (in fact there is) we should revert this and apply #23302

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants