Bug #70965 [Csd->Ver]: `yield from` with a common iterator primes too much
Edit report at https://bugs.php.net/bug.php?id=70965&edit=1
ID: 70965
Updated by: bwoebi@php.net
Reported by: srice at fb dot com
Summary: yield from with a common iterator primes too much
-Status: Closed
+Status: Verified
Type: Bug
Package: Scripting Engine problem
Operating System: Linux
PHP Version: 7.0.0RC7
Assigned To: bwoebi
Block user comment: N
Private report: N
New Comment:
You are right⦠re-opening, will fix tomorrowâ¦
Previous Comments:
------------------------------------------------------------------------
[2015-11-24 23:11:51] srice at fb dot com
Thanks for the quick response! To be clear, the issue isnt the null at the end, its that
int(2) never gets yielded. An element is skipped in the iterator.
I'll let you decide to reopen the bug or not (cause I'm not sure if its still fixed by
your other change), but I'm pretty sure the last two values shouldn't be
int(10) int(10).
------------------------------------------------------------------------
[2015-11-24 22:55:54] bwoebi@php.net
Just seen this now⦠I've just fixed this "accidentally" as a side effect by the
bugfix for #70904 :-)
The last two values should be int(10) int(10); this is the case because the validity of the calling
generator is not affected by the validity of the yielded generator. The values are just synchronized
between all generators. So the last value of the generators is actually the last value of the
subgenerator you yielded from. (which is why it's twice.)
------------------------------------------------------------------------
[2015-11-24 21:14:38] srice at fb dot com
I used a similar test case for both of them, but I actually worked around the linked bug in this
test case (notice the while statement is checking the inner generator for validity,
while the linked bug checks the outer generator for validity).
This one seems to be due to autopriming (autopriming the second generator advances the shared
iterator) while the other is due to the valid method returning the result of valid on the delegate
generator (which is not an assumption you can make, since the outer generator still might have
yields to execute).
------------------------------------------------------------------------
[2015-11-24 20:56:05] requinix@php.net
Looks similar to bug #70904.
------------------------------------------------------------------------
[2015-11-24 17:35:25] srice at fb dot com
Description:
------------
When two separate generator instances yield from a common iterator the second element
of the iterator gets skipped. There is a test case to keep this from happening with a common shared
generator (and the fix keeps track of which generator is priming or not) but it doesnt work with
iterators. See the sample script below (which is mostly just a small change to the
multiple_yield_from_on_same_generator test that already exists).
Test script:
---------------
<?php
function it() {
yield from [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
}
function bar($g) {
yield from $g;
}
$gen = it();
$gens[] = bar($gen);
$gens[] = bar($gen);
do {
foreach($gens as $g) {
var_dump($g->current());
$gen->next();
}
} while ($gen->valid());
Expected result:
----------------
int(1)
int(2)
int(3)
int(4)
int(5)
int(6)
int(7)
int(8)
int(9)
int(10)
Actual result:
--------------
int(1)
int(3)
int(4)
int(5)
int(6)
int(7)
int(8)
int(9)
int(10)
NULL
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70965&edit=1
Thread (7 messages)