Skip to content

Commit

Permalink
Fix ConstantArrayType intersecting with HasOffsetValueType
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Aug 28, 2022
1 parent 092ef3b commit 9c49d4c
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
17 changes: 15 additions & 2 deletions src/Type/TypeCombinator.php
Expand Up @@ -867,14 +867,27 @@ public static function intersect(Type ...$types): Type
}

if ($types[$i] instanceof ConstantArrayType && $types[$j] instanceof HasOffsetValueType) {
$types[$i] = $types[$i]->setOffsetValueType($types[$j]->getOffsetType(), $types[$j]->getValueType());
$offsetType = $types[$j]->getOffsetType();
$valueType = $types[$j]->getValueType();
$newValueType = self::intersect($types[$i]->getOffsetValueType($offsetType), $valueType);
if ($newValueType instanceof NeverType) {
return new NeverType();
}
$types[$i] = $types[$i]->setOffsetValueType($offsetType, $newValueType);
array_splice($types, $j--, 1);
$typesCount--;
continue;
}

if ($types[$j] instanceof ConstantArrayType && $types[$i] instanceof HasOffsetValueType) {
$types[$j] = $types[$j]->setOffsetValueType($types[$i]->getOffsetType(), $types[$i]->getValueType());
$offsetType = $types[$i]->getOffsetType();
$valueType = $types[$i]->getValueType();
$newValueType = self::intersect($types[$j]->getOffsetValueType($offsetType), $valueType);
if ($newValueType instanceof NeverType) {
return new NeverType();
}

$types[$j] = $types[$j]->setOffsetValueType($offsetType, $newValueType);
array_splice($types, $i--, 1);
$typesCount--;
continue 2;
Expand Down
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/data/bug-4099.php
Expand Up @@ -27,7 +27,7 @@ function arrayHint(array $arr): void
assertNativeType('mixed', $arr['key']);

if (!array_key_exists('inner', $arr['key'])) {
assertType('array{key: *NEVER*}', $arr);
assertType('*NEVER*', $arr);
assertNativeType('array&hasOffset(\'key\')', $arr);
assertType('*NEVER*', $arr['key']);
assertNativeType('mixed', $arr['key']);
Expand Down
2 changes: 1 addition & 1 deletion tests/PHPStan/Analyser/data/has-offset-type-bug.php
Expand Up @@ -123,7 +123,7 @@ class AssignVsNarrow
public function doFoo(array $a)
{
if (is_int($a['a'])) {
assertType('array{a: *NEVER*}', $a);
assertType('*NEVER*', $a);
}
}

Expand Down

0 comments on commit 9c49d4c

Please sign in to comment.