Include the source location in Closure names (#13550)

* Include the source location in Closure names

This change makes stack traces involving Closures, especially multiple
different Closures, much more useful, because it's more easily visible *which*
closure was called for a given stack frame.

The implementation is similar to that of anonymous classes which already
include the file name and line number within their generated classname.

* Update scripts/dev/bless_tests.php for closure naming

* Adjust existing tests for closure naming

* Adjust tests for closure naming that were not caught locally

* Drop the namespace from closure names

This is redundant with the included filename.

* Include filename and line number as separate keys in Closure debug info

* Fix test

* Fix test

* Include the surrounding class and function name in closure names

* Fix test

* Relax test expecations

* Fix tests after merge

* NEWS / UPGRADING
This commit is contained in:
Tim Düsterhus 2024-04-12 18:21:13 +02:00 committed by GitHub
parent ab589e4481
commit 08b2ab22f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
141 changed files with 945 additions and 533 deletions

1
NEWS
View File

@ -19,6 +19,7 @@ PHP NEWS
. Added sparc64 arch assembly support for zend fiber. (Claudio Jeker)
. Fixed GH-13581 no space available for TLS on NetBSD. (Paul Ripke)
. Added fiber Sys-V loongarch64 support. (qiangxuhui)
. Adjusted closure names to include the parent function's name. (timwolla)
- Curl:
. Deprecated the CURLOPT_BINARYTRANSFER constant. (divinity76)

View File

@ -172,6 +172,8 @@ PHP 8.4 UPGRADE NOTES
RFC: https://wiki.php.net/rfc/rfc1867-non-post
. Getting the debug info for WeakReference will now also output the object
it references, or null if the reference is no longer valid.
. The output of Closure::__debugInfo() now includes the name, file, and line
of the Closure.
- Curl:
. curl_version() returns an additional feature_list value, which is an
@ -620,6 +622,10 @@ PHP 8.4 UPGRADE NOTES
13. Other Changes
========================================
* Closure names have been adjusted to include the parent function's name
and the line of definition to make them easier to distinguish, for example
within stack traces.
========================================
14. Performance Improvements
========================================

View File

@ -32,7 +32,7 @@ try {
--EXPECTF--
int(2)
int(10)
{closure}(): Argument #1 ($x) must be of type int, string given, called in %s on line %d
{closure:%s:%d}(): Argument #1 ($x) must be of type int, string given, called in %s on line %d
array(3) {
[0]=>
int(20)
@ -41,4 +41,4 @@ array(3) {
[2]=>
int(30)
}
{closure}(): Argument #2 must be of type ?int, string given, called in %s on line %d
{closure:%s:%d}(): Argument #2 must be of type ?int, string given, called in %s on line %d

View File

@ -12,8 +12,8 @@ spl_autoload_register(function ($name) {
var_dump(class_exists('NotExistingClass'));
?>
--EXPECT--
{closure}(NotExistingClass)
--EXPECTF--
{closure:%s:%d}(NotExistingClass)
bool(false)
{closure}(NotExistingClass), done
{closure:%s:%d}(NotExistingClass), done
bool(false)

View File

@ -37,11 +37,11 @@ while($test++ < 5)
?>
===DONE===
--EXPECTF--
{closure}(Test1,1)
{closure:%s:%d}(Test1,1)
Caught: Test1::__construct
{closure}(Test2,2)
Caught: {closure}
{closure}(Test3,3)
{closure:%s:%d}(Test2,2)
Caught: {closure:%s:%d}
{closure:%s:%d}(Test3,3)
Fatal error: Uncaught Error: Class "Test3" not found in %s:%d
Stack trace:

View File

@ -29,7 +29,7 @@ string(3) "Bar"
Fatal error: Uncaught Exception: Bar in %s:%d
Stack trace:
#0 %s(%d): {closure}('Bar')
#1 %s(%d): {closure}('Foo')
#0 %s(%d): {closure:%s:%d}('Bar')
#1 %s(%d): {closure:%s:%d}('Foo')
#2 {main}
thrown in %s on line %d

View File

@ -35,43 +35,85 @@ array(0) {
}
array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
int(2)
array(1) {
[0]=>
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["h"]=>
&array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
}
}
}
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["h"]=>
&array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
}
}
array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
array(2) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
[1]=>
int(5)

View File

@ -16,7 +16,13 @@ trigger_error('Error!');
--EXPECTF--
NULL
Intercepted error!
object(Closure)#1 (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
Notice: Error! in %s on line %d

View File

@ -13,7 +13,13 @@ throw new Exception('Exception!');
?>
--EXPECTF--
NULL
object(Closure)#1 (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
Fatal error: Uncaught Exception: Exception! in %s:%d

View File

@ -14,7 +14,7 @@ require 'notfound.php';
error(require(notfound.php): Failed to open stream: %s)
Fatal error: Uncaught Exception: Foo in %sbug60909_1.php:5
Stack trace:
#0 %sbug60909_1.php(8): {closure}(2, 'require(notfoun...', '%s', 8)
#0 %s(%d): {closure:%s:%d}(2, 'require(notfoun...', '%s', 8)
#1 %sbug60909_1.php(8): require()
#2 {main}
thrown in %sbug60909_1.php on line 5

View File

@ -12,5 +12,5 @@ call_user_func_array(function(&$a) {}, $args);
echo strval("okey");
?>
--EXPECTF--
Warning: {closure}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
okey

View File

@ -20,14 +20,18 @@ Error handler called (Undefined variable $undefined)
Fatal error: Uncaught ErrorException: Undefined variable $undefined in %sbug61767.php:%d
Stack trace:
#0 %sbug61767.php(%d): {closure}(%s, 'Undefined varia...', '%s', %d)
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', 13)
#1 {main}
thrown in %sbug61767.php on line %d
Shutting down
Array
(
[type] => 1
[message] => %a
[message] => Uncaught ErrorException: Undefined variable $undefined in %s:%d
Stack trace:
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', 13)
#1 {main}
thrown
[file] => %sbug61767.php
[line] => %d
)

View File

@ -37,7 +37,7 @@ Deprecated: Creation of dynamic property Exception::$_trace is deprecated in %s
Fatal error: Uncaught Exception in %sbug64960.php:19
Stack trace:
#0 [internal function]: {closure}(8, 'ob_end_clean():...', '%s', 9)
#0 [internal function]: {closure:%s:%d}(8, 'ob_end_clean():...', '%s', 9)
#1 %sbug64960.php(9): ob_end_clean()
#2 [internal function]: ExceptionHandler->__invoke(Object(Exception))
#3 {main}

View File

@ -8,15 +8,15 @@ var_dump(array_reduce($array, function(&$a, &$b) {
}, 0));
?>
--EXPECTF--
Warning: {closure}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
Warning: {closure}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
Warning: {closure}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #1 ($a) must be passed by reference, value given in %s on line %d
Warning: {closure}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #2 ($b) must be passed by reference, value given in %s on line %d
int(6)

View File

@ -39,11 +39,23 @@ var_dump($foo->bar->onBaz);
--EXPECTF--
array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
array(1) {
[0]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}

View File

@ -78,7 +78,7 @@ $foo->bar($a, $b, $c);
--EXPECTF--
Fatal error: Uncaught Error: Class "DoesNotExists" not found in %s:%d
Stack trace:
#0 %sbug72101.php(%d): {closure}(2, 'MethodCallbackB...', '%s', 8)
#0 %s(%d): {closure:%s:%d}(2, 'MethodCallbackB...', '%s', 8)
#1 %sbug72101.php(%d): PHPUnit_Framework_MockObject_Stub_ReturnCallback->invoke(Object(PHPUnit_Framework_MockObject_Invocation_Static))
#2 %sbug72101.php(%d): PHPUnit_Framework_MockObject_Matcher->invoked(Object(PHPUnit_Framework_MockObject_Invocation_Static))
#3 %sbug72101.php(%d): PHPUnit_Framework_MockObject_InvocationMocker->invoke(Object(PHPUnit_Framework_MockObject_Invocation_Static))

View File

@ -12,9 +12,9 @@ set_error_handler(function ($type, $msg) {
call_user_func(function (array &$ref) {var_dump("xxx");}, 'not_an_array_variable');
?>
--EXPECTF--
Fatal error: Uncaught Exception: Foo\{closure}(): Argument #1 ($ref) must be passed by reference, value given in %s:%d
Fatal error: Uncaught Exception: {closure:%s:%d}(): Argument #1 ($ref) must be passed by reference, value given in %s:%d
Stack trace:
#0 [internal function]: Foo\{closure}(%s)
#0 [internal function]: {closure:%s:%d}(2, '%s', '%s', 9)
#1 %sbug74164.php(%d): call_user_func(%s)
#2 {main}
thrown in %sbug74164.php on line %d

View File

@ -31,6 +31,6 @@ int(123)
Fatal error: Uncaught Error: Cannot access private property Foo::$bar in %s:%d
Stack trace:
#0 %s(%d): A->{closure}()
#0 %s(%d): A->{closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -8,8 +8,8 @@ var_dump((new ReflectionFunction('sin'))->getClosure());
var_dump(function ($someThing) {});
?>
--EXPECT--
object(Closure)#2 (2) {
--EXPECTF--
object(Closure)#%d (2) {
["function"]=>
string(3) "sin"
["parameter"]=>
@ -18,7 +18,13 @@ object(Closure)#2 (2) {
string(10) "<required>"
}
}
object(Closure)#2 (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["parameter"]=>
array(1) {
["$someThing"]=>

View File

@ -12,6 +12,6 @@ $y = &$x["2bar"];
--EXPECTF--
Fatal error: Uncaught Exception: Illegal string offset "2bar" in %s:%d
Stack trace:
#0 %sbug76534.php(%d): {closure}(2, 'Illegal string ...', '%s', %d)
#0 %s(%d): {closure:%s:%d}(2, 'Illegal string ...', '%s', 7)
#1 {main}
thrown in %sbug76534.php on line %d

View File

@ -36,7 +36,7 @@ get(...loop());
Fatal error: Uncaught Exception in %s:%d
Stack trace:
#0 %s(%d): throwException()
#1 %s(%d): {closure}()
#1 %s(%d): {closure:%s:%d}()
#2 %s(%d): loop()
#3 {main}
thrown in %s on line %d

View File

@ -24,8 +24,14 @@ var_dump($closure1);
print_r($closure1);
?>
--EXPECT--
object(Closure)#1 (1) {
--EXPECTF--
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["var"]=>
@ -34,6 +40,9 @@ object(Closure)#1 (1) {
}
Closure Object
(
[name] => {closure:%s:%d}
[file] => %s
[line] => %d
[static] => Array
(
[var] =>
@ -41,7 +50,13 @@ Closure Object
)
Undefined constant "CONST_REF"
object(Closure)#1 (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["var"]=>
@ -50,13 +65,22 @@ object(Closure)#1 (1) {
}
Closure Object
(
[name] => {closure:%s:%d}
[file] => %s
[line] => %d
[static] => Array
(
[var] =>
)
)
object(Closure)#1 (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["var"]=>
@ -65,6 +89,9 @@ object(Closure)#1 (1) {
}
Closure Object
(
[name] => {closure:%s:%d}
[file] => %s
[line] => %d
[static] => Array
(
[var] => foo

View File

@ -4,6 +4,12 @@ Bug #81076 Invalid implicit binds cause incorrect static var count in closure de
<?php
var_dump(fn() => [$why, $do, $we, $count]);
?>
--EXPECT--
object(Closure)#1 (0) {
--EXPECTF--
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}

View File

@ -21,11 +21,23 @@ var_dump(call_user_func(function() use (&$foo) { return $foo; }, '__invoke'));
?>
--EXPECTF--
string(3) "OK!"
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["instance"]=>
object(Closure)#%d (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
}
}

