1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-27 04:45:20 +01:00

Fix #3481 - treat an iterable like a Traversable when comparing to object

This commit is contained in:
Brown 2020-05-31 01:22:43 -04:00
parent 86b894eca5
commit be8fd3ea19
2 changed files with 32 additions and 10 deletions

View File

@ -514,16 +514,6 @@ class TypeAnalyzer
$allow_interface_equality,
?TypeComparisonResult $atomic_comparison_result
) {
if ($container_type_part instanceof TIterable
&& !$container_type_part->extra_types
&& !$input_type_part instanceof TIterable
) {
$container_type_part = new TGenericObject(
'Traversable',
$container_type_part->type_params
);
}
$intersection_input_types = $input_type_part->extra_types ?: [];
$intersection_input_types[$input_type_part->getKey(false)] = $input_type_part;
@ -2129,6 +2119,16 @@ class TypeAnalyzer
) : bool {
$all_types_contain = true;
if ($container_type_part instanceof TIterable
&& !$container_type_part->extra_types
&& !$input_type_part instanceof TIterable
) {
$container_type_part = new TGenericObject(
'Traversable',
$container_type_part->type_params
);
}
if ($container_type_part instanceof TGenericObject || $container_type_part instanceof TIterable) {
if (!$input_type_part instanceof TGenericObject && !$input_type_part instanceof TIterable) {
if ($input_type_part instanceof TNamedObject

View File

@ -4092,6 +4092,28 @@ class ClassTemplateExtendsTest extends TestCase
public abstract function accept () {}
}'
],
'extendedIntoIterable' => [
'<?php
interface ISubject {}
/**
* @extends \IteratorAggregate<int, ISubject>
*/
interface SubjectCollection extends \IteratorAggregate
{
/**
* @return \Iterator<int, ISubject>
*/
public function getIterator(): \Iterator;
}
/** @param iterable<int, ISubject> $_ */
function takesSubjects(iterable $_): void {}
function givesSubjects(SubjectCollection $subjects): void {
takesSubjects($subjects);
}'
],
];
}