|
181 | 181 | use PHPStan\Type\Generic\TemplateTypeVarianceMap; |
182 | 182 | use PHPStan\Type\IntegerType; |
183 | 183 | use PHPStan\Type\IntersectionType; |
184 | | -use PHPStan\Type\IterableType; |
185 | 184 | use PHPStan\Type\MixedType; |
186 | 185 | use PHPStan\Type\NeverType; |
187 | 186 | use PHPStan\Type\NullType; |
@@ -1251,19 +1250,6 @@ private function processStmtNode( |
1251 | 1250 | $exprType = $scope->getType($stmt->expr); |
1252 | 1251 | $isIterableAtLeastOnce = $exprType->isIterableAtLeastOnce(); |
1253 | 1252 | if ($exprType->isIterable()->no() || $isIterableAtLeastOnce->maybe()) { |
1254 | | - $foreachType = $this->getForeachIterateeType(); |
1255 | | - if ( |
1256 | | - !$foreachType->isSuperTypeOf($exprType)->yes() |
1257 | | - && $finalScope->getType($stmt->expr)->equals($foreachType) |
1258 | | - ) { |
1259 | | - // restore iteratee type, in case the type was narrowed while entering the foreach |
1260 | | - $finalScope = $finalScope->assignExpression( |
1261 | | - $stmt->expr, |
1262 | | - $exprType, |
1263 | | - $scope->getNativeType($stmt->expr), |
1264 | | - ); |
1265 | | - } |
1266 | | - |
1267 | 1253 | $finalScope = $finalScope->mergeWith($scope->filterByTruthyValue(new BooleanOr( |
1268 | 1254 | new BinaryOp\Identical( |
1269 | 1255 | $stmt->expr, |
@@ -6078,16 +6064,18 @@ private function produceArrayDimFetchAssignValueToWrite(array $dimFetchStack, ar |
6078 | 6064 | } |
6079 | 6065 | $valueToWrite = $offsetValueType->setExistingOffsetValueType($offsetType, $valueToWrite); |
6080 | 6066 |
|
6081 | | - if ($hasOffsetType !== null) { |
6082 | | - $valueToWrite = TypeCombinator::intersect( |
6083 | | - $valueToWrite, |
6084 | | - $hasOffsetType, |
6085 | | - ); |
6086 | | - } elseif ($valueToWrite->isArray()->yes()) { |
6087 | | - $valueToWrite = TypeCombinator::intersect( |
6088 | | - $valueToWrite, |
6089 | | - new NonEmptyArrayType(), |
6090 | | - ); |
| 6067 | + if ($valueToWrite->isArray()->yes()) { |
| 6068 | + if ($hasOffsetType !== null) { |
| 6069 | + $valueToWrite = TypeCombinator::intersect( |
| 6070 | + $valueToWrite, |
| 6071 | + $hasOffsetType, |
| 6072 | + ); |
| 6073 | + } else { |
| 6074 | + $valueToWrite = TypeCombinator::intersect( |
| 6075 | + $valueToWrite, |
| 6076 | + new NonEmptyArrayType(), |
| 6077 | + ); |
| 6078 | + } |
6091 | 6079 | } |
6092 | 6080 |
|
6093 | 6081 | } else { |
@@ -6327,32 +6315,12 @@ private function processVarAnnotation(MutatingScope $scope, array $variableNames |
6327 | 6315 | return $scope; |
6328 | 6316 | } |
6329 | 6317 |
|
6330 | | - private function getForeachIterateeType(): Type |
6331 | | - { |
6332 | | - return new IterableType(new MixedType(), new MixedType()); |
6333 | | - } |
6334 | | - |
6335 | 6318 | private function enterForeach(MutatingScope $scope, MutatingScope $originalScope, Foreach_ $stmt): MutatingScope |
6336 | 6319 | { |
6337 | 6320 | if ($stmt->expr instanceof Variable && is_string($stmt->expr->name)) { |
6338 | 6321 | $scope = $this->processVarAnnotation($scope, [$stmt->expr->name], $stmt); |
6339 | 6322 | } |
6340 | 6323 |
|
6341 | | - // narrow the iteratee type to those supported by foreach |
6342 | | - $foreachType = $this->getForeachIterateeType(); |
6343 | | - $scope = $scope->specifyExpressionType( |
6344 | | - $stmt->expr, |
6345 | | - TypeCombinator::intersect( |
6346 | | - $scope->getType($stmt->expr), |
6347 | | - $foreachType, |
6348 | | - ), |
6349 | | - TypeCombinator::intersect( |
6350 | | - $scope->getNativeType($stmt->expr), |
6351 | | - $foreachType, |
6352 | | - ), |
6353 | | - TrinaryLogic::createYes(), |
6354 | | - ); |
6355 | | - |
6356 | 6324 | $iterateeType = $originalScope->getType($stmt->expr); |
6357 | 6325 | if ( |
6358 | 6326 | ($stmt->valueVar instanceof Variable && is_string($stmt->valueVar->name)) |
|
0 commit comments