diff --git a/src/Type/StaticType.php b/src/Type/StaticType.php index 2f1e27ee22..682bc77d30 100644 --- a/src/Type/StaticType.php +++ b/src/Type/StaticType.php @@ -16,6 +16,7 @@ use PHPStan\Reflection\Type\UnresolvedPropertyPrototypeReflection; use PHPStan\TrinaryLogic; use PHPStan\Type\Enum\EnumCaseObjectType; +use PHPStan\Type\Generic\GenericClassStringType; use PHPStan\Type\Generic\GenericObjectType; use PHPStan\Type\Generic\TemplateTypeHelper; use PHPStan\Type\Traits\NonGeneralizableTypeTrait; @@ -200,7 +201,7 @@ public function isObject(): TrinaryLogic public function getClassStringType(): Type { - return $this->getStaticObjectType()->getClassStringType(); + return new GenericClassStringType($this); } public function isEnum(): TrinaryLogic diff --git a/tests/PHPStan/Analyser/data/bug-7391b.php b/tests/PHPStan/Analyser/data/bug-7391b.php index 9970ec7d47..ec49707ceb 100644 --- a/tests/PHPStan/Analyser/data/bug-7391b.php +++ b/tests/PHPStan/Analyser/data/bug-7391b.php @@ -16,7 +16,7 @@ public static function m() { assertType('Bug7391B\Foo', (self::class)::m()); assertType('static(Bug7391B\Foo)', (static::class)::m()); assertType('Bug7391B\Foo', get_class(new self(2))::m()); - assertType('Bug7391B\Foo', get_class(new static(2))::m()); + assertType('static(Bug7391B\Foo)', get_class(new static(2))::m()); throw new \Error('For static analysis only, return type is resolved purely by DynamicStaticMethodReturnTypeExtension'); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-4860.php b/tests/PHPStan/Analyser/nsrt/bug-4860.php new file mode 100644 index 0000000000..d2caf7c9cf --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-4860.php @@ -0,0 +1,25 @@ +', get_class($this)); + return $this->copyTo(get_class($this)); + } + + /** + * @template T + * @param class-string $targetEntity + * @return T + */ + public function copyTo(string $targetEntity) + { + /** @var T */ + return new $targetEntity(); + } +} diff --git a/tests/PHPStan/Analyser/nsrt/get-parent-class.php b/tests/PHPStan/Analyser/nsrt/get-parent-class.php index 90832eacea..5e6c291e6e 100644 --- a/tests/PHPStan/Analyser/nsrt/get-parent-class.php +++ b/tests/PHPStan/Analyser/nsrt/get-parent-class.php @@ -11,7 +11,7 @@ public function doFoo() { assertType('false', get_parent_class()); assertType('false', get_parent_class($this)); - assertType('class-string', get_class($this)); + assertType('class-string<$this(ParentClass\Foo)>', get_class($this)); assertType('\'ParentClass\\\\Foo\'', get_class()); } diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index d08594257f..2450cb19b3 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -566,7 +566,7 @@ public function testBug3633(): void $tipText = 'Because the type is coming from a PHPDoc, you can turn off this check by setting treatPhpDocTypesAsCertain: false in your %configurationFile%.'; $this->analyse([__DIR__ . '/data/bug-3633.php'], [ [ - 'Strict comparison using === between class-string and \'Bug3633\\\OtherClass\' will always evaluate to false.', + 'Strict comparison using === between class-string<$this(Bug3633\HelloWorld)> and \'Bug3633\\\OtherClass\' will always evaluate to false.', 37, $tipText, ], @@ -580,7 +580,7 @@ public function testBug3633(): void 44, ], [ - 'Strict comparison using === between class-string and \'Bug3633\\\HelloWorld\' will always evaluate to false.', + 'Strict comparison using === between class-string<$this(Bug3633\OtherClass)> and \'Bug3633\\\HelloWorld\' will always evaluate to false.', 64, $tipText, ], @@ -595,12 +595,12 @@ public function testBug3633(): void $tipText, ], [ - 'Strict comparison using === between class-string and \'Bug3633\\\HelloWorld\' will always evaluate to false.', + 'Strict comparison using === between class-string<$this(Bug3633\FinalClass)> and \'Bug3633\\\HelloWorld\' will always evaluate to false.', 93, $tipText, ], [ - 'Strict comparison using === between class-string and \'Bug3633\\\OtherClass\' will always evaluate to false.', + 'Strict comparison using === between class-string<$this(Bug3633\FinalClass)> and \'Bug3633\\\OtherClass\' will always evaluate to false.', 96, $tipText, ],