forked from phpstan/phpstan-src
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbug-11730.php
More file actions
104 lines (79 loc) · 3.2 KB
/
bug-11730.php
File metadata and controls
104 lines (79 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
<?php // lint >= 8.1
declare(strict_types = 1);
namespace Bug11730;
use function PHPStan\Testing\assertType;
class Foo {
public bool $active = false;
}
/** @return ($value is Foo ? true : false) */
function isFoo(mixed $value): bool {
return $value instanceof Foo;
}
/** @phpstan-assert-if-true Foo $value */
function checkFoo(mixed $value): bool {
return $value instanceof Foo;
}
$data = [new Foo, new Foo];
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, isFoo(...)));
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, checkFoo(...)));
/** @param array{Foo|int, Foo|int} $data */
function doFoo ($data) {
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, isFoo(...)));
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, checkFoo(...)));
}
class Asserter {
/** @return ($value is Foo ? true : false) */
function isFoo(mixed $value): bool {
return $value instanceof Foo;
}
/** @phpstan-assert-if-true Foo $value */
function checkFoo(mixed $value): bool {
return $value instanceof Foo;
}
/** @return ($value is Foo ? true : false) */
static function isFooStatic(mixed $value): bool {
return $value instanceof Foo;
}
/** @phpstan-assert-if-true Foo $value */
static function checkFooStatic(mixed $value): bool {
return $value instanceof Foo;
}
}
function doBar(): void {
$data = [new Foo, new Foo];
$asserter = new Asserter;
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, $asserter->isFoo(...)));
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, $asserter->checkFoo(...)));
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, Asserter::isFooStatic(...)));
assertType('array{Bug11730\Foo, Bug11730\Foo}', array_filter($data, Asserter::checkFooStatic(...)));
}
/** @param array{Foo|int, Foo|int} $data */
function doBaz(array $data): void {
$asserter = new Asserter;
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, $asserter->isFoo(...)));
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, $asserter->checkFoo(...)));
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, Asserter::isFooStatic(...)));
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, Asserter::checkFooStatic(...)));
}
class CallableAsserterConditionalReturn {
/** @return ($value is Foo ? true : false) */
function __invoke(mixed $value): bool {
return $value instanceof Foo;
}
}
$data = [new Foo, new Foo];
assertType('array<0|1, Bug11730\Foo>', array_filter($data, new CallableAsserterConditionalReturn())); // could be array{Foo, Foo}
class CallableAssertIfTrue {
/** @phpstan-assert-if-true Foo $value */
function __invoke(mixed $value): bool {
return $value instanceof Foo;
}
}
$data = [new Foo, new Foo];
assertType('array<0|1, Bug11730\Foo>', array_filter($data, new CallableAssertIfTrue())); // could be array{Foo, Foo}
/** @phpstan-assert-if-true =Foo $value */
function checkFooAndMore(mixed $value): bool {
return $value instanceof Foo && $value->active;
}
$data = [new Foo, new Foo];
assertType('array{0?: Bug11730\Foo, 1?: Bug11730\Foo}', array_filter($data, checkFooAndMore(...)));