mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
Don’t remove clauses on mixed, just substitute for wedges
This commit is contained in:
parent
651b375c62
commit
e5e0c56abc
@ -177,29 +177,27 @@ class IfChecker
|
||||
);
|
||||
|
||||
$if_clauses = array_values(
|
||||
array_filter(
|
||||
$if_clauses,
|
||||
/** @return bool */
|
||||
array_map(
|
||||
/**
|
||||
* @return Clause
|
||||
*/
|
||||
function (Clause $c) use ($mixed_var_ids) {
|
||||
$keys = array_keys($c->possibilities);
|
||||
|
||||
foreach ($keys as $key) {
|
||||
foreach ($mixed_var_ids as $mixed_var_id) {
|
||||
if (preg_match('/^' . preg_quote($mixed_var_id, '/') . '(\[|-)/', $key)) {
|
||||
return false;
|
||||
return new Clause([], true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return $c;
|
||||
},
|
||||
$if_clauses
|
||||
)
|
||||
);
|
||||
|
||||
if (!$if_clauses) {
|
||||
$if_clauses = [new Clause([], true)];
|
||||
}
|
||||
|
||||
// this will see whether any of the clauses in set A conflict with the clauses in set B
|
||||
AlgebraChecker::checkForParadox(
|
||||
$context->clauses,
|
||||
|
@ -475,21 +475,30 @@ class Union
|
||||
|
||||
foreach ($old_type->types as $old_type_part) {
|
||||
if (!$this->removeType($old_type_part->getKey())) {
|
||||
if ($old_type_part instanceof Type\Atomic\TFalse && isset($this->types['bool'])) {
|
||||
if ($old_type_part instanceof Type\Atomic\TFalse
|
||||
&& isset($this->types['bool'])
|
||||
&& !isset($this->types['true'])
|
||||
) {
|
||||
$this->removeType('bool');
|
||||
$this->types['true'] = new Type\Atomic\TTrue;
|
||||
} elseif ($old_type_part instanceof Type\Atomic\TTrue && isset($this->types['bool'])) {
|
||||
} elseif ($old_type_part instanceof Type\Atomic\TTrue
|
||||
&& isset($this->types['bool'])
|
||||
&& !isset($this->types['false'])
|
||||
) {
|
||||
$this->removeType('bool');
|
||||
$this->types['false'] = new Type\Atomic\TFalse;
|
||||
} elseif (isset($this->types['iterable'])) {
|
||||
if ($old_type_part instanceof Type\Atomic\TNamedObject
|
||||
&& $old_type_part->value === 'Traversable'
|
||||
&& !isset($this->types['array'])
|
||||
) {
|
||||
$this->removeType('iterable');
|
||||
$this->types['array'] = new Type\Atomic\TArray([Type::getMixed(), Type::getMixed()]);
|
||||
}
|
||||
|
||||
if ($old_type_part instanceof Type\Atomic\TArray) {
|
||||
if ($old_type_part instanceof Type\Atomic\TArray
|
||||
&& !isset($this->types['traversable'])
|
||||
) {
|
||||
$this->removeType('iterable');
|
||||
$this->types['traversable'] = new Type\Atomic\TNamedObject('Traversable');
|
||||
}
|
||||
|
@ -315,6 +315,24 @@ class RedundantConditionTest extends TestCase
|
||||
'assignments' => [],
|
||||
'error_levels' => [],
|
||||
],
|
||||
'replaceFalseTypeWithTrueConditionalOnMixedEquality' => [
|
||||
'<?php
|
||||
function getData() {
|
||||
return rand(0, 1) ? [1, 2, 3] : false;
|
||||
}
|
||||
|
||||
$a = false;
|
||||
|
||||
while ($i = getData()) {
|
||||
if (!$a && $i[0] === 2) {
|
||||
$a = true;
|
||||
}
|
||||
|
||||
if ($a === false) {}
|
||||
}',
|
||||
'assignments' => [],
|
||||
'error_levels' => ['MixedAssignment', 'MissingReturnType', 'MixedArrayAccess'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user