Skip to content

Fix phpstan/phpstan#4860: Error „should return static(Test) but returns Test“#5190

Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-maf6i34
Open

Fix phpstan/phpstan#4860: Error „should return static(Test) but returns Test“#5190
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-maf6i34

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

get_class($this) was returning class-string<ClassName> instead of class-string<static(ClassName)>, causing false positive errors when the result was passed to a template method that should preserve the static type. For example, a copy(): static method calling $this->copyTo(get_class($this)) where copyTo has @template T and @param class-string<T> / @return T would incorrectly report "should return static(Test) but returns Test".

Changes

  • Modified StaticType::getClassStringType() in src/Type/StaticType.php to return new GenericClassStringType($this) instead of delegating to getStaticObjectType()->getClassStringType(), which was losing the static type information
  • Updated test expectations in tests/PHPStan/Analyser/data/bug-7391b.php, tests/PHPStan/Analyser/nsrt/get-parent-class.php, and tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php to reflect the more precise type descriptions

Root cause

StaticType::getClassStringType() was delegating to getStaticObjectType() which resolves the StaticType to a plain ObjectType, losing the static/$this information. This meant get_class($this) returned class-string<Foo> instead of class-string<$this(Foo)>. When this was passed to a template method with @param class-string<T> @return T, the template T resolved to Foo instead of static(Foo), causing the false positive.

Test

Added tests/PHPStan/Analyser/nsrt/bug-4860.php which verifies that get_class($this) returns class-string<$this(ClassName)> and that passing it to a template method correctly preserves the static type.

Fixes phpstan/phpstan#4860

- StaticType::getClassStringType() was delegating to getStaticObjectType() which
  returned the base ObjectType, losing the static/this type information
- Changed it to return GenericClassStringType($this) directly, preserving the
  static type so get_class($this) correctly returns class-string<static(T)>
- This fixes false positives when passing get_class($this) to template methods
  expecting class-string<T> and returning T, where the return should be static
- New regression test in tests/PHPStan/Analyser/nsrt/bug-4860.php
- Updated existing test expectations to reflect the more precise type
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant