diff --git a/src/Type/Generic/TemplateTypeHelper.php b/src/Type/Generic/TemplateTypeHelper.php index 6f09c29ccb..5933be8e5b 100644 --- a/src/Type/Generic/TemplateTypeHelper.php +++ b/src/Type/Generic/TemplateTypeHelper.php @@ -142,9 +142,9 @@ public static function generalizeInferredTemplateType(TemplateType $templateType { if (!$templateType->getVariance()->covariant()) { $isArrayKey = $templateType->getBound()->describe(VerbosityLevel::precise()) === '(int|string)'; - if ($type->isScalar()->yes() && $isArrayKey) { + if ($type->isInteger()->yes() && $isArrayKey) { $type = $type->generalize(GeneralizePrecision::templateArgument()); - } elseif ($type->isConstantValue()->yes() && (!$templateType->getBound()->isScalar()->yes() || $isArrayKey)) { + } elseif ($type->isConstantValue()->yes() && !$templateType->getBound()->isScalar()->yes()) { $type = $type->generalize(GeneralizePrecision::templateArgument()); } } diff --git a/tests/PHPStan/Analyser/nsrt/bug-13144.php b/tests/PHPStan/Analyser/nsrt/bug-13144.php index fb47f4d862..280c6fa07c 100644 --- a/tests/PHPStan/Analyser/nsrt/bug-13144.php +++ b/tests/PHPStan/Analyser/nsrt/bug-13144.php @@ -8,7 +8,7 @@ $arr = new ArrayObject(['a' => 1, 'b' => 2]); -assertType('ArrayObject', $arr); // correctly inferred as `ArrayObject` +assertType("ArrayObject<'a'|'b', int>", $arr); $a = $arr['a']; // ok $b = $arr['b']; // ok diff --git a/tests/PHPStan/Analyser/nsrt/bug-8031.php b/tests/PHPStan/Analyser/nsrt/bug-8031.php new file mode 100644 index 0000000000..e07707109a --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-8031.php @@ -0,0 +1,32 @@ += 8.0 + +declare(strict_types = 1); + +namespace Bug8031; + +use function PHPStan\Testing\assertType; + +/** + * @template TKey of array-key + * @template TValue of mixed + */ +class Collection +{ + /** + * @param array $val + */ + public function __construct(protected array $val) {} +} + +/** + * @return Collection<'one'|'two', int> + */ +function test(): Collection +{ + $c = new Collection([ + 'one' => 1, + 'two' => 2, + ]); + assertType("Bug8031\Collection<'one'|'two', int>", $c); + return $c; +} diff --git a/tests/PHPStan/Analyser/nsrt/native-reflection-default-values.php b/tests/PHPStan/Analyser/nsrt/native-reflection-default-values.php index 5d0b8cdeab..86bc65ddf4 100644 --- a/tests/PHPStan/Analyser/nsrt/native-reflection-default-values.php +++ b/tests/PHPStan/Analyser/nsrt/native-reflection-default-values.php @@ -7,5 +7,5 @@ function () { assertType('ArrayObject<*NEVER*, *NEVER*>', new \ArrayObject()); assertType('ArrayObject<*NEVER*, *NEVER*>', new \ArrayObject([])); - assertType('ArrayObject', new \ArrayObject(['key' => 1])); + assertType("ArrayObject<'key', int>", new \ArrayObject(['key' => 1])); };