Skip to content

Commit dcdd6fa

Browse files
Fix phpstan/phpstan#4860: Error „should return static(Test) but returns Test“ (#5190)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 9e4186e commit dcdd6fa

File tree

5 files changed

+33
-7
lines changed

5 files changed

+33
-7
lines changed

src/Type/StaticType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection;
1717
use PHPStan\TrinaryLogic;
1818
use PHPStan\Type\Enum\EnumCaseObjectType;
19+
use PHPStan\Type\Generic\GenericClassStringType;
1920
use PHPStan\Type\Generic\GenericObjectType;
2021
use PHPStan\Type\Generic\TemplateTypeHelper;
2122
use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
@@ -200,7 +201,7 @@ public function isObject(): TrinaryLogic
200201

201202
public function getClassStringType(): Type
202203
{
203-
return $this->getStaticObjectType()->getClassStringType();
204+
return new GenericClassStringType($this);
204205
}
205206

206207
public function isEnum(): TrinaryLogic

tests/PHPStan/Analyser/data/bug-7391b.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public static function m() {
1616
assertType('Bug7391B\Foo', (self::class)::m());
1717
assertType('static(Bug7391B\Foo)', (static::class)::m());
1818
assertType('Bug7391B\Foo', get_class(new self(2))::m());
19-
assertType('Bug7391B\Foo', get_class(new static(2))::m());
19+
assertType('static(Bug7391B\Foo)', get_class(new static(2))::m());
2020

2121
throw new \Error('For static analysis only, return type is resolved purely by DynamicStaticMethodReturnTypeExtension');
2222
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug4860;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Test
8+
{
9+
public function copy(): static
10+
{
11+
assertType('class-string<$this(Bug4860\Test)>', get_class($this));
12+
return $this->copyTo(get_class($this));
13+
}
14+
15+
/**
16+
* @template T
17+
* @param class-string<T> $targetEntity
18+
* @return T
19+
*/
20+
public function copyTo(string $targetEntity)
21+
{
22+
/** @var T */
23+
return new $targetEntity();
24+
}
25+
}

tests/PHPStan/Analyser/nsrt/get-parent-class.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public function doFoo()
1111
{
1212
assertType('false', get_parent_class());
1313
assertType('false', get_parent_class($this));
14-
assertType('class-string<ParentClass\Foo>', get_class($this));
14+
assertType('class-string<$this(ParentClass\Foo)>', get_class($this));
1515
assertType('\'ParentClass\\\\Foo\'', get_class());
1616
}
1717

tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -566,7 +566,7 @@ public function testBug3633(): void
566566
$tipText = '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%</>.';
567567
$this->analyse([__DIR__ . '/data/bug-3633.php'], [
568568
[
569-
'Strict comparison using === between class-string<Bug3633\HelloWorld> and \'Bug3633\\\OtherClass\' will always evaluate to false.',
569+
'Strict comparison using === between class-string<$this(Bug3633\HelloWorld)> and \'Bug3633\\\OtherClass\' will always evaluate to false.',
570570
37,
571571
$tipText,
572572
],
@@ -580,7 +580,7 @@ public function testBug3633(): void
580580
44,
581581
],
582582
[
583-
'Strict comparison using === between class-string<Bug3633\OtherClass> and \'Bug3633\\\HelloWorld\' will always evaluate to false.',
583+
'Strict comparison using === between class-string<$this(Bug3633\OtherClass)> and \'Bug3633\\\HelloWorld\' will always evaluate to false.',
584584
64,
585585
$tipText,
586586
],
@@ -595,12 +595,12 @@ public function testBug3633(): void
595595
$tipText,
596596
],
597597
[
598-
'Strict comparison using === between class-string<Bug3633\FinalClass> and \'Bug3633\\\HelloWorld\' will always evaluate to false.',
598+
'Strict comparison using === between class-string<$this(Bug3633\FinalClass)> and \'Bug3633\\\HelloWorld\' will always evaluate to false.',
599599
93,
600600
$tipText,
601601
],
602602
[
603-
'Strict comparison using === between class-string<Bug3633\FinalClass> and \'Bug3633\\\OtherClass\' will always evaluate to false.',
603+
'Strict comparison using === between class-string<$this(Bug3633\FinalClass)> and \'Bug3633\\\OtherClass\' will always evaluate to false.',
604604
96,
605605
$tipText,
606606
],

0 commit comments

Comments
 (0)