Repository navigation
Regression: constructor-promoted asymmetric visibility public private(set) — compile fatal (re-#4690) #6981
Copy link
Copy link
Closed
Labels
area:compilerCompiler / CFG / JITCompiler / CFG / JITarea:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language featuresPhase 2 – language features
Description
Category
language · php-src-strict
Problem
PHP 8.4 allows asymmetric visibility on constructor-promoted properties, e.g. public function __construct(public private(set) string $name). Non-promoted public private(set) string $name compiles and enforces correctly on VM today, but the promoted form fails at compile with:
Multiple access type modifiers are not allowed
Closed #4690 tracked this gap; the parser/rewriter still rejects valid php-src syntax, blocking PHP 8.4 parity and self-host code using promoted asymmetric properties.
php-src reference
- php/php-src
Zend/zend_compile.c— promoted parameter → property with asymmetric set visibility - php/php-src
Zend/zend_object_handlers.c— external write rejection onprivate(set) - RFC: Asymmetric Visibility
Repro (failure today)
<?php
class User {
public function __construct(
public private(set) string $name,
) {}
}
$u = new User('alice');
echo $u->name, "\n";
try {
$u->name = 'bob';
} catch (Error $e) {
echo $e->getMessage(), "\n";
}./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php bin/vm.php repro.php
'| Runtime | Compile | Runtime |
|---|---|---|
| Zend PHP 8.4+ | OK | alice + cannot modify private(set) |
| vm.php today | Fatal: Multiple access type modifiers | — |
Control (works today): non-promoted public private(set) string $name = 'x'; in the same file compiles and throws on external write.
Also fails: public readonly private(set) on promoted parameters (same parse fatal).
Scope (this repo)
| Layer | Path |
|---|---|
| Parser / preprocessor | lib/SourcePreprocessor/AsymmetricVisibilityRewriter.php — allow private(set) on promoted params |
| Compiler | lib/Compiler.php — promoted param metadata → asymmetricSetVisibilityFromCfgOp |
| VM / JIT | lib/VM.php, lib/JIT/AsymmetricVisibilityGuard.php — same guards as non-promoted |
| Tests | test/compliance/cases/language/asymmetric_visibility_promoted_ctor.phpt |
PHP-in-PHP: no new C runtime branches.
Done when
- Repro compiles on VM, JIT, and AOT
- External
$u->name = 'bob'throws catchableErrormatching Zend message - Writes from inside class / constructor still allowed
- Non-promoted asymmetric properties remain green (no regression)
-
./script/ci-fast.sh --filter asymmetric_visibility_promotedgreen
Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && ./vendor/bin/phpunit --filter asymmetric_visibility_promoted'Related
- Language: asymmetric visibility on constructor-promoted properties (zend_compile.c parity) #4690 (closed prematurely) · Language: property hooks with asymmetric set visibility set (protected) => — parse fails (zend_property_hooks.c) #6898 asymmetric set visibility parse · Language: PHP 8.4 asymmetric property visibility (public/private(set), etc.) #3165 / Language: PHP 8.4 asymmetric visibility private(set) — JIT enforce + catchable Error (phase 2 of #3165) #4029 base asymmetric · Language: constructor property promotion — non-readonly classes fail with Missing required argument 0 (zend_compile.c) #4770 promoted ctor · Epic: Self-host critical path — compiler compiles itself (M3→M5) #1492
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:compilerCompiler / CFG / JITCompiler / CFG / JITarea:vmVirtual machineVirtual machineenhancementNew feature or requestNew feature or requestimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claimphase-2:languagePhase 2 – language featuresPhase 2 – language features
Activity
PurHur commentedon Jun 6, 2026
claim: worker-lane-b — starting this run
Fix constructor-promoted asymmetric visibility compile check (#6981). (…
PurHur commentedon Jun 6, 2026
Merged via #6988.
Fix:
AsymmetricVisibilityCompileCheck::verifyPromotedParam()no longer treatspublicpromotion +private(set)as duplicate modifiers — matches PHP 8.4 RFC asymmetric-visibility-v2 /zend_compile.c.Verification:
→ compiles, prints
alice, external write throwsCannot modify private(set) property User::$name from global scope.Reject public private(set) on promoted constructor params (#9691) (#9699
Add compliance guard for promoted public private(set) (#10001) (#10052)