Skip to content

Commit e450d3c

Browse files
Fix ClassConstantAccessType to return mixed for untyped constants on 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>
1 parent cccf92c commit e450d3c

File tree

2 files changed

+11
-12
lines changed

2 files changed

+11
-12
lines changed

src/Type/ClassConstantAccessType.php

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,15 @@ protected function getResult(): Type
5757

5858
$constantReflection = $this->type->getConstant($this->constantName);
5959

60-
if (
61-
$this->type instanceof StaticType
62-
&& !$this->type->getClassReflection()->isFinal()
63-
&& !$constantReflection->isFinal()
64-
) {
65-
if ($constantReflection->hasNativeType() || $constantReflection->hasPhpDocType()) {
66-
return $constantReflection->getValueType();
60+
if (!$constantReflection->isFinal()) {
61+
$classReflections = $this->type->getObjectClassReflections();
62+
if (count($classReflections) === 1 && !$classReflections[0]->isFinal()) {
63+
if ($constantReflection->hasNativeType() || $constantReflection->hasPhpDocType()) {
64+
return $constantReflection->getValueType();
65+
}
66+
67+
return new MixedType();
6768
}
68-
69-
return new MixedType();
7069
}
7170

7271
return $constantReflection->getValueType();

tests/PHPStan/Analyser/nsrt/bug-13828.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ class BarBaz extends FooBar
2222

2323
function test(FooBar $foo, BarBaz $bar): void
2424
{
25-
assertType("'foo'", $foo->test());
26-
assertType("'bar'", $bar->test());
25+
assertType('mixed', $foo->test());
26+
assertType('mixed', $bar->test());
2727
}
2828

2929
final class FinalFoo
@@ -146,5 +146,5 @@ public function test(): string
146146

147147
function testUntypedConstant(WithUntypedConstant $foo): void
148148
{
149-
assertType("'foo'", $foo->test());
149+
assertType('mixed', $foo->test());
150150
}

0 commit comments

Comments
 (0)