File tree Expand file tree Collapse file tree
tests/PHPStan/Rules/Classes Expand file tree Collapse file tree Original file line number Diff line number Diff line change 22
33namespace PHPStan \Type \Accessory ;
44
5+ use Closure ;
56use PHPStan \PhpDocParser \Ast \Type \IdentifierTypeNode ;
67use PHPStan \PhpDocParser \Ast \Type \TypeNode ;
78use PHPStan \Reflection \ClassMemberAccessAnswerer ;
1718use PHPStan \Type \ErrorType ;
1819use PHPStan \Type \IntersectionType ;
1920use PHPStan \Type \IsSuperTypeOfResult ;
21+ use PHPStan \Type \ObjectType ;
2022use PHPStan \Type \StringType ;
2123use PHPStan \Type \Traits \NonGeneralizableTypeTrait ;
2224use PHPStan \Type \Traits \NonGenericTypeTrait ;
@@ -83,7 +85,11 @@ public function isSubTypeOf(Type $otherType): IsSuperTypeOfResult
8385 return $ otherType ->isSuperTypeOf ($ this );
8486 }
8587
86- if ($ this ->isCallable ()->yes () && $ otherType ->isCallable ()->yes ()) {
88+ if (
89+ $ this ->isCallable ()->yes ()
90+ && $ otherType ->isCallable ()->yes ()
91+ && !(new ObjectType (Closure::class))->isSuperTypeOf ($ otherType )->yes ()
92+ ) {
8793 return IsSuperTypeOfResult::createYes ();
8894 }
8995
Original file line number Diff line number Diff line change @@ -569,4 +569,17 @@ public function testBug13469(): void
569569 ]);
570570 }
571571
572+ public static function dataBug13975 (): iterable
573+ {
574+ yield [__DIR__ . '/data/bug-13975-a.php ' ];
575+ yield [__DIR__ . '/data/bug-13975-b.php ' ];
576+ }
577+
578+ #[DataProvider('dataBug13975 ' )]
579+ public function testBug13975 (string $ file ): void
580+ {
581+ $ this ->treatPhpDocTypesAsCertain = true ;
582+ $ this ->analyse ([$ file ], []);
583+ }
584+
572585}
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types=1 );
2+
3+ namespace Bug13975a ;
4+
5+ function foo (): callable
6+ {
7+ return new class () {
8+ public function __invoke (): void
9+ {
10+ }
11+ };
12+ }
13+
14+ $ foo = foo ();
15+
16+ if (\is_object ($ foo ) && method_exists ($ foo , '__invoke ' ) && !$ foo instanceof \Closure) {
17+ echo 'true ' ;
18+ }
Original file line number Diff line number Diff line change 1+ <?php declare (strict_types=1 );
2+
3+ namespace Bug13975b ;
4+
5+ class X {}
6+
7+ function foo (): callable
8+ {
9+ return new class () {
10+ public function __invoke (): void
11+ {
12+ }
13+ };
14+ }
15+
16+ $ foo = foo ();
17+
18+ $ class = \Closure::class;
19+ if (rand (0 , 1 )) {
20+ $ class = X::class;
21+ }
22+
23+ if (\is_object ($ foo ) && method_exists ($ foo , '__invoke ' ) && !$ foo instanceof $ class ) {
24+ echo 'true ' ;
25+ }
You can’t perform that action at this time.
0 commit comments