Skip to content

chore: upgrade PHPStan to 2.2.6 - #2240

Closed
SanderMuller wants to merge 1 commit into
tempestphp:3.xfrom
SanderMuller:phpstan-2.2
Closed

chore: upgrade PHPStan to 2.2.6#2240
SanderMuller wants to merge 1 commit into
tempestphp:3.xfrom
SanderMuller:phpstan-2.2

Conversation

@SanderMuller

Copy link
Copy Markdown
Contributor

Summary

Upgrades phpstan/phpstan from 2.1.40 to 2.2.6.

Why

Mainly speed. On this codebase (full src, packages and tests, level 5, single process, cold cache), 2.2.6 uses about 14% less CPU than 2.1.40, 63.9s against 74.6s as the min of three runs, and a little less peak memory (895 MB against 964 MB). CI runs in parallel, so in practice that is a shorter run and more room under the 1G limit.

Composer resolves it as a single-package upgrade. None of the PHPStan extensions here (phpat, disallowed-calls, deprecation-rules) need a version change.

Findings addressed

2.2 reports nine things 2.1.40 did not. None are 2.2 bugs. Three kinds:

Stale ignores that 2.2 made unnecessary by fixing the false positives they suppressed, removed:

  • Option::displayValue: two @phpstan-ignore-next-line on the method_exists() guard and the toString() call. 2.2 narrows method_exists(), so neither is needed.
  • BootDiscovery::resolveDiscovery(): @phpstan-ignore catch.neverThrown. 2.2 sees new $discoveryClass() can throw ArgumentCountError, so the catch is reachable.

Dead code, removed (behavior unchanged):

  • GenericContainer::invoke(): once is_array($method) narrows the callable to its two-element array form, count($method) === 2 is always true.
  • Cookie::createFromString(): 'value' is always set, so ?? null never fired; secure and httponly are only ever set to true, so isset(...) && ... === true is just isset(...).

False positives, ignored with a reason:

  • SignerTest::test_no_signing_key(): the sign() call is there to trigger the expected exception, so its result is unused on purpose.
  • TempestViewLexer::lexTag(): seek() is stateful, and consume() moved the cursor past = earlier in the branch, so the === "'" check is not actually always false. 2.2 does not track the mutation across the two calls.

Checks

  • composer phpstan green on 2.2.6, no baseline changes.
  • composer lint (mago) and formatting clean.
  • Full unit test suite green: 4660 tests, 14475 assertions, 1 skipped (pre-existing).

Bumps phpstan/phpstan from 2.1.40 to 2.2.6. Composer resolves it as a
single-package upgrade; none of the PHPStan extensions need a version change.

2.2 surfaces nine findings that 2.1.40 did not. None are 2.2 bugs:

- Removed three now-stale ignores that 2.2 no longer needs (2.2 narrows
  method_exists() and sees `new $class()` can throw ArgumentCountError):
  Option::displayValue and BootDiscovery::resolveDiscovery().
- Dropped provably dead code flagged by the sharper analysis: the redundant
  count($method) === 2 in GenericContainer::invoke(), the dead ?? null and the
  === true checks in Cookie::createFromString().
- Ignored two false positives with a reason: the intentionally-unused sign()
  call in a test that expects an exception, and a stateful seek() comparison in
  TempestViewLexer that is not actually constant.
@brendt

brendt commented Jul 27, 2026

Copy link
Copy Markdown
Member

Awesome! We just merged #2234 though :D

Nonetheless, I appreciate the effort!

@brendt brendt closed this Jul 27, 2026
@SanderMuller

Copy link
Copy Markdown
Contributor Author

Awesome! We just merged #2234 though :D

Nonetheless, I appreciate the effort!

Whoops totally missed that one, awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants