Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Zend/tests/readonly_props/readonly_trait_mismatch.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ class C {

?>
--EXPECTF--
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible: only one of them is readonly. Class was composed in %s on line %d
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ class C {

?>
--EXPECTF--
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible: the default values differ. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/bug60369.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ class Properties {

?>
--EXPECTF--
Fatal error: Properties and PropertiesTrait define the same property ($same) in the composition of Properties. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: Properties and PropertiesTrait define the same property ($same) in the composition of Properties. However, the definition differs and is considered incompatible: only one of them is static. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/bug60536_002.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ $t->hello = "foo";
PRE-CLASS-GUARD
POST-CLASS-GUARD

Fatal error: TraitsTest and THello1 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: TraitsTest and THello1 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible: the visibility differs. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/bug74269.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ class PropertiesExample
}
?>
--EXPECTF--
Fatal error: PropertiesExample and PropertiesTrait define the same property ($same) in the composition of PropertiesExample. However, the definition differs and is considered incompatible. Class was composed in %s
Fatal error: PropertiesExample and PropertiesTrait define the same property ($same) in the composition of PropertiesExample. However, the definition differs and is considered incompatible: the default values differ. Class was composed in %s
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ $obj = new baz();
echo $obj->zoo, "\n";
?>
--EXPECTF--
Fatal error: baz and foo define the same property ($zoo) in the composition of baz. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: baz and foo define the same property ($zoo) in the composition of baz. However, the definition differs and is considered incompatible: the default values differ. Class was composed in %s on line %d
18 changes: 18 additions & 0 deletions Zend/tests/traits/gh16643.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
GH-16643: Incompatible trait property error message states the reason
--FILE--
<?php

trait FooTrait {
private array $options = [];
}

class Foo {
use FooTrait;

public function __construct(private array $options = []) {}
}

?>
--EXPECTF--
Fatal error: Foo and FooTrait define the same property ($options) in the composition of Foo. However, the definition differs and is considered incompatible: only one of them has a default value. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/property003.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ $t->hello = "foo";
--EXPECTF--
PRE-CLASS-GUARD

Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible: the visibility differs. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/property004.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ $t = new TraitsTest;
--EXPECTF--
PRE-CLASS-GUARD

Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: THello1 and THello2 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible: the visibility differs. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/traits/property005.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,4 @@ $t->hello = "foo";
PRE-CLASS-GUARD
POST-CLASS-GUARD

Fatal error: TraitsTest and THello1 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: TraitsTest and THello1 define the same property ($hello) in the composition of TraitsTest. However, the definition differs and is considered incompatible: the visibility differs. Class was composed in %s on line %d
2 changes: 1 addition & 1 deletion Zend/tests/type_declarations/typed_properties_085.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ class C {
}
?>
--EXPECTF--
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible. Class was composed in %s on line %d
Fatal error: T1 and T2 define the same property ($prop) in the composition of C. However, the definition differs and is considered incompatible: the types differ. Class was composed in %s on line %d
30 changes: 20 additions & 10 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -2909,8 +2909,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
zend_hash_del(&ce->properties_info, prop_name);
flags |= ZEND_ACC_CHANGED;
} else {
bool is_compatible = false;
uint32_t flags_mask = ZEND_ACC_PPP_MASK | ZEND_ACC_STATIC | ZEND_ACC_READONLY;
const char *reason = NULL;

if (colliding_prop->hooks || property_info->hooks) {
zend_error_noreturn(E_COMPILE_ERROR,
Expand All @@ -2921,10 +2920,16 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
ce->name);
}

if ((colliding_prop->flags & flags_mask) == (flags & flags_mask) &&
verify_property_type_compatibility(property_info, colliding_prop, PROP_INVARIANT, false, false) == INHERITANCE_SUCCESS
) {
/* the flags are identical, thus, the properties may be compatible */
if ((colliding_prop->flags & ZEND_ACC_PPP_MASK) != (flags & ZEND_ACC_PPP_MASK)) {
reason = "the visibility differs";
} else if ((colliding_prop->flags & ZEND_ACC_STATIC) != (flags & ZEND_ACC_STATIC)) {
reason = "only one of them is static";
} else if ((colliding_prop->flags & ZEND_ACC_READONLY) != (flags & ZEND_ACC_READONLY)) {
reason = "only one of them is readonly";
} else if (verify_property_type_compatibility(property_info, colliding_prop, PROP_INVARIANT, false, false) != INHERITANCE_SUCCESS) {
reason = "the types differ";
} else {
/* the flags and types are identical, thus, the properties may be compatible */
zval *op1, *op2;

if (flags & ZEND_ACC_STATIC) {
Expand All @@ -2936,16 +2941,21 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
op1 = &ce->default_properties_table[OBJ_PROP_TO_NUM(colliding_prop->offset)];
op2 = &traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)];
}
is_compatible = check_trait_property_or_constant_value_compatibility(ce, op1, op2);
if ((Z_TYPE_P(op1) == IS_UNDEF) != (Z_TYPE_P(op2) == IS_UNDEF)) {
reason = "only one of them has a default value";
} else if (!check_trait_property_or_constant_value_compatibility(ce, op1, op2)) {
reason = "the default values differ";
}
}

if (!is_compatible) {
if (reason) {
zend_error_noreturn(E_COMPILE_ERROR,
"%pS and %pS define the same property ($%pS) in the composition of %pS. However, the definition differs and is considered incompatible. Class was composed",
"%pS and %pS define the same property ($%pS) in the composition of %pS. However, the definition differs and is considered incompatible: %s. Class was composed",
find_first_property_definition(ce, traits, i, prop_name, colliding_prop->ce)->name,
property_info->ce->name,
prop_name,
ce->name);
ce->name,
reason);
}
continue;
}
Expand Down
Loading