Skip to content

Commit c0eed2a

Browse files
rvanvelzenondrejmirtes
authored andcommitted
Fix intersecting array shapes with different optional keys
1 parent ec3d5b7 commit c0eed2a

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

src/Type/TypeCombinator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,7 @@ public static function intersect(Type ...$types): Type
987987
$newArray->setOffsetValueType(
988988
self::intersect($keyType, $types[$j]->getIterableKeyType()),
989989
self::intersect($valueTypes[$k], $types[$j]->getIterableValueType()),
990-
$types[$i]->isOptionalKey($k),
990+
$types[$i]->isOptionalKey($k) && !$types[$j]->hasOffsetValueType($keyType)->yes(),
991991
);
992992
}
993993
$types[$i] = $newArray->getArray();
@@ -1003,7 +1003,7 @@ public static function intersect(Type ...$types): Type
10031003
$newArray->setOffsetValueType(
10041004
self::intersect($keyType, $types[$i]->getIterableKeyType()),
10051005
self::intersect($valueTypes[$k], $types[$i]->getIterableValueType()),
1006-
$types[$j]->isOptionalKey($k),
1006+
$types[$j]->isOptionalKey($k) && !$types[$i]->hasOffsetValueType($keyType)->yes(),
10071007
);
10081008
}
10091009
$types[$j] = $newArray->getArray();

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,7 @@ public function dataFileAsserts(): iterable
11291129
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Variables/data/bug-8113.php');
11301130
yield from $this->gatherAssertTypes(__DIR__ . '/data/phpunit-integration.php');
11311131
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-8361.php');
1132+
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-8373.php');
11321133
}
11331134

11341135
/**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug8373;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
function (string $one, string $two): string {
8+
$args = [$one, $two];
9+
10+
assertType('array{string, string}', $args);
11+
assertType('array{0?: non-falsy-string, 1?: non-falsy-string}', array_filter($args));
12+
13+
\assert(array_filter($args) === $args);
14+
15+
assertType('array{non-falsy-string, non-falsy-string}', $args);
16+
assertType('array{non-falsy-string, non-falsy-string}', array_filter($args));
17+
18+
return $args[1];
19+
};

0 commit comments

Comments
 (0)