From 64a80feba2d1c3a548faa2e29ccb798f9f770159 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Mon, 2 Sep 2024 09:44:20 +0200 Subject: [PATCH] TypeSpecifier: Narrow `(string) $expr` like `$expr != false` --- src/Analyser/TypeSpecifier.php | 7 +++++++ .../Analyser/nsrt/narrow-bool-cast.php | 21 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/Analyser/TypeSpecifier.php b/src/Analyser/TypeSpecifier.php index b279185906..66a60954b6 100644 --- a/src/Analyser/TypeSpecifier.php +++ b/src/Analyser/TypeSpecifier.php @@ -196,6 +196,13 @@ public function specifyTypesInCondition( $context, $rootExpr, ); + } elseif ($expr instanceof Expr\Cast\String_) { + return $this->specifyTypesInCondition( + $scope, + new Node\Expr\BinaryOp\NotEqual($expr->expr, new ConstFetch(new Name\FullyQualified('false'))), + $context, + $rootExpr, + ); } elseif ($expr instanceof Expr\Cast\Bool_) { return $this->resolveEqual(new Expr\BinaryOp\Equal($expr->expr, new ConstFetch(new Name\FullyQualified('true'))), $scope, $context, $rootExpr); } elseif ($expr instanceof Node\Expr\BinaryOp\Equal) { diff --git a/tests/PHPStan/Analyser/nsrt/narrow-bool-cast.php b/tests/PHPStan/Analyser/nsrt/narrow-bool-cast.php index 582062deb7..ea9486a77d 100644 --- a/tests/PHPStan/Analyser/nsrt/narrow-bool-cast.php +++ b/tests/PHPStan/Analyser/nsrt/narrow-bool-cast.php @@ -27,3 +27,24 @@ function doFoo(string $x, array $arr): void { } assertType('array{}|array{string}', $matches); } + +/** @param int<-5, 5> $x */ +function castString($x, string $s, bool $b) { + if ((string) $x) { + assertType('int<-5, -1>|int<1, 5>', $x); + } else { + assertType('0', $x); + } + + if ((string) $b) { + assertType('true', $b); + } else { + assertType('false', $b); + } + + if ((string) strrchr($s, 'xy')) { + assertType('string', $s); // could be non-empty-string + } else { + assertType('string', $s); + } +}