From 4457c55eda33ef04164f531e42f382c0a1a14f52 Mon Sep 17 00:00:00 2001 From: staabm <120441+staabm@users.noreply.github.com> Date: Sat, 28 Feb 2026 10:13:27 +0000 Subject: [PATCH] Fix incorrect dependent type inference after repeated boolean checks - Fixed conditional expression resolution in filterBySpecifiedTypes to intersect types instead of overwriting when multiple conditional expressions fire for the same target - When two conditionals with the same guard produced different types (one more specific than the other), the less specific type could overwrite specifiedExpressions, causing cascading wrong matches that led to variables being incorrectly narrowed to *NEVER* - New regression test in tests/PHPStan/Analyser/nsrt/bug-14211.php Closes https://github.com/phpstan/phpstan/issues/14211 --- src/Analyser/MutatingScope.php | 10 ++++++++- tests/PHPStan/Analyser/nsrt/bug-14211.php | 25 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Analyser/nsrt/bug-14211.php diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index a26a86a066..48f592e4c5 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -3833,7 +3833,15 @@ public function filterBySpecifiedTypes(SpecifiedTypes $specifiedTypes): self } $conditions[$conditionalExprString][] = $conditionalExpression; - $specifiedExpressions[$conditionalExprString] = $conditionalExpression->getTypeHolder(); + $newTypeHolder = $conditionalExpression->getTypeHolder(); + if (array_key_exists($conditionalExprString, $specifiedExpressions) && $specifiedExpressions[$conditionalExprString]->getCertainty()->yes() && $newTypeHolder->getCertainty()->yes()) { + $specifiedExpressions[$conditionalExprString] = ExpressionTypeHolder::createYes( + $newTypeHolder->getExpr(), + TypeCombinator::intersect($specifiedExpressions[$conditionalExprString]->getType(), $newTypeHolder->getType()), + ); + } else { + $specifiedExpressions[$conditionalExprString] = $newTypeHolder; + } } } } diff --git a/tests/PHPStan/Analyser/nsrt/bug-14211.php b/tests/PHPStan/Analyser/nsrt/bug-14211.php new file mode 100644 index 0000000000..8effe5a25a --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-14211.php @@ -0,0 +1,25 @@ + $data */ +function doSomething(array $data): bool { + + if (!isset($data['x'])) + return false; + + $m = isset($data['y']); + + if ($m) { + assertType('true', $m); + } + assertType('bool', $m); + + if ($m) { + assertType('true', $m); + } + + return true; +}