Skip to content

Fix prototype for trait methods #14148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions Zend/tests/gh14009_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
--TEST--
GH-14009: Traits inherit prototype
--FILE--
<?php

class P {
protected function common() {
throw new Exception('Unreachable');
}
}

class A extends P {
public function test(P $sibling) {
$sibling->common();
}
}

class B extends P {
protected function common() {
echo __METHOD__, "\n";
}
}

trait T {
protected function common() {
echo __METHOD__, "\n";
}
}

class C extends P {
use T;
}

$a = new A();
$a->test(new B());
$a->test(new C());

?>
--EXPECT--
B::common
T::common
22 changes: 22 additions & 0 deletions Zend/tests/gh14009_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
--TEST--
GH-14009: Traits inherit prototype
--FILE--
<?php

class P {
protected function common() {}
}

class A extends P {}

trait T {
private abstract function common(int $param);
}

class B extends P {
use T;
}

?>
--EXPECTF--
Fatal error: Declaration of P::common() must be compatible with T::common(int $param) in %s on line %d
19 changes: 19 additions & 0 deletions Zend/tests/gh14009_003.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
GH-14009: Traits inherit prototype
--FILE--
<?php

class A {
private function test() {}
}

trait T {
private function test() {}
}

class B extends A {
use T;
}

?>
--EXPECT--
37 changes: 37 additions & 0 deletions Zend/tests/gh14009_004.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
--TEST--
GH-14009: Traits inherit prototype
--FILE--
<?php

class A {
protected function test() {
throw new Exception('Unreachable');
}
}

class B extends A {
// Prototype is A::test().
protected function test() {
echo __METHOD__, "\n";
}
}

trait T {
protected abstract function test();
}

class C extends B {
use T;
}

class D extends A {
public static function callTest($sibling) {
$sibling->test();
}
}

D::callTest(new C());

?>
--EXPECT--
B::test
19 changes: 19 additions & 0 deletions Zend/tests/interface_constructor_prototype_001.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
--TEST--
Interfaces don't set prototypes to their parent method
--FILE--
<?php

interface A {
public function __construct(int $param);
}
interface B extends A {
public function __construct(int|float $param);
}
class Test implements B {
public function __construct(int $param) {}
}
new Test(42);

?>
--EXPECTF--
Fatal error: Declaration of Test::__construct(int $param) must be compatible with B::__construct(int|float $param) in %s on line %d
26 changes: 26 additions & 0 deletions Zend/tests/interface_constructor_prototype_002.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
Interfaces don't set prototypes to their parent method
--XFAIL--
X::__constructor()'s prototype is set to B::__construct(). Y::__construct() then
uses prototype to verify LSP, but misses A::__construct() which has a stricter
signature.
--FILE--
<?php

interface A {
public function __construct(int|float $param);
}
interface B {
public function __construct(int $param);
}
class X implements A, B {
public function __construct(int|float $param) {}
}
class Y extends X {
public function __construct(int $param) {}
}
new Y(42);

?>
--EXPECTF--
Fatal error: Declaration of Y::__construct(int $param) must be compatible with A::__construct(int|float $param) in %s on line %d
Loading
Loading