Bug #75079 [NEW]: self is only resolved once for closure in trait
| From: | aidantwoods at gmail dot com | Date: | Wed, 16 Aug 2017 18:12:17 +0000 |
| Subject: | Bug #75079 [NEW]: self is only resolved once for closure in trait | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-210694@lists.php.net to get a copy of this message | ||
From: aidantwoods at gmail dot com
Operating system: OSX; Kali Linux (Debian)
PHP version: 7.1.8
Package: Class/Object related
Bug Type: Bug
Bug description:self is only resolved once for closure in trait
Description:
------------
Traits are meant to be syntactic sugar for "copy-pasting" things into
classes. As such, when the self keyword is used inside a trait, it does
not resolve to the name of the trait, but rather resolves to be the name
of the class in which the trait was used in.
If the self keyword is used within a type hint in a closure that is used
inside a trait, this closure does not appear to be re-resolved per
inclusion.
For example, from the test script included, it should not be possible
for the closure to throw a TypeError in any circumstance (if a type
error is to be thrown, it should be thrown by the outer method)
public function selfDo(self ...$Selfs)
{
array_map(
function (self $Self) : self
{
return $Self;
},
$Selfs
);
}
As expected, when calling exclusively the following
$Bar->selfDo($Bar, $Bar);
No TypeError is thrown. Alternatively, when calling exclusively the
following
$Baz->selfDo($Baz, $Baz);
Also no TypeError is thrown.
The problem arises when calling one after the other (does not need to be
immediately after).
Depending on the order those last two lines of the test script are
called in, you will see a different error thrown. In the order given,
the following is generated (trimmed for brevity)
Fatal error: Uncaught TypeError: Argument 1 passed to
Baz::{closure}() must be an instance of Bar, instance of Baz given
in[...]
It seems that once the method is initially called, the self type hint in
the closure in the trait resolves to be the name of the class in which
it was used in (no bug here), the bug is that this initial class name is
now permanently resolved as its current value in latter calls to the
same method (from a different unrelated class).
Test script:
---------------
<?php
trait Foo
{
public function selfDo(self ...$Selfs)
{
array_map(
function (self $Self) : self
{
return $Self;
},
$Selfs
);
}
}
class Bar
{
use Foo;
}
class Baz
{
use Foo;
}
$Bar = new Bar;
$Baz = new Baz;
$Bar->selfDo($Bar, $Bar);
$Baz->selfDo($Baz, $Baz);
Actual result:
--------------
Fatal error: Uncaught TypeError: Argument 1 passed to Baz::{closure}()
must be an instance of Bar, instance of Baz given in
/Users/Aidan/traits.php:8
Stack trace:
#0 [internal function]: Baz->{closure}(Object(Baz))
#1 /Users/Aidan/traits.php(12): array_map(Object(Closure), Array)
#2 /Users/Aidan/traits.php(31): Baz->selfDo(Object(Baz), Object(Baz))
#3 {main}
thrown in /Users/Aidan/traits.php on line 8
--
Edit bug report at https://bugs.php.net/bug.php?id=75079&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=75079&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=75079&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=75079&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=75079&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=75079&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=75079&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=75079&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=75079&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=75079&r=support
Expected behavior: https://bugs.php.net/fix.php?id=75079&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=75079&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=75079&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=75079&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=75079&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=75079&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=75079&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=75079&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=75079&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=75079&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=75079&r=mysqlcfg