You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Method with this-out cannot apply union to template type of array-key #13374
It appears that PHPStan does not add "normal" types to $this when using @phpstan-this-out.
It appears that PHPStan is unable to union a template type via this-out (and presumably static-out) when the existing template type has a boundary of array-key
Assume a class with the following template types: K of array-key and V
changed the title [-]Method with this-out does not support union of template type and normal type[/-][+]Method with this-out cannot apply union to template type with boundary[/+]on Aug 9, 2025
changed the title [-]Method with this-out cannot apply union to template type with boundary[/-][+]Method with this-out cannot apply union to template type of array-key[/+]on Aug 9, 2025
array-key is a benevolent union of int and string.
so int|(int|string) is simplified to (int|string) in your phpdoc which is your template,
so int|TKey is indeed simplified to TKey.
Activity
axlon commentedon Aug 9, 2025
It appears that it has nothing to do with part of the union not being a template type; I am able to reproduce the issue with a union of two template types: https://phpstan.org/r/be6cc85e-bd4a-482a-803d-61cb0fd95b12
My best guess is that the
of array-keyon the class template type is causing this, because when I remove (line 7) it it does seem to work: https://phpstan.org/r/425539f8-daa0-467c-9330-ac6661a124d0[-]Method with this-out does not support union of template type and normal type[/-][+]Method with this-out cannot apply union to template type with boundary[/+][-]Method with this-out cannot apply union to template type with boundary[/-][+]Method with this-out cannot apply union to template type of array-key[/+]VincentLanglet commentedon Aug 10, 2025
array-keyis a benevolent union ofintandstring.so
int|(int|string)is simplified to(int|string)in your phpdoc which is your template,so
int|TKeyis indeed simplified toTKey.You won't get the issue by using
int|stringinstead.https://phpstan.org/r/3577d04a-545c-4431-b404-9ee5d00c86d8
ondrejmirtes commentedon Sep 2, 2025
int|TKeyshouldn't be normalized. When doing type normalization (https://phpstan.org/developing-extensions/type-system#type-normalization) parts of a union type are consumed by another when$eaterType->isSuperTypeOf($consumedType)->yes().But with
intandTKeyneither type is a super type of each other.VincentLanglet commentedon Sep 3, 2025
Let's say
$intis int et$tkeyisTKey.The call
is triggering
since
TKeyis a CompoundType because it's an UnionType(benevolent one)The implementation is
so we're doing
which is
$int->isSuperTypeOf($benevolentUnionIntOrString)which is YES.That's the issue with using a Benevolent bound...
phpstan-bot commentedon Sep 9, 2026
Closed via merging phpstan/phpstan-src#6376
github-actions commentedon Oct 11, 2026
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.