Skip to content

PHPStan 2.2 compatibility#85

Merged
ruudk merged 4 commits into
mainfrom
ruudk/phpstan-2-2
May 28, 2026
Merged

PHPStan 2.2 compatibility#85
ruudk merged 4 commits into
mainfrom
ruudk/phpstan-2-2

Conversation

@ruudk

@ruudk ruudk commented May 28, 2026

Copy link
Copy Markdown
Owner

Bump to PHPStan 2.2

Pass JSON_THROW_ON_ERROR as $flags, not $depth

PHPStan 2.2 flags the constant in the third arg of json_decode, since $depth only accepts integer depths. Move it to the $flags slot with the default depth of 512.

Unseal generated array shapes for PHPStan 2.2

PHPStan 2.2 enforces sealed array shapes by default, rejecting the generator's pattern where a parent forwards $this->data (or a wider loaders registry) into a child fragment, inline-fragment, error, or loader constructor that declared a narrower shape. The forwarding is structurally correct — children only read the keys they declare — but the sealed-shape rule treats the extras as type errors.

Mark generated payload, error, hooks, and loaders shapes as unsealed so the wider parent shape fits. HookLoader's template params become @template-covariant so any specific instantiation fits the unsealed extras slot in nested classes' \$loaders parameter. Input object shapes stay sealed — those describe a closed GraphQL input schema and are constructed by user code with exactly the declared fields.

Extras are emitted explicitly as ...<int|string, mixed> rather than the short ..., since PHPStan's missingType.iterableValue rule at level 6+ rejects the implicit array-key, mixed extras.

ruudk added 3 commits May 28, 2026 12:06
PHPStan 2.2 flags the constant in the third arg of `json_decode`,
since `$depth` only accepts integer depths. Move it to the `$flags`
slot with the default depth of 512.
PHPStan 2.2 enforces sealed array shapes by default, rejecting the
generator's pattern where a parent forwards `$this->data` (or a wider
loaders registry) into a child fragment, inline-fragment, error, or
loader constructor that declared a narrower shape. The forwarding is
structurally correct — children only read the keys they declare — but
the sealed-shape rule treats the extras as type errors.

Mark generated payload, error, hooks, and loaders shapes as unsealed so
the wider parent shape fits. `HookLoader`'s template params become
`@template-covariant` so any specific instantiation fits the unsealed
extras slot in nested classes' `\$loaders` parameter. Input object
shapes stay sealed — those describe a closed GraphQL input schema and
are constructed by user code with exactly the declared fields.

Extras are emitted explicitly as `...<int|string, mixed>` rather than
the short `...`, since PHPStan's `missingType.iterableValue` rule at
level 6+ rejects the implicit `array-key, mixed` extras.
@ruudk ruudk force-pushed the ruudk/phpstan-2-2 branch from b9a67a7 to 8f382e6 Compare May 28, 2026 10:06
@ruudk ruudk changed the title Update PHPStan to 2.2 and fix related issues PHPStan 2.2 compatibility May 28, 2026
@ruudk ruudk enabled auto-merge (squash) May 28, 2026 10:17
@ruudk ruudk disabled auto-merge May 28, 2026 10:17
@ruudk ruudk enabled auto-merge (squash) May 28, 2026 10:17
@ruudk ruudk merged commit 81e7857 into main May 28, 2026
3 checks passed
@ruudk ruudk deleted the ruudk/phpstan-2-2 branch May 28, 2026 10:17
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.

1 participant