1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-21 21:31:13 +01:00

Fix #873 - allow unpacking of all iterables

This commit is contained in:
Matt Brown 2018-07-09 09:59:51 -04:00
parent 3b12ce4a31
commit bbf48bbdfe
4 changed files with 52 additions and 20 deletions

View File

@ -911,15 +911,19 @@ class CallChecker
// fall through
}
} else {
if (IssueBuffer::accepts(
new InvalidArgument(
'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id
. ' expects array, ' . $arg->value->inferredType . ' provided',
$code_location
),
$statements_checker->getSuppressedIssues()
)) {
return false;
foreach ($arg->value->inferredType->getTypes() as $atomic_type) {
if (!$atomic_type->isIterable($codebase)) {
if (IssueBuffer::accepts(
new InvalidArgument(
'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id
. ' expects array, ' . $atomic_type . ' provided',
$code_location
),
$statements_checker->getSuppressedIssues()
)) {
return false;
}
}
}
}

View File

@ -587,17 +587,7 @@ class TypeChecker
return false;
}
if ($input_type_part instanceof TNamedObject
&& (strtolower($input_type_part->value) === 'traversable'
|| $codebase->classExtendsOrImplements(
$input_type_part->value,
'Traversable'
) || $codebase->interfaceExtends(
$input_type_part->value,
'Traversable'
)
)
) {
if ($input_type_part->isTraversable($codebase)) {
return true;
}
}

View File

@ -158,6 +158,34 @@ abstract class Atomic
return $this instanceof TObject || $this instanceof TNamedObject;
}
/**
* @return bool
*/
public function isIterable(Codebase $codebase)
{
return $this instanceof TNamedObject && (strtolower($this->value) === 'iterable')
|| $this->isTraversable($codebase)
|| $this instanceof TArray
|| $this instanceof ObjectLike;
}
/**
* @return bool
*/
public function isTraversable(Codebase $codebase)
{
return $this instanceof TNamedObject
&& (strtolower($this->value) === 'traversable'
|| $codebase->classExtendsOrImplements(
$this->value,
'Traversable'
) || $codebase->interfaceExtends(
$this->value,
'Traversable'
)
);
}
/**
* @param StatementsSource $source
* @param CodeLocation $code_location

View File

@ -230,6 +230,16 @@ class Php56Test extends TestCase
foo(...$arr);
foo(...$arr);',
],
'iterableSplat' => [
'<?php
function foo(iterable $args): int {
return intval(...$args);
}
function foo(ArrayIterator $args): int {
return intval(...$args);
}',
],
];
}