Skip to content

Commit 07a29ab

Browse files
Resolve array~list as non-empty-array
1 parent 8bb2a20 commit 07a29ab

File tree

4 files changed

+111
-7
lines changed

4 files changed

+111
-7
lines changed

src/Type/ArrayType.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,10 @@ public function tryRemove(Type $typeToRemove): ?Type
609609
return TypeCombinator::intersect($this, new NonEmptyArrayType());
610610
}
611611

612+
if ($typeToRemove->isSuperTypeOf(new ConstantArrayType([], []))->yes()) {
613+
return TypeCombinator::intersect($this, new NonEmptyArrayType());
614+
}
615+
612616
if ($typeToRemove instanceof NonEmptyArrayType) {
613617
return new ConstantArrayType([], []);
614618
}

tests/PHPStan/Analyser/nsrt/array-is-list-type-specifying.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function foo(array $foo) {
88
if (array_is_list($foo)) {
99
assertType('list', $foo);
1010
} else {
11-
assertType('array', $foo);
11+
assertType('non-empty-array', $foo);
1212
}
1313
}
1414

@@ -51,7 +51,7 @@ function foo4(array $foo) {
5151
if (array_is_list($foo)) {
5252
assertType('list', $foo);
5353
} else {
54-
assertType('array<int|string, mixed>', $foo);
54+
assertType('non-empty-array<int|string, mixed>', $foo);
5555
}
5656

5757
$baz = [];

tests/PHPStan/Analyser/nsrt/assert-docblock.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function takesArrayIfTrue(array $arr) : void {
7171
if (validateStringArrayIfTrue($arr)) {
7272
assertType('array<string>', $arr);
7373
} else {
74-
assertType('array<mixed>', $arr);
74+
assertType('non-empty-array<mixed>', $arr);
7575
}
7676
}
7777
/**
@@ -81,7 +81,7 @@ function takesArrayIfTrue1(array $arr) : void {
8181
assertType('array<mixed>', $arr);
8282

8383
if (!validateStringArrayIfTrue($arr)) {
84-
assertType('array<mixed>', $arr);
84+
assertType('non-empty-array<mixed>', $arr);
8585
} else {
8686
assertType('array<string>', $arr);
8787
}
@@ -96,7 +96,7 @@ function takesArrayIfFalse(array $arr) : void {
9696
if (!validateStringArrayIfFalse($arr)) {
9797
assertType('array<string>', $arr);
9898
} else {
99-
assertType('array<mixed>', $arr);
99+
assertType('non-empty-array<mixed>', $arr);
100100
}
101101
}
102102

@@ -107,7 +107,7 @@ function takesArrayIfFalse1(array $arr) : void {
107107
assertType('array<mixed>', $arr);
108108

109109
if (validateStringArrayIfFalse($arr)) {
110-
assertType('array<mixed>', $arr);
110+
assertType('non-empty-array<mixed>', $arr);
111111
} else {
112112
assertType('array<string>', $arr);
113113
}

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

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function doFoo(array $a): void
1717
if (array_is_list($a)) {
1818
assertType('list', $a);
1919
} else {
20-
assertType('array<mixed>', $a); // could be non-empty-array
20+
assertType('non-empty-array<mixed>', $a);
2121
}
2222
}
2323

@@ -44,4 +44,104 @@ public function doFoo3(array $a): void
4444
}
4545
}
4646

47+
/**
48+
* @param mixed $a
49+
* @return void
50+
*/
51+
public function doFoo4($a): void
52+
{
53+
if (array_is_list($a)) {
54+
assertType('list', $a);
55+
} else {
56+
assertType('mixed~list', $a);
57+
}
58+
}
59+
60+
}
61+
62+
class Bar
63+
{
64+
/**
65+
* @param array<array-key, mixed> $value
66+
* @return ($value is non-empty-list ? true : false)
67+
*/
68+
public function assertIsNonEmptyList($value): bool
69+
{
70+
return false;
71+
}
72+
73+
/**
74+
* @param array<array-key, mixed> $value
75+
* @return ($value is list<string> ? true : false)
76+
*/
77+
public function assertIsStringList($value): bool
78+
{
79+
return false;
80+
}
81+
82+
/**
83+
* @param array<array-key, mixed> $value
84+
* @return ($value is list{string, string} ? true : false)
85+
*/
86+
public function assertIsConstantList($value): bool
87+
{
88+
return false;
89+
}
90+
91+
/**
92+
* @param array<array-key, mixed> $value
93+
* @return ($value is list{0?: string, 1?: string} ? true : false)
94+
*/
95+
public function assertIsOptionalConstantList($value): bool
96+
{
97+
return false;
98+
}
99+
100+
/**
101+
* @param array<array-key, mixed> $value
102+
* @return ($value is array<string> ? true : false)
103+
*/
104+
public function assertIsStringArray($value): bool
105+
{
106+
return false;
107+
}
108+
109+
/**
110+
* @param array<mixed> $a
111+
* @return void
112+
*/
113+
public function doFoo(array $a): void
114+
{
115+
if ($this->assertIsNonEmptyList($a)) {
116+
assertType('non-empty-list', $a);
117+
} else {
118+
assertType('array<mixed>', $a);
119+
}
120+
121+
if ($this->assertIsStringList($a)) {
122+
assertType('list<string>', $a);
123+
} else {
124+
assertType('non-empty-array', $a);
125+
}
126+
127+
if ($this->assertIsConstantList($a)) {
128+
assertType('array{string, string}', $a);
129+
} else {
130+
assertType('array', $a);
131+
}
132+
133+
if ($this->assertIsOptionalConstantList($a)) {
134+
assertType('list{0?: string, 1?: string}', $a);
135+
} else {
136+
assertType('non-empty-array', $a);
137+
}
138+
139+
if ($this->assertIsStringArray($a)) {
140+
assertType('array<string>', $a);
141+
} else {
142+
assertType('non-empty-array', $a);
143+
}
144+
}
145+
146+
47147
}

0 commit comments

Comments
 (0)