diff --git a/src/Type/UnionType.php b/src/Type/UnionType.php index c5c9f65415..4fd4bfe8ce 100644 --- a/src/Type/UnionType.php +++ b/src/Type/UnionType.php @@ -581,7 +581,11 @@ public function getUnresolvedMethodPrototype(string $methodName, ClassMemberAcce continue; } - $methodPrototypes[] = $type->getUnresolvedMethodPrototype($methodName, $scope)->withCalledOnType($this); + $prototype = $type->getUnresolvedMethodPrototype($methodName, $scope); + if ($this instanceof TemplateType) { + $prototype = $prototype->withCalledOnType($this); + } + $methodPrototypes[] = $prototype; } $methodsCount = count($methodPrototypes); diff --git a/tests/PHPStan/Analyser/nsrt/bug-11687.php b/tests/PHPStan/Analyser/nsrt/bug-11687.php new file mode 100644 index 0000000000..0455d3b2a2 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-11687.php @@ -0,0 +1,60 @@ += 8.0 + +namespace Bug12562; + +use function PHPStan\Testing\assertType; + +class UserV1 +{ + public function toV2(): UserV2 + { + return new UserV2(); + } +} + +class UserV2 +{ + public function toV2(): self + { + return $this; + } +} + +class UserV2a extends UserV2 +{ + /** + * @return $this + */ + public function toV2(): self + { + return $this; + } +} + +function doSomething(UserV1|UserV2 $user, UserV1|UserV2a $user2): void +{ + assertType('Bug12562\UserV2', $user->toV2()); + assertType('Bug12562\UserV2', $user2->toV2()); +} diff --git a/tests/PHPStan/Analyser/nsrt/static-late-binding.php b/tests/PHPStan/Analyser/nsrt/static-late-binding.php index 0493475f76..8e5b345826 100644 --- a/tests/PHPStan/Analyser/nsrt/static-late-binding.php +++ b/tests/PHPStan/Analyser/nsrt/static-late-binding.php @@ -85,7 +85,7 @@ public function foo(): void assertType('static(StaticLateBinding\B)', parent::retStatic()); assertType('static(StaticLateBinding\B)', $this->retStatic()); assertType('bool', X::retStatic()); - assertType('bool|StaticLateBinding\A|StaticLateBinding\X', $clUnioned::retStatic()); // should be bool|StaticLateBinding\A https://github.com/phpstan/phpstan/issues/11687 + assertType('bool|StaticLateBinding\A', $clUnioned::retStatic()); // should be bool|StaticLateBinding\A https://github.com/phpstan/phpstan/issues/11687 assertType('StaticLateBinding\A', A::retStatic(...)()); assertType('StaticLateBinding\B', B::retStatic(...)());