Skip to content

Commit bd7bbec

Browse files
committed
Merge branch 2.1.x into 2.2.x
2 parents 5d7995f + 58b873f commit bd7bbec

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/Type/Constant/ConstantArrayType.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,8 @@ public function spliceArray(Type $offsetType, Type $lengthType, Type $replacemen
11941194
->spliceArray($offsetType, $lengthType, $replacementType);
11951195
}
11961196

1197+
$allKeysInteger = $this->getIterableKeyType()->isInteger()->yes();
1198+
11971199
if ($keyTypesCount + $offset <= 0) {
11981200
// A negative offset cannot reach left outside the array twice
11991201
$offset = 0;
@@ -1271,7 +1273,11 @@ public function spliceArray(Type $offsetType, Type $lengthType, Type $replacemen
12711273
);
12721274
}
12731275

1274-
$types[] = $builder->getArray();
1276+
$builtType = $builder->getArray();
1277+
if ($allKeysInteger && !$builtType->isList()->yes()) {
1278+
$builtType = TypeCombinator::intersect($builtType, new AccessoryArrayListType());
1279+
}
1280+
$types[] = $builtType;
12751281
}
12761282

12771283
return TypeCombinator::union(...$types);
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug14472;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
class Foo
8+
{
9+
/**
10+
* @param string[] $replacement
11+
*/
12+
public function arraySpliceOnConstantArrayWithIntKeys(array $replacement): void
13+
{
14+
$headers = [
15+
'last_name',
16+
'first_name',
17+
'email',
18+
'phone',
19+
'position',
20+
'client_identifier',
21+
'profile',
22+
'hierarchy_role',
23+
'hierarchy_role_name',
24+
'state',
25+
'admin',
26+
'confirmed',
27+
'invited',
28+
'using_native_app',
29+
'using_sso',
30+
'last_connection',
31+
];
32+
33+
assertType("array{'last_name', 'first_name', 'email', 'phone', 'position', 'client_identifier', 'profile', 'hierarchy_role', 'hierarchy_role_name', 'state', 'admin', 'confirmed', 'invited', 'using_native_app', 'using_sso', 'last_connection'}", $headers);
34+
35+
array_splice($headers, 9, 0, $replacement);
36+
assertType("non-empty-list<string>", $headers);
37+
}
38+
39+
/**
40+
* @param list<string> $replacement
41+
*/
42+
public function arraySpliceOnConstantArrayWithIntKeysListReplacement(array $replacement): void
43+
{
44+
$headers = ['a', 'b', 'c'];
45+
array_splice($headers, 1, 0, $replacement);
46+
assertType("non-empty-list<string>", $headers);
47+
}
48+
49+
public function arraySpliceOnConstantArrayWithStringKeys(): void
50+
{
51+
$headers = ['a' => 'x', 'b' => 'y', 'c' => 'z'];
52+
array_splice($headers, 1, 1, ['replacement']);
53+
assertType("array{a: 'x', 0: 'replacement', c: 'z'}", $headers);
54+
}
55+
}

0 commit comments

Comments
 (0)