Skip to content

Commit

Permalink
Fix specifying types for chained assignments
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanvelzen authored and ondrejmirtes committed Jun 24, 2022
1 parent b95606e commit b614619
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/Analyser/TypeSpecifier.php
Expand Up @@ -1155,10 +1155,43 @@ public function create(
return new SpecifiedTypes([], [], false, [], $rootExpr);
}

while ($expr instanceof Expr\Assign) {
$expr = $expr->var;
$specifiedExprs = [];

if ($expr instanceof Expr\Assign) {
$specifiedExprs[] = $expr->var;

while ($expr->expr instanceof Expr\Assign) {
$specifiedExprs[] = $expr->expr->var;
$expr = $expr->expr;
}
} else {
$specifiedExprs[] = $expr;
}

$types = null;

foreach ($specifiedExprs as $specifiedExpr) {
$newTypes = $this->createForExpr($specifiedExpr, $type, $context, $overwrite, $scope, $rootExpr);

if ($types === null) {
$types = $newTypes;
} else {
$types = $types->unionWith($newTypes);
}
}

return $types;
}

private function createForExpr(
Expr $expr,
Type $type,
TypeSpecifierContext $context,
bool $overwrite = false,
?Scope $scope = null,
?Expr $rootExpr = null,
): SpecifiedTypes
{
if ($scope !== null) {
if ($context->true()) {
$resultType = TypeCombinator::intersect($scope->getType($expr), $type);
Expand Down
Expand Up @@ -416,4 +416,10 @@ public function testBug7229(): void
]);
}

public function testBug7142(): void
{
$this->checkExplicitMixed = true;
$this->analyse([__DIR__ . '/data/bug-7142.php'], []);
}

}
26 changes: 26 additions & 0 deletions tests/PHPStan/Rules/Arrays/data/bug-7142.php
@@ -0,0 +1,26 @@
<?php declare(strict_types = 1);

namespace Bug7142;

/**
* @return array{id: int}|null
*/

function maybeNull(){
if ((rand(3)%2) != 0) {
return ['id' => 1];
}
return null;
}

/**
* @return void
*/
function foo(){
if (!is_null($a = $b = $c = maybeNull())){
echo $a['id'];
echo $b['id']; // 20 "Offset 'id' does not exist on array{id: int}|null."
echo $c['id']; // 21 "Offset 'id' does not exist on array{id: int}|null."
}
}

0 comments on commit b614619

Please sign in to comment.