diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index 3e50294c94b..6441c094726 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -1548,6 +1548,20 @@ private function specifyTypesForConstantBinaryExpression( )->setRootExpr($rootExpr)); } + if ( + $context->true() + && $constantType->toBoolean()->isTrue()->yes() + && ($exprNode instanceof FuncCall || $exprNode instanceof Expr\MethodCall || $exprNode instanceof Expr\StaticCall) + ) { + $types = $this->create($exprNode, $constantType, $context, $scope)->setRootExpr($rootExpr); + + return $types->unionWith($this->specifyTypesInCondition( + $scope, + $exprNode, + TypeSpecifierContext::createTrue(), + )->setRootExpr($rootExpr)); + } + return null; } diff --git a/tests/PHPStan/Analyser/nsrt/non-empty-string-str-containing-fns.php b/tests/PHPStan/Analyser/nsrt/non-empty-string-str-containing-fns.php index 19482b7fd04..bc3887d19a7 100644 --- a/tests/PHPStan/Analyser/nsrt/non-empty-string-str-containing-fns.php +++ b/tests/PHPStan/Analyser/nsrt/non-empty-string-str-containing-fns.php @@ -92,19 +92,72 @@ public function variants(string $s) { if (strpos($s, ':') !== false) { assertType('non-falsy-string', $s); + } else { + assertType('string', $s); } assertType('string', $s); if (strpos($s, ':') === false) { assertType('string', $s); + } else { + assertType('non-falsy-string', $s); } assertType('string', $s); - if (strpos($s, ':') === 5) { + if (strpos($s, '0') == 0) { // 0|false + assertType('string', $s); + } else { + assertType('string', $s); + } + assertType('string', $s); + + $oneOrZero = rand(0, 1); + if (strpos($s, '0') == $oneOrZero) { // 0|1|false + assertType('string', $s); + } else { + assertType('string', $s); + } + assertType('string', $s); + + $oneOrZero = rand(0, 1); + if (strpos($s, '0') === $oneOrZero) { + assertType('string', $s); // could be non-empty-string + } else { + assertType('string', $s); + } + assertType('string', $s); + + if (strpos($s, '0') == 1) { + assertType('string', $s); // could be non-empty-string + } else { + assertType('string', $s); + } + assertType('string', $s); + + if (strpos($s, '0') === 0) { assertType('string', $s); // could be non-empty-string + } else { + assertType('string', $s); + } + assertType('string', $s); + + if (strpos($s, '0') === 5) { + assertType('non-empty-string', $s); // could be non-falsy-string + } else { + assertType('string', $s); } assertType('string', $s); + + if (strpos($s, ':') === 5) { + assertType('non-falsy-string', $s); + } else { + assertType('string', $s); + } + assertType('string', $s); + if (strpos($s, ':') !== 5) { assertType('string', $s); + } else { + assertType('non-falsy-string', $s); } assertType('string', $s); @@ -152,7 +205,7 @@ public function variants(string $s) { assertType('string', $s); if (mb_strpos($s, ':') === 5) { - assertType('string', $s); // could be non-empty-string + assertType('non-falsy-string', $s); } assertType('string', $s); if (mb_strpos($s, ':') !== 5) {