Skip to content

Commit a9ec174

Browse files
committed
Fix array dim fetches with treatPhpDocTypesAsCertain: false
1 parent 43fca8d commit a9ec174

File tree

3 files changed

+58
-0
lines changed

3 files changed

+58
-0
lines changed

src/Analyser/MutatingScope.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,17 @@ public function getNativeType(Expr $expr): Type
20392039
return $this->nativeExpressionTypes[$key];
20402040
}
20412041

2042+
if ($expr instanceof Expr\ArrayDimFetch && $expr->dim !== null) {
2043+
return $this->getNullsafeShortCircuitingType(
2044+
$expr->var,
2045+
$this->getTypeFromArrayDimFetch(
2046+
$expr,
2047+
$this->getNativeType($expr->dim),
2048+
$this->getNativeType($expr->var)
2049+
)
2050+
);
2051+
}
2052+
20422053
return $this->getType($expr);
20432054
}
20442055

tests/PHPStan/Analyser/NodeScopeResolverTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10347,6 +10347,11 @@ public function dataIncDecInConditions(): array
1034710347
return $this->gatherAssertTypes(__DIR__ . '/data/inc-dec-in-conditions.php');
1034810348
}
1034910349

10350+
public function dataBug4099(): array
10351+
{
10352+
return $this->gatherAssertTypes(__DIR__ . '/data/bug-4099.php');
10353+
}
10354+
1035010355
/**
1035110356
* @param string $file
1035210357
* @return array<string, mixed[]>
@@ -10529,6 +10534,7 @@ private function gatherAssertTypes(string $file): array
1052910534
* @dataProvider dataComparisonOperators
1053010535
* @dataProvider dataBug3880
1053110536
* @dataProvider dataIncDecInConditions
10537+
* @dataProvider dataBug4099
1053210538
* @param string $assertType
1053310539
* @param string $file
1053410540
* @param mixed ...$args
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Bug4099;
4+
5+
use function PHPStan\Analyser\assertNativeType;
6+
use function PHPStan\Analyser\assertType;
7+
8+
class Foo
9+
{
10+
11+
/**
12+
* @param array{key: array{inner: mixed}} $arr
13+
*/
14+
function arrayHint(array $arr): void
15+
{
16+
assertType('array(\'key\' => array(\'inner\' => mixed))', $arr);
17+
assertNativeType('array', $arr);
18+
19+
if (!array_key_exists('key', $arr)) {
20+
assertType('*NEVER*', $arr);
21+
assertNativeType('array', $arr);
22+
throw new \Exception('no key "key" found.');
23+
}
24+
assertType('array(\'key\' => array(\'inner\' => mixed))', $arr);
25+
assertNativeType('array&hasOffset(\'key\')', $arr);
26+
assertType('array(\'inner\' => mixed)', $arr['key']);
27+
assertNativeType('mixed', $arr['key']);
28+
29+
if (!array_key_exists('inner', $arr['key'])) {
30+
assertType('array(\'key\' => *NEVER*)', $arr);
31+
//assertNativeType('array(\'key\' => mixed)', $arr);
32+
assertType('*NEVER*', $arr['key']);
33+
//assertNativeType('mixed', $arr['key']);
34+
throw new \Exception('need key.inner');
35+
}
36+
37+
assertType('array(\'key\' => array(\'inner\' => mixed))', $arr);
38+
assertNativeType('array(\'key\' => array(\'inner\' => mixed))', $arr);
39+
}
40+
41+
}

0 commit comments

Comments
 (0)