diff --git a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php index 1850c5c2f..932787779 100644 --- a/src/Psalm/Internal/Type/SimpleAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleAssertionReconciler.php @@ -143,7 +143,8 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler $code_location, $suppressed_issues, $failed_reconciliation, - false + false, + $inside_loop ); } @@ -2218,7 +2219,8 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler ?CodeLocation $code_location, array $suppressed_issues, int &$failed_reconciliation, - bool $recursive_check + bool $recursive_check, + bool $inside_loop ) : Union { $old_var_type_string = $existing_var_type->getId(); $existing_var_atomic_types = $existing_var_type->getAtomicTypes(); @@ -2363,20 +2365,22 @@ class SimpleAssertionReconciler extends \Psalm\Type\Reconciler if (!$existing_var_atomic_type->as->isMixed()) { $template_did_fail = 0; - $existing_var_atomic_type = clone $existing_var_atomic_type; + $tmp_existing_var_atomic_type = clone $existing_var_atomic_type; - $existing_var_atomic_type->as = self::reconcileFalsyOrEmpty( + $reconciled_type = self::reconcileFalsyOrEmpty( $assertion, - $existing_var_atomic_type->as, + $tmp_existing_var_atomic_type->as, $key, $negated, $code_location, $suppressed_issues, $template_did_fail, - $recursive_check + $recursive_check, + $inside_loop ); - if (!$template_did_fail) { + if (!$template_did_fail && !$inside_loop) { + $existing_var_atomic_type->as = $reconciled_type; $existing_var_type->addType($existing_var_atomic_type); } } diff --git a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php index 9f14afc3e..4ff27e089 100644 --- a/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php +++ b/src/Psalm/Internal/Type/SimpleNegatedAssertionReconciler.php @@ -180,7 +180,8 @@ class SimpleNegatedAssertionReconciler extends Reconciler $failed_reconciliation, $is_equality, $is_strict_equality, - false + false, + $inside_loop ); } @@ -570,7 +571,8 @@ class SimpleNegatedAssertionReconciler extends Reconciler int &$failed_reconciliation, bool $is_equality, bool $is_strict_equality, - bool $recursive_check + bool $recursive_check, + bool $inside_loop ) : Type\Union { $old_var_type_string = $existing_var_type->getId(); $existing_var_atomic_types = $existing_var_type->getAtomicTypes(); @@ -728,11 +730,11 @@ class SimpleNegatedAssertionReconciler extends Reconciler if (!$is_equality && !$existing_var_atomic_type->as->isMixed()) { $template_did_fail = 0; - $existing_var_atomic_type = clone $existing_var_atomic_type; + $tmp_existing_var_atomic_type = clone $existing_var_atomic_type; - $existing_var_atomic_type->as = self::reconcileFalsyOrEmpty( + $reconciled_type = self::reconcileFalsyOrEmpty( $assertion, - $existing_var_atomic_type->as, + $tmp_existing_var_atomic_type->as, $key, $negated, $code_location, @@ -740,10 +742,12 @@ class SimpleNegatedAssertionReconciler extends Reconciler $template_did_fail, $is_equality, $is_strict_equality, - true + true, + $inside_loop ); - if (!$template_did_fail) { + if (!$template_did_fail && !$inside_loop) { + $existing_var_atomic_type->as = $reconciled_type; $existing_var_type->addType($existing_var_atomic_type); } } diff --git a/tests/Template/ConditionalReturnTypeTest.php b/tests/Template/ConditionalReturnTypeTest.php index 676a48d8a..6c97ebaa3 100644 --- a/tests/Template/ConditionalReturnTypeTest.php +++ b/tests/Template/ConditionalReturnTypeTest.php @@ -811,6 +811,21 @@ class ConditionalReturnTypeTest extends TestCase return iterator_to_array($iterable, false); }' ], + 'dontChokeOnFalsyAssertionsWithTemplatesInLoop' => [ + '