readonly and clone, still awkward in 8.3

8.3 relaxed one readonly restriction and not the one everybody wants, so a wither is still a constructor call.

final readonly class Money
{
    public function __construct(public int $cents, public string $currency) {}

    public function withCents(int $cents): self
    {
        $copy = clone $this;
        $copy->cents = $cents;   // Error: cannot modify readonly

        return new self($cents, $this->currency);   // the only way
    }
}

// what 8.3 DID allow: reinitialising a readonly property
// from inside __clone(), which helps deep-cloning and not this.

The __clone relaxation is narrower than it first reads: it permits a readonly property to be written during the clone magic method, which makes a deep clone of a nested object possible and does nothing for the wither pattern, where the caller wants to change a value. The constructor call stays, and on a class with seven properties it stays verbose — a private helper taking an overrides array is the usual containment.