diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index 20e700c34f..c0fd91af84 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -552,23 +552,26 @@ private function resolveType(Expr $node): Type $result = new ConstantBooleanType(true); foreach ($node->vars as $var) { if ($var instanceof Expr\ArrayDimFetch && $var->dim !== null) { - $hasOffset = $this->getType($var->var)->hasOffsetValueType( - $this->getType($var->dim) - )->toBooleanType(); - if ($hasOffset instanceof ConstantBooleanType) { - if (!$hasOffset->getValue()) { - return $hasOffset; + $variableType = $this->getType($var->var); + $dimType = $this->getType($var->dim); + $hasOffset = $variableType->hasOffsetValueType($dimType); + $offsetValueType = $variableType->getOffsetValueType($dimType); + $offsetValueIsNotNull = (new NullType())->isSuperTypeOf($offsetValueType)->negate(); + $isset = $hasOffset->and($offsetValueIsNotNull)->toBooleanType(); + if ($isset instanceof ConstantBooleanType) { + if (!$isset->getValue()) { + return $isset; } continue; } - $result = $hasOffset; + $result = $isset; continue; } if ($var instanceof Expr\Variable && is_string($var->name)) { - $variableType = $this->resolveType($var); + $variableType = $this->getType($var); $isNullSuperType = (new NullType())->isSuperTypeOf($variableType); $has = $this->hasVariableType($var->name); if ($has->no() || $isNullSuperType->yes()) { diff --git a/tests/PHPStan/Analyser/NodeScopeResolverTest.php b/tests/PHPStan/Analyser/NodeScopeResolverTest.php index 7a3d6e9fdb..68e29fba16 100644 --- a/tests/PHPStan/Analyser/NodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/NodeScopeResolverTest.php @@ -10194,6 +10194,11 @@ public function dataBug3961(): array return $this->gatherAssertTypes(__DIR__ . '/data/bug-3961.php'); } + public function dataBug1924(): array + { + return $this->gatherAssertTypes(__DIR__ . '/data/bug-1924.php'); + } + /** * @dataProvider dataBug2574 * @dataProvider dataBug2577 @@ -10275,6 +10280,7 @@ public function dataBug3961(): array * @dataProvider dataNotEmptyArray * @dataProvider dataClassConstantOnExpression * @dataProvider dataBug3961 + * @dataProvider dataBug1924 * @param string $assertType * @param string $file * @param mixed ...$args diff --git a/tests/PHPStan/Analyser/data/bug-1924.php b/tests/PHPStan/Analyser/data/bug-1924.php new file mode 100644 index 0000000000..d14bd79498 --- /dev/null +++ b/tests/PHPStan/Analyser/data/bug-1924.php @@ -0,0 +1,27 @@ + $this->getArrayOrNull(), + 'b' => $this->getArrayOrNull(), + ]; + assertType('array(\'a\' => array|null, \'b\' => array|null)', $arr); + + $cond = isset($arr['a']) && isset($arr['b']); + assertType('bool', $cond); + } + +}