Repository navigation
Language: static closure bindTo()/bind() with $this must Error (Zend/zend_closures.c parity) #4613
Description
Activity
- addedenhancementNew feature or requestNew feature or requestphase-2:languagePhase 2 – language featuresPhase 2 – language featuresarea:compilerCompiler / CFG / JITCompiler / CFG / JITarea:vmVirtual machineVirtual machineimplementation-readySpec complete: repro, php-src ref, done-when — safe for workers to claimSpec complete: repro, php-src ref, done-when — safe for workers to claim
on Jun 2, 2026 claim: worker-lane-c — starting this run
Merged via #4619.
Verification
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && vendor/bin/phpunit test/compliance/ClosureVMTest.php --filter static_closure_bind'— OK (1 test)./script/docker-exec.sh -- bash -lc 'source script/php-env.sh && php bin/jit.php'on issue repro —Error: Cannot bind static closure to object
VM and JIT now match Zend for
static function+bindTo/bindwith an object$this;bindTo(null)still allowed.- added a commit that references this issue
on Jun 2, 2026 claim: cursor-agent-lane-c — reopening: static_closure_bind.phpt fatals in returnTypeCallableName (func->class Literal); fixing and re-verifying #4613 done-when.
- added a commit that references this issue
on Jun 21, 2026 Merged via #10425.
Root cause:
returnTypeCallableName()concatenatedfunc->class(aPHPCfg\Operand\Literal) when enforcing: Closurereturn types, fatally aborting beforeClosureSupport::bindTo()could throw.Fix: Read
func->class->valuefor the callable label. VM/JIT now emitError: Cannot bind static closure to objectper Zend;bindTo(null)still returns an object.Verification:
```bash
./script/docker-exec.sh -- bash -lc 'source script/php-env.sh
php bin/vm.php test/compliance/cases/language/static_closure_bind.phpt
php bin/jit.php test/compliance/cases/language/static_closure_bind.phpt
./vendor/bin/phpunit --filter static_closure_bind
'
```
Category
languageProblem
PHP
static function () { ... }closures must not receive a bound$this. Zend rejectsClosure::bindTo($obj)andClosure::bind($closure, $obj, ...)on static closures with:This compiler creates static closures without
boundThis(lib/VM.phpFLAG_STATICcheck) butClosureSupport::bindTo()(lib/VM/ClosureSupport.php) does not verify the closure is non-static — binding$thissucceeds silently, breaking visibility/$thissemantics vs Zend.php-src reference
Zend/zend_closures.c—zend_closure_bind(), static-closure guardZend/zend_closures.h—ZEND_ACC_STATICon closure functionRepro (behavior gap today)
Error: Cannot bind static closure to objectbin/vm.phptrue(bind appears to succeed) ❌Also test
Closure::bind($fn, $obj, 'C')— same Error on Zend.Scope (this repo)
lib/VM/ClosureSupport.php— detect static closure (ClosureState/ wrapped funcFLAG_STATIC) before assigningboundThislib/JIT/ClosureBindHelper.php— emit same Error pathtest/compliance/cases/language/static_closure_bind.phptTrack
static fn () =>(arrow) separately if desugar omits static flag — should share the same guard.Done when
Errorwith Zend message on VMbindTo(null)/ unbind still allowed on static closures (Zend permits)./phpc jit repro.php)./script/ci-fast.sh --filter static_closure_bindgreenRelated