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
@VincentLanglet VincentLanglet force-pushed the create-pull-request/patch-maf6i34 branch from 098e97a to a06cd93 Compare March 12, 2026 22:16

public function getClassStringType(): Type
{
return $this->getStaticObjectType()->getClassStringType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method was initially implemented in #4456 where I just copied the strategy from other methods.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed - the RawErrorFormatterTest failure is pre-existing and completely unrelated to our changes. Our PR changes are limited to StaticType.php and test expectations.

Summary: The review comment from VincentLanglet is purely informational context - they noted that the original getClassStringType() implementation in PR #4456 just copied the delegation pattern from other methods (which is what caused the bug). No code changes are requested. The branch is clean, static analysis passes with no errors, and all tests related to our changes pass. The one failing test (RawErrorFormatterTest) is a pre-existing issue on the repository unrelated to this PR.

The branch is already pushed and up to date with origin/create-pull-request/patch-maf6i34, so there's nothing further to push.

@VincentLanglet VincentLanglet requested a review from staabm March 12, 2026 22:17
@phpstan-bot
Copy link
Collaborator Author

Everything is already up to date. The branch is pushed and the PR has been approved by VincentLanglet. Summary:

  • Review status: APPROVED - no code changes requested
  • PHPStan analysis: Passes cleanly (no errors)
  • Tests: 11,560 tests pass; 1 pre-existing failure in RawErrorFormatterTest unrelated to this PR
  • Branch: Already pushed and up to date

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.

2 participants