Fix #13828: Reference to static const behaves as self const#5510
Merged
VincentLanglet merged 7 commits intophpstan:2.1.xfrom Apr 22, 2026
Merged
Conversation
- Added ClassConstantAccessType that wraps StaticType + constant name and implements LateResolvableType, deferring resolution until the caller type is known - Modified TypeNodeResolver::resolveConstTypeNode() and resolveArrayShapeOffsetType() to create ClassConstantAccessType when the keyword is 'static' instead of resolving eagerly like 'self' - The StaticType inside ClassConstantAccessType gets replaced with the concrete ObjectType during CalledOnTypeUnresolvedMethodPrototypeReflection::transformStaticType(), then the constant is resolved on the correct class - New regression test in tests/PHPStan/Analyser/nsrt/bug-13828.php
When the inner type is still a StaticType (not yet resolved to a concrete class), use the declared type (native or PHPDoc) instead of the literal value for non-final constants on non-final classes. For final constants or final classes, the literal value is preserved since subclasses cannot override them. Added test cases for: - Constants with native type (const string) - Constants with PHPDoc type (@var non-empty-string) - Constants with both native and PHPDoc types - Final constants on non-final classes - Untyped constants Co-authored-by: Ondřej Mirtes <ondrejmirtes@users.noreply.github.com>
…non-final classes When static::CONST is used and the constant has no native type or PHPDoc type, and neither the class nor the constant is final, return mixed instead of the literal value — since a subclass could override the constant with any value. Also unified the logic to use getObjectClassReflections() instead of instanceof StaticType, so it works for both unresolved StaticType and resolved ObjectType (e.g., FooBar $foo where $foo could be a subclass). Co-authored-by: Ondřej Mirtes <ondrejmirtes@users.noreply.github.com>
…solver logic Restructured getResult() to match the $isObject path in InitializerExprTypeResolver::getClassConstFetchTypeByReflection(): - Extract ClassReflection first via getObjectClassReflections() - Add enum case handling (EnumCaseObjectType) - Match exact condition structure: class not final AND constant not final AND no phpDocType AND no nativeType → mixed - Otherwise use getValueType() (declared type for typed constants, literal for untyped constants) Added test cases for final child class inheriting @return static::CONST and for final typed constant on non-final class. Co-authored-by: Ondřej Mirtes <ondrejmirtes@users.noreply.github.com>
…comparison Co-authored-by: Markus Staab <markus.staab@redaxo.de> Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Automated fix attempt 1 for CI failures.
Automated fix attempt 2 for CI failures.
Collaborator
|
This pull request has been marked as ready for review. |
staabm
approved these changes
Apr 22, 2026
|
Many thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR #4906 with a rebase.
Was previously approved by ondrej.
Fixes phpstan/phpstan#13828
Closes #4906