php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70722 self return type in interface does not behave as expected
Submitted: 2015-10-16 00:27 UTC Modified: 2015-10-16 02:08 UTC
From: eric at ericstern dot com Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.0.0RC5 OS: OS X
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: eric at ericstern dot com
New email:
PHP Version: OS:

 

 [2015-10-16 00:27 UTC] eric at ericstern dot com
Description:
------------
When implementing an interface where a method is typehinted to return `self`, the return type in the implementing class must explicitly name the interface, rather than being allowed to use `self` as the typehint in the implementing class.

While the RFC (https://wiki.php.net/rfc/return_types) calls out hinting a child class as invalid, `self` on an implementing class seems like it should be valid, as `self` in the implementing class will, by definition, be an instance of the interface which is being implemented. Also, in practice, it makes writing out the code to implement the interface very tedious.

Test script:
---------------
// Does not work, unexpected:

<?php

interface Chainable {

    public function something(): self;

}

class MyChainable implements Chainable {

    public function something(): self {
        return $this;
    }

}

$x = new MyChainable();
print_r($x->something());

// Currently works (expected)
<?php

interface Chainable {

    public function something(): self;

}

class MyChainable implements Chainable {

    public function something(): Chainable{
        return $this;
    }

}

$x = new MyChainable();
print_r($x->something());

Expected result:
----------------
MyChainable Object
(
)


Actual result:
--------------
PHP Fatal error:  Declaration of MyChainable::something(): MyChainable must be compatible with Chainable::something(): Chainable in /Users/firehed/dev/7/ret.php on line 9


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-16 00:29 UTC] eric at ericstern dot com
-Package: Compile Failure +Package: Scripting Engine problem
 [2015-10-16 00:29 UTC] eric at ericstern dot com
Changed package; I'm assuming the compiler package is compiling PHP itself, rather than PHP processing a script
 [2015-10-16 02:08 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2015-10-16 02:08 UTC] requinix@php.net
The RFC also mentions that the return type must be identical.
> The enforcement of the declared return type during inheritance is invariant;
> this means that when a sub-type overrides a parent method then the return type
> of the child must exactly match the parent

and then
> Covariant return types are considered to be type sound and are used in many
> other languages. This RFC originally proposed covariant return types but was
> changed to invariant because of a few issues. It is possible to add covariant
> return types at some point in the future.

So for now the return type must be Chainable; specifying "Chainable" rather than "self" can help you with that.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 20:01:31 2024 UTC