Skip to content

Commit 09749db

Browse files
Fix preserving list when setting union offset type to a ConstantArrayTypeBuilder
1 parent ab787e2 commit 09749db

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
199199
return;
200200
}
201201

202-
$this->isList = TrinaryLogic::createNo();
203-
204202
$scalarTypes = $offsetType->getConstantScalarTypes();
205203
if (count($scalarTypes) === 0) {
206204
$integerRanges = TypeUtils::getIntegerRanges($offsetType);
@@ -257,6 +255,8 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
257255
return;
258256
}
259257
}
258+
259+
$this->isList = TrinaryLogic::createNo();
260260
}
261261

262262
if ($offsetType === null) {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace ArrayIsListUnset;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo {
8+
/**
9+
* @param array{bool, bool, bool} $array
10+
* @param int<0, 1> $key
11+
*/
12+
public function test(array $array, int $key) {
13+
assertType('int<0, 1>', $key);
14+
assertType('true', array_is_list($array));
15+
16+
$array[$key] = false;
17+
assertType('true', array_is_list($array));
18+
}
19+
}

tests/PHPStan/Type/Constant/ConstantArrayTypeBuilderTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPStan\Type\BooleanType;
66
use PHPStan\Type\NullType;
77
use PHPStan\Type\StringType;
8+
use PHPStan\Type\TypeCombinator;
89
use PHPStan\Type\VerbosityLevel;
910
use PHPUnit\Framework\TestCase;
1011

@@ -128,4 +129,37 @@ public function testIsList(): void
128129
$this->assertFalse($builder->isList());
129130
}
130131

132+
public function testIsListWithUnion(): void
133+
{
134+
$builder = ConstantArrayTypeBuilder::createEmpty();
135+
136+
$builder->setOffsetValueType(null, new ConstantIntegerType(0));
137+
$this->assertTrue($builder->isList());
138+
139+
$builder->setOffsetValueType(new ConstantIntegerType(0), new NullType());
140+
$this->assertTrue($builder->isList());
141+
142+
$builder->setOffsetValueType(new ConstantIntegerType(1), new NullType());
143+
$this->assertTrue($builder->isList());
144+
145+
$builder->setOffsetValueType(new ConstantIntegerType(2), new NullType());
146+
$this->assertTrue($builder->isList());
147+
148+
$oneOrZero = TypeCombinator::union(
149+
new ConstantIntegerType(0),
150+
new ConstantIntegerType(1),
151+
);
152+
153+
$builder->setOffsetValueType($oneOrZero, new NullType());
154+
$this->assertTrue($builder->isList());
155+
156+
$oneOrFour = TypeCombinator::union(
157+
new ConstantIntegerType(1),
158+
new ConstantIntegerType(4),
159+
);
160+
161+
$builder->setOffsetValueType($oneOrFour, new NullType());
162+
$this->assertFalse($builder->isList());
163+
}
164+
131165
}

0 commit comments

Comments
 (0)