mirror of
https://github.com/danog/psalm.git
synced 2025-01-22 05:41:20 +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
|
// fall through
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IssueBuffer::accepts(
|
foreach ($arg->value->inferredType->getTypes() as $atomic_type) {
|
||||||
new InvalidArgument(
|
if (!$atomic_type->isIterable($codebase)) {
|
||||||
'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id
|
if (IssueBuffer::accepts(
|
||||||
. ' expects array, ' . $arg->value->inferredType . ' provided',
|
new InvalidArgument(
|
||||||
$code_location
|
'Argument ' . ($argument_offset + 1) . ' of ' . $cased_method_id
|
||||||
),
|
. ' expects array, ' . $atomic_type . ' provided',
|
||||||
$statements_checker->getSuppressedIssues()
|
$code_location
|
||||||
)) {
|
),
|
||||||
return false;
|
$statements_checker->getSuppressedIssues()
|
||||||
|
)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,17 +587,7 @@ class TypeChecker
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($input_type_part instanceof TNamedObject
|
if ($input_type_part->isTraversable($codebase)) {
|
||||||
&& (strtolower($input_type_part->value) === 'traversable'
|
|
||||||
|| $codebase->classExtendsOrImplements(
|
|
||||||
$input_type_part->value,
|
|
||||||
'Traversable'
|
|
||||||
) || $codebase->interfaceExtends(
|
|
||||||
$input_type_part->value,
|
|
||||||
'Traversable'
|
|
||||||
)
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,34 @@ abstract class Atomic
|
|||||||
return $this instanceof TObject || $this instanceof TNamedObject;
|
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 StatementsSource $source
|
||||||
* @param CodeLocation $code_location
|
* @param CodeLocation $code_location
|
||||||
|
@ -230,6 +230,16 @@ class Php56Test extends TestCase
|
|||||||
foo(...$arr);
|
foo(...$arr);
|
||||||
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