Skip to content

Commit 800641c

Browse files
committed
Ignore negative keys on checking whether a ConstantArray is a list
1 parent 60b29fa commit 800641c

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed

src/Type/Constant/ConstantArrayTypeBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ public function setOffsetValueType(?Type $offsetType, Type $valueType, bool $opt
162162
$this->keyTypes[] = $offsetType;
163163
$this->valueTypes[] = $valueType;
164164

165-
if ($offsetType instanceof ConstantIntegerType) {
165+
if ($offsetType instanceof ConstantIntegerType && $offsetType->getValue() >= 0) {
166166
$min = min($this->nextAutoIndexes);
167167
$max = max($this->nextAutoIndexes);
168168
if ($offsetType->getValue() > $min) {

tests/PHPStan/Rules/PhpDoc/VarTagChangedExpressionTypeRuleTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,25 @@ public function testBug10130(): void
7878
]);
7979
}
8080

81+
public function testBug12708(): void
82+
{
83+
$this->analyse([__DIR__ . '/data/bug-12708.php'], [
84+
[
85+
"PHPDoc tag @var with type list<string> is not subtype of native type array{1: 'b', 2: 'c'}.",
86+
12,
87+
],
88+
[
89+
"PHPDoc tag @var with type list<string> is not subtype of native type array{0: 'a', 2: 'c'}.",
90+
18,
91+
],
92+
[
93+
"PHPDoc tag @var with type list<string> is not subtype of native type array{-1: 'z', 0: 'a', 1: 'b', 2: 'c'}.",
94+
24,
95+
],
96+
[
97+
"PHPDoc tag @var with type list<string> is not subtype of native type array{0: 'a', -1: 'z', 1: 'b', 2: 'c'}.",
98+
30,
99+
],
100+
]);
101+
}
81102
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php declare(strict_types = 1);
2+
3+
function do0()
4+
{
5+
/** @var list<string> */
6+
return [0 => 'a', 1 => 'b', 2 => 'c'];
7+
}
8+
9+
function do1()
10+
{
11+
/** @var list<string> */
12+
return [1 => 'b', 2 => 'c'];
13+
}
14+
15+
function do2()
16+
{
17+
/** @var list<string> */
18+
return [0 => 'a', 2 => 'c'];
19+
}
20+
21+
function do3()
22+
{
23+
/** @var list<string> */
24+
return [-1 => 'z', 0 => 'a', 1 => 'b', 2 => 'c'];
25+
}
26+
27+
function do4()
28+
{
29+
/** @var list<string> */
30+
return [0 => 'a', -1 => 'z', 1 => 'b', 2 => 'c'];
31+
}

0 commit comments

Comments
 (0)