Repository navigation
Keep the creation-time fixpoint for closures assigned to their own by-ref variable - #6912
Open
ondrejmirtes wants to merge 2 commits into
Open
ondrejmirtes wants to merge 2 commits into
ondrejmirtes wants to merge 2 commits into
Conversation
…-ref variable A closure assigned to one of its by-ref variables - $f = function () use (&$f) - reaches itself through that variable in ways invocations cannot all be followed: call_user_func($f), $f->__invoke(), aliasing. Its by-ref uses now keep the creation-time fixpoint instead of seeing the variable as null. Nested closures are scanned only for the variables they capture, and arrow functions without those shadowed by their parameters, so an unrelated nested $count() no longer widens the enclosing closure's by-ref $count. Amp-Thread-ID: https://ampcode.com/threads/T-01a19c29-188b-7572-9730-387584a8a9fd
…e walk The check looked the closure up in a per-frame map of every closure assigned in the body, nested function-likes included: a linear search per question over all closures assigned to the variable, and each enclosing frame of a nested closure walking the same subtree again. The walk now marks the closures themselves, so each closure is decided once, by the first walk that reaches it, and getAssignedClosures() is back to the top-level map findAssignedClosures() needs. Amp-Thread-ID: https://ampcode.com/threads/T-01a19c29-188b-7572-9730-387584a8a9fd
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.
Follow-up to 9ed2617, which covered
$fx()called from nested closures but still analysed these asnull:call_user_func($fx),$fx->__invoke(),$a = $fx; $a();inside$fx = static function () use (&$fx) { … }A closure assigned to one of its own by-ref variables now keeps the creation-time fixpoint for its by-ref uses (approach from #6818).
It also restores precision lost in that commit: nested closures are scanned only for the variables they
use, and arrow functions without names shadowed by their parameters, sofunction (Closure $count) { $count(); }inside a closure withuse (&$count)no longer widens0toint<0, max>(approach from #6721).Both are mirrored in turbo-ext.
Tests:
nsrt/bug-15442.phpandCallCallablesRuleTest::testBug15442; they fail without the change (5 assertions / 1 error) and pass with it, with and without the extension. Full suite passes in both modes,walk-trace.phpis identical on the new fixtures.Closes phpstan/phpstan#15442