View File

@ -18,11 +18,17 @@ var_dump(call_user_func(array('foo', 'teste')));
?>
--EXPECTF--
Deprecated: {closure}(): Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter in %s on line %d
Deprecated: {closure:%s:%d}(): Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter in %s on line %d
string(1) "x"
array(1) {
[0]=>
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["parameter"]=>
array(2) {
["$a"]=>

View File

@ -73,6 +73,6 @@ Destroyed
Fatal error: Uncaught Error: Using $this when not in object context in %sclosure_005.php:28
Stack trace:
#0 %s(%d): A::{closure}()
#0 %s(%d): A::{closure:%s:%d}()
#1 {main}
thrown in %sclosure_005.php on line 28

View File

@ -26,7 +26,7 @@ int(9)
Notice: Only variable references should be returned by reference in %sclosure_019.php on line 4
int(81)
Fatal error: Uncaught Error: {closure}(): Argument #1 ($x) could not be passed by reference in %s:%d
Fatal error: Uncaught Error: {closure:%s:%d}(): Argument #1 ($x) could not be passed by reference in %s:%d
Stack trace:
#0 %s(%d): test()
#1 {main}

View File

@ -28,7 +28,13 @@ object(foo)#%d (2) {
["test":"foo":private]=>
int(3)
["a"]=>
object(Closure)#%d (2) {
object(Closure)#%d (5) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["a"]=>

View File

@ -33,7 +33,13 @@ object(foo)#%d (1) {
["a"]=>
array(1) {
[0]=>
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["this"]=>
*RECURSION*
}
@ -44,7 +50,13 @@ int(1)
string(1) "a"
array(1) {
[0]=>
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["this"]=>
object(foo)#%d (1) {
["a"]=>

View File

@ -28,7 +28,7 @@ object(stdClass)#%d (0) {
NULL
Warning: Undefined variable $y in %s on line %d
Exception: Too few arguments to function {closure}(), 0 passed in %s on line %d and exactly 1 expected
Exception: Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected
Fatal error: Uncaught TypeError: test(): Argument #1 ($a) must be of type Closure, stdClass given, called in %s:%d
Stack trace:

View File

@ -20,7 +20,7 @@ Array
(
[file] => %s
[line] => %d
[function] => {closure}
[function] => {closure:%s:%d}
[args] => Array
(
[0] => 23
@ -29,14 +29,14 @@ Array
)
)
#0 %s(%d): {closure}(23)
#0 %s(%d): {closure:%s:%d}(23)
Array
(
[0] => Array
(
[file] => %s
[line] => %d
[function] => {closure}
[function] => {closure:%s:%d}
[args] => Array
(
[0] => 23
@ -53,6 +53,9 @@ Array
(
[0] => Closure Object
(
[name] => {closure:%s:%d}
[file] => %s
[line] => 8
[parameter] => Array
(
[$param] => <required>
@ -65,5 +68,5 @@ Array
)
)
#0 %s(%d): {closure}(23)
#0 %s(%d): {closure:%s:%d}(23)
#1 %s(%d): test(Object(Closure))

View File

@ -23,7 +23,7 @@ $o->func();
?>
===DONE===
--EXPECTF--
{closure}()
{closure:%s:%d}()
Fatal error: Uncaught Error: Call to private method Test::func() from global scope in %s:%d
Stack trace:

View File

@ -8,7 +8,13 @@ var_dump($a);
?>
--EXPECTF--
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["a"]=>

View File

@ -15,7 +15,13 @@ var_dump($x());
?>
--EXPECTF--
object(Closure)#%d (1) {
object(Closure)#%d (4) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["x"]=>

View File

@ -57,6 +57,6 @@ int(24)
Fatal error: Uncaught Error: Cannot access private property B::$x in %s:%d
Stack trace:
#0 %s(%d): Closure->{closure}()
#0 %s(%d): Closure->{closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -57,6 +57,6 @@ int(24)
Fatal error: Uncaught Error: Cannot access private property B::$x in %s:%d
Stack trace:
#0 %s(%d): Closure->{closure}()
#0 %s(%d): Closure->{closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -34,6 +34,6 @@ try {
}
?>
--EXPECTF--
Exception: {closure}(): Argument #1 ($a) must be of type A, B given, called in %s on line %d
Exception: {closure}(): Argument #1 ($a) must be of type A, B given
Exception: {closure}(): Argument #1 ($a) must be of type A, B given
Exception: {closure:%s:%d}(): Argument #1 ($a) must be of type A, B given, called in %s on line %d
Exception: {closure:%s:%d}(): Argument #1 ($a) must be of type A, B given
Exception: {closure:%s:%d}(): Argument #1 ($a) must be of type A, B given

View File

@ -0,0 +1,32 @@
--TEST--
The closure name includes the source location
--FILE--
<?php
function get_closure3($c) {
return function () use ($c) {
return $c();
};
}
function throws() {
throw new \Exception();
}
$throws = throws(...);
$closure1 = function() use ($throws) { $throws(); };
$closure2 = fn () => $closure1();
$closure3 = get_closure3($closure2);
\array_map(
function ($item) use ($closure3) { $closure3(); },
[1]
);
?>
--EXPECTF--
Fatal error: Uncaught Exception in %s:8
Stack trace:
#0 %s(11): throws()
#1 %s(12): {closure:%s:11}()
#2 %s(4): {closure:%s:12}()
#3 %s(15): {closure:%s:3}()
#4 [internal function]: {closure:%s:15}(1)
#5 %s(14): array_map(Object(Closure), Array)
#6 {main}
thrown in %s on line 8

View File

@ -0,0 +1,88 @@
--TEST--
The closure name includes the source location (2)
--FILE--
<?php
namespace NameSpaceName {
class ClassName {
public function methodName() {
$c = function () {};
$r = new \ReflectionFunction($c);
var_dump($r->name);
}
public function nestedClosure() {
$c = function () {
$c = function () {
$c = function () {};
$r = new \ReflectionFunction($c);
var_dump($r->name);
};
$c();
};
$c();
}
}
function function_name() {
$c = function () { };
$r = new \ReflectionFunction($c);
var_dump($r->name);
}
}
namespace {
class ClassName {
public function methodName() {
$c = function () {};
$r = new \ReflectionFunction($c);
var_dump($r->name);
}
public function nestedClosure() {
$c = function () {
$c = function () {
$c = function () {};
$r = new \ReflectionFunction($c);
var_dump($r->name);
};
$c();
};
$c();
}
}
function function_name() {
$c = function () { };
$r = new \ReflectionFunction($c);
var_dump($r->name);
}
$class = new \NameSpaceName\ClassName();
$class->methodName();
$class->nestedClosure();
\NameSpaceName\function_name();
$class = new \ClassName();
$class->methodName();
$class->nestedClosure();
\function_name();
$c = function () { };
$r = new \ReflectionFunction($c);
var_dump($r->name);
}
?>
--EXPECTF--
string(49) "{closure:NameSpaceName\ClassName::methodName():6}"
string(79) "{closure:{closure:{closure:NameSpaceName\ClassName::nestedClosure():12}:13}:14}"
string(42) "{closure:NameSpaceName\function_name():27}"
string(36) "{closure:ClassName::methodName():36}"
string(65) "{closure:{closure:{closure:ClassName::nestedClosure():42}:43}:44}"
string(28) "{closure:function_name():57}"
string(%d) "{closure:%sclosure_%d.php:72}"

View File

@ -0,0 +1,20 @@
--TEST--
Dumping closures includes the name.
--FILE--
<?php
var_dump(function($foo) { });
?>
--EXPECTF--
object(Closure)#1 (4) {
["name"]=>
string(%d) "{closure:%s:2}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["parameter"]=>
array(1) {
["$foo"]=>
string(10) "<required>"
}
}

View File

@ -19,5 +19,5 @@ $class = new class extends DateTime {
--EXPECTF--
Fatal error: During inheritance of DateTime: Uncaught Exception: Return type of DateTime@anonymous::getTimezone() should either be compatible with DateTime::getTimezone(): DateTimeZone|false, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in %s:%d
Stack trace:
#0 %s(%d): {closure}(8192, 'Return type of ...', '%s', 8)
#0 %s(%d): {closure:%s:%d}(8192, 'Return type of ...', '%s', 8)
#1 {main} in %s on line %d

View File

@ -11,6 +11,6 @@ Ensure proper backtraces with anon classes
--EXPECTF--
Fatal error: Uncaught Exception in %s:%d
Stack trace:
#0 %s(%d): {closure}(Object(class@anonymous))
#0 %s(%d): {closure:%s:%d}(Object(class@anonymous))
#1 {main}
thrown in %s on line %d

View File

@ -24,5 +24,5 @@ Q
Fatal error: During inheritance of B, while autoloading Y: Uncaught Error: Class "Q" not found in %s:%d
Stack trace:
#0 %s(%d): {closure}('Y')
#0 %s(%d): {closure:%s:%d}('Y')
#1 {main} in %s on line %d

View File

@ -16,5 +16,5 @@ class B extends A {
--EXPECTF--
Fatal error: During inheritance of B, while autoloading Y: Uncaught Exception in %s:%d
Stack trace:
#0 %s(%d): {closure}('Y')
#0 %s(%d): {closure:%s:%d}('Y')
#1 {main} in %s on line %d

View File

@ -13,6 +13,6 @@ $function("secrets", "arewrong");
--EXPECTF--
Fatal error: Uncaught Exception in %sexception_ignore_args.php:3
Stack trace:
#0 %sexception_ignore_args.php(8): {closure}()
#0 %s(%d): {closure:%s:%d}()
#1 {main}
thrown in %sexception_ignore_args.php on line 3

View File

@ -48,7 +48,7 @@ Stack trace:
#10 %sbacktrace-deep-nesting.php(%d): suspend_fiber(2)
#11 %sbacktrace-deep-nesting.php(%d): suspend_fiber(1)
#12 %sbacktrace-deep-nesting.php(%d): suspend_fiber(0)
#13 [internal function]: {closure}()
#13 [internal function]: {closure:%s:%d}()
#14 %sbacktrace-deep-nesting.php(%d): Fiber->resume('test')
#15 {main}
thrown in %sbacktrace-deep-nesting.php on line %d

View File

@ -22,7 +22,7 @@ $fiber->resume();
Fatal error: Uncaught Exception in %sbacktrace-nested.php:%d
Stack trace:
#0 %sbacktrace-nested.php(%d): suspend_fiber()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 %sbacktrace-nested.php(%d): Fiber->resume()
#3 {main}
thrown in %sbacktrace-nested.php on line %d

View File

@ -17,5 +17,5 @@ $fiber->start();
?>
--EXPECTF--
#0 %sdebug-backtrace.php(9): inner_function()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 %sdebug-backtrace.php(12): Fiber->start()

View File

@ -19,7 +19,7 @@ string(4) "test"
Fatal error: Uncaught Exception: test in %sfailing-fiber.php:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 %sfailing-fiber.php(%d): Fiber->resume('test')
#2 {main}
thrown in %sfailing-fiber.php on line %d

View File

@ -22,9 +22,9 @@ int(3)
Fatal error: Uncaught Exception: test in %sfailing-nested-fiber.php:6
Stack trace:
#0 [internal function]: {closure}(1, 2)
#0 [internal function]: {closure:%s:%d}(1, 2)
#1 %sfailing-nested-fiber.php(%d): Fiber->resume(3)
#2 [internal function]: {closure}()
#2 [internal function]: {closure:%s:%d}()
#3 %sfailing-nested-fiber.php(%d): Fiber->start()
#4 {main}
thrown in %sfailing-nested-fiber.php on line %d

View File

@ -27,6 +27,6 @@ Fatal error: Allowed memory size of %d bytes exhausted%s(tried to allocate %d by
Fatal error: Uncaught FiberError: Cannot get fiber return value: The fiber exited with a fatal error in %sget-return-after-bailout.php:%d
Stack trace:
#0 %sget-return-after-bailout.php(%d): Fiber->getReturn()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 {main}
thrown in %sget-return-after-bailout.php on line %d

View File

@ -26,6 +26,6 @@ finally
Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in %sno-switch-force-close-finally.php:%d
Stack trace:
#0 %sno-switch-force-close-finally.php(%d): Fiber->start()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 {main}
thrown in %sno-switch-force-close-finally.php on line %d

View File

@ -30,7 +30,7 @@ Stack trace:
#0 %sno-switch-gc.php(%d): Fiber::suspend()
#1 [internal function]: class@anonymous->__destruct()
#2 %sno-switch-gc.php(%d): gc_collect_cycles()
#3 [internal function]: {closure}()
#3 [internal function]: {closure:%s:%d}()
#4 %sno-switch-gc.php(%d): Fiber->start()
#5 {main}
thrown in %sno-switch-gc.php on line %d

View File

@ -20,9 +20,9 @@ $fiber->start();
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sresume-previous-fiber.php:%d
Stack trace:
#0 %sresume-previous-fiber.php(%d): Fiber->resume()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 %sresume-previous-fiber.php(%d): Fiber->start()
#3 [internal function]: {closure}()
#3 [internal function]: {closure:%s:%d}()
#4 %sresume-previous-fiber.php(%d): Fiber->start()
#5 {main}
thrown in %sresume-previous-fiber.php on line %d

View File

@ -15,7 +15,7 @@ $fiber->start();
Fatal error: Uncaught FiberError: Cannot resume a fiber that is not suspended in %sresume-running-fiber.php:%d
Stack trace:
#0 %sresume-running-fiber.php(%d): Fiber->resume()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 %sresume-running-fiber.php(%d): Fiber->start()
#3 {main}
thrown in %sresume-running-fiber.php on line %d

View File

@ -30,8 +30,8 @@ Fiber start
Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in %ssignal-async.php:%d
Stack trace:
#0 %ssignal-async.php(%d): Fiber::suspend()
#1 %ssignal-async.php(%d): {closure}(%d, Array)
#2 [internal function]: {closure}()
#1 %ssignal-async.php(%d): {closure:%s:%d}(%d, Array)
#2 [internal function]: {closure:%s:%d}()
#3 %ssignal-async.php(%d): Fiber->start()
#4 {main}
thrown in %ssignal-async.php on line %d

View File

@ -38,9 +38,9 @@ Fiber start
FiberError: Cannot switch fibers in current execution context in %ssignal-dispatch.php:%d
Stack trace:
#0 %ssignal-dispatch.php(%d): Fiber::suspend()
#1 [internal function]: {closure}(%d, Array)
#1 [internal function]: {closure:%s:%d}(%d, Array)
#2 %ssignal-dispatch.php(%d): pcntl_signal_dispatch()
#3 [internal function]: {closure}()
#3 [internal function]: {closure:%s:%d}()
#4 %ssignal-dispatch.php(%d): Fiber->start()
#5 {main}
Fiber end

View File

@ -21,9 +21,9 @@ $fiber->start('test');
--EXPECTF--
int(1)
Fatal error: Uncaught TypeError: {closure}(): Argument #1 ($x) must be of type int, string given in %sstart-arguments.php:%d
Fatal error: Uncaught TypeError: {closure:%s:%d}(): Argument #1 ($x) must be of type int, string given in %s:%d
Stack trace:
#0 [internal function]: {closure}('test')
#0 [internal function]: {closure:%s:%d}('test')
#1 %sstart-arguments.php(%d): Fiber->start('test')
#2 {main}
thrown in %sstart-arguments.php on line %d

View File

@ -22,6 +22,6 @@ done
Fatal error: Uncaught FiberError: Cannot suspend in a force-closed fiber in %ssuspend-in-force-close-fiber-after-shutdown.php:%d
Stack trace:
#0 %ssuspend-in-force-close-fiber-after-shutdown.php(%d): Fiber::suspend()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 {main}
thrown in %ssuspend-in-force-close-fiber-after-shutdown.php on line %d

View File

@ -20,6 +20,6 @@ unset($fiber);
Fatal error: Uncaught FiberError: Cannot suspend in a force-closed fiber in %ssuspend-in-force-close-fiber.php:%d
Stack trace:
#0 %ssuspend-in-force-close-fiber.php(%d): Fiber::suspend()
#1 [internal function]: {closure}()
#1 [internal function]: {closure:%s:%d}()
#2 {main}
thrown in %ssuspend-in-force-close-fiber.php on line %d

View File

@ -16,6 +16,6 @@ throw new Exception("Exception 1");
--EXPECTF--
Fatal error: Uncaught Exception: Exception 2 in %s:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -37,11 +37,11 @@ done
Fatal error: Uncaught Exception: test1 in %sthrow-in-multiple-destroyed-fibers-after-shutdown.php:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 {main}
Next Exception: test2 in %sthrow-in-multiple-destroyed-fibers-after-shutdown.php:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 {main}
thrown in %sthrow-in-multiple-destroyed-fibers-after-shutdown.php on line %d

View File

@ -26,8 +26,8 @@ $fiber->start();
Fatal error: Uncaught FiberError: Cannot switch fibers in current execution context in %sticks.php:%d
Stack trace:
#0 %sticks.php(%d): Fiber::suspend()
#1 %sticks.php(%d): {closure}()
#2 [internal function]: {closure}()
#1 %s(%d): {closure:%s:%d}()
#2 [internal function]: {closure:%s:%d}()
#3 %sticks.php(%d): Fiber->start()
#4 {main}
thrown in %sticks.php on line %d

View File

@ -58,7 +58,7 @@ $bar(
unset($foo, $bar,);
var_dump(isset($foo, $bar,));
?>
--EXPECT--
--EXPECTF--
foo
array(2) {
[0]=>
@ -87,7 +87,7 @@ array(2) {
[1]=>
string(3) "bar"
}
{closure}
{closure:%s:%d}
array(2) {
[0]=>
string(7) "closure"

View File

@ -17,7 +17,7 @@ array(1) {
["line"]=>
int(5)
["function"]=>
string(9) "{closure}"
string(%d) "{closure:%s:%d}"
["args"]=>
array(1) {
[0]=>

View File

@ -14,7 +14,7 @@ $test('sensitive');
?>
--EXPECTF--
#0 %ssensitive_parameter_closure.php(10): {closure}(Object(SensitiveParameterValue))
#0 %s(%d): {closure:%s:%d}(Object(SensitiveParameterValue))
array(1) {
[0]=>
array(4) {
@ -23,7 +23,7 @@ array(1) {
["line"]=>
int(10)
["function"]=>
string(9) "{closure}"
string(%d) "{closure:%s:%d}"
["args"]=>
array(1) {
[0]=>
@ -40,7 +40,7 @@ array(1) {
["line"]=>
int(10)
["function"]=>
string(9) "{closure}"
string(%d) "{closure:%s:%d}"
["args"]=>
array(1) {
[0]=>

View File

@ -19,6 +19,6 @@ Warning: Undefined variable $a in %s on line %d
Fatal error: Uncaught Error: Keys must be of type int|string during array unpacking in %s:%d
Stack trace:
#0 %s(%d): {closure}()
#0 %s(%d): {closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -14,6 +14,6 @@ Caught: main
Fatal error: Uncaught Exception: exception handler in %s:%d
Stack trace:
#0 [internal function]: {closure}(Object(Exception))
#0 [internal function]: {closure:%s:%d}(Object(Exception))
#1 {main}
thrown in %s on line %d

View File

@ -14,6 +14,6 @@ GH-8810: Fix reported line number of multi-line closure call
--EXPECTF--
Fatal error: Uncaught Exception in %s:4
Stack trace:
#0 %s(6): {closure}('foo')
#0 %s(%d): {closure:%s:%d}('foo')
#1 {main}
thrown in %s on line 4

View File

@ -25,6 +25,6 @@ Before calling f()
Fatal error: Uncaught Error: Call to undefined function f() in %s:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -28,8 +28,8 @@ Finally
Fatal error: Uncaught Error: Cannot use "yield from" in a force-closed generator in %s:%d
Stack trace:
#0 [internal function]: {closure}()
#0 [internal function]: {closure:%s:%d}()
#1 %s(%d): Generator->current()
#2 [internal function]: {closure}()
#2 [internal function]: {closure:%s:%d}()
#3 {main}
thrown in %s on line %d

View File

@ -18,6 +18,6 @@ echo "unreachable\n";
--EXPECTF--
Fatal error: Uncaught Exception: Custom error handler: Undefined variable $undefVar in %s029.php:4
Stack trace:
#0 %s029.php(7): {closure}(%d, 'Undefined varia...', '%s', %d)
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', %d)
#1 {main}
thrown in %s029.php on line 4

View File

@ -18,6 +18,6 @@ echo "unreachable\n";
--EXPECTF--
Fatal error: Uncaught Exception: Custom error handler: Undefined variable $undefVar in %s030.php:4
Stack trace:
#0 %s030.php(7): {closure}(%d, 'Undefined varia...', '%s', %d)
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', %d)
#1 {main}
thrown in %s030.php on line 4

View File

@ -79,10 +79,10 @@ array(2) {
string(1) "C"
}
Warning: {closure}(): Argument #1 ($ref) must be passed by reference, value given in %s on line %d
Warning: {closure:%s:%d}(): Argument #1 ($ref) must be passed by reference, value given in %s on line %d
a = a, b = b, c = D
NULL
{closure}(): Argument #1 ($a) not passed
{closure:%s:%d}(): Argument #1 ($a) not passed
array_slice(): Argument #2 ($offset) not passed
array(2) {
[3]=>

View File

@ -27,13 +27,13 @@ $c = Foo::bar();
$c();
?>
--EXPECT--
--EXPECTF--
string(7) "Baz\foo"
string(7) "Baz\foo"
string(0) ""
string(3) "bar"
string(12) "Baz\Foo::bar"
string(7) "Baz\Foo"
string(13) "Baz\{closure}"
string(13) "Baz\{closure}"
string(%d) "{closure:%s:%d}"
string(%d) "{closure:%s:%d}"
string(7) "Baz\Foo"

View File

@ -14,7 +14,7 @@ $x(new \stdclass);
?>
--EXPECTF--
Deprecated: foo\{closure}(): Implicitly marking parameter $x as nullable is deprecated, the explicit nullable type must be used instead in %s on line %d
Deprecated: {closure:%s:%d}(): Implicitly marking parameter $x as nullable is deprecated, the explicit nullable type must be used instead in %s on line %d
NULL
object(stdClass)#%d (0) {
}

View File

@ -10,4 +10,10 @@ var_dump(foo());
?>
--EXPECTF--
object(Closure)#%d (%d) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}

View File

@ -14,14 +14,20 @@ class foo {
$baz = new foo();
var_dump($baz->bar());
?>
--EXPECT--
object(Closure)#2 (2) {
--EXPECTF--
object(Closure)#%d (5) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
["static"]=>
array(1) {
["test"]=>
string(3) "one"
}
["this"]=>
object(foo)#1 (0) {
object(foo)#%d (0) {
}
}

View File

@ -15,8 +15,8 @@ $baz = new foo();
var_dump($func=$baz->bar(), $func());
?>
--EXPECTF--
Fatal error: Uncaught TypeError: foo::{closure}(): Return value must be of type array, null returned in %s:%d
Fatal error: Uncaught TypeError: foo::{closure:%s:%d}(): Return value must be of type array, null returned in %s:%d
Stack trace:
#0 %s(%d): foo->{closure}()
#0 %s(%d): foo->{closure:%s:%d}()
#1 {main}
thrown in %s on line %d

View File

@ -21,7 +21,13 @@ foo(array("bar", "baz"));
--EXPECTF--
string(6) "strpos"
string(3) "foo"
object(Closure)#1 (0) {
object(Closure)#%d (3) {
["name"]=>
string(%d) "{closure:%s:%d}"
["file"]=>
string(%d) "%s"
["line"]=>
int(%d)
}
array(2) {
[0]=>

View File

@ -76,19 +76,19 @@ E_DEPRECATED: Implicit conversion from float 1.5 to int loses precision on line
int(1)
*** Trying string(2) "1a"
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying int(%d)
int(%d)
*** Trying float(NAN)
*** Caught {closure}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Trying bool(true)
int(1)
@ -97,22 +97,22 @@ int(1)
int(0)
*** Trying NULL
*** Caught {closure}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Trying object(stdClass)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, StringCapable given, called in %s on line %d
*** Trying resource(%d) of type (stream)
*** Caught {closure}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
Testing 'float' type:
@ -129,13 +129,13 @@ float(1)
float(1.5)
*** Trying string(2) "1a"
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying int(%d)
float(%s)
@ -150,22 +150,22 @@ float(1)
float(0)
*** Trying NULL
*** Caught {closure}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Trying object(stdClass)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, StringCapable given, called in %s on line %d
*** Trying resource(%d) of type (stream)
*** Caught {closure}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
Testing 'string' type:
@ -203,22 +203,22 @@ string(1) "1"
string(0) ""
*** Trying NULL
*** Caught {closure}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Trying object(stdClass)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#%s (0) {
}
string(6) "foobar"
*** Trying resource(%d) of type (stream)
*** Caught {closure}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
Testing 'bool' type:
@ -256,21 +256,21 @@ bool(true)
bool(false)
*** Trying NULL
*** Caught {closure}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Trying object(stdClass)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, StringCapable given, called in %s on line %d
*** Trying resource(%d) of type (stream)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
Done

View File

@ -26,13 +26,13 @@ echo PHP_EOL . "Done";
?>
--EXPECTF--
Testing int:
*** Caught Too few arguments to function {closure}(), 0 passed in %s on line %d and exactly 1 expected
*** Caught Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected
Testing float:
*** Caught Too few arguments to function {closure}(), 0 passed in %s on line %d and exactly 1 expected
*** Caught Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected
Testing string:
*** Caught Too few arguments to function {closure}(), 0 passed in %s on line %d and exactly 1 expected
*** Caught Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected
Testing bool:
*** Caught Too few arguments to function {closure}(), 0 passed in %s on line %d and exactly 1 expected
*** Caught Too few arguments to function {closure:%s:%d}(), 0 passed in %s on line %d and exactly 1 expected
Testing int nullable:
NULL
Testing float nullable:

View File

@ -27,13 +27,13 @@ echo PHP_EOL . "Done";
?>
--EXPECTF--
Testing int:
*** Caught {closure}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
Testing float:
*** Caught {closure}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
Testing string:
*** Caught {closure}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
Testing bool:
*** Caught {closure}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
Testing int nullable:
NULL
Testing float nullable:

View File

@ -74,32 +74,32 @@ int(1)
E_DEPRECATED: Implicit conversion from float 1.5 to int loses precision on line %d
int(1)
*** Trying string(2) "1a"
*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, string returned in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, string returned in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Return value must be of type int, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, string returned in %s on line %d
*** Trying int(9223372036854775807)
int(9223372036854775807)
*** Trying float(NAN)
*** Caught {closure}(): Return value must be of type int, float returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, float returned in %s on line %d
*** Trying bool(true)
int(1)
*** Trying bool(false)
int(0)
*** Trying NULL
*** Caught {closure}(): Return value must be of type int, null returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, null returned in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Return value must be of type int, array returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, array returned in %s on line %d
*** Trying object(stdClass)#6 (0) {
}
*** Caught {closure}(): Return value must be of type int, stdClass returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, stdClass returned in %s on line %d
*** Trying object(StringCapable)#7 (0) {
}
*** Caught {closure}(): Return value must be of type int, StringCapable returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, StringCapable returned in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Return value must be of type int, resource returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type int, resource returned in %s on line %d
Testing 'float' type:
*** Trying int(1)
@ -111,11 +111,11 @@ float(1)
*** Trying float(1.5)
float(1.5)
*** Trying string(2) "1a"
*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, string returned in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, string returned in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Return value must be of type float, string returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, string returned in %s on line %d
*** Trying int(9223372036854775807)
float(9.223372036854776E+18)
*** Trying float(NAN)
@ -125,18 +125,18 @@ float(1)
*** Trying bool(false)
float(0)
*** Trying NULL
*** Caught {closure}(): Return value must be of type float, null returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, null returned in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Return value must be of type float, array returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, array returned in %s on line %d
*** Trying object(stdClass)#6 (0) {
}
*** Caught {closure}(): Return value must be of type float, stdClass returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, stdClass returned in %s on line %d
*** Trying object(StringCapable)#7 (0) {
}
*** Caught {closure}(): Return value must be of type float, StringCapable returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, StringCapable returned in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Return value must be of type float, resource returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type float, resource returned in %s on line %d
Testing 'string' type:
*** Trying int(1)
@ -162,18 +162,18 @@ string(1) "1"
*** Trying bool(false)
string(0) ""
*** Trying NULL
*** Caught {closure}(): Return value must be of type string, null returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type string, null returned in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Return value must be of type string, array returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type string, array returned in %s on line %d
*** Trying object(stdClass)#6 (0) {
}
*** Caught {closure}(): Return value must be of type string, stdClass returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type string, stdClass returned in %s on line %d
*** Trying object(StringCapable)#7 (0) {
}
string(6) "foobar"
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Return value must be of type string, resource returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type string, resource returned in %s on line %d
Testing 'bool' type:
*** Trying int(1)
@ -199,17 +199,17 @@ bool(true)
*** Trying bool(false)
bool(false)
*** Trying NULL
*** Caught {closure}(): Return value must be of type bool, null returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type bool, null returned in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Return value must be of type bool, array returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type bool, array returned in %s on line %d
*** Trying object(stdClass)#6 (0) {
}
*** Caught {closure}(): Return value must be of type bool, stdClass returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type bool, stdClass returned in %s on line %d
*** Trying object(StringCapable)#7 (0) {
}
*** Caught {closure}(): Return value must be of type bool, StringCapable returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type bool, StringCapable returned in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Return value must be of type bool, resource returned in %s on line %d
*** Caught {closure:%s:%d}(): Return value must be of type bool, resource returned in %s on line %d
Done

View File

@ -60,52 +60,52 @@ Testing 'int' type:
int(1)
*** Trying string(1) "1"
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying float(1)
*** Caught {closure}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Trying float(1.5)
*** Caught {closure}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Trying string(2) "1a"
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying int(9223372036854775807)
int(9223372036854775807)
*** Trying float(NAN)
*** Caught {closure}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Trying bool(true)
*** Caught {closure}(): Argument #1 ($i) must be of type int, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, true given, called in %s on line %d
*** Trying bool(false)
*** Caught {closure}(): Argument #1 ($i) must be of type int, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, false given, called in %s on line %d
*** Trying NULL
*** Caught {closure}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Trying object(stdClass)#5 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, StringCapable given, called in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
Testing 'float' type:
@ -113,7 +113,7 @@ Testing 'float' type:
float(1)
*** Trying string(1) "1"
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying float(1)
float(1)
@ -122,13 +122,13 @@ float(1)
float(1.5)
*** Trying string(2) "1a"
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying int(9223372036854775807)
float(9.223372036854776E+18)
@ -137,42 +137,42 @@ float(9.223372036854776E+18)
float(NAN)
*** Trying bool(true)
*** Caught {closure}(): Argument #1 ($f) must be of type float, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, true given, called in %s on line %d
*** Trying bool(false)
*** Caught {closure}(): Argument #1 ($f) must be of type float, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, false given, called in %s on line %d
*** Trying NULL
*** Caught {closure}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Trying object(stdClass)#5 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, StringCapable given, called in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
Testing 'string' type:
*** Trying int(1)
*** Caught {closure}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Trying string(1) "1"
string(1) "1"
*** Trying float(1)
*** Caught {closure}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Trying float(1.5)
*** Caught {closure}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Trying string(2) "1a"
string(2) "1a"
@ -184,63 +184,63 @@ string(1) "a"
string(0) ""
*** Trying int(9223372036854775807)
*** Caught {closure}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Trying float(NAN)
*** Caught {closure}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Trying bool(true)
*** Caught {closure}(): Argument #1 ($s) must be of type string, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, true given, called in %s on line %d
*** Trying bool(false)
*** Caught {closure}(): Argument #1 ($s) must be of type string, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, false given, called in %s on line %d
*** Trying NULL
*** Caught {closure}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Trying object(stdClass)#5 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, StringCapable given, called in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
Testing 'bool' type:
*** Trying int(1)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Trying string(1) "1"
*** Caught {closure}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Trying float(1)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Trying float(1.5)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Trying string(2) "1a"
*** Caught {closure}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Trying string(1) "a"
*** Caught {closure}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Trying string(0) ""
*** Caught {closure}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Trying int(9223372036854775807)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Trying float(NAN)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Trying bool(true)
bool(true)
@ -249,21 +249,21 @@ bool(true)
bool(false)
*** Trying NULL
*** Caught {closure}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Trying array(0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Trying object(stdClass)#5 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, StringCapable given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, StringCapable given, called in %s on line %d
*** Trying resource(5) of type (stream)
*** Caught {closure}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
Done

View File

@ -57,28 +57,28 @@ Testing 'int' type:
int(1)
*** Trying float value
*** Caught {closure}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, float given, called in %s on line %d
*** Trying string value
*** Caught {closure}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, string given, called in %s on line %d
*** Trying true value
*** Caught {closure}(): Argument #1 ($i) must be of type int, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, true given, called in %s on line %d
*** Trying false value
*** Caught {closure}(): Argument #1 ($i) must be of type int, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, false given, called in %s on line %d
*** Trying null value
*** Caught {closure}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, null given, called in %s on line %d
*** Trying array value
*** Caught {closure}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, array given, called in %s on line %d
*** Trying object value
*** Caught {closure}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, stdClass given, called in %s on line %d
*** Trying resource value
*** Caught {closure}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($i) must be of type int, resource given, called in %s on line %d
Testing 'float' type:
@ -89,65 +89,65 @@ float(1)
float(1)
*** Trying string value
*** Caught {closure}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, string given, called in %s on line %d
*** Trying true value
*** Caught {closure}(): Argument #1 ($f) must be of type float, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, true given, called in %s on line %d
*** Trying false value
*** Caught {closure}(): Argument #1 ($f) must be of type float, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, false given, called in %s on line %d
*** Trying null value
*** Caught {closure}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, null given, called in %s on line %d
*** Trying array value
*** Caught {closure}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, array given, called in %s on line %d
*** Trying object value
*** Caught {closure}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, stdClass given, called in %s on line %d
*** Trying resource value
*** Caught {closure}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($f) must be of type float, resource given, called in %s on line %d
Testing 'string' type:
*** Trying integer value
*** Caught {closure}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, int given, called in %s on line %d
*** Trying float value
*** Caught {closure}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, float given, called in %s on line %d
*** Trying string value
string(1) "1"
*** Trying true value
*** Caught {closure}(): Argument #1 ($s) must be of type string, true given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, true given, called in %s on line %d
*** Trying false value
*** Caught {closure}(): Argument #1 ($s) must be of type string, false given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, false given, called in %s on line %d
*** Trying null value
*** Caught {closure}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, null given, called in %s on line %d
*** Trying array value
*** Caught {closure}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, array given, called in %s on line %d
*** Trying object value
*** Caught {closure}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, stdClass given, called in %s on line %d
*** Trying resource value
*** Caught {closure}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($s) must be of type string, resource given, called in %s on line %d
Testing 'bool' type:
*** Trying integer value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, int given, called in %s on line %d
*** Trying float value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, float given, called in %s on line %d
*** Trying string value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, string given, called in %s on line %d
*** Trying true value
bool(true)
@ -156,15 +156,15 @@ bool(true)
bool(false)
*** Trying null value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, null given, called in %s on line %d
*** Trying array value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, array given, called in %s on line %d
*** Trying object value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, stdClass given, called in %s on line %d
*** Trying resource value
*** Caught {closure}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
*** Caught {closure:%s:%d}(): Argument #1 ($b) must be of type bool, resource given, called in %s on line %d
Done

View File

@ -67,25 +67,25 @@ $test = $test->bindTo($a);
var_dump($test($a));
?>
--EXPECT--
object(A)#3 (0) {
--EXPECTF--
object(A)#%d (0) {
}
object(B)#3 (0) {
object(B)#%d (0) {
}
object(A)#3 (0) {
object(A)#%d (0) {
}
A::test2(): Return value must be of type B, A returned
object(A)#3 (0) {
object(A)#%d (0) {
}
object(C)#3 (0) {
object(C)#%d (0) {
}
object(A)#3 (0) {
object(A)#%d (0) {
}
A::test4(): Return value must be of type B|array, A returned
{closure}(): Return value must be of type static, stdClass returned
object(A)#1 (0) {
{closure:%s:%d}(): Return value must be of type static, stdClass returned
object(A)#%d (0) {
}

View File

@ -24,6 +24,6 @@ int(2)
Fatal error: Uncaught TypeError: Cannot assign string to reference held by property A::$bar of type int in %s:%d
Stack trace:
#0 %s(%d): {closure}(2)
#0 %s(%d): {closure:%s:%d}(2)
#1 {main}
thrown in %s on line %d

View File

@ -61,91 +61,91 @@ test('string|array', $values);
test('bool|array', $values);
?>
--EXPECT--
--EXPECTF--
Type int|float:
42 => 42
42.0 => 42.0
INF => INF
"42" => Argument ... must be of type int|float, string given
"42.0" => Argument ... must be of type int|float, string given
"42x" => Argument ... must be of type int|float, string given
"x" => Argument ... must be of type int|float, string given
"" => Argument ... must be of type int|float, string given
true => Argument ... must be of type int|float, true given
false => Argument ... must be of type int|float, false given
null => Argument ... must be of type int|float, null given
[] => Argument ... must be of type int|float, array given
new stdClass => Argument ... must be of type int|float, stdClass given
new WithToString => Argument ... must be of type int|float, WithToString given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
true => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, true given
false => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, false given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, WithToString given
Type int|float|false:
42 => 42
42.0 => 42.0
INF => INF
"42" => Argument ... must be of type int|float|false, string given
"42.0" => Argument ... must be of type int|float|false, string given
"42x" => Argument ... must be of type int|float|false, string given
"x" => Argument ... must be of type int|float|false, string given
"" => Argument ... must be of type int|float|false, string given
true => Argument ... must be of type int|float|false, true given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
true => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, true given
false => false
null => Argument ... must be of type int|float|false, null given
[] => Argument ... must be of type int|float|false, array given
new stdClass => Argument ... must be of type int|float|false, stdClass given
new WithToString => Argument ... must be of type int|float|false, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, WithToString given
Type int|float|bool:
42 => 42
42.0 => 42.0
INF => INF
"42" => Argument ... must be of type int|float|bool, string given
"42.0" => Argument ... must be of type int|float|bool, string given
"42x" => Argument ... must be of type int|float|bool, string given
"x" => Argument ... must be of type int|float|bool, string given
"" => Argument ... must be of type int|float|bool, string given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, string given
true => true
false => false
null => Argument ... must be of type int|float|bool, null given
[] => Argument ... must be of type int|float|bool, array given
new stdClass => Argument ... must be of type int|float|bool, stdClass given
new WithToString => Argument ... must be of type int|float|bool, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, WithToString given
Type int|bool:
42 => 42
42.0 => Argument ... must be of type int|bool, float given
INF => Argument ... must be of type int|bool, float given
"42" => Argument ... must be of type int|bool, string given
"42.0" => Argument ... must be of type int|bool, string given
"42x" => Argument ... must be of type int|bool, string given
"x" => Argument ... must be of type int|bool, string given
"" => Argument ... must be of type int|bool, string given
42.0 => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, float given
INF => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, float given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, string given
true => true
false => false
null => Argument ... must be of type int|bool, null given
[] => Argument ... must be of type int|bool, array given
new stdClass => Argument ... must be of type int|bool, stdClass given
new WithToString => Argument ... must be of type int|bool, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, WithToString given
Type int|string|null:
42 => 42
42.0 => Argument ... must be of type string|int|null, float given
INF => Argument ... must be of type string|int|null, float given
42.0 => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, float given
INF => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, float given
"42" => "42"
"42.0" => "42.0"
"42x" => "42x"
"x" => "x"
"" => ""
true => Argument ... must be of type string|int|null, true given
false => Argument ... must be of type string|int|null, false given
true => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, true given
false => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, false given
null => null
[] => Argument ... must be of type string|int|null, array given
new stdClass => Argument ... must be of type string|int|null, stdClass given
new WithToString => Argument ... must be of type string|int|null, WithToString given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, WithToString given
Type string|bool:
42 => Argument ... must be of type string|bool, int given
42.0 => Argument ... must be of type string|bool, float given
INF => Argument ... must be of type string|bool, float given
42 => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, int given
42.0 => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, float given
INF => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, float given
"42" => "42"
"42.0" => "42.0"
"42x" => "42x"
@ -153,55 +153,55 @@ INF => Argument ... must be of type string|bool, float given
"" => ""
true => true
false => false
null => Argument ... must be of type string|bool, null given
[] => Argument ... must be of type string|bool, array given
new stdClass => Argument ... must be of type string|bool, stdClass given
new WithToString => Argument ... must be of type string|bool, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, WithToString given
Type float|array:
42 => 42.0
42.0 => 42.0
INF => INF
"42" => Argument ... must be of type array|float, string given
"42.0" => Argument ... must be of type array|float, string given
"42x" => Argument ... must be of type array|float, string given
"x" => Argument ... must be of type array|float, string given
"" => Argument ... must be of type array|float, string given
true => Argument ... must be of type array|float, true given
false => Argument ... must be of type array|float, false given
null => Argument ... must be of type array|float, null given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
true => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, true given
false => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, false given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, null given
[] => []
new stdClass => Argument ... must be of type array|float, stdClass given
new WithToString => Argument ... must be of type array|float, WithToString given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, WithToString given
Type string|array:
42 => Argument ... must be of type array|string, int given
42.0 => Argument ... must be of type array|string, float given
INF => Argument ... must be of type array|string, float given
42 => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, int given
42.0 => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, float given
INF => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, float given
"42" => "42"
"42.0" => "42.0"
"42x" => "42x"
"x" => "x"
"" => ""
true => Argument ... must be of type array|string, true given
false => Argument ... must be of type array|string, false given
null => Argument ... must be of type array|string, null given
true => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, true given
false => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, false given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, null given
[] => []
new stdClass => Argument ... must be of type array|string, stdClass given
new WithToString => Argument ... must be of type array|string, WithToString given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, WithToString given
Type bool|array:
42 => Argument ... must be of type array|bool, int given
42.0 => Argument ... must be of type array|bool, float given
INF => Argument ... must be of type array|bool, float given
"42" => Argument ... must be of type array|bool, string given
"42.0" => Argument ... must be of type array|bool, string given
"42x" => Argument ... must be of type array|bool, string given
"x" => Argument ... must be of type array|bool, string given
"" => Argument ... must be of type array|bool, string given
42 => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, int given
42.0 => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, float given
INF => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, float given
"42" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, string given
"42.0" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, string given
true => true
false => false
null => Argument ... must be of type array|bool, null given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, null given
[] => []
new stdClass => Argument ... must be of type array|bool, stdClass given
new WithToString => Argument ... must be of type array|bool, WithToString given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, WithToString given

View File

@ -59,22 +59,22 @@ test('string|array', $values);
test('bool|array', $values);
?>
--EXPECT--
--EXPECTF--
Type int|float:
42 => 42
42.0 => 42.0
INF => INF
"42" => 42
"42.0" => 42.0
"42x" => Argument ... must be of type int|float, string given
"x" => Argument ... must be of type int|float, string given
"" => Argument ... must be of type int|float, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, string given
true => 1
false => 0
null => Argument ... must be of type int|float, null given
[] => Argument ... must be of type int|float, array given
new stdClass => Argument ... must be of type int|float, stdClass given
new WithToString => Argument ... must be of type int|float, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float, WithToString given
Type int|float|false:
42 => 42
@ -82,15 +82,15 @@ Type int|float|false:
INF => INF
"42" => 42
"42.0" => 42.0
"42x" => Argument ... must be of type int|float|false, string given
"x" => Argument ... must be of type int|float|false, string given
"" => Argument ... must be of type int|float|false, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, string given
true => 1
false => false
null => Argument ... must be of type int|float|false, null given
[] => Argument ... must be of type int|float|false, array given
new stdClass => Argument ... must be of type int|float|false, stdClass given
new WithToString => Argument ... must be of type int|float|false, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|false, WithToString given
Type int|float|bool:
42 => 42
@ -103,10 +103,10 @@ INF => INF
"" => false
true => true
false => false
null => Argument ... must be of type int|float|bool, null given
[] => Argument ... must be of type int|float|bool, array given
new stdClass => Argument ... must be of type int|float|bool, stdClass given
new WithToString => Argument ... must be of type int|float|bool, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|float|bool, WithToString given
Type int|bool:
42 => 42
@ -119,10 +119,10 @@ INF => true
"" => false
true => true
false => false
null => Argument ... must be of type int|bool, null given
[] => Argument ... must be of type int|bool, array given
new stdClass => Argument ... must be of type int|bool, stdClass given
new WithToString => Argument ... must be of type int|bool, WithToString given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type int|bool, WithToString given
Type int|string|null:
42 => 42
@ -136,8 +136,8 @@ INF => "INF"
true => 1
false => 0
null => null
[] => Argument ... must be of type string|int|null, array given
new stdClass => Argument ... must be of type string|int|null, stdClass given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|int|null, stdClass given
new WithToString => "__toString()"
Type string|bool:
@ -151,9 +151,9 @@ INF => "INF"
"" => ""
true => true
false => false
null => Argument ... must be of type string|bool, null given
[] => Argument ... must be of type string|bool, array given
new stdClass => Argument ... must be of type string|bool, stdClass given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, null given
[] => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, array given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type string|bool, stdClass given
new WithToString => "__toString()"
Type float|array:
@ -162,15 +162,15 @@ Type float|array:
INF => INF
"42" => 42.0
"42.0" => 42.0
"42x" => Argument ... must be of type array|float, string given
"x" => Argument ... must be of type array|float, string given
"" => Argument ... must be of type array|float, string given
"42x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"x" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
"" => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, string given
true => 1.0
false => 0.0
null => Argument ... must be of type array|float, null given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, null given
[] => []
new stdClass => Argument ... must be of type array|float, stdClass given
new WithToString => Argument ... must be of type array|float, WithToString given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|float, WithToString given
Type string|array:
42 => "42"
@ -183,9 +183,9 @@ INF => "INF"
"" => ""
true => "1"
false => ""
null => Argument ... must be of type array|string, null given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, null given
[] => []
new stdClass => Argument ... must be of type array|string, stdClass given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|string, stdClass given
new WithToString => "__toString()"
Type bool|array:
@ -199,7 +199,7 @@ INF => true
"" => false
true => true
false => false
null => Argument ... must be of type array|bool, null given
null => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, null given
[] => []
new stdClass => Argument ... must be of type array|bool, stdClass given
new WithToString => Argument ... must be of type array|bool, WithToString given
new stdClass => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, stdClass given
new WithToString => {closure:%s:%d}(): Argument #1 ($arg) must be of type array|bool, WithToString given

View File

@ -44,5 +44,5 @@ Class A does not exist
Fatal error: During inheritance of B with variance dependencies: Uncaught Exception: Class A does not exist in %s:%d
Stack trace:
#0 %s(%d): {closure}('A')
#0 %s(%d): {closure:%s:%d}('A')
#1 {main} in %s on line %d

View File

@ -46,5 +46,5 @@ Class I does not exist
Fatal error: During inheritance of B with variance dependencies: Uncaught Exception: Class I does not exist in %s:%d
Stack trace:
#0 %s(%d): {closure}('I')
#0 %s(%d): {closure:%s:%d}('I')
#1 {main} in %s on line %d

View File

@ -17,7 +17,7 @@ test();
--EXPECTF--
Fatal error: Uncaught ErrorException: Undefined variable $test in %s:%d
Stack trace:
#0 %s(%d): {closure}(2, 'Undefined varia...', '%s', 8)
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', 8)
#1 %s(%d): test()
#2 {main}
thrown in %s on line %d

View File

@ -15,6 +15,6 @@ class A implements I {
Fatal error: Uncaught ReflectionException: Class "A" does not exist in %s:%d
Stack trace:
#0 %s(%d): ReflectionClass->__construct('A')
#1 %s(%d): {closure}('I')
#1 %s(%d): {closure:%s:%d}('I')
#2 {main}
thrown in %s on line %d

View File

@ -603,6 +603,15 @@ static HashTable *zend_closure_get_debug_info(zend_object *object, int *is_temp)
ZVAL_STR_COPY(&val, closure->func.common.function_name);
}
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_FUNCTION), &val);
} else {
ZVAL_STR_COPY(&val, closure->func.common.function_name);
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_NAME), &val);
ZVAL_STR_COPY(&val, closure->func.op_array.filename);
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_FILE), &val);
ZVAL_LONG(&val, closure->func.op_array.line_start);
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_LINE), &val);
}
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {

View File

@ -7683,8 +7683,48 @@ static zend_string *zend_begin_func_decl(znode *result, zend_op_array *op_array,
zend_string *unqualified_name, *name, *lcname;
zend_op *opline;
unqualified_name = decl->name;
op_array->function_name = name = zend_prefix_with_ns(unqualified_name);
if (op_array->fn_flags & ZEND_ACC_CLOSURE) {
zend_string *filename = op_array->filename;
uint32_t start_lineno = decl->start_lineno;
zend_string *class = zend_empty_string;
zend_string *separator = zend_empty_string;
zend_string *function = filename;
char *parens = "";
if (CG(active_op_array) && CG(active_op_array)->function_name) {
if (CG(active_op_array)->fn_flags & ZEND_ACC_CLOSURE) {
/* If the parent function is a closure, don't redundantly
* add the classname and parentheses.
*/
function = CG(active_op_array)->function_name;
} else {
function = CG(active_op_array)->function_name;
parens = "()";
if (CG(active_class_entry) && CG(active_class_entry)->name) {
class = CG(active_class_entry)->name;
separator = ZSTR_KNOWN(ZEND_STR_PAAMAYIM_NEKUDOTAYIM);
}
}
}
unqualified_name = zend_strpprintf_unchecked(
0,
"{closure:%S%S%S%s:%" PRIu32 "}",
class,
separator,
function,
parens,
start_lineno
);
op_array->function_name = name = unqualified_name;
} else {
unqualified_name = decl->name;
op_array->function_name = name = zend_prefix_with_ns(unqualified_name);
}
lcname = zend_string_tolower(name);
if (FC(imports_function)) {

View File

@ -1263,12 +1263,12 @@ inline_function:
function returns_ref backup_doc_comment '(' parameter_list ')' lexical_vars return_type
backup_fn_flags '{' inner_statement_list '}' backup_fn_flags
{ $$ = zend_ast_create_decl(ZEND_AST_CLOSURE, $2 | $13, $1, $3,
ZSTR_INIT_LITERAL("{closure}", 0),
NULL,
$5, $7, $11, $8, NULL); CG(extra_fn_flags) = $9; }
| fn returns_ref backup_doc_comment '(' parameter_list ')' return_type
T_DOUBLE_ARROW backup_fn_flags backup_lex_pos expr backup_fn_flags
{ $$ = zend_ast_create_decl(ZEND_AST_ARROW_FUNC, $2 | $12, $1, $3,
ZSTR_INIT_LITERAL("{closure}", 0), $5, NULL, $11, $7, NULL);
NULL, $5, NULL, $11, $7, NULL);
CG(extra_fn_flags) = $9; }
;

View File

@ -32,7 +32,7 @@ echo "done\n";
--EXPECTF--
Warning: Uncaught RuntimeException: Not allowed in %s:%d
Stack trace:
#0 %s(%d): {closure}()
#0 %s(%d): {closure:%s:%d}()
#1 %s(%d): FFI->bug79177()
#2 {main}
thrown in %s on line %d

View File

@ -21,7 +21,7 @@ try {
echo "Done.\n";
?>
--EXPECT--
--EXPECTF--
bool(true)
Exception: Too few arguments to function {closure}(), 3 passed and exactly 4 expected
Exception: Too few arguments to function {closure:%s:%d}(), 3 passed and exactly 4 expected
Done.

View File

@ -19,6 +19,6 @@ try {
--EXPECTF--
Fatal error: Uncaught Error: Undefined constant "y" in %sassign_055.php:3
Stack trace:
#0 %sassign_055.php(7): {closure}(2, 'Undefined varia...', '%s', 7)
#0 %s(%d): {closure:%s:%d}(2, 'Undefined varia...', '%s', 7)
#1 {main}
thrown in %sassign_055.php on line 3
thrown in %sassign_055.php on line 3

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