Skip to content

Support PHPStan 2.2.10 scope changes - #8420

Merged
TomasVotruba merged 1 commit into
mainfrom
tv-phpstan-210
Aug 30, 2026
Merged

Support PHPStan 2.2.10 scope changes#8420
TomasVotruba merged 1 commit into
mainfrom
tv-phpstan-210

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

PHPStan 2.2.10 emits node callbacks after a node's results are stored and replaces FiberScope with NodeCallbackScope. This flipped the parent/child callback ordering, so Rector's manual scope seeding on child expressions overwrote the correct, narrowed scope PHPStan had already attached. That broke type/scope resolution inside arrow functions, &&/|| operands, and nullsafe calls.

Changes

  • PHPStanNodeScopeResolver
    • Unwrap the new NodeCallbackScope via toWalkScope().
    • Stop clobbering the arrow-function body scope, so fn($v) => $v['x'] infers from the outer array shape again.
    • Only seed a BinaryOp operand scope when PHPStan has not already set one, preserving is_array()/truthy narrowing on the right operand of && and ||.
  • CallCollectionAnalyzer - strip null before resolving the object class of a nullsafe call caller; 2.2.10 no longer reports object class names for a nullable union, which made RemoveUnusedPrivateMethodRector drop methods called via ?->.
  • NullToStrictStringIntConverter - drop the handling for the removed FiberScope.
  • Bump required phpstan/phpstan to ^2.2.10.

Fixed failing fixtures

  • SimplifyEmptyCheckOnEmptyArrayRector - replace_is_array_check
  • RemoveUnusedPrivateMethodRector - keep_nullsafe_called_method
  • RenameParamToMatchTypeRector - used_in_arrow_function_param
  • AddArrowFunctionReturnTypeRector - return_by_array_shape_type

Full test suite, ECS, PHPStan level 8, and composer rector all pass locally.

PHPStan 2.2.10 emits node callbacks after a node's results are stored
and replaces FiberScope with NodeCallbackScope. This flipped the
parent/child callback ordering, so Rector's manual scope seeding on
child expressions now overwrote the correct, narrowed scope PHPStan
had already attached.

- PHPStanNodeScopeResolver: unwrap NodeCallbackScope via toWalkScope();
  stop clobbering arrow-function body scope; only seed a BinaryOp
  operand scope when PHPStan has not already set one, preserving
  is_array()/truthy narrowing on the right operand of && and ||.
- CallCollectionAnalyzer: strip null before resolving the object class
  of a nullsafe call caller, as 2.2.10 no longer reports object class
  names for a nullable union.
- NullToStrictStringIntConverter: drop the removed FiberScope handling.

Bump required phpstan to ^2.2.10.
@TomasVotruba
TomasVotruba merged commit ffe4c32 into main Aug 30, 2026
43 of 44 checks passed
@TomasVotruba
TomasVotruba deleted the tv-phpstan-210 branch August 30, 2026 19:51
staabm pushed a commit to SanderMuller/phpstan that referenced this pull request Sep 8, 2026
Both Rector jobs have been failing since 2.2.10. The pinned b14e0ab4 is
from 2026-08-05 and predates Rector's adaptation to the node callback
ordering that changed in that release: rectorphp/rector-src#8420,
"Support PHPStan 2.2.10 scope changes", landed 2026-08-30 and updated
CallCollectionAnalyzer and PHPStanNodeScopeResolver.

Bumping the pin past that commit and refreshing rector-composer.lock
against it, generated with PHP 8.4 since that is what the jobs run.

Verified by replaying the job from the committed lock: the two rule
tests that were failing, RemoveUnusedPrivateMethodRector and
SimplifyEmptyCheckOnEmptyArrayRector, are OK (63 tests, 66 assertions).

Only the rector-src pin is touched here. The separate
rector-downgrade-php job has its own pin and its own failure, which I
have not looked into.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant