Skip to content

Commit 53a5171

Browse files
committed
Fixed assert(is_numeric($x)) false positive
1 parent 88d2607 commit 53a5171

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

src/Rules/Comparison/ImpossibleCheckTypeHelper.php

-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use PHPStan\Type\MixedType;
1818
use PHPStan\Type\NeverType;
1919
use PHPStan\Type\ObjectType;
20-
use PHPStan\Type\StringType;
2120
use PHPStan\Type\TypeCombinator;
2221
use PHPStan\Type\TypeUtils;
2322
use PHPStan\Type\TypeWithClassName;
@@ -82,10 +81,6 @@ public function findSpecifiedType(
8281
if (count(TypeUtils::getConstantScalars($argType)) > 0) {
8382
return !$argType->toNumber() instanceof ErrorType;
8483
}
85-
86-
if (!(new StringType())->isSuperTypeOf($argType)->no()) {
87-
return null;
88-
}
8984
} elseif ($functionName === 'defined') {
9085
return null;
9186
} elseif (

src/Type/Php/IsNumericFunctionTypeSpecifyingExtension.php

+5
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
3434
throw new \PHPStan\ShouldNotHappenException();
3535
}
3636

37+
$argType = $scope->getType($node->args[0]->value);
38+
if (!(new StringType())->isSuperTypeOf($argType)->no()) {
39+
return new SpecifiedTypes([], []);
40+
}
41+
3742
$numericTypes = [
3843
new IntegerType(),
3944
new FloatType(),

tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php

+20
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,22 @@ public function testImpossibleCheckTypeFunctionCall(): void
206206
677,
207207
'Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.',
208208
],
209+
[
210+
'Call to function is_numeric() with \'123\' will always evaluate to true.',
211+
692,
212+
],
213+
[
214+
'Call to function is_numeric() with \'blabla\' will always evaluate to false.',
215+
693,
216+
],
217+
[
218+
'Call to function assert() with true will always evaluate to true.',
219+
700,
220+
],
221+
[
222+
'Call to function is_numeric() with 123|float will always evaluate to true.',
223+
700,
224+
],
209225
]
210226
);
211227
}
@@ -298,6 +314,10 @@ public function testImpossibleCheckTypeFunctionCallWithoutAlwaysTrue(): void
298314
'Call to function method_exists() with \'CheckTypeFunctionCa…\' and \'unknown\' will always evaluate to false.',
299315
648,
300316
],
317+
[
318+
'Call to function is_numeric() with \'blabla\' will always evaluate to false.',
319+
693,
320+
],
301321
]
302322
);
303323
}

tests/PHPStan/Rules/Comparison/data/check-type-function-call.php

+19
Original file line numberDiff line numberDiff line change
@@ -682,3 +682,22 @@ public function doFoo($a): bool
682682
}
683683

684684
}
685+
686+
class AssertIsNumeric
687+
{
688+
689+
public function doFoo(string $str, float $float)
690+
{
691+
assert(is_numeric($str));
692+
assert(is_numeric('123'));
693+
assert(is_numeric('blabla'));
694+
695+
$isNumeric = $float;
696+
if (doFoo()) {
697+
$isNumeric = 123;
698+
}
699+
700+
assert(is_numeric($isNumeric));
701+
}
702+
703+
}

0 commit comments

Comments
 (0)