diff --git a/src/Type/StaticType.php b/src/Type/StaticType.php index 0243c96256..2f1e27ee22 100644 --- a/src/Type/StaticType.php +++ b/src/Type/StaticType.php @@ -369,6 +369,13 @@ private function transformStaticType(Type $type, ClassMemberAccessAnswerer $scop $type = new self($type->getClassReflection(), $type->getSubtractedType()); } + if ($this->getSubtractedType() !== null) { + $type = $type->subtract($this->getSubtractedType()); + if (!$type instanceof StaticType) { + return $traverse($type); + } + } + if (!$isFinal || $type instanceof ThisType) { return $traverse($type); } diff --git a/tests/PHPStan/Analyser/nsrt/bug-12244.php b/tests/PHPStan/Analyser/nsrt/bug-12244.php new file mode 100644 index 0000000000..ba792e4625 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-12244.php @@ -0,0 +1,32 @@ += 8.1 + +declare(strict_types = 1); + +namespace Bug12244; + +use function PHPStan\Testing\assertType; + +enum X: string { + case A = 'a'; + case B = 'b'; + case C = 'c'; + + /** @return ($this is self::A ? int : null) */ + public function get(): ?int { + return ($this === self::A) ? 123 : null; + } + + public function doSomething(): void { + if ($this !== self::A) { + assertType('$this(Bug12244\X~Bug12244\X::A)', $this); + assertType('null', $this->get()); + } + } + + public static function doSomethingFor(X $x): void { + if ($x !== self::A) { + assertType('Bug12244\X~Bug12244\X::A', $x); + assertType('null', $x->get()); + } + } +}