Scope
master targets PHP 8.5, so it can adopt 8.5-only language features that the 8.4 branch cannot. To keep the merge-up cascade clean, this pass should land on master only, after the current 8.4 modernization PRs cascade up.
Candidates (verified against the current tree)
clone with for CacheMetaInfo::with*() — src/OpCache/CacheMetaInfo.php:116-166 reconstructs the object with three near-identical 6-argument positional new self(...) calls; transposing two int arguments compiles and corrupts a cache header silently. On 8.4 the mitigation is named arguments; on master clone($this, [...]) removes the reconstruction entirely.
#[\NoDiscard] on must-use returns where a discarded result is a refcount/state leak:
StringEntry::copy() / its successor addReference() (discarding means the addref happened but the caller lost the handle),
PersistentHeap::attach() and similar handle-returning APIs,
Core::trackedNew().
array_first() / array_last() replacing reset()/end()/[array_key_first(...)] idioms.
- Final property promotion and
final on promoted constructor properties where the 8.4 pass introduces promotion.
get_error_handler() in the error-callback hook path (ErrorCallbackHook) instead of the set/restore dance used to discover the current handler, where applicable.
- Pipe operator
|> — evaluate sparingly; only where a real left-to-right transformation chain exists (the generator tooling is the likeliest candidate). Not worth churn in src/.
Also: audit the 8.4→master cascade of the modernization PRs for spots where the 8.4-compatible form has a strictly better 8.5 form.
Found during the 2026-08 modernization review; blocked on the 8.4 modernization wave cascading up.
Scope
mastertargets PHP 8.5, so it can adopt 8.5-only language features that the8.4branch cannot. To keep the merge-up cascade clean, this pass should land on master only, after the current 8.4 modernization PRs cascade up.Candidates (verified against the current tree)
clone withforCacheMetaInfo::with*()—src/OpCache/CacheMetaInfo.php:116-166reconstructs the object with three near-identical 6-argument positionalnew self(...)calls; transposing twointarguments compiles and corrupts a cache header silently. On 8.4 the mitigation is named arguments; on masterclone($this, [...])removes the reconstruction entirely.#[\NoDiscard]on must-use returns where a discarded result is a refcount/state leak:StringEntry::copy()/ its successoraddReference()(discarding means the addref happened but the caller lost the handle),PersistentHeap::attach()and similar handle-returning APIs,Core::trackedNew().array_first()/array_last()replacingreset()/end()/[array_key_first(...)]idioms.finalon promoted constructor properties where the 8.4 pass introduces promotion.get_error_handler()in the error-callback hook path (ErrorCallbackHook) instead of the set/restore dance used to discover the current handler, where applicable.|>— evaluate sparingly; only where a real left-to-right transformation chain exists (the generator tooling is the likeliest candidate). Not worth churn insrc/.Also: audit the 8.4→master cascade of the modernization PRs for spots where the 8.4-compatible form has a strictly better 8.5 form.
Found during the 2026-08 modernization review; blocked on the 8.4 modernization wave cascading up.