Skip to content

Commit 7429a18

Browse files
committed
Merge remote-tracking branch 'origin/1.12.x' into 2.1.x
2 parents f2cf5ca + 36b3925 commit 7429a18

11 files changed

+112
-11
lines changed

src/Type/Accessory/AccessoryNumericStringType.php

+7-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,13 @@ public function toArray(): Type
210210

211211
public function toArrayKey(): Type
212212
{
213-
return new IntegerType();
213+
return new UnionType([
214+
new IntegerType(),
215+
new IntersectionType([
216+
new StringType(),
217+
new AccessoryNumericStringType(),
218+
]),
219+
]);
214220
}
215221

216222
public function toCoercedArgumentType(bool $strictTypes): Type

src/Type/Constant/ConstantArrayType.php

+9-3
Original file line numberDiff line numberDiff line change
@@ -580,11 +580,17 @@ public function findTypeAndMethodNames(): array
580580

581581
public function hasOffsetValueType(Type $offsetType): TrinaryLogic
582582
{
583-
$offsetType = $offsetType->toArrayKey();
583+
$offsetArrayKeyType = $offsetType->toArrayKey();
584+
585+
return $this->recursiveHasOffsetValueType($offsetArrayKeyType);
586+
}
587+
588+
private function recursiveHasOffsetValueType(Type $offsetType): TrinaryLogic
589+
{
584590
if ($offsetType instanceof UnionType) {
585591
$results = [];
586592
foreach ($offsetType->getTypes() as $innerType) {
587-
$results[] = $this->hasOffsetValueType($innerType);
593+
$results[] = $this->recursiveHasOffsetValueType($innerType);
588594
}
589595

590596
return TrinaryLogic::extremeIdentity(...$results);
@@ -594,7 +600,7 @@ public function hasOffsetValueType(Type $offsetType): TrinaryLogic
594600
if ($finiteTypes !== []) {
595601
$results = [];
596602
foreach ($finiteTypes as $innerType) {
597-
$results[] = $this->hasOffsetValueType($innerType);
603+
$results[] = $this->recursiveHasOffsetValueType($innerType);
598604
}
599605

600606
return TrinaryLogic::extremeIdentity(...$results);

src/Type/IntersectionType.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -1103,7 +1103,10 @@ public function toArray(): Type
11031103
public function toArrayKey(): Type
11041104
{
11051105
if ($this->isNumericString()->yes()) {
1106-
return new IntegerType();
1106+
return TypeCombinator::union(
1107+
new IntegerType(),
1108+
$this,
1109+
);
11071110
}
11081111

11091112
if ($this->isString()->yes()) {

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function doLorem(
5252
{
5353
$a = [];
5454
$a[$numericString] = 'foo';
55-
assertType('non-empty-array<int, \'foo\'>', $a);
55+
assertType('non-empty-array<int|numeric-string, \'foo\'>', $a);
5656
}
5757

5858
}
+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug8592;
4+
5+
use function PHPStan\Testing\assertType;
6+
7+
/**
8+
* @param array<numeric-string, mixed> $foo
9+
*/
10+
function foo(array $foo): void
11+
{
12+
foreach ($foo as $key => $value) {
13+
assertType('int|numeric-string', $key);
14+
}
15+
}

tests/PHPStan/Analyser/nsrt/isset-coalesce-empty-type.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ class Bug4671
296296
*/
297297
public function doFoo(int $intput, array $strings): void
298298
{
299-
assertType('false', isset($strings[(string) $intput]));
299+
assertType('bool', isset($strings[(string) $intput]));
300300
}
301301

302302
}

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,11 @@ public function testBug2634(): void
754754
$this->analyse([__DIR__ . '/data/bug-2634.php'], []);
755755
}
756756

757+
public function testBug11390(): void
758+
{
759+
$this->analyse([__DIR__ . '/data/bug-11390.php'], []);
760+
}
761+
757762
public function testInternalClassesWithOverloadedOffsetAccess(): void
758763
{
759764
$this->analyse([__DIR__ . '/data/internal-classes-overload-offset-access.php'], []);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug11390;
4+
5+
/**
6+
* @param array<array{
7+
* id: numeric-string,
8+
* tagName: string
9+
* }> $tags
10+
* @param numeric-string $tagId
11+
*/
12+
function printTagName(array $tags, string $tagId): void
13+
{
14+
// Adding the second `*` to either of the following lines makes the error disappear
15+
16+
$tagsById = array_combine(array_column($tags, 'id'), $tags);
17+
if (false !== $tagsById) {
18+
echo $tagsById[$tagId]['tagName'] . PHP_EOL;
19+
}
20+
}
21+
22+
printTagName(
23+
[
24+
['id' => '123', 'tagName' => 'abc'],
25+
['id' => '4.5', 'tagName' => 'def'],
26+
['id' => '6e78', 'tagName' => 'ghi']
27+
],
28+
'4.5'
29+
);

tests/PHPStan/Rules/Methods/ReturnTypeRuleTest.php

+10
Original file line numberDiff line numberDiff line change
@@ -1101,6 +1101,16 @@ public function testBug10653(): void
11011101
$this->analyse([__DIR__ . '/data/bug-10653.php'], []);
11021102
}
11031103

1104+
public function testBug4163(): void
1105+
{
1106+
$this->analyse([__DIR__ . '/data/bug-4163.php'], [
1107+
[
1108+
'Method Bug4163\HelloWorld::lall() should return array<string, string> but returns array<int|string, string>.',
1109+
28,
1110+
],
1111+
]);
1112+
}
1113+
11041114
public function testBug11663(): void
11051115
{
11061116
$this->analyse([__DIR__ . '/data/bug-11663.php'], []);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug4163;
4+
5+
class HelloWorld
6+
{
7+
/**
8+
* @phpstan-var numeric
9+
*/
10+
public $lall = 0;
11+
12+
/**
13+
* @phpstan-return array<string, string>
14+
*/
15+
function lall() {
16+
$helloCollection = [new HelloWorld(), new HelloWorld()];
17+
$result = [];
18+
19+
foreach ($helloCollection as $hello) {
20+
$key = (string)$hello->lall;
21+
22+
if (!isset($result[$key])) {
23+
$lall = 'do_something_here';
24+
$result[$key] = $lall;
25+
}
26+
}
27+
28+
return $result;
29+
}
30+
}

tests/PHPStan/Rules/Variables/IssetRuleTest.php

+1-4
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,7 @@ public function testBug4290(): void
230230
public function testBug4671(): void
231231
{
232232
$this->treatPhpDocTypesAsCertain = true;
233-
$this->analyse([__DIR__ . '/data/bug-4671.php'], [[
234-
'Offset numeric-string on array<string, string> in isset() does not exist.',
235-
13,
236-
]]);
233+
$this->analyse([__DIR__ . '/data/bug-4671.php'], []);
237234
}
238235

239236
public function testVariableCertaintyInIsset(): void

0 commit comments

Comments
 (0)