diff --git a/src/Type/TypeCombinator.php b/src/Type/TypeCombinator.php index d3442f0470..e7a0d6bdf5 100644 --- a/src/Type/TypeCombinator.php +++ b/src/Type/TypeCombinator.php @@ -1212,7 +1212,7 @@ public static function intersect(Type ...$types): Type for ($i = 0; $i < $typesCount; $i++) { $type = $types[$i]; - if ($type instanceof IntersectionType) { + if ($type instanceof IntersectionType && !$type instanceof TemplateType) { // transform A & (B & C) to A & B & C array_splice($types, $i--, 1, $type->getTypes()); $typesCount = count($types); diff --git a/tests/PHPStan/Analyser/nsrt/bug-13577.php b/tests/PHPStan/Analyser/nsrt/bug-13577.php new file mode 100644 index 0000000000..2406bd0f95 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-13577.php @@ -0,0 +1,35 @@ +b($foo); + } + + /** + * @param T $foo + */ + public function b($foo): void {} +} diff --git a/tests/PHPStan/Analyser/nsrt/bug-14348.php b/tests/PHPStan/Analyser/nsrt/bug-14348.php new file mode 100644 index 0000000000..b0e728ea8d --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-14348.php @@ -0,0 +1,23 @@ + $tgs + */ + public function computeForFrontByPosition(array $tgs): void + { + assertType('T of Bug14348\PositionEntityInterface&Bug14348\TgEntityInterface (method Bug14348\HelloWorld::computeForFrontByPosition(), argument)', $tgs[0]); + } +} diff --git a/tests/PHPStan/Analyser/nsrt/bug-9961.php b/tests/PHPStan/Analyser/nsrt/bug-9961.php new file mode 100644 index 0000000000..0e3535ee27 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-9961.php @@ -0,0 +1,35 @@ +getDisplayName() . '=final', ]; + + // https://github.com/phpstan/phpstan/issues/14348 + yield [ + [ + TemplateTypeFactory::create( + TemplateTypeScope::createWithFunction('a'), + 'T', + new IntersectionType([new ObjectType('Iterator'), new ObjectType('Countable')]), + TemplateTypeVariance::createInvariant(), + ), + new MixedType(), + ], + TemplateIntersectionType::class, + 'T of Countable&Iterator (function a(), parameter)', + ]; } /**