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:
parent
3b12ce4a31
commit
bbf48bbdfe
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user