mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix self inheritance type checks for traits
Fixes GH-18295 Closes GH-18296
This commit is contained in:
parent
c97bdce962
commit
03d2226f45
9 changed files with 40 additions and 12 deletions
|
@ -19,4 +19,4 @@ class B extends Foo
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Declaration of T::bar() must be compatible with Foo::bar($a = 'Foo') in %s on line %d
|
Fatal error: Declaration of B::bar() must be compatible with Foo::bar($a = 'Foo') in %s on line %d
|
||||||
|
|
|
@ -25,4 +25,4 @@ B::createApp();
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Cannot make non static method A::createApp() static in class C in %s on line %d
|
Fatal error: Cannot make non static method A::createApp() static in class B in %s on line %d
|
||||||
|
|
|
@ -17,4 +17,4 @@ class B extends A {
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Declaration of T::foo(): string must be compatible with A::foo(): int in %sbug81192_trait.inc on line 4
|
Fatal error: Declaration of B::foo(): string must be compatible with A::foo(): int in %sbug81192_trait.inc on line 4
|
||||||
|
|
|
@ -22,4 +22,4 @@ class TraitsTest1 {
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
|
Fatal error: Declaration of TraitsTest1::hello() must be compatible with THelloA::hello($a) in %s on line %d
|
||||||
|
|
|
@ -23,4 +23,4 @@ class TraitsTest1 {
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
|
Fatal error: Declaration of TraitsTest1::hello() must be compatible with THelloA::hello($a) in %s on line %d
|
||||||
|
|
21
Zend/tests/traits/gh18295.phpt
Normal file
21
Zend/tests/traits/gh18295.phpt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
--TEST--
|
||||||
|
GH-18295: Parent self is substitutable with child self through trait
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class A {
|
||||||
|
public function create(): ?A {}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait T {
|
||||||
|
public function create(): self {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B extends A {
|
||||||
|
use T;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
===DONE===
|
||||||
|
--EXPECT--
|
||||||
|
===DONE===
|
|
@ -35,4 +35,4 @@ $o->sayHello(array());
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
World!
|
World!
|
||||||
|
|
||||||
Fatal error: Declaration of SayWorld::sayHello(Base $d) must be compatible with Base::sayHello(array $a) in %s on line %d
|
Fatal error: Declaration of MyHelloWorld::sayHello(Base $d) must be compatible with Base::sayHello(array $a) in %s on line %d
|
||||||
|
|
|
@ -17,4 +17,4 @@ class U extends X {
|
||||||
|
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Could not check compatibility between T::method($r): B and X::method($a): A, because class B is not available in %s on line %d
|
Fatal error: Could not check compatibility between U::method($r): B and X::method($a): A, because class B is not available in %s on line %d
|
||||||
|
|
|
@ -3608,6 +3608,11 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
|
||||||
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, false, &trait_contains_abstract_methods);
|
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, false, &trait_contains_abstract_methods);
|
||||||
zend_do_traits_constant_binding(ce, traits_and_interfaces);
|
zend_do_traits_constant_binding(ce, traits_and_interfaces);
|
||||||
zend_do_traits_property_binding(ce, traits_and_interfaces);
|
zend_do_traits_property_binding(ce, traits_and_interfaces);
|
||||||
|
|
||||||
|
zend_function *fn;
|
||||||
|
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
|
||||||
|
zend_fixup_trait_method(fn, ce);
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
if (parent) {
|
if (parent) {
|
||||||
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
|
if (!(parent->ce_flags & ZEND_ACC_LINKED)) {
|
||||||
|
@ -3618,6 +3623,13 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
|
||||||
if (ce->num_traits) {
|
if (ce->num_traits) {
|
||||||
if (trait_contains_abstract_methods) {
|
if (trait_contains_abstract_methods) {
|
||||||
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, true, &trait_contains_abstract_methods);
|
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, true, &trait_contains_abstract_methods);
|
||||||
|
|
||||||
|
/* New abstract methods may have been added, make sure to add
|
||||||
|
* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS to ce. */
|
||||||
|
zend_function *fn;
|
||||||
|
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
|
||||||
|
zend_fixup_trait_method(fn, ce);
|
||||||
|
} ZEND_HASH_FOREACH_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trait_exclude_tables) {
|
if (trait_exclude_tables) {
|
||||||
|
@ -3634,11 +3646,6 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
|
||||||
if (trait_aliases) {
|
if (trait_aliases) {
|
||||||
efree(trait_aliases);
|
efree(trait_aliases);
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_function *fn;
|
|
||||||
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
|
|
||||||
zend_fixup_trait_method(fn, ce);
|
|
||||||
} ZEND_HASH_FOREACH_END();
|
|
||||||
}
|
}
|
||||||
if (ce->num_interfaces) {
|
if (ce->num_interfaces) {
|
||||||
/* Also copy the parent interfaces here, so we don't need to reallocate later. */
|
/* Also copy the parent interfaces here, so we don't need to reallocate later. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue