diff --git a/tests/PHPStan/Analyser/nsrt/more-types.php b/tests/PHPStan/Analyser/nsrt/more-types.php index f1b742f170e..1f74b7c8c56 100644 --- a/tests/PHPStan/Analyser/nsrt/more-types.php +++ b/tests/PHPStan/Analyser/nsrt/more-types.php @@ -17,6 +17,8 @@ class Foo * @param non-empty-scalar $nonEmptyScalar * @param empty-scalar $emptyScalar * @param non-empty-mixed $nonEmptyMixed + * @param lowercase-string $lowercaseString + * @param non-empty-lowercase-string $nonEmptyLowercaseString */ public function doFoo( $pureCallable, @@ -27,7 +29,9 @@ public function doFoo( $nonEmptyLiteralString, $nonEmptyScalar, $emptyScalar, - $nonEmptyMixed + $nonEmptyMixed, + $lowercaseString, + $nonEmptyLowercaseString, ): void { assertType('pure-callable(): mixed', $pureCallable); @@ -39,6 +43,8 @@ public function doFoo( assertType('float|int|int<1, max>|non-falsy-string|true', $nonEmptyScalar); assertType("0|0.0|''|'0'|false", $emptyScalar); assertType("mixed~0|0.0|''|'0'|array{}|false|null", $nonEmptyMixed); + assertType('lowercase-string', $lowercaseString); + assertType('lowercase-string&non-empty-string', $nonEmptyLowercaseString); } } diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index 71be1465a4f..f626fc4ec1f 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -1052,6 +1052,54 @@ public function testBug10697(): void $this->analyse([__DIR__ . '/data/bug-10697.php'], []); } + public function testLowercaseString(): void + { + $errors = [ + [ + "Strict comparison using === between lowercase-string and 'AB' will always evaluate to false.", + 10, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + [ + "Strict comparison using === between 'AB' and lowercase-string will always evaluate to false.", + 11, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + [ + "Strict comparison using !== between 'AB' and lowercase-string will always evaluate to true.", + 12, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + [ + "Strict comparison using === between lowercase-string and 'aBc' will always evaluate to false.", + 15, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + [ + "Strict comparison using !== between lowercase-string and 'aBc' will always evaluate to true.", + 16, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ], + ]; + + if (PHP_VERSION_ID < 80000) { + $errors[] = [ + "Strict comparison using === between lowercase-string|false and 'AB' will always evaluate to false.", + 28, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ]; + } else { + $errors[] = [ + "Strict comparison using === between lowercase-string and 'AB' will always evaluate to false.", + 28, + 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.', + ]; + } + + $this->checkAlwaysTrueStrictComparison = true; + $this->analyse([__DIR__ . '/data/lowercase-string.php'], $errors); + } + public function testBug10493(): void { $this->checkAlwaysTrueStrictComparison = true; diff --git a/tests/PHPStan/Rules/Comparison/data/lowercase-string.php b/tests/PHPStan/Rules/Comparison/data/lowercase-string.php new file mode 100644 index 00000000000..772939626ab --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/lowercase-string.php @@ -0,0 +1,31 @@ +