On 3 August 2025 10:30:13 BST, Rob Landers <rob@bottled.codes> wrote: >I'm not sure that this is a bug. You can redeclare the same type and add hooks >(or change them), which breaks all assumptions about substitutability.
If substitutability was the problem, access to the re-declared property should be forbidden to the parent class as well, but it's not: https://3v4l.org/OEadK In fact, there's no break in the *contract* of the property there, only the *implementation*, just like a method can be redefined to have completely different behaviour. If anything, refusing access to a sibling class is a break in contact: in the original example, class C is written with the expectation that property $v will be visible to it, for any instance of P it receives. class P { protected $v = 1; } class C extends P { public function test(P $i) { return $i->v; } } This expectation holds, and appears to be a valid contract, regardless of whether the object given is an instance of P itself or of a subclass. But, a completely unrelated class can create an object which satisfies instanceof P, but forbids access to property $v: class C2 extends P { protected $v = 2; } Why should C2 have the right to break the expectation of C in that way? Rowan Tommins [IMSoP]