Skip to content

Commit ff42ae6

Browse files
VincentLangletphpstan-bot
authored andcommitted
Do not let method_exists() check fall through to general logic when object type contains template types
- When the specific `method_exists` handling in `ImpossibleCheckTypeHelper` cannot determine the result (no concrete class names, no GenericClassStringType), it falls through to the general type specifier logic - The general logic uses `HasMethodType::isSuperTypeOf()` which calls `hasMethod()` on the argument type; for `object&T` where T is a TemplateMixedType, this returns Yes (inherited from MixedType), causing a false positive "will always evaluate to true" - Add early `return null` when `$objectType->hasTemplateOrLateResolvableType()` is true, preventing the general logic from running on types where method existence is uncertain - Verified analogous cases: `property_exists` is not affected (its type specifying extension returns empty SpecifiedTypes for non-native properties); `is_callable` is not affected; `class-string<T>` template bounds are correctly handled by the existing GenericClassStringType block
1 parent 0beee48 commit ff42ae6

3 files changed

Lines changed: 28 additions & 0 deletions

File tree

src/Rules/Comparison/ImpossibleCheckTypeHelper.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ public function findSpecifiedType(
242242
return false;
243243
}
244244
}
245+
246+
if ($objectType->hasTemplateOrLateResolvableType()) {
247+
return null;
248+
}
245249
}
246250
}
247251
}

tests/PHPStan/Rules/Comparison/ImpossibleCheckTypeFunctionCallRuleTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,4 +1224,10 @@ public function testBug12063(): void
12241224
$this->analyse([__DIR__ . '/data/bug-12063.php'], []);
12251225
}
12261226

1227+
public function testBug8217(): void
1228+
{
1229+
$this->treatPhpDocTypesAsCertain = true;
1230+
$this->analyse([__DIR__ . '/data/bug-8217.php'], []);
1231+
}
1232+
12271233
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug8217;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @template T
9+
*
10+
* @param T $object
11+
*/
12+
public static function check($object): void
13+
{
14+
if (is_object($object) && method_exists($object, 'method')) {
15+
echo 1;
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)