Skip to content

Fix seemingly same type reports as invalid/incompatible.#5094

Open
VincentLanglet wants to merge 4 commits intophpstan:2.1.xfrom
VincentLanglet:create-pull-request/patch-v6x5b0k
Open

Fix seemingly same type reports as invalid/incompatible.#5094
VincentLanglet wants to merge 4 commits intophpstan:2.1.xfrom
VincentLanglet:create-pull-request/patch-v6x5b0k

Conversation

@VincentLanglet
Copy link
Contributor

@VincentLanglet VincentLanglet commented Feb 28, 2026

Rework of #5073

Closes phpstan/phpstan#13440

The issue was that one closure was changed into Closure(template-strict-mixed), while the other stayed Closure(template-mixed) and therefor they were not equal.

Instead of just transforming common in return type, we should transform them in parameter and return types.
Best way to do it it's to transform common type on the closure. (Cf commit 2)

And then when I thought again about it, I think there is some loss on calling transformCommonType inside the TypeTraverser::map call since we might call in multiple times when traversing the types. The first one will transform the mixed to strict mixed, but other call will be useless.
So it's seems better to just call it once on the whole accepted type at the end.

github-actions bot and others added 3 commits February 27, 2026 15:17
…tity

- TemplateMixedType and TemplateStrictMixedType with same scope+name represent
  the same template parameter but fail equals() due to different concrete classes
- At level 9+ transformCommonType converts TemplateMixedType to
  TemplateStrictMixedType in accepting type but not in accepted closure params
- Added fallback check in isValidVariance() for invariant templates: if both
  sides are TemplateType with matching scope and name, treat as equal
- New regression test in tests/PHPStan/Rules/Classes/data/bug-13440.php

Closes phpstan/phpstan#13440

return new CallableType(
$acceptedType->getParameters(),
$traverse($this->transformCommonType($acceptedType->getReturnType())),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need another test for callable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@staabm
Copy link
Contributor

staabm commented Feb 28, 2026

Instead of just transforming common in return type, we should transform them in parameter and return types.

What about throws type?

@VincentLanglet
Copy link
Contributor Author

Instead of just transforming common in return type, we should transform them in parameter and return types.

What about throws type?

ClosureType::traverse only touch param and return type.

And it kinda make sens here since we're interesting removing null or transforming mixed into strict ; two things which does not make sens for throw type.

@VincentLanglet VincentLanglet marked this pull request as ready for review February 28, 2026 13:27
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

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.

3 participants