Skip to content

Commit a44f10c

Browse files
ekisuondrejmirtes
authored andcommitted
Add support and tests for $this type assertions
1 parent d67f5eb commit a44f10c

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,7 @@ public function dataFileAsserts(): iterable
11511151
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-empty.php');
11521152
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-method.php');
11531153
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-property.php');
1154+
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-this.php');
11541155
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-methods.php');
11551156
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-intersected.php');
11561157
yield from $this->gatherAssertTypes(__DIR__ . '/data/assert-invariant.php');
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
namespace AssertThis;
4+
5+
use RuntimeException;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
/**
10+
* @template TOk
11+
* @template TErr
12+
*/
13+
interface Result {
14+
/**
15+
* @phpstan-assert-if-true Ok<TOk> $this
16+
* @phpstan-assert-if-false Err<TErr> $this
17+
*/
18+
public function isOk(): bool;
19+
20+
/**
21+
* @return TOk|never
22+
*/
23+
public function unwrap();
24+
}
25+
26+
/**
27+
* @template TOk
28+
* @template-implements Result<TOk, never>
29+
*/
30+
class Ok implements Result {
31+
public function __construct(private $value) {
32+
}
33+
34+
/**
35+
* @return true
36+
*/
37+
public function isOk(): bool {
38+
return true;
39+
}
40+
41+
/**
42+
* @return TOk
43+
*/
44+
public function unwrap() {
45+
return $this->value;
46+
}
47+
}
48+
49+
/**
50+
* @template TErr
51+
* @template-implements Result<never, TErr>
52+
*/
53+
class Err implements Result {
54+
public function __construct(private $value) {
55+
}
56+
57+
/**
58+
* @return false
59+
*/
60+
public function isOk(): bool {
61+
return false;
62+
}
63+
64+
/**
65+
* @return never
66+
*/
67+
public function unwrap() {
68+
throw new RuntimeException('Tried to unwrap() an Err value');
69+
}
70+
}
71+
72+
function () {
73+
/** @var Result<int, string> $result */
74+
$result = new Ok(123);
75+
assertType('AssertThis\\Result<int, string>', $result);
76+
77+
if ($result->isOk()) {
78+
assertType('AssertThis\\Ok<int>', $result);
79+
assertType('int', $result->unwrap());
80+
} else {
81+
assertType('AssertThis\\Err<string>', $result);
82+
assertType('never', $result->unwrap());
83+
}
84+
};

0 commit comments

Comments
 (0)