Skip to content

Commit 616b0d4

Browse files
Better strategy
1 parent c89e58b commit 616b0d4

4 files changed

+39
-16
lines changed

src/Type/Php/IsAFunctionTypeSpecifyingExtension.php

+2-8
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\Reflection\FunctionReflection;
12-
use PHPStan\Type\ClassStringType;
1312
use PHPStan\Type\Constant\ConstantBooleanType;
1413
use PHPStan\Type\Constant\ConstantStringType;
1514
use PHPStan\Type\FunctionTypeSpecifyingExtension;
16-
use PHPStan\Type\ObjectWithoutClassType;
17-
use PHPStan\Type\TypeCombinator;
1815
use function count;
1916
use function strtolower;
2017

@@ -50,17 +47,14 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
5047
$allowStringType = isset($node->getArgs()[2]) ? $scope->getType($node->getArgs()[2]->value) : new ConstantBooleanType(false);
5148
$allowString = !$allowStringType->equals(new ConstantBooleanType(false));
5249

53-
$superType = $allowString
54-
? TypeCombinator::union(new ObjectWithoutClassType(), new ClassStringType())
55-
: new ObjectWithoutClassType();
56-
5750
$resultType = $this->isAFunctionTypeSpecifyingHelper->determineType($objectOrClassType, $classType, $allowString, true);
5851

5952
// prevent false-positives in IsAFunctionTypeSpecifyingHelper
60-
if ($resultType->equals($superType) && $resultType->isSuperTypeOf($objectOrClassType)->yes()) {
53+
if ([] === $classType->getConstantStrings() && $resultType->isSuperTypeOf($objectOrClassType)->yes()) {
6154
return new SpecifiedTypes([], []);
6255
}
6356

57+
6458
return $this->typeSpecifier->create(
6559
$node->getArgs()[0]->value,
6660
$resultType,

src/Type/Php/IsSubclassOfFunctionTypeSpecifyingExtension.php

+1-8
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@
99
use PHPStan\Analyser\TypeSpecifierAwareExtension;
1010
use PHPStan\Analyser\TypeSpecifierContext;
1111
use PHPStan\Reflection\FunctionReflection;
12-
use PHPStan\Type\ClassStringType;
1312
use PHPStan\Type\Constant\ConstantBooleanType;
1413
use PHPStan\Type\FunctionTypeSpecifyingExtension;
1514
use PHPStan\Type\Generic\GenericClassStringType;
16-
use PHPStan\Type\ObjectWithoutClassType;
17-
use PHPStan\Type\TypeCombinator;
1815
use function count;
1916
use function strtolower;
2017

@@ -51,14 +48,10 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
5148
return new SpecifiedTypes([], []);
5249
}
5350

54-
$superType = $allowString
55-
? TypeCombinator::union(new ObjectWithoutClassType(), new ClassStringType())
56-
: new ObjectWithoutClassType();
57-
5851
$resultType = $this->isAFunctionTypeSpecifyingHelper->determineType($objectOrClassType, $classType, $allowString, false);
5952

6053
// prevent false-positives in IsAFunctionTypeSpecifyingHelper
61-
if ($resultType->equals($superType) && $resultType->isSuperTypeOf($objectOrClassType)->yes()) {
54+
if ([] === $classType->getConstantStrings() && $resultType->isSuperTypeOf($objectOrClassType)->yes()) {
6255
return new SpecifiedTypes([], []);
6356
}
6457

tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php

+12
Original file line numberDiff line numberDiff line change
@@ -1127,4 +1127,16 @@ public function testBug8954(): void
11271127
$this->analyse([__DIR__ . '/data/bug-8954.php'], []);
11281128
}
11291129

1130+
public function testBugPR3404(): void
1131+
{
1132+
$this->checkAlwaysTrueCheckTypeFunctionCall = true;
1133+
$this->treatPhpDocTypesAsCertain = true;
1134+
$this->analyse([__DIR__ . '/data/bug-pr-3404.php'], [
1135+
[
1136+
'Call to function is_a() with arguments BugPR3404\Location, \'BugPR3404\\\\Location\' and true will always evaluate to true.',
1137+
21
1138+
],
1139+
]);
1140+
}
1141+
11301142
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php // lint >= 8.0
2+
3+
namespace BugPR3404;
4+
5+
interface Location
6+
{
7+
8+
}
9+
10+
/** @return class-string<Location> */
11+
function aaa(): string
12+
{
13+
14+
}
15+
16+
function (Location $l): void {
17+
if (is_a($l, aaa(), true)) {
18+
// might not always be true. $l might be one subtype of Location, aaa() might return a name of a different subtype of Location
19+
}
20+
21+
if (is_a($l, Location::class, true)) {
22+
// always true
23+
}
24+
};

0 commit comments

Comments
 (0)