diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 404097352b..3b2605ffbf 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -78,6 +78,7 @@ use PHPStan\Type\ErrorType; use PHPStan\Type\ExpressionTypeResolverExtensionRegistry; use PHPStan\Type\GeneralizePrecision; +use PHPStan\Type\Generic\TemplateType; use PHPStan\Type\Generic\TemplateTypeHelper; use PHPStan\Type\Generic\TemplateTypeMap; use PHPStan\Type\IntegerRangeType; @@ -2731,7 +2732,7 @@ public function specifyExpressionType(Expr $expr, Type $type, Type $nativeType, if ($dimType->isInteger()->yes() || $dimType->isString()->yes()) { $exprVarType = $scope->getType($expr->var); $isArray = $exprVarType->isArray(); - if (!$exprVarType instanceof MixedType && !$isArray->no()) { + if (!$exprVarType instanceof MixedType && !$isArray->no() && !$exprVarType instanceof TemplateType) { $tooManyHasOffsetValueTypes = false; $varType = $exprVarType; diff --git a/tests/PHPStan/Analyser/nsrt/bug-10172.php b/tests/PHPStan/Analyser/nsrt/bug-10172.php new file mode 100644 index 0000000000..460accccdf --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-10172.php @@ -0,0 +1,27 @@ +} + * + * @param T $a + * + * @return T + */ + public function foo(array $a): array + { + assertType('T of array{data: array} (method Bug10172\HelloWorld::foo(), argument)', $a); + + foreach ($a['data'] as $i) { + } + + assertType('T of array{data: array} (method Bug10172\HelloWorld::foo(), argument)', $a); + + return $a; + } +}