Declare tentative return types for Zend (#7251)

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
This commit is contained in:
Máté Kocsis 2021-07-19 13:44:20 +02:00 committed by GitHub
parent 26fc7c4256
commit 75a678a7e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
130 changed files with 627 additions and 597 deletions

View File

@ -5,18 +5,18 @@ Using indirect append on ArrayAccess object
class AA implements ArrayAccess {
private $data = [];
public function &offsetGet($name) {
public function &offsetGet($name): mixed {
if (null === $name) {
return $this->data[];
} else {
return $this->data[$name];
}
}
public function offsetSet($name, $value) {
public function offsetSet($name, $value): void {
$this->data[$name] = $value;
}
public function offsetUnset($name) {}
public function offsetExists($name) {}
public function offsetUnset($name): void {}
public function offsetExists($name): bool {}
}
$aa = new AA;

View File

@ -12,10 +12,10 @@ class Outer {
public function getArrayAccess() {
/* create a proxy object implementing array access */
return new class($this->data) extends Outer implements ArrayAccess {
public function offsetGet($offset) { return $this->data[$offset]; }
public function offsetSet($offset, $data) { return ($this->data[$offset] = $data); }
public function offsetUnset($offset) { unset($this->data[$offset]); }
public function offsetExists($offset) { return isset($this->data[$offset]); }
public function offsetGet($offset): mixed { return $this->data[$offset]; }
public function offsetSet($offset, $data): void { $this->data[$offset] = $data; }
public function offsetUnset($offset): void { unset($this->data[$offset]); }
public function offsetExists($offset): bool { return isset($this->data[$offset]); }
};
}
}

View File

@ -14,10 +14,10 @@ class Outer {
/* create a child object implementing array access */
/* this grants you access to protected methods and members */
return new class($this->data) implements ArrayAccess {
public function offsetGet($offset) { return $this->data[$offset]; }
public function offsetSet($offset, $data) { return ($this->data[$offset] = $data); }
public function offsetUnset($offset) { unset($this->data[$offset]); }
public function offsetExists($offset) { return isset($this->data[$offset]); }
public function offsetGet($offset): mixed { return $this->data[$offset]; }
public function offsetSet($offset, $data): void { $this->data[$offset] = $data; }
public function offsetUnset($offset): void { unset($this->data[$offset]); }
public function offsetExists($offset): bool { return isset($this->data[$offset]); }
};
}
}

View File

@ -8,7 +8,7 @@ function test(...$args) {
}
class Foo implements IteratorAggregate {
public function getIterator() {
public function getIterator(): Traversable {
throw new Exception('getIterator');
}
}

View File

@ -3,9 +3,9 @@ Bug #55719 (Argument restriction should come with a more specific error message)
--FILE--
<?php
class Sub implements ArrayAccess {
public function offsetSet() {
public function offsetSet(): void {
}
}
?>
--EXPECTF--
Fatal error: Declaration of Sub::offsetSet() must be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value) in %sargument_restriction_005.php on line %d
Fatal error: Declaration of Sub::offsetSet(): void must be compatible with ArrayAccess::offsetSet(mixed $offset, mixed $value): void in %sargument_restriction_005.php on line %d

View File

@ -26,15 +26,15 @@ try {
var_dump($ary);
class AA implements ArrayAccess {
public function offsetExists($k) {
public function offsetExists($k): bool {
return true;
}
public function &offsetGet($k) {
public function &offsetGet($k): mixed {
$var = ["foo" => "bar"];
return $var;
}
public function offsetSet($k,$v) {}
public function offsetUnset($k) {}
public function offsetSet($k,$v): void {}
public function offsetUnset($k): void {}
}
class Dtor {
@ -52,14 +52,14 @@ try {
var_dump($foo);
class AA2 implements ArrayAccess {
public function offsetExists($k) {
public function offsetExists($k): bool {
return false;
}
public function offsetGet($k) {
public function offsetGet($k): mixed {
return null;
}
public function offsetSet($k,$v) {}
public function offsetUnset($k) {}
public function offsetSet($k,$v): void {}
public function offsetUnset($k): void {}
}
$ary = ["foo" => new AA2];

View File

@ -13,19 +13,19 @@ class AA implements ArrayAccess {
public function __construct($data = []) {
$this->data = $data;
}
public function &offsetGet($k) {
public function &offsetGet($k): mixed {
echo "offsetGet($k)\n";
return $this->data[$k];
}
public function offsetExists($k) {
public function offsetExists($k): bool {
echo "offsetExists($k)\n";
return array_key_exists($k, $this->data);
}
public function offsetSet($k,$v) {
public function offsetSet($k,$v): void {
echo "offsetSet($k,$v)\n";
$this->data[$k] = $v;
}
public function offsetUnset($k) { }
public function offsetUnset($k): void { }
}
$ary = new AA(["foo" => new AA, "null" => null]);

View File

@ -4,6 +4,7 @@ Bug #26229 (getIterator() segfaults when it returns arrays or scalars)
<?php
class array_iterator implements IteratorAggregate {
#[ReturnTypeWillChange]
public function getIterator() {
return array('foo', 'bar');
}

View File

@ -6,10 +6,10 @@ Bug #30346 (arrayAccess and using $this)
class Test implements ArrayAccess
{
public function __construct() { }
public function offsetExists( $offset ) { return false; }
public function offsetGet( $offset ) { return $offset; }
public function offsetSet( $offset, $data ) { }
public function offsetUnset( $offset ) { }
public function offsetExists( $offset ): bool { return false; }
public function offsetGet( $offset ): mixed { return $offset; }
public function offsetSet( $offset, $data ): void { }
public function offsetUnset( $offset ): void { }
}
$post = new Test;

View File

@ -5,7 +5,7 @@ Bug #30725 (PHP segfaults when an exception is thrown in getIterator() within fo
class Test implements IteratorAggregate
{
function getIterator()
function getIterator(): Traversable
{
throw new Exception();
}

View File

@ -22,25 +22,26 @@ class Foo implements ArrayAccess {
$test = 'bug';
}
function offsetget($test) {
function offsetget($test): mixed {
var_dump($test);
$test = 'bug';
return 123;
}
function offsetset($test, $val) {
function offsetset($test, $val): void {
var_dump($test);
var_dump($val);
$test = 'bug';
$val = 'bug';
}
function offsetexists($test) {
function offsetexists($test): bool {
var_dump($test);
$test = 'bug';
return true;
}
function offsetunset($test) {
function offsetunset($test): void {
var_dump($test);
$test = 'bug';
}

View File

@ -5,25 +5,25 @@ Bug #32252 (Segfault when offsetSet throws an Exception (only without debug))
class Test implements ArrayAccess
{
function offsetExists($offset)
function offsetExists($offset): bool
{
echo __METHOD__ . "($offset)\n";
return false;
}
function offsetGet($offset)
function offsetGet($offset): mixed
{
echo __METHOD__ . "($offset)\n";
return null;
}
function offsetSet($offset, $value)
function offsetSet($offset, $value): void
{
echo __METHOD__ . "($offset, $value)\n";
throw new Exception("Ooops");
}
function offsetUnset($offset)
function offsetUnset($offset): void
{
echo __METHOD__ . "($offset)\n";
}

View File

@ -9,31 +9,31 @@ class collection implements Iterator {
public function __construct() {
}
public function rewind() {
public function rewind(): void {
reset($this->_elements);
}
public function count() {
public function count(): int {
return count($this->_elements);
}
public function current() {
public function current(): mixed {
$element = current($this->_elements);
return $element;
}
public function next() {
public function next(): void {
$element = next($this->_elements);
return $element;
$element;
}
public function key() {
public function key(): mixed {
$this->_fillCollection();
$element = key($this->_elements);
return $element;
}
public function valid() {
public function valid(): bool {
throw new Exception('shit happened');
return ($this->current() !== false);

View File

@ -6,11 +6,11 @@ class Test implements Iterator {
public $arr = array();
public function rewind() { return reset($this->arr); }
public function current() { throw new Exception(); }
public function key() { return key($this->arr); }
public function next() { return next($this->arr); }
public function valid() { return (current($this->arr) !== false); }
public function rewind(): void { reset($this->arr); }
public function current(): mixed { throw new Exception(); }
public function key(): mixed { return key($this->arr); }
public function next(): void { next($this->arr); }
public function valid(): bool { return (current($this->arr) !== false); }
}
$t = new Test();

View File

@ -5,10 +5,10 @@ Bug #33710 (ArrayAccess objects doesn't initialize $this)
class Foo implements ArrayAccess
{
function offsetExists($offset) {/*...*/}
function offsetGet($offset) {/*...*/}
function offsetSet($offset, $value) {/*...*/}
function offsetUnset($offset) {/*...*/}
function offsetExists($offset): bool { return true;}
function offsetGet($offset): mixed { return null; }
function offsetSet($offset, $value): void {/*...*/}
function offsetUnset($offset): void {/*...*/}
function fail()
{

View File

@ -10,20 +10,20 @@ class MyTree implements ArrayAccess {
public $parent;
public $children = array();
public function offsetExists($offset) {
public function offsetExists($offset): bool {
}
public function offsetUnset($offset) {
public function offsetUnset($offset): void {
}
public function offsetSet($offset, $value) {
public function offsetSet($offset, $value): void {
echo "offsetSet()\n";
$cannonicalName = strtolower($offset);
$this->children[$cannonicalName] = $value;
$value->parent = $this;
}
public function offsetGet($offset) {
public function offsetGet($offset): mixed {
echo "offsetGet()\n";
$cannonicalName = strtolower($offset);
return $this->children[$cannonicalName];

View File

@ -35,22 +35,22 @@ Bug #40833 (Crash when using unset() on an ArrayAccess object retrieved via __ge
$this->entity->whatever = null;
}
function offsetUnset($offset)
function offsetUnset($offset): void
{
$this->clear();
// $this->entity->{$this->name} = null;
}
function offsetSet($offset, $value)
function offsetSet($offset, $value): void
{
}
function offsetGet($offset)
function offsetGet($offset): mixed
{
return 'Bogus ';
}
function offsetExists($offset)
function offsetExists($offset): bool
{
}
}

View File

@ -20,13 +20,13 @@ class cache implements ArrayAccess
{
private $container = array();
public function offsetGet($id) {}
public function offsetGet($id): mixed {}
public function offsetSet($id, $value) {}
public function offsetSet($id, $value): void {}
public function offsetUnset($id) {}
public function offsetUnset($id): void {}
public function offsetExists($id)
public function offsetExists($id): bool
{
return isset($this->containers[(string) $id]);
}

View File

@ -5,14 +5,14 @@ Bug #49269 (Ternary operator fails on Iterator object when used inside foreach d
class TestObject implements Iterator
{
public $n = 0;
function valid()
function valid(): bool
{
return ($this->n < 3);
}
function current() {return $this->n;}
function next() {$this->n++;}
function key() { }
function rewind() {$this->n = 0;}
function current(): mixed {return $this->n;}
function next(): void {$this->n++;}
function key(): mixed { }
function rewind(): void {$this->n = 0;}
}

View File

@ -4,11 +4,11 @@ Bug #54367 (Use of closure causes problem in ArrayAccess)
<?php
class MyObjet implements ArrayAccess
{
public function offsetSet($offset, $value) { }
public function offsetExists($offset) { }
public function offsetUnset($offset) { }
public function offsetSet($offset, $value): void { }
public function offsetExists($offset): bool { }
public function offsetUnset($offset): void { }
public function offsetGet ($offset)
public function offsetGet($offset): mixed
{
return function ($var) use ($offset) { // here is the problem
var_dump($offset, $var);

View File

@ -7,7 +7,7 @@ interface Foo extends Traversable {
}
class Example implements Foo, IteratorAggregate {
public function getIterator() {
public function getIterator(): Traversable {
return new ArrayIterator([]);
}
}

View File

@ -6,7 +6,7 @@ Bug #62609: Allow implementing Traversable on abstract classes (work)
abstract class AbstractTraversable implements Traversable {}
class NonAbstractTraversable extends AbstractTraversable implements IteratorAggregate {
public function getIterator() {
public function getIterator(): Traversable {
yield "foo";
yield "bar";
}

View File

@ -7,21 +7,23 @@ opcache.optimization_level=-1
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($offset) {
public function offsetExists($offset): bool {
echo "offsetExists given ";
var_dump($offset);
return true;
}
public function offsetUnset($offset) {
public function offsetUnset($offset): void {
echo "offsetUnset given ";
var_dump($offset);
}
public function offsetSet($offset, $value) {
public function offsetSet($offset, $value): void {
echo "offsetSet given ";
var_dump($offset);
}
public function offsetGet($offset) {
public function offsetGet($offset): mixed {
echo "offsetGet given ";
var_dump($offset);
return null;
}
}

View File

@ -4,20 +4,20 @@ Bug #64417 (BC break: ArrayAccess::&offsetGet() in a trait causes fatal error)
<?php
trait aa {
private $container = array();
public function offsetSet($offset, $value) {
public function offsetSet($offset, $value): void {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
public function offsetExists($offset): bool {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
public function offsetUnset($offset): void {
unset($this->container[$offset]);
}
public function &offsetGet($offset) {
public function &offsetGet($offset): mixed {
$result = null;
if (isset($this->container[$offset])) {
$result = &$this->container[$offset];

View File

@ -4,16 +4,16 @@ Bug #68896 (Changing ArrayObject value cause Segment Fault)
<?php
class A implements ArrayAccess {
private $a = [];
function offsetGet($offset) {
function offsetGet($offset): mixed {
return $this->a[$offset];
}
function offsetSet($offset, $value) {
function offsetSet($offset, $value): void {
$this->a[$offset] = $value;
}
function offsetExists($offset) {
function offsetExists($offset): bool {
isset($this->a[$offset]);
}
function offsetUnset($offset) {
function offsetUnset($offset): void {
unset($this->a[$offset]);
}
}

View File

@ -4,19 +4,19 @@ Bug #69955 (Segfault when trying to combine [] and assign-op on ArrayAccess obje
<?php
class C10 implements ArrayAccess
{
function offsetExists($offset)
function offsetExists($offset): bool
{
echo "\nInside " . __METHOD__ . "\n"; var_dump($offset);
}
function offsetGet($offset)
function offsetGet($offset): mixed
{
echo "\nInside " . __METHOD__ . "\n"; var_dump($offset); return 100;
}
function offsetSet($offset, $value)
function offsetSet($offset, $value): void
{
echo "\nInside " . __METHOD__ . "\n"; var_dump($offset); var_dump($value);
}
function offsetUnset($offset)
function offsetUnset($offset): void
{
echo "\nInside " . __METHOD__ . "\n"; var_dump($offset);
}

View File

@ -15,15 +15,15 @@ class foo implements arrayAccess
return $bar;
}
public function & offsetGet($key) {
public function & offsetGet($key): mixed {
$bar = $this->bar;
return $bar;
}
public function offsetSet($key, $val) {
public function offsetSet($key, $val): void {
}
public function offsetUnset($key) {
public function offsetUnset($key): void {
}
public function offsetExists($key) {
public function offsetExists($key): bool {
}
}
class bar { public $onBaz = []; }

View File

@ -5,22 +5,22 @@ Bug #71731: Null coalescing operator and ArrayAccess
class AA implements ArrayAccess {
private $data = [];
public function offsetExists($name) {
public function offsetExists($name): bool {
echo "offsetExists($name)\n";
return array_key_exists($name, $this->data);
}
public function &offsetGet($name) {
public function &offsetGet($name): mixed {
echo "offsetGet($name)\n";
if (!array_key_exists($name, $this->data)) {
throw new Exception('Unknown offset');
}
return $this->data[$name];
}
public function offsetSet($name, $value) {
public function offsetSet($name, $value): void {
echo "offsetSet($name)\n";
$this->data[$name] = $value;
}
public function offsetUnset($name) {
public function offsetUnset($name): void {
echo "offsetUnset($name)\n";
unset($this->data[$name]);
}

View File

@ -3,10 +3,10 @@ Bug #75420.10 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.11 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.12 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.13 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["obj"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["obj"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.14 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["obj"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["obj"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.15 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { }
public function offsetGet($x) { }
public function offsetSet($x, $y) { $GLOBALS["name"] = 24; var_dump($x); }
public function offsetUnset($x) { }
public function offsetExists($x): bool { }
public function offsetGet($x): mixed { }
public function offsetSet($x, $y): void { $GLOBALS["name"] = 24; var_dump($x); }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.16 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { }
public function offsetGet($x) { }
public function offsetSet($x, $y) { $GLOBALS["obj"] = 24; var_dump($this); }
public function offsetUnset($x) { }
public function offsetExists($x): bool { }
public function offsetGet($x): mixed { }
public function offsetSet($x, $y): void { $GLOBALS["obj"] = 24; var_dump($this); }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,10 +3,10 @@ Bug #75420.9 (Indirect modification of magic method argument)
--FILE--
<?php
class Test implements ArrayAccess {
public function offsetExists($x) { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x) { var_dump($x); return 42; }
public function offsetSet($x, $y) { }
public function offsetUnset($x) { }
public function offsetExists($x): bool { $GLOBALS["name"] = 24; return true; }
public function offsetGet($x): mixed { var_dump($x); return 42; }
public function offsetSet($x, $y): void { }
public function offsetUnset($x): void { }
}
$obj = new Test;

View File

@ -3,16 +3,16 @@ Bug #78356: Array returned from ArrayAccess is incorrectly unpacked as argument
--FILE--
<?php
$object = new class implements ArrayAccess {
public function offsetGet($offset)
public function offsetGet($offset): mixed
{
return [1, 2];
}
public function offsetExists($offset)
public function offsetExists($offset): bool
{
return true;
}
public function offsetUnset($offset) {}
public function offsetSet($offset, $value) {}
public function offsetUnset($offset): void {}
public function offsetSet($offset, $value): void {}
};
var_dump(max(...$object[0]));
?>

View File

@ -14,16 +14,16 @@ class obj implements arrayaccess {
"three" => 3,
);
}
public function offsetSet($offset, $value) {
public function offsetSet($offset, $value): void {
$this->container[$offset] = $value;
}
public function offsetExists($offset) {
public function offsetExists($offset): bool {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
public function offsetUnset($offset): void {
unset($this->container[$offset]);
}
public function offsetGet($offset) {
public function offsetGet($offset): mixed {
return isset($this->container[$offset]) ? $this->container[$offset] : null;
}
}

View File

@ -6,13 +6,13 @@ Enum offsetGet in constant expression
enum Foo implements ArrayAccess {
case Bar;
public function offsetGet($key) {
public function offsetGet($key): mixed {
return 42;
}
public function offsetExists($key) {}
public function offsetSet($key, $value) {}
public function offsetUnset($key) {}
public function offsetExists($key): bool {}
public function offsetSet($key, $value): void {}
public function offsetUnset($key): void {}
}
class X {

View File

@ -18,11 +18,11 @@ class IT implements Iterator {
}
}
function rewind() {$this->trap(__FUNCTION__); $this->n = 0;}
function valid() {$this->trap(__FUNCTION__); return $this->n < $this->count;}
function key() {$this->trap(__FUNCTION__); return $this->n;}
function current() {$this->trap(__FUNCTION__); return $this->n;}
function next() {$this->trap(__FUNCTION__); $this->n++;}
function rewind(): void {$this->trap(__FUNCTION__); $this->n = 0;}
function valid(): bool {$this->trap(__FUNCTION__); return $this->n < $this->count;}
function key(): mixed {$this->trap(__FUNCTION__); return $this->n;}
function current(): mixed {$this->trap(__FUNCTION__); return $this->n;}
function next(): void {$this->trap(__FUNCTION__); $this->n++;}
}
foreach(['rewind', 'valid', 'key', 'current', 'next'] as $trap) {

View File

@ -4,7 +4,7 @@ Empty foreach loops with exception must not leak
<?php
class Foo implements IteratorAggregate {
public function getIterator() {
public function getIterator(): Traversable {
return new ArrayIterator([]);
}
public function __destruct() {

View File

@ -6,11 +6,11 @@ Bug #71013 (Incorrect exception handler with yield from)
class FooBar implements Iterator {
function __construct() { echo "Constructing new FooBar\n"; }
function __destruct() { echo "Destructing FooBar\n"; }
function current () { throw new Exception; }
function key () { return 0; }
function next () {}
function rewind () {}
function valid () { return true; }
function current (): mixed { throw new Exception; }
function key (): int { return 0; }
function next (): void {}
function rewind (): void {}
function valid (): bool { return true; }
}
function foo() {

View File

@ -10,7 +10,7 @@ class Test implements IteratorAggregate {
$this->data = $data;
}
public function getIterator() {
public function getIterator(): Traversable {
foreach ($this->data as $value) {
yield $value;
}

View File

@ -14,7 +14,7 @@ class Test implements IteratorAggregate {
return $this->data;
}
public function &getIterator() {
public function &getIterator(): Traversable {
foreach ($this->data as $key => &$value) {
yield $key => $value;
}

View File

@ -4,7 +4,7 @@ yield from with an IteratorAggregate
<?php
class foo implements \IteratorAggregate {
public $prop = 1;
function getIterator() {
function getIterator(): Traversable {
var_dump($this->prop);
yield;
}

View File

@ -4,11 +4,11 @@ Exception from valid() during yield from
<?php
class FooBar implements Iterator {
function rewind() {}
function current() {}
function key() {}
function next() {}
function valid() {
function rewind(): void {}
function current(): mixed {}
function key(): mixed {}
function next(): void {}
function valid(): bool {
throw new Exception("Exception from valid()");
}
}

View File

@ -5,10 +5,10 @@
class StorageNoRef implements ArrayAccess {
private $s = [];
function __construct(array $a) { $this->s = $a; }
function offsetSet ($k, $v) { $this->s[$k] = $v; }
function offsetGet ($k) { return $this->s[$k]; }
function offsetExists ($k) { return isset($this->s[$k]); }
function offsetUnset ($k) { unset($this->s[$k]); }
function offsetSet ($k, $v): void { $this->s[$k] = $v; }
function offsetGet ($k): mixed { return $this->s[$k]; }
function offsetExists ($k): bool { return isset($this->s[$k]); }
function offsetUnset ($k): void { unset($this->s[$k]); }
}
$a = new StorageNoRef([1, 2]);

View File

@ -6,10 +6,10 @@
class StorageRef implements ArrayAccess {
private $s = [];
function __construct(array $a) { $this->s = $a; }
function offsetSet ($k, $v) { $this->s[$k] = $v; }
function &offsetGet ($k) { return $this->s[$k]; }
function offsetExists ($k) { return isset($this->s[$k]); }
function offsetUnset ($k) { unset($this->s[$k]); }
function offsetSet ($k, $v): void { $this->s[$k] = $v; }
function &offsetGet ($k): mixed { return $this->s[$k]; }
function offsetExists ($k): bool { return isset($this->s[$k]); }
function offsetUnset ($k): void { unset($this->s[$k]); }
}
$a = new StorageRef([1, 2]);

View File

@ -12,12 +12,12 @@ class Obj {
class Arr implements ArrayAccess {
public $values = [];
public function offsetSet($name, $value) {
public function offsetSet($name, $value): void {
$this->values[$name] = $value;
}
public function offsetGet($name) {}
public function offsetExists($name) {}
public function offsetUnset($name) {}
public function offsetGet($name): mixed {}
public function offsetExists($name): bool {}
public function offsetUnset($name): void {}
}
$str = 'ab';

View File

@ -25,15 +25,16 @@ echo PHP_EOL;
class IndexPrinter implements ArrayAccess
{
public function offsetGet($offset) {
public function offsetGet($offset): mixed {
echo "GET ";
var_dump($offset);
return null;
}
public function offsetSet($offset, $value) {
public function offsetSet($offset, $value): void {
}
public function offsetExists($offset) {
public function offsetExists($offset): bool {
}
public function offsetUnset($offset) {
public function offsetUnset($offset): void {
}
}

View File

@ -32,7 +32,7 @@ class Indexable implements ArrayAccess
echo "Offset $offset removed.", PHP_EOL;
}
public function offsetGet($offset) {
public function offsetGet($offset): mixed {
echo "Offset $offset retrieved.", PHP_EOL;
return $this->array[$offset];
}

View File

@ -19,16 +19,18 @@ class foo implements ArrayAccess {
static function __callStatic($func, $args) {
$GLOBALS["y"] = $func;
}
function offsetGet($index) {
function offsetGet($index): mixed {
$GLOBALS["y"] = $index;
return null;
}
function offsetSet($index, $newval): void {
$GLOBALS["y"] = $index;
}
function offsetSet($index, $newval) {
function offsetExists($index): bool {
$GLOBALS["y"] = $index;
return true;
}
function offsetExists($index) {
$GLOBALS["y"] = $index;
}
function offsetUnset($index) {
function offsetUnset($index): void {
$GLOBALS["y"] = $index;
}
}

View File

@ -6,15 +6,15 @@ Covariant return-by-ref constraints
class A implements ArrayAccess {
public $foo = array();
public function &offsetGet($n) {
public function &offsetGet($n): mixed {
return $this->foo[$n];
}
public function offsetSet($n, $v) {
public function offsetSet($n, $v): void {
}
public function offsetUnset($n) {
public function offsetUnset($n): void {
}
public function offsetExists($n) {
public function offsetExists($n): bool {
}
}

View File

@ -52,10 +52,10 @@ try {
try {
$foo = new class implements ArrayAccess {
function offsetGet($x) { return [0]; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed { return [0]; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
};
var_dump($foo[0] += [new class {
function __destruct() { throw new Exception; }
@ -65,10 +65,10 @@ try {
try {
$foo = new class implements ArrayAccess {
public $foo = [0];
function &offsetGet($x) { return $this->foo; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function &offsetGet($x): bool { return $this->foo; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
};
var_dump($foo[0] += [new class {
function __destruct() { throw new Exception; }
@ -123,20 +123,20 @@ try {
try {
var_dump((function() { return new class implements ArrayAccess {
function offsetGet($x) { return [new stdClass]; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed { return [new stdClass]; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
function __destruct() { throw new Exception; }
}; })()[0]++);
} catch (Exception $e) { print "caught Exception 15\n"; }
try {
var_dump(++(function() { return new class implements ArrayAccess {
function offsetGet($x) { return [new stdClass]; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed { return [new stdClass]; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
function __destruct() { throw new Exception; }
}; })()[0]);
} catch (Exception $e) { print "caught Exception 16\n"; }
@ -158,10 +158,10 @@ try {
try {
var_dump((new class implements ArrayAccess {
function offsetGet($x) { return [new stdClass]; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed { return [new stdClass]; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
function __destruct() { throw new Exception; }
})[0]);
} catch (Exception $e) { print "caught Exception 19\n"; }
@ -183,10 +183,10 @@ try {
try {
var_dump(isset((new class implements ArrayAccess {
function offsetGet($x) { return [new stdClass]; }
function offsetSet($x, $y) {}
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed { return [new stdClass]; }
function offsetSet($x, $y): void {}
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
function __destruct() { throw new Exception; }
})[0]->bar));
} catch (Exception $e) { print "caught Exception 22\n"; }
@ -222,10 +222,10 @@ try {
try {
$foo = new class implements ArrayAccess {
function offsetGet($x) {}
function offsetSet($x, $y) { throw new Exception; }
function offsetExists($x) { return true; }
function offsetUnset($x) {}
function offsetGet($x): mixed {}
function offsetSet($x, $y): void { throw new Exception; }
function offsetExists($x): bool { return true; }
function offsetUnset($x): void {}
};
var_dump($foo[0] = new stdClass);
} catch (Exception $e) { print "caught Exception 27\n"; }

View File

@ -6,10 +6,10 @@ Typed property on by-ref array dimension
$a = new class implements ArrayAccess {
public int $foo = 1;
function offsetExists($o) { return 1; }
function &offsetGet($o) { return $this->foo; }
function offsetSet($o, $v) { print "offsetSet($v)\n"; }
function offsetUnset($o) { print "offsetUnset() ?!?"; }
function offsetExists($o): bool { return 1; }
function &offsetGet($o): mixed { return $this->foo; }
function offsetSet($o, $v): void { print "offsetSet($v)\n"; }
function offsetUnset($o): void { print "offsetUnset() ?!?"; }
};
$a[0] += 1;

View File

@ -36,8 +36,8 @@ class Exception implements Throwable
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) {}
/** @return void */
public function __wakeup() {}
/** @tentative-return-type */
public function __wakeup(): void {}
final public function getMessage(): string {}
@ -92,10 +92,10 @@ class Error implements Throwable
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null) {}
/**
* @return void
* @tentative-return-type
* @implementation-alias Exception::__wakeup
*/
public function __wakeup() {}
public function __wakeup(): void {}
/** @implementation-alias Exception::getMessage */
final public function getMessage(): string {}

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 9a9ce2975a7449a621d364beca646525fc56b294 */
* Stub hash: 48d8444730a0e1fbc5d81965733deb3d3c11e122 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Throwable_getMessage, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO()
@ -29,7 +29,8 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Exception___construct, 0, 0, 0)
ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, previous, Throwable, 1, "null")
ZEND_END_ARG_INFO()
#define arginfo_class_Exception___wakeup arginfo_class_Throwable_getCode
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Exception___wakeup, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Exception_getMessage arginfo_class_Throwable_getMessage
@ -62,7 +63,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_Error___construct arginfo_class_Exception___construct
#define arginfo_class_Error___wakeup arginfo_class_Throwable_getCode
#define arginfo_class_Error___wakeup arginfo_class_Exception___wakeup
#define arginfo_class_Error_getMessage arginfo_class_Throwable_getMessage

View File

@ -6,44 +6,44 @@ interface Traversable {}
interface IteratorAggregate extends Traversable
{
/** @return Traversable */
public function getIterator();
/** @tentative-return-type */
public function getIterator(): Traversable;
}
interface Iterator extends Traversable
{
/** @return mixed */
public function current();
/** @tentative-return-type */
public function current(): mixed;
/** @return void */
public function next();
/** @tentative-return-type */
public function next(): void;
/** @return mixed */
public function key();
/** @tentative-return-type */
public function key(): mixed;
/** @return bool */
public function valid();
/** @tentative-return-type */
public function valid(): bool;
/** @return void */
public function rewind();
/** @tentative-return-type */
public function rewind(): void;
}
interface ArrayAccess
{
/** @return bool */
public function offsetExists(mixed $offset);
/** @tentative-return-type */
public function offsetExists(mixed $offset): bool;
/**
* Actually this should be return by ref but atm cannot be.
* @return mixed
* @tentative-return-type
*/
public function offsetGet(mixed $offset);
public function offsetGet(mixed $offset): mixed;
/** @return void */
public function offsetSet(mixed $offset, mixed $value);
/** @tentative-return-type */
public function offsetSet(mixed $offset, mixed $value): void;
/** @return void */
public function offsetUnset(mixed $offset);
/** @tentative-return-type */
public function offsetUnset(mixed $offset): void;
}
interface Serializable
@ -57,8 +57,8 @@ interface Serializable
interface Countable
{
/** @return int */
public function count();
/** @tentative-return-type */
public function count(): int;
}
interface Stringable
@ -68,17 +68,15 @@ interface Stringable
final class InternalIterator implements Iterator
{
private function __construct();
private function __construct() {}
/** @return mixed */
public function current();
public function current(): mixed {}
/** @return mixed */
public function key();
public function key(): mixed {}
public function next(): void;
public function next(): void {}
public function valid(): bool;
public function valid(): bool {}
public function rewind(): void;
public function rewind(): void {}
}

View File

@ -1,48 +1,58 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 34aa50c74f10106c6abd0ed2956d41c98aae6452 */
* Stub hash: 339e326a82a7fd1e2ae419c8c86095e29028fbd6 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_IteratorAggregate_getIterator, 0, 0, 0)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_OBJ_INFO_EX(arginfo_class_IteratorAggregate_getIterator, 0, 0, Traversable, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Iterator_current arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Iterator_current, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Iterator_next arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Iterator_next, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Iterator_key arginfo_class_IteratorAggregate_getIterator
#define arginfo_class_Iterator_key arginfo_class_Iterator_current
#define arginfo_class_Iterator_valid arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Iterator_valid, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Iterator_rewind arginfo_class_IteratorAggregate_getIterator
#define arginfo_class_Iterator_rewind arginfo_class_Iterator_next
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ArrayAccess_offsetExists, 0, 0, 1)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ArrayAccess_offsetExists, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_ArrayAccess_offsetGet arginfo_class_ArrayAccess_offsetExists
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ArrayAccess_offsetGet, 0, 1, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ArrayAccess_offsetSet, 0, 0, 2)
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ArrayAccess_offsetSet, 0, 2, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_ArrayAccess_offsetUnset arginfo_class_ArrayAccess_offsetExists
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_ArrayAccess_offsetUnset, 0, 1, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, offset, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Serializable_serialize arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Serializable_serialize, 0, 0, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Serializable_unserialize, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, data, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Countable_count arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_WITH_TENTATIVE_RETURN_TYPE_INFO_EX(arginfo_class_Countable_count, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Stringable___toString, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_InternalIterator___construct arginfo_class_IteratorAggregate_getIterator
#define arginfo_class_InternalIterator___construct arginfo_class_Serializable_serialize
#define arginfo_class_InternalIterator_current arginfo_class_IteratorAggregate_getIterator
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_InternalIterator_current, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_InternalIterator_key arginfo_class_IteratorAggregate_getIterator
#define arginfo_class_InternalIterator_key arginfo_class_InternalIterator_current
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_InternalIterator_next, 0, 0, IS_VOID, 0)
ZEND_END_ARG_INFO()

View File

@ -15,9 +15,7 @@ final class WeakReference
/** @strict-properties */
final class WeakMap implements ArrayAccess, Countable, IteratorAggregate
{
/**
* @param object $object
*/
/** @param object $object */
public function offsetGet($object): mixed {}
/** @param object $object */

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 97fff017125955a3def85d9ed5a31746de7b808a */
* Stub hash: c849da0cac9ed05fedacf10ef57449a4596b3c07 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_WeakReference___construct, 0, 0, 0)
ZEND_END_ARG_INFO()

View File

@ -10,10 +10,10 @@ opcache
namespace Foo;
class Bar { public function get() {} }
class Record implements \ArrayAccess {
public function offsetSet($offset, $value) { throw new \Exception; }
public function offsetGet($offset) { var_dump($offset); }
public function offsetExists($offset) { throw new \Exception; }
public function offsetUnset($offset) { throw new \Exception; }
public function offsetSet($offset, $value): void { throw new \Exception; }
public function offsetGet($offset): mixed { var_dump($offset); return null; }
public function offsetExists($offset): bool { throw new \Exception; }
public function offsetUnset($offset): void { throw new \Exception; }
}
class Baz {
public function run() {

View File

@ -19,21 +19,22 @@ class myIterator implements Iterator
var $a;
var $count = 1;
function next() {
return (++$this->count < 3000) ? 'f' . $this->count : false;
function next(): void {
++$this->count;
}
function current() {
function current(): mixed {
if (($this->count % 100) === 0) {
echo $this->count, "\n";
}
return $GLOBALS['fname2'];
}
function key() {
function key(): mixed {
return 'f' . $this->count;
}
function valid() {
function valid(): bool {
return $this->count < 3000;
}
#[ReturnTypeWillChange]
function rewind() {
$this->count = 1;
return $GLOBALS['fname2'];

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return is_object(current($this->a));
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return (bool) current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return (bool) current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return (bool) current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return is_object(current($this->a));
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -14,25 +14,25 @@ class myIterator implements Iterator
{
$this->a = $a;
}
function next() {
function next(): void {
echo "next\n";
return next($this->a);
next($this->a);
}
function current() {
function current(): mixed {
echo "current\n";
return current($this->a);
}
function key() {
function key(): mixed {
echo "key\n";
return key($this->a);
}
function valid() {
function valid(): bool {
echo "valid\n";
return current($this->a);
return is_resource(current($this->a));
}
function rewind() {
function rewind(): void {
echo "rewind\n";
return reset($this->a);
reset($this->a);
}
}
try {

View File

@ -10,14 +10,14 @@ Interface ExtendsIterator extends Iterator {
Interface ExtendsIteratorAggregate extends IteratorAggregate {
}
Class IteratorImpl implements Iterator {
public function next() {}
public function key() {}
public function rewind() {}
public function current() {}
public function valid() {}
public function next(): void {}
public function key(): mixed {}
public function rewind(): void {}
public function current(): mixed {}
public function valid(): bool {}
}
Class IteratorAggregateImpl implements IteratorAggregate {
public function getIterator() {}
public function getIterator(): Traversable {}
}
Class ExtendsIteratorImpl extends IteratorImpl {
}

View File

@ -7,11 +7,11 @@ Felix De Vliegher <felix.devliegher@gmail.com>, Marc Veldman <marc@ibuildings.nl
class IteratorClass implements Iterator {
public function __construct() { }
public function key() {}
public function current() {}
function next() {}
function valid() {}
function rewind() {}
public function key(): mixed {}
public function current(): mixed {}
function next(): void {}
function valid(): bool {}
function rewind(): void {}
}
class DerivedClass extends IteratorClass {}
class NonIterator {}

View File

@ -29,7 +29,7 @@ dumpType($rp->getType());
interface y {}
class x implements Y, Countable {
public function count() {}
public function count(): int { return 0; }
}
$test = new Test;
$test->prop = new x;

View File

@ -13,11 +13,11 @@ class ItemArray implements Iterator {
$this->a = $a;
}
public function rewind() { return reset($this->a); }
public function current() { return current($this->a); }
public function key() { return key($this->a); }
public function next() { return next($this->a); }
public function valid() { return (current($this->a) !== false); }
public function rewind(): void { reset($this->a); }
public function current(): mixed { return current($this->a); }
public function key(): mixed { return key($this->a); }
public function next(): void { next($this->a); }
public function valid(): bool { return (current($this->a) !== false); }
}
class Item {

View File

@ -123,10 +123,10 @@ class DirectoryIterator extends SplFileInfo implements SeekableIterator
public function valid(): bool {}
/** @return int */
public function key() {} // TODO change return type to string
public function key(): mixed {} // TODO change return type to string
/** @return DirectoryIterator */
public function current() {} // TODO fix return type so that FilesystemIterator::current() remains compatible
public function current(): mixed {} // TODO narrow return type
/** @tentative-return-type */
public function next(): void {}

View File

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: fcfc6e8120dff87ab81d9b5491f27e695b3790f4 */
* Stub hash: 7c64c21963df5a11e902298eb5957b868c4b48cf */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_SplFileInfo___construct, 0, 0, 1)
ZEND_ARG_TYPE_INFO(0, filename, IS_STRING, 0)
@ -102,7 +102,7 @@ ZEND_END_ARG_INFO()
#define arginfo_class_DirectoryIterator_valid arginfo_class_SplFileInfo_isWritable
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, 0)
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_DirectoryIterator_key, 0, 0, IS_MIXED, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_DirectoryIterator_current arginfo_class_DirectoryIterator_key

View File

@ -4,6 +4,7 @@ RecursiveIteratorIterator constructor should thrown if IteratorAggregate does no
<?php
class MyIteratorAggregate implements IteratorAggregate {
#[ReturnTypeWillChange]
function getIterator() {
return null;
}

View File

@ -69,7 +69,7 @@ class StudentList implements IteratorAggregate
return false;
}
public function getIterator() {
public function getIterator(): Traversable {
return $this->students->getIterator();
}
}

View File

@ -18,7 +18,7 @@ class test implements IteratorAggregate
$this->imp = "implicit";
}
function getIterator()
function getIterator(): Traversable
{
$it = new ArrayObject($this);
return $it->getIterator();

View File

@ -8,7 +8,7 @@ class Foo implements IteratorAggregate
throw new Exception;
}
public function getIterator() {
public function getIterator(): Traversable {
return new ArrayIterator($this->bar());
}
}

View File

@ -65,7 +65,7 @@ class Tree
/**
* @return \RecursiveIteratorIterator
*/
public function getIterator()
public function getIterator(): Traversable
{
return new \RecursiveIteratorIterator(
$this->head->getChildren(),

View File

@ -24,6 +24,7 @@ Interface [ <internal%s> interface Countable ] {
- Parameters [0] {
}
- Tentative return [ int ]
}
}
}

View File

@ -4,29 +4,34 @@ SPL: Countable::count() with wrong return types and exception.
<?php
Class returnNull implements Countable {
function count() {
function count(): int {
return 0;
}
}
Class returnString implements Countable {
#[ReturnTypeWillChange]
function count() {
return "hello";
}
}
Class returnObject implements Countable {
#[ReturnTypeWillChange]
function count() {
return new returnObject;
}
}
Class returnArray implements Countable {
#[ReturnTypeWillChange]
function count() {
return array(1,2,3);
}
}
Class throwException implements Countable {
#[ReturnTypeWillChange]
function count() {
throw new Exception('Thrown from count');
}

View File

@ -83,14 +83,14 @@ class DualIterator implements Iterator
/** @return whether both inner iterators are valid
*/
function valid()
function valid(): bool
{
return $this->lhs->valid() && $this->rhs->valid();
}
/** @return current value depending on CURRENT_* flags
*/
function current()
function current(): mixed
{
switch($this->flags & 0x0F)
{
@ -108,7 +108,7 @@ class DualIterator implements Iterator
/** @return key value depending on KEY_* flags
*/
function key()
function key(): mixed
{
switch($this->flags & 0xF0)
{
@ -124,7 +124,7 @@ class DualIterator implements Iterator
/** move both inner iterators forward
*/
function next()
function next(): void
{
$this->lhs->next();
$this->rhs->next();

View File

@ -69,7 +69,7 @@ class StudentList implements IteratorAggregate
return false;
}
public function getIterator() {
public function getIterator(): Traversable {
return new CachingIterator($this->students->getIterator(), true);
}
}

View File

@ -79,7 +79,7 @@ class SubjectImpl implements SplSubject
$this->observers->detach($observer);
}
function count()
function count(): int
{
return $this->observers->count();
}

View File

@ -27,7 +27,7 @@ class RecursiveArrayIteratorAggregated implements IteratorAggregate {
function __construct($it) {
$this->it = new RecursiveArrayIterator($it);
}
function getIterator() {
function getIterator(): Traversable {
return $this->it;
}
}

View File

@ -12,7 +12,7 @@ class RecursiveArrayIteratorAggregated implements IteratorAggregate {
function __construct($it) {
$this->it = new RecursiveArrayIterator($it);
}
function getIterator() {
function getIterator(): Traversable {
return $this->it;
}
}

View File

@ -8,11 +8,11 @@ Lance Kesson jac_kesson@hotmail.com
class myIterator implements Iterator {
function current (){}
function key ( ){}
function next ( ){}
function rewind ( ){}
function valid ( ){}
function current (): mixed { return null; }
function key ( ): mixed { return ""; }
function next ( ): void {}
function rewind ( ): void {}
function valid ( ): bool {}
}

View File

@ -8,11 +8,11 @@ Lance Kesson jac_kesson@hotmail.com
class myIterator implements Iterator {
function current (){}
function key ( ){}
function next ( ){}
function rewind ( ){}
function valid ( ){}
function current (): mixed{ return null;}
function key ( ): mixed{ return "";}
function next ( ): void{}
function rewind ( ): void{}
function valid ( ): bool{}
}

View File

@ -5,7 +5,7 @@ SPL: Countable
class Test implements Countable
{
function count()
function count(): int
{
return 4;
}

View File

@ -5,6 +5,7 @@ error_reporting=0
--FILE--
<?php
class Test implements Countable {
#[ReturnTypeWillChange]
public function count() {
return $some;
}

Some files were not shown because too many files have changed in this diff Show More