Skip to content

Commit 03d2226

Browse files
committed
Fix self inheritance type checks for traits
Fixes GH-18295 Closes GH-18296
1 parent c97bdce commit 03d2226

File tree

9 files changed

+40
-12
lines changed

9 files changed

+40
-12
lines changed

Zend/tests/inheritance/bug70957.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,4 @@ class B extends Foo
1919
}
2020
?>
2121
--EXPECTF--
22-
Fatal error: Declaration of T::bar() must be compatible with Foo::bar($a = 'Foo') in %s on line %d
22+
Fatal error: Declaration of B::bar() must be compatible with Foo::bar($a = 'Foo') in %s on line %d

Zend/tests/traits/bug78776.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ B::createApp();
2525

2626
?>
2727
--EXPECTF--
28-
Fatal error: Cannot make non static method A::createApp() static in class C in %s on line %d
28+
Fatal error: Cannot make non static method A::createApp() static in class B in %s on line %d

Zend/tests/traits/bug81192.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ class B extends A {
1717

1818
?>
1919
--EXPECTF--
20-
Fatal error: Declaration of T::foo(): string must be compatible with A::foo(): int in %sbug81192_trait.inc on line 4
20+
Fatal error: Declaration of B::foo(): string must be compatible with A::foo(): int in %sbug81192_trait.inc on line 4

Zend/tests/traits/bugs/abstract-methods05.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ class TraitsTest1 {
2222

2323
?>
2424
--EXPECTF--
25-
Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
25+
Fatal error: Declaration of TraitsTest1::hello() must be compatible with THelloA::hello($a) in %s on line %d

Zend/tests/traits/bugs/abstract-methods06.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ class TraitsTest1 {
2323

2424
?>
2525
--EXPECTF--
26-
Fatal error: Declaration of THelloB::hello() must be compatible with THelloA::hello($a) in %s on line %d
26+
Fatal error: Declaration of TraitsTest1::hello() must be compatible with THelloA::hello($a) in %s on line %d

Zend/tests/traits/gh18295.phpt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-18295: Parent self is substitutable with child self through trait
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public function create(): ?A {}
8+
}
9+
10+
trait T {
11+
public function create(): self {}
12+
}
13+
14+
class B extends A {
15+
use T;
16+
}
17+
18+
?>
19+
===DONE===
20+
--EXPECT--
21+
===DONE===

Zend/tests/traits/inheritance003.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ $o->sayHello(array());
3535
--EXPECTF--
3636
World!
3737

38-
Fatal error: Declaration of SayWorld::sayHello(Base $d) must be compatible with Base::sayHello(array $a) in %s on line %d
38+
Fatal error: Declaration of MyHelloWorld::sayHello(Base $d) must be compatible with Base::sayHello(array $a) in %s on line %d

Zend/tests/type_declarations/variance/trait_error.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ class U extends X {
1717

1818
?>
1919
--EXPECTF--
20-
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
20+
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

Zend/zend_inheritance.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,6 +3608,11 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
36083608
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, false, &trait_contains_abstract_methods);
36093609
zend_do_traits_constant_binding(ce, traits_and_interfaces);
36103610
zend_do_traits_property_binding(ce, traits_and_interfaces);
3611+
3612+
zend_function *fn;
3613+
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
3614+
zend_fixup_trait_method(fn, ce);
3615+
} ZEND_HASH_FOREACH_END();
36113616
}
36123617
if (parent) {
36133618
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
36183623
if (ce->num_traits) {
36193624
if (trait_contains_abstract_methods) {
36203625
zend_do_traits_method_binding(ce, traits_and_interfaces, trait_exclude_tables, trait_aliases, true, &trait_contains_abstract_methods);
3626+
3627+
/* New abstract methods may have been added, make sure to add
3628+
* ZEND_ACC_IMPLICIT_ABSTRACT_CLASS to ce. */
3629+
zend_function *fn;
3630+
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
3631+
zend_fixup_trait_method(fn, ce);
3632+
} ZEND_HASH_FOREACH_END();
36213633
}
36223634

36233635
if (trait_exclude_tables) {
@@ -3634,11 +3646,6 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
36343646
if (trait_aliases) {
36353647
efree(trait_aliases);
36363648
}
3637-
3638-
zend_function *fn;
3639-
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, fn) {
3640-
zend_fixup_trait_method(fn, ce);
3641-
} ZEND_HASH_FOREACH_END();
36423649
}
36433650
if (ce->num_interfaces) {
36443651
/* Also copy the parent interfaces here, so we don't need to reallocate later. */

0 commit comments

Comments
 (0)