Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Type/Constant/ConstantArrayTypeBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
return;
}

$this->isList = TrinaryLogic::createNo();

$scalarTypes = $offsetType->getConstantScalarTypes();
if (count($scalarTypes) === 0) {
$integerRanges = TypeUtils::getIntegerRanges($offsetType);
Expand Down Expand Up @@ -257,6 +255,8 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
return;
}
}

$this->isList = TrinaryLogic::createNo();
}

if ($offsetType === null) {
Expand Down
19 changes: 19 additions & 0 deletions tests/PHPStan/Analyser/nsrt/array-is-list-offset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace ArrayIsListUnset;

use function PHPStan\Testing\assertType;

class Foo {
/**
* @param array{bool, bool, bool} $array
* @param int<0, 1> $key
*/
public function test(array $array, int $key) {
assertType('int<0, 1>', $key);
assertType('true', array_is_list($array));

$array[$key] = false;
assertType('true', array_is_list($array));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prior to this PR, it was considered as false.

}
}
26 changes: 26 additions & 0 deletions tests/PHPStan/Type/Constant/ConstantArrayTypeBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPStan\Type\BooleanType;
use PHPStan\Type\NullType;
use PHPStan\Type\StringType;
use PHPStan\Type\TypeCombinator;
use PHPStan\Type\VerbosityLevel;
use PHPUnit\Framework\TestCase;

Expand Down Expand Up @@ -128,4 +129,29 @@ public function testIsList(): void
$this->assertFalse($builder->isList());
}

public function testIsListWithUnion(): void
{
$builder = ConstantArrayTypeBuilder::createEmpty();

$builder->setOffsetValueType(null, new ConstantIntegerType(0));
$this->assertTrue($builder->isList());

$builder->setOffsetValueType(new ConstantIntegerType(0), new NullType());
$this->assertTrue($builder->isList());

$builder->setOffsetValueType(new ConstantIntegerType(1), new NullType());
$this->assertTrue($builder->isList());

$builder->setOffsetValueType(new ConstantIntegerType(2), new NullType());
$this->assertTrue($builder->isList());

$oneOrZero = TypeCombinator::union(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also write some counter-example test as well. Like when we're setting a union offset that does not exist yet, that will make the array be no longer a list. Thanks.

new ConstantIntegerType(0),
new ConstantIntegerType(1),
);

$builder->setOffsetValueType($oneOrZero, new NullType());
$this->assertTrue($builder->isList());
}

}
Loading