Re: [RFC] Allow Reassignment of Promoted Readonly Properties in Constructor

From: Date: Thu, 19 Feb 2026 09:49:27 +0000
Subject: Re: [RFC] Allow Reassignment of Promoted Readonly Properties in Constructor
References: 1 2 3 4 5 6 7 8 9 10  Groups: php.internals 
Request: Send a blank email to internals+get-130095@lists.php.net to get a copy of this message
Hi Tim, Le mer. 18 févr. 2026 à 22:29, Tim Düsterhus <tim@bastelstu.be> a écrit : > Hi > > On 2/16/26 19:20, Nicolas Grekas wrote: > > To be sure I understood you well: you are suggesting that mutability > should > > be scoped to the constructor that declares the property (not any > > constructor on the object). > > Yes, because otherwise you might rely on implementation details of the > parent constructor: Depending on whether the parent constructor > reassigns internally, your reassignment in the child constructor either > succeeds or fails. > > > This makes sense and I’ve implemented exactly that model: > > - Reassignment is allowed only while the declaring class constructor is > > active (including methods/closures called from it). > > - A child constructor can no longer reassign a parent-declared promoted > > readonly property. > > - “Child sets first, then parent::__construct()” now throws as expected. > > - The thrown Error is catchable from the child (around > > parent::__construct()), but not from inside the parent body before > implicit > > CPP init. > > - Calling __construct() on an already-constructed object still cannot > > mutate readonly state. > > > > I also updated the RFC text and examples to state this explicitly, and > > added/updated tests for the inheritance/preemption scenarios. > > Thank you. I've checked the RFC and the explanation and semantics make > sense to me. I've also reviewed (parts) of the tests and provided some > feedback there. I'll take another look at the tests when you made the > adjustments to make sure that everything in the RFC is properly tested > to make sure we didn't miss and edge case. > > > Anything else? > > Yes, there is one edge case related to inheritance that isn't mentioned > in the RFC and from what I see it's not tested either. > > Child classes can redefine readonly properties and they are then “owned” > by the child class. Thus we need to explain what happens in that case. > I've prepared example for the three relevant cases I can think of. The > follow from the existing semantics in a straight-forward fashion, but > it's good to spell them out explicitly (and particularly test them). > > 1. Parent uses CPP, child redefines and reassigns. > > class P1 { > public function __construct( > public readonly string $x = 'P', > ) { } > } > > class C1 extends P1 { > public readonly string $x; > > public function __construct() { > parent::__construct(); > > $this->x = 'C'; // This should fail. > } > } > > 2. Parent uses CPP and reassigns, child redefines. > > class P2 { > public function __construct( > public readonly string $x = 'P1', > ) { > $this->x = 'P2'; // This should be legal. > } > } > > class C2 extends P2 { > public readonly string $x; > > public function __construct() { > parent::__construct(); > } > } > > 3. Parent uses CPP, child uses CPP redefinition. > > class P3 { > public function __construct( > public readonly string $x = 'P', > ) { } > } > > class C3 extends P3 { > public function __construct( > public readonly string $x = 'C1', > ) { > parent::__construct(); // This should fail. > } > } > > Thanks, I've added new test cases to cover this. I've also improved tests as suggested on the PR. And finally I updated the implementation to reuse IS_PROP_REINITABLE instead of adding new flags + use an approach that doesn't require walking the call stack. PR and RFC updated accordingly, all green. Nicolas

« previous php.internals (#130095) next »