Skip to content

test: update literal types after template union fix - #6404

Merged
ondrejmirtes merged 1 commit into
phpstan:2.3.xfrom
calebdw:calebdw/push-urnqrnkskvqk
Sep 9, 2026
Merged

test: update literal types after template union fix#6404
ondrejmirtes merged 1 commit into
phpstan:2.3.xfrom
calebdw:calebdw/push-urnqrnkskvqk

Conversation

@calebdw

@calebdw calebdw commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@phpstan-bot

Copy link
Copy Markdown
Collaborator

You've opened the pull request against the latest branch 2.3.x. PHPStan 2.3 is not going to be released for months. If your code is relevant on 2.2.x and you want it to be released sooner, please rebase your pull request and change its target to 2.2.x.

@staabm

staabm commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

@ondrejmirtes its a 2.3.x only change in expectations. Please have a look

@SanderMuller

Copy link
Copy Markdown
Contributor

I am not the maintainer, so the semantics call here is Ondřej's. What I can add is where the change comes
from, because it is not one of the template commits on 2.3.x.

The transcription is faithful. On upstream/2.3.x the analyser produces exactly the three values this
PR writes down:

Expected: Bug13374\Collection<int|string, int|string>   Actual: Bug13374\Collection<int|string, 'foo'|int>
Expected: Bug13374\Collection<int|string, int>          Actual: Bug13374\Collection<123|string, int>
Expected: Bug13374\Collection<int|string, int|string>   Actual: Bug13374\Collection<123|789|string, 'foo'|int>

The test fails on 2.3.x without the PR and passes with it. On 2.2.x it passes as it stands, so "2.3.x only"
is right.

Where it started. I bisected 2.2.x..2.3.x with the test file pinned, so the oracle stayed the same at
every step. The first commit with the new behaviour is d9bba3628, the last merge of 2.2.x into 2.3.x, and
that merge brought exactly one commit: ea3e1126d, #6376. That is the PR that created this test file. So
this is #6376's new test meeting the template work on 2.3.x, not a regression from a single 2.3.x commit.

The new values follow from the annotations. With @phpstan-this-out static<TKey|TPutKey, TValue|TPutValue>
and a receiver that keeps its mutated type:

call this-out result
push(123) int|string, int|123 int|123 collapses to int
push('foo') int|string, int|'foo' 'foo'|int
put(123, 456) string|123, int|456 123|string, int
put(789, 'foo') 123|string|789, int|'foo' 123|789|string, 'foo'|int

That also explains why only three of the four assertions move. In the first one 123 is absorbed by int,
so it reads the same under either behaviour and cannot tell them apart.

One thing I checked and it is not the cause. This is not a general shift toward literal template
arguments. A plain @template T @param T $v @return T returns 'foo', and @template TK of array-key
returns 123, on both branches. The difference is narrower: 2.2.x generalises the TValue|TPutValue
union that @phpstan-this-out composes, and 2.3.x keeps it literal.

Worth a decision rather than a review comment. The key accumulates across sequential calls, so
123|789|string after two put() calls. In straight-line code each further call adds another literal. If
this-out should generalise, then the fix belongs in the inference and this PR would be pinning the wrong
values.

Nothing to measure here, the PR touches no src/. All three red checks belong to the base:
PHPStan (8.1, windows-latest) and the two macos-15-intel Turbo legs are red on #6392, #6398 and #6403
as well.

@ondrejmirtes
ondrejmirtes merged commit 32fadd3 into phpstan:2.3.x Sep 9, 2026
486 of 489 checks passed
@ondrejmirtes

Copy link
Copy Markdown
Member

Thank you!

@calebdw
calebdw deleted the calebdw/push-urnqrnkskvqk branch September 9, 2026 20:19
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.

5 participants