Skip to content

Commit 9f706c8

Browse files
authored
Merge branch refs/heads/2.1.x into 2.2.x
2 parents dc5c822 + 4b2e7e5 commit 9f706c8

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

src/Type/StaticType.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,13 @@ private function transformStaticType(Type $type, ClassMemberAccessAnswerer $scop
369369
$type = new self($type->getClassReflection(), $type->getSubtractedType());
370370
}
371371

372+
if ($this->getSubtractedType() !== null) {
373+
$type = $type->subtract($this->getSubtractedType());
374+
if (!$type instanceof StaticType) {
375+
return $traverse($type);
376+
}
377+
}
378+
372379
if (!$isFinal || $type instanceof ThisType) {
373380
return $traverse($type);
374381
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php // lint >= 8.1
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug12244;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
enum X: string {
10+
case A = 'a';
11+
case B = 'b';
12+
case C = 'c';
13+
14+
/** @return ($this is self::A ? int : null) */
15+
public function get(): ?int {
16+
return ($this === self::A) ? 123 : null;
17+
}
18+
19+
public function doSomething(): void {
20+
if ($this !== self::A) {
21+
assertType('$this(Bug12244\X~Bug12244\X::A)', $this);
22+
assertType('null', $this->get());
23+
} else {
24+
assertType('int', $this->get());
25+
}
26+
27+
if ($this !== self::B && $this !== self::C) {
28+
assertType('int', $this->get());
29+
}
30+
}
31+
32+
public static function doSomethingFor(X $x): void {
33+
if ($x !== self::A) {
34+
assertType('Bug12244\X~Bug12244\X::A', $x);
35+
assertType('null', $x->get());
36+
} else {
37+
assertType('int', $x->get());
38+
}
39+
40+
if ($x !== self::B && $x !== self::C) {
41+
assertType('int', $x->get());
42+
}
43+
}
44+
}
45+
46+
enum Y: string {
47+
case A = 'a';
48+
case B = 'b';
49+
case C = 'c';
50+
51+
/** @param-out ($this is self::A ? int : null) $i */
52+
public function get(?int &$i): void {
53+
($this === self::A) ? $i=null : $i=123;
54+
}
55+
56+
public function doSomething(): void {
57+
$i = 0;
58+
if ($this !== self::A) {
59+
$this->get($i);
60+
assertType('null', $i); // null
61+
} else {
62+
$this->get($i);
63+
assertType('int', $i); // int
64+
}
65+
}
66+
67+
public static function doSomethingFor(Y $x): void {
68+
$i = 0;
69+
if ($x !== self::A) {
70+
$x->get($i);
71+
assertType('null', $i); // null
72+
} else {
73+
$x->get($i);
74+
assertType('int', $i); // int
75+
}
76+
}
77+
}

0 commit comments

Comments
 (0)