Bug #78407 [Com]: Contravariant Parameters bug
| From: | rowan dot collins at gmail dot com | Date: | Mon, 12 Aug 2019 21:52:51 +0000 |
| Subject: | Bug #78407 [Com]: Contravariant Parameters bug | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-222203@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=78407&edit=1
ID: 78407
Comment by: rowan dot collins at gmail dot com
Reported by: damian dot jozwiak dot lodz at gmail dot com
Summary: Contravariant Parameters bug
Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Ubuntu 18.04
PHP Version: 7.4.0beta2
Block user comment: N
Private report: N
New Comment:
It's easy to get in a muddle about co- and contravariance, but this error is indeed correct.
The promise of the interface is not "I don't care about the type", it's
"you can safely pass me any type"; so adding a type constraint ("I only accept
string") violates the interface's promise. In technical terms, you are attempting
covariance where only contravariance is safe.
You might (or might not) find my attempt to demonstrate the concepts with ASCII art interesting: https://github.com/IMSoP/variance-pipes/
Previous Comments:
------------------------------------------------------------------------
[2019-08-12 19:20:58] phpbugreports at gmail dot com
> You can drop a parameter type, but you can't add one
but taht is nonsense, when the parent don#t care about types at all a typehint is a subset of
"don't care" and compatible no matter what
------------------------------------------------------------------------
[2019-08-12 19:01:26] nikic@php.net
This is intentionally not allowed, because it is unsound. You can drop a parameter type, but you
can't add one.
------------------------------------------------------------------------
[2019-08-12 18:55:46] damian dot jozwiak dot lodz at gmail dot com
Description:
------------
When class implement an interface it is not possible to override function parameter.
The code works fine if base function is in class
Test script:
---------------
interface Test{
public function f1($param);
}
class inherited implements Test {
public function f1(string $param):\DOMElement{
return new \DOMElement($param);
}
}
$data = new inherited();
$node = $data->f1("node");
var_dump($node->nodeName);
Expected result:
----------------
string(4) "node"
Actual result:
--------------
Fatal error: Declaration of inherited::f1(string $param): DOMElement must be compatible with
Test::f1($param)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=78407&edit=1