Skip to content

Commit 1893100

Browse files
jlherrenondrejmirtes
authored andcommitted
Fix isset() with multiple arguments
Fixes phpstan/phpstan#1884
1 parent 5be8b80 commit 1893100

File tree

3 files changed

+38
-26
lines changed

3 files changed

+38
-26
lines changed

src/Analyser/NodeScopeResolver.php

+19-26
Original file line numberDiff line numberDiff line change
@@ -1221,36 +1221,25 @@ private function ensureNonNullability(MutatingScope $scope, Expr $expr, bool $fi
12211221
{
12221222
$exprToSpecify = $expr;
12231223
$specifiedExpressions = [];
1224-
while (
1225-
$exprToSpecify instanceof PropertyFetch
1226-
|| $exprToSpecify instanceof StaticPropertyFetch
1227-
|| (
1228-
$findMethods && (
1229-
$exprToSpecify instanceof MethodCall
1230-
|| $exprToSpecify instanceof StaticCall
1231-
)
1232-
)
1233-
) {
1234-
if (
1235-
$exprToSpecify instanceof PropertyFetch
1236-
|| $exprToSpecify instanceof MethodCall
1237-
) {
1224+
while (true) {
1225+
$exprType = $scope->getType($exprToSpecify);
1226+
$exprTypeWithoutNull = TypeCombinator::removeNull($exprType);
1227+
if (!$exprType->equals($exprTypeWithoutNull)) {
1228+
$specifiedExpressions[] = new EnsuredNonNullabilityResultExpression($exprToSpecify, $exprType);
1229+
$scope = $scope->specifyExpressionType($exprToSpecify, $exprTypeWithoutNull);
1230+
}
1231+
1232+
if ($exprToSpecify instanceof PropertyFetch) {
1233+
$exprToSpecify = $exprToSpecify->var;
1234+
} elseif ($exprToSpecify instanceof StaticPropertyFetch && $exprToSpecify->class instanceof Expr) {
1235+
$exprToSpecify = $exprToSpecify->class;
1236+
} elseif ($findMethods && $exprToSpecify instanceof MethodCall) {
12381237
$exprToSpecify = $exprToSpecify->var;
1239-
} elseif ($exprToSpecify->class instanceof Expr) {
1238+
} elseif ($findMethods && $exprToSpecify instanceof StaticCall && $exprToSpecify->class instanceof Expr) {
12401239
$exprToSpecify = $exprToSpecify->class;
12411240
} else {
12421241
break;
12431242
}
1244-
1245-
$exprType = $scope->getType($exprToSpecify);
1246-
$exprTypeWithoutNull = TypeCombinator::removeNull($exprType);
1247-
if ($exprType->equals($exprTypeWithoutNull)) {
1248-
continue;
1249-
}
1250-
1251-
$specifiedExpressions[] = new EnsuredNonNullabilityResultExpression($exprToSpecify, $exprType);
1252-
1253-
$scope = $scope->specifyExpressionType($exprToSpecify, $exprTypeWithoutNull);
12541243
}
12551244

12561245
return new EnsuredNonNullabilityResult($scope, $specifiedExpressions);
@@ -1861,15 +1850,19 @@ static function () use ($expr, $rightResult): MutatingScope {
18611850
$scope = $this->lookForExitVariableAssign($scope, $expr->expr);
18621851
} elseif ($expr instanceof Expr\Isset_) {
18631852
$hasYield = false;
1853+
$nonNullabilityResults = [];
18641854
foreach ($expr->vars as $var) {
18651855
$nonNullabilityResult = $this->ensureNonNullability($scope, $var, true);
18661856
$scope = $this->lookForEnterVariableAssign($nonNullabilityResult->getScope(), $var);
18671857
$result = $this->processExprNode($var, $scope, $nodeCallback, $context->enterDeep());
18681858
$scope = $result->getScope();
18691859
$hasYield = $hasYield || $result->hasYield();
1870-
$scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions());
1860+
$nonNullabilityResults[] = $nonNullabilityResult;
18711861
$scope = $this->lookForExitVariableAssign($scope, $var);
18721862
}
1863+
foreach (array_reverse($nonNullabilityResults) as $nonNullabilityResult) {
1864+
$scope = $this->revertNonNullability($scope, $nonNullabilityResult->getSpecifiedExpressions());
1865+
}
18731866
} elseif ($expr instanceof Instanceof_) {
18741867
$result = $this->processExprNode($expr->expr, $scope, $nodeCallback, $context->enterDeep());
18751868
$scope = $result->getScope();

tests/PHPStan/Rules/Properties/AccessPropertiesRuleTest.php

+4
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ public function testAccessProperties(): void
168168
'Cannot access property $selfOrNull on TestAccessProperties\RevertNonNullabilityForIsset|null.',
169169
402,
170170
],
171+
[
172+
'Cannot access property $array on stdClass|null.',
173+
412,
174+
],
171175
]
172176
);
173177
}

tests/PHPStan/Rules/Properties/data/access-properties.php

+15
Original file line numberDiff line numberDiff line change
@@ -403,3 +403,18 @@ public function doFoo()
403403
}
404404

405405
}
406+
407+
class Bug1884
408+
{
409+
410+
function mustReport(?\stdClass $nullable): bool
411+
{
412+
return isset($nullable->array['key']);
413+
}
414+
415+
function mustNotReport(?\stdClass $nullable): bool
416+
{
417+
return isset($nullable, $nullable->array['key']);
418+
}
419+
420+
}

0 commit comments

Comments
 (0)