Repository navigation
Declare the five implicitly-nullable parameters nullable (PHP 8.4 readiness) - #24972
Merged
Merged
Conversation
…diness)
PHP 8.4 deprecates `Foo $x = null` and writes the notice to stderr, which the
compliance harness compares — so on an 8.4 host every case carrying one of
these on its path would differ from Zend on stderr alone.
ext/gettext/GettextFunction.php int $max -> ?int $max
lib/Func/Internal.php string $name -> ?string $name
lib/Visitor/ExitFunctionResolver.php Block $prior -> ?Block $prior
lib/Visitor/InOperatorResolver.php Block $prior -> ?Block $prior
lib/Visitor/VoidCastResolver.php Block $prior -> ?Block $prior
`?Type` has been valid since PHP 7.1 and the declarations already accepted
null, so this changes no behaviour on any supported version.
Five, not the 37 I first reported. The first scan counted three things that
are not deprecated at all: typed properties (`protected ?SplObjectStorage
$seen = null`), unions that already include null (`null|string|Variable|
ClosureState $handler = null`), and `mixed $x = null` — mixed already
includes null, and rewriting it to `?mixed` is a FATAL ERROR. That last one
was caught by dry-running the fixer before applying it.
Verified in php-compiler:8.4-dev (PHP 8.4.23):
- bin/vm.php hello-world: rc=0, stdout "hello 3"
- implicit-nullable deprecations from lib/ + ext/: 4 -> 0
- total deprecations on that path: 22 -> 17 (remainder is vendor/ircmaxell,
which needs a patches/ entry, plus one unrelated class)
- php -l clean on all five files
And in php-compiler:22.04-dev (PHP 8.2.32): same run, rc=0, zero stderr.
Not the only 8.4 deprecation in the tree — ext/gettext/_.php also trips
"Using \"_\" as a class name is deprecated since 8.4". Enumerating the rest by
measurement rather than from memory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Jul 29, 2026
PurHur
pushed a commit
that referenced
this pull request
Jul 29, 2026
Completes the implicit-nullable work started in #24972. PHP 8.4 deprecates `Foo $x = null` and writes the notice to stderr, which the compliance harness compares — so on an 8.4 host every case whose path touches one of these would differ from Zend on stderr alone. 35 parameters across 23 files in php-cfg and php-optimizer, via the existing patches/ layer (167 patches already there). `?Type` has been valid since PHP 7.1 and these declarations already accepted null, so behaviour is unchanged on every supported version. The counterpart declarations in lib/Visitor/* were fixed directly in #24972, so interface and implementations stay consistent. Measured in php-compiler:8.4-dev (PHP 8.4.23), bin/vm.php hello-world: implicit-nullable deprecations 16 -> 0 total deprecations 17 -> 1 The one remaining is a different 8.4 deprecation class entirely — `Using "_" as a class name is deprecated since 8.4` in ext/gettext/_.php — and is not addressed here. Verified: - apply-patches.sh rc=0, and rc=0 again on a second run (idempotent; the three "error"-matching lines are pre-existing "Skip ... (already applied)" messages whose PATCH NAMES contain "error", identical on master) - php-compiler:22.04-dev (PHP 8.2.32) with a fresh composer install: apply-patches rc=0, vm rc=0, stdout "hello 3", ZERO stderr - patch generated by diffing a pristine backup, then vendor restored and confirmed byte-identical before committing, so the patch is the only thing that applies the change Note on process: the first attempt wired the apply_patch call into a conditional helper whose anchor appears twice, the edit asserted and failed, and the follow-up measurement showed 16 deprecations — which looked like the patch not working rather than the patch never having run. Wired at top level instead, next to the other unconditional php-llvm patches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PurHur
pushed a commit
that referenced
this pull request
Jul 29, 2026
Completes the implicit-nullable work started in #24972. PHP 8.4 deprecates `Foo $x = null` and writes the notice to stderr, which the compliance harness compares — so on an 8.4 host every case whose path touches one of these would differ from Zend on stderr alone. 35 parameters across 23 files in php-cfg and php-optimizer, via the existing patches/ layer (167 patches already there). `?Type` has been valid since PHP 7.1 and these declarations already accepted null, so behaviour is unchanged on every supported version. The counterpart declarations in lib/Visitor/* were fixed directly in #24972, so interface and implementations stay consistent. Measured in php-compiler:8.4-dev (PHP 8.4.23), bin/vm.php hello-world: implicit-nullable deprecations 16 -> 0 total deprecations 17 -> 1 The one remaining is a different 8.4 deprecation class entirely — `Using "_" as a class name is deprecated since 8.4` in ext/gettext/_.php — and is not addressed here. Verified: - apply-patches.sh rc=0, and rc=0 again on a second run (idempotent; the three "error"-matching lines are pre-existing "Skip ... (already applied)" messages whose PATCH NAMES contain "error", identical on master) - php-compiler:22.04-dev (PHP 8.2.32) with a fresh composer install: apply-patches rc=0, vm rc=0, stdout "hello 3", ZERO stderr - patch generated by diffing a pristine backup, then vendor restored and confirmed byte-identical before committing, so the patch is the only thing that applies the change Note on process: the first attempt wired the apply_patch call into a conditional helper whose anchor appears twice, the edit asserted and failed, and the follow-up measurement showed 16 deprecations — which looked like the patch not working rather than the patch never having run. Wired at top level instead, next to the other unconditional php-llvm patches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PurHur
added a commit
that referenced
this pull request
Jul 29, 2026
#24988) * Patch the 35 implicitly-nullable vendor parameters (PHP 8.4 readiness) Completes the implicit-nullable work started in #24972. PHP 8.4 deprecates `Foo $x = null` and writes the notice to stderr, which the compliance harness compares — so on an 8.4 host every case whose path touches one of these would differ from Zend on stderr alone. 35 parameters across 23 files in php-cfg and php-optimizer, via the existing patches/ layer (167 patches already there). `?Type` has been valid since PHP 7.1 and these declarations already accepted null, so behaviour is unchanged on every supported version. The counterpart declarations in lib/Visitor/* were fixed directly in #24972, so interface and implementations stay consistent. Measured in php-compiler:8.4-dev (PHP 8.4.23), bin/vm.php hello-world: implicit-nullable deprecations 16 -> 0 total deprecations 17 -> 1 The one remaining is a different 8.4 deprecation class entirely — `Using "_" as a class name is deprecated since 8.4` in ext/gettext/_.php — and is not addressed here. Verified: - apply-patches.sh rc=0, and rc=0 again on a second run (idempotent; the three "error"-matching lines are pre-existing "Skip ... (already applied)" messages whose PATCH NAMES contain "error", identical on master) - php-compiler:22.04-dev (PHP 8.2.32) with a fresh composer install: apply-patches rc=0, vm rc=0, stdout "hello 3", ZERO stderr - patch generated by diffing a pristine backup, then vendor restored and confirmed byte-identical before committing, so the patch is the only thing that applies the change Note on process: the first attempt wired the apply_patch call into a conditional helper whose anchor appears twice, the edit asserted and failed, and the follow-up measurement showed 16 deprecations — which looked like the patch not working rather than the patch never having run. Wired at top level instead, next to the other unconditional php-llvm patches. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Fix php-vendor-implicit-nullable-84.patch to apply after overlays The hunks were diffed against post-overlay vendor (Exit_/Property/StaticVar comments and signatures), so applying before php-cfg overlays failed on a fresh composer install and broke the PR gate. Move the apply after the php-cfg overlay block, regenerate the patch, and add an idempotency guard. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: PurHur <tedyyyyy@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: PurHur <PurHur@users.noreply.github.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Owner
Author
|
Follow-up vendor patch merged in #24988 ( The first PR gate failed because the patch was applied before php-cfg overlays while hunks matched post-overlay vendor. Regenerated the patch, moved apply after the overlay block, added an idempotency guard. Local verify: fresh |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PHP 8.4 deprecates
Foo $x = nulland writes the notice to stderr, which the compliance harness compares. On an 8.4 host, every case whose path touches one of these would differ from Zend on stderr alone.?Typehas been valid since PHP 7.1 and these declarations already accepted null, so behaviour is unchanged on every supported version.Five, not the 37 I first reported
My first scan counted three things that are not deprecated:
protected ?SplObjectStorage $seen = null;null|string|Variable|ClosureState $handler = nullmixed—mixed $x = nullis not deprecated, and rewriting it to?mixedis a fatal errorThat last one would have broken the build. It was caught by dry-running the fixer and reading its output before applying anything, which is the only reason it didn't ship.
Verified
In
php-compiler:8.4-dev(PHP 8.4.23):bin/vm.phphello-worldhello 3lib/+ext/php -lon all five filesThe remaining 16 are
vendor/ircmaxelland need apatches/entry — the layer already carries ~40 php-cfg patches.In
php-compiler:22.04-dev(PHP 8.2.32): same run, rc=0, zero stderr.Not the only 8.4 deprecation
ext/gettext/_.php:10tripsUsing "_" as a class name is deprecated since 8.4— a different class entirely. I am enumerating the rest by running the corpus on both hosts and diffing failing case names, rather than listing them from memory.🤖 Generated with Claude Code