mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Fix #1320 - allow iterable comparison
This commit is contained in:
parent
8fc0b43973
commit
867ea1fa34
@ -693,6 +693,44 @@ class Reconciler
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
if ($new_var_type === 'iterable' && !$existing_var_type->hasMixed()) {
|
||||
$iterable_types = [];
|
||||
$did_remove_type = false;
|
||||
|
||||
foreach ($existing_var_atomic_types as $type) {
|
||||
if ($type->isIterable($codebase)) {
|
||||
$iterable_types[] = $type;
|
||||
} elseif ($type instanceof TObject) {
|
||||
$iterable_types[] = new Type\Atomic\TCallableObject();
|
||||
$did_remove_type = true;
|
||||
} else {
|
||||
$did_remove_type = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!$iterable_types || !$did_remove_type) && !$is_equality) {
|
||||
if ($key && $code_location) {
|
||||
self::triggerIssueForImpossible(
|
||||
$existing_var_type,
|
||||
$old_var_type_string,
|
||||
$key,
|
||||
$new_var_type,
|
||||
!$did_remove_type,
|
||||
$code_location,
|
||||
$suppressed_issues
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($iterable_types) {
|
||||
return new Type\Union($iterable_types);
|
||||
}
|
||||
|
||||
$failed_reconciliation = 2;
|
||||
|
||||
return Type::getMixed();
|
||||
}
|
||||
|
||||
if ($new_var_type === 'numeric' && !$existing_var_type->hasMixed()) {
|
||||
$numeric_types = [];
|
||||
$did_remove_type = false;
|
||||
@ -1717,6 +1755,12 @@ class Reconciler
|
||||
$existing_var_type->removeType($atomic_key);
|
||||
}
|
||||
}
|
||||
|
||||
return $existing_var_type;
|
||||
}
|
||||
|
||||
if ($new_var_type === 'iterable') {
|
||||
$existing_var_type->removeType('array');
|
||||
}
|
||||
|
||||
if ($new_var_type === 'non-empty-countable') {
|
||||
@ -1797,8 +1841,6 @@ class Reconciler
|
||||
) {
|
||||
$existing_var_type->removeType('array-key');
|
||||
$existing_var_type->addType(new TInt);
|
||||
} elseif ($new_var_type === 'iterable') {
|
||||
$existing_var_type->removeType('array');
|
||||
} elseif (strtolower($new_var_type) === 'int'
|
||||
&& isset($existing_var_type->getTypes()['array-key'])
|
||||
) {
|
||||
|
@ -1186,13 +1186,38 @@ class TypeReconciliationTest extends TestCase
|
||||
return is_object($maybe) ? get_class($maybe) : $maybe;
|
||||
}'
|
||||
],
|
||||
'removeIterable' => [
|
||||
'removeArrayWithIterableCheck' => [
|
||||
'<?php
|
||||
$s = rand(0,1) ? "foo" : [1];
|
||||
if (!is_iterable($s)) {
|
||||
strlen($s);
|
||||
}',
|
||||
],
|
||||
'removeIterableWithIterableCheck' => [
|
||||
'<?php
|
||||
/** @var string|iterable */
|
||||
$s = rand(0,1) ? "foo" : [1];
|
||||
if (!is_iterable($s)) {
|
||||
strlen($s);
|
||||
}',
|
||||
],
|
||||
'removeArrayWithIterableCheckWithExit' => [
|
||||
'<?php
|
||||
$a = rand(0,1) ? "foo" : [1];
|
||||
if (is_iterable($a)) {
|
||||
return;
|
||||
}
|
||||
strlen($a);',
|
||||
],
|
||||
'removeIterableWithIterableCheckWithExit' => [
|
||||
'<?php
|
||||
/** @var string|iterable */
|
||||
$a = rand(0,1) ? "foo" : [1];
|
||||
if (is_iterable($a)) {
|
||||
return;
|
||||
}
|
||||
strlen($a);',
|
||||
],
|
||||
'removeCallable' => [
|
||||
'<?php
|
||||
$s = rand(0,1) ? "strlen" : [1];
|
||||
|
Loading…
x
Reference in New Issue
Block a user