1
0
mirror of https://github.com/php/php-src.git synced 2026-04-24 16:38:25 +02:00

Merge branch 'PHP-8.1'

* PHP-8.1:
  Don't implement Stringable on traits
This commit is contained in:
Nikita Popov
2021-11-05 09:48:33 +01:00
6 changed files with 30 additions and 10 deletions
+1 -1
View File
@@ -8,4 +8,4 @@ class Foo {
}
?>
--EXPECTF--
Fatal error: Declaration of Foo::__toString(): bool must be compatible with Stringable::__toString(): string in %s on line %d
Fatal error: Foo::__toString(): Return type must be string when declared in %s on line %d
+18
View File
@@ -8,13 +8,31 @@ trait T {
return "ok";
}
}
trait T2 {
use T;
}
class C {
use T;
}
class C2 {
use T2;
}
var_dump(new C instanceof Stringable);
var_dump(new C2 instanceof Stringable);
// The traits themselves should not implement Stringable -- traits cannot implement interfaces.
$rc = new ReflectionClass(T::class);
var_dump($rc->getInterfaceNames());
$rc = new ReflectionClass(T2::class);
var_dump($rc->getInterfaceNames());
?>
--EXPECT--
bool(true)
bool(true)
array(0) {
}
array(0) {
}
+1 -7
View File
@@ -9,12 +9,6 @@ trait T {
}
}
class C {
use T;
}
var_dump(new C instanceof Stringable);
?>
--EXPECTF--
Fatal error: Declaration of T::__toString(): int must be compatible with Stringable::__toString(): string in %s on line %d
Fatal error: T::__toString(): Return type must be string when declared in %s on line %d
+6
View File
@@ -2436,6 +2436,11 @@ static void zend_check_magic_method_return_type(const zend_class_entry *ce, cons
return;
}
if (ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & MAY_BE_NEVER) {
/* It is always legal to specify the never type. */
return;
}
bool is_complex_type = ZEND_TYPE_IS_COMPLEX(fptr->common.arg_info[-1].type);
uint32_t extra_types = ZEND_TYPE_PURE_MASK(fptr->common.arg_info[-1].type) & ~return_type;
if (extra_types & MAY_BE_STATIC) {
@@ -2544,6 +2549,7 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce,
zend_check_magic_method_args(0, ce, fptr, error_type);
zend_check_magic_method_non_static(ce, fptr, error_type);
zend_check_magic_method_public(ce, fptr, error_type);
zend_check_magic_method_return_type(ce, fptr, error_type, MAY_BE_STRING);
} else if (zend_string_equals_literal(lcname, ZEND_DEBUGINFO_FUNC_NAME)) {
zend_check_magic_method_args(0, ce, fptr, error_type);
zend_check_magic_method_non_static(ce, fptr, error_type);
+2 -1
View File
@@ -7008,7 +7008,8 @@ static zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string
}
zend_add_magic_method(ce, (zend_function *) op_array, lcname);
if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)) {
if (zend_string_equals_literal(lcname, ZEND_TOSTRING_FUNC_NAME)
&& !(ce->ce_flags & ZEND_ACC_TRAIT)) {
add_stringable_interface(ce);
}
+2 -1
View File
@@ -2885,7 +2885,8 @@ ZEND_API zend_class_entry *zend_do_link_class(zend_class_entry *ce, zend_string
/* Normally Stringable is added during compilation. However, if it is imported from a trait,
* we need to explicilty add the interface here. */
if (ce->__tostring && !zend_class_implements_interface(ce, zend_ce_stringable)) {
if (ce->__tostring && !(ce->ce_flags & ZEND_ACC_TRAIT)
&& !zend_class_implements_interface(ce, zend_ce_stringable)) {
ZEND_ASSERT(ce->__tostring->common.fn_flags & ZEND_ACC_TRAIT_CLONE);
ce->ce_flags |= ZEND_ACC_RESOLVED_INTERFACES;
ce->num_interfaces++;