diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index d161f40cdd1..c9106febd15 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -588,7 +588,7 @@ private static function handleUnpackedArray( $array_creation_info->can_create_objectlike = false; - if (!UnionTypeComparator::canBeContainedBy( + if (!UnionTypeComparator::isContainedBy( $codebase, $iterable_type->type_params[0], Type::getArrayKey(), diff --git a/tests/ArrayAssignmentTest.php b/tests/ArrayAssignmentTest.php index 8cc2f3a30a7..9558b0f6590 100644 --- a/tests/ArrayAssignmentTest.php +++ b/tests/ArrayAssignmentTest.php @@ -1674,17 +1674,30 @@ function foobar(Foo $foo): array 'ignored_issues' => [], 'php_version' => '8.1', ], - 'unpackIncorrectlyExtendedTraversable' => [ + 'unpackIncorrectlyExtendedInterface' => [ 'code' => ' */ + /** + * @template TKey + * @template TValue of scalar + * @extends Traversable + */ interface Foo extends Traversable {} /** - * @return array + * @psalm-suppress MissingTemplateParam + * @template TKey + * @extends Foo */ - function foobar(Foo $foo): array + interface Bar extends Foo {} + + /** + * @param Bar $bar + * @return list + */ + function foobar(Bar $bar): array { - return [...$foo]; + $unpacked = [...$bar]; + return $unpacked; } ', ], @@ -2407,6 +2420,21 @@ class Foo {} ', 'error_message' => 'InvalidOperand', ], + 'unpackTraversableWithKeyOmitted' => [ + 'code' => ' */ + interface Foo extends Traversable {} + + /** + * @return array + */ + function foobar(Foo $foo): array + { + return [...$foo]; + } + ', + 'error_message' => 'InvalidOperand', + ], ]; } }