diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php index e75611f77..09d587b78 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php @@ -472,6 +472,32 @@ class AssignmentAnalyzer } } } + + if ($assign_value_type->getId() === 'bool' + && ($assign_value instanceof PhpParser\Node\Expr\BinaryOp + || ($assign_value instanceof PhpParser\Node\Expr\BooleanNot + && $assign_value->expr instanceof PhpParser\Node\Expr\BinaryOp)) + ) { + $var_object_id = \spl_object_id($assign_var); + $cond_object_id = \spl_object_id($assign_value); + + $right_clauses = \Psalm\Internal\Algebra\FormulaGenerator::getFormula( + $cond_object_id, + $cond_object_id, + $assign_value, + $context->self, + $statements_analyzer, + $codebase + ); + + $assignment_clauses = \Psalm\Internal\Algebra::combineOredClauses( + [new \Psalm\Internal\Clause([$var_id => ['falsy']], $var_object_id, $var_object_id)], + $right_clauses, + $cond_object_id + ); + + $context->clauses = array_merge($context->clauses, $assignment_clauses); + } } } else { $was_inside_use = $context->inside_use; diff --git a/tests/TypeReconciliation/TypeAlgebraTest.php b/tests/TypeReconciliation/TypeAlgebraTest.php index 8992b22ce..b1d23aa1a 100644 --- a/tests/TypeReconciliation/TypeAlgebraTest.php +++ b/tests/TypeReconciliation/TypeAlgebraTest.php @@ -1034,6 +1034,24 @@ class TypeAlgebraTest extends \Psalm\Tests\TestCase return $c; }' ], + 'dependentType' => [ + 'isValid(); + + if ($is_valid_a) { + $a->foo(); + } + }' + ], ]; } @@ -1255,6 +1273,29 @@ class TypeAlgebraTest extends \Psalm\Tests\TestCase }', 'error_message' => 'RedundantCondition', ], + 'dependentTypeInvalidated' => [ + 'isValid(); + + if (rand(0, 1)) { + $is_valid_a = false; + } + + if ($is_valid_a) { + $a->foo(); + } + }', + 'error_message' => 'PossiblyNullReference', + ], ]; } }