Skip to content

Commit 46a8f32

Browse files
committed
Narrow $data[$key] after specifying $key
1 parent f3c3b44 commit 46a8f32

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

src/Analyser/MutatingScope.php

+32-1
Original file line numberDiff line numberDiff line change
@@ -3511,14 +3511,45 @@ private function specifyExpressionType(Expr $expr, Type $type, ?Type $nativeType
35113511
$conditionalExpressions[$conditionalExprString] = $holders;
35123512
}
35133513

3514+
$moreSpecificTypeHolders = $this->moreSpecificTypes;
3515+
foreach ($moreSpecificTypeHolders as $specifiedExprString => $specificTypeHolder) {
3516+
if (!$specificTypeHolder->getCertainty()->yes()) {
3517+
continue;
3518+
}
3519+
3520+
$specifiedExprString = (string) $specifiedExprString;
3521+
$specifiedExpr = $this->exprStringToExpr($specifiedExprString);
3522+
if ($specifiedExpr === null) {
3523+
continue;
3524+
}
3525+
if (!$specifiedExpr instanceof Expr\ArrayDimFetch) {
3526+
continue;
3527+
}
3528+
3529+
if (!$specifiedExpr->dim instanceof Variable) {
3530+
continue;
3531+
}
3532+
3533+
if (!is_string($specifiedExpr->dim->name)) {
3534+
continue;
3535+
}
3536+
3537+
if ($specifiedExpr->dim->name !== $variableName) {
3538+
continue;
3539+
}
3540+
3541+
$moreSpecificTypeHolders[$specifiedExprString] = VariableTypeHolder::createYes($this->getType($specifiedExpr->var)->getOffsetValueType($type));
3542+
unset($nativeTypes[$specifiedExprString]);
3543+
}
3544+
35143545
return $this->scopeFactory->create(
35153546
$this->context,
35163547
$this->isDeclareStrictTypes(),
35173548
$this->constantTypes,
35183549
$this->getFunction(),
35193550
$this->getNamespace(),
35203551
$variableTypes,
3521-
$this->moreSpecificTypes,
3552+
$moreSpecificTypeHolders,
35223553
$conditionalExpressions,
35233554
$this->inClosureBindScopeClass,
35243555
$this->anonymousFunctionReflection,

tests/PHPStan/Analyser/NodeScopeResolverTest.php

+1
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,7 @@ public function dataFileAsserts(): iterable
980980
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7788.php');
981981
yield from $this->gatherAssertTypes(__DIR__ . '/data/bug-7809.php');
982982
yield from $this->gatherAssertTypes(__DIR__ . '/data/composer-non-empty-array-after-unset.php');
983+
yield from $this->gatherAssertTypes(__DIR__ . '/../Rules/Arrays/data/bug-6000.php');
983984
}
984985

985986
/**

tests/PHPStan/Rules/Arrays/data/bug-6000.php

+4
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
namespace Bug6000;
44

5+
use function PHPStan\Testing\assertType;
6+
57
function (): void {
68
/** @var array{psr-4?: array<string, string|string[]>, classmap?: list<string>} $data */
79
$data = [];
810

911
foreach ($data as $key => $value) {
12+
assertType('array<int|string, array<string>|string>', $data[$key]);
1013
if ($key === 'classmap') {
14+
assertType('array<int, string>', $data[$key]);
1115
echo implode(', ', $value); // not working :(
1216
echo implode(', ', $data[$key]); // this works though?!
1317
}

tests/PHPStan/Rules/Functions/ImplodeFunctionRuleTest.php

+1-7
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,7 @@ public function testFile(): void
5050

5151
public function testBug6000(): void
5252
{
53-
$this->analyse([__DIR__ . '/../Arrays/data/bug-6000.php'], [
54-
[
55-
// shouldn't be happening...
56-
'Parameter #2 $array of function implode expects array<string>, array<int|string, array<string>|string> given.',
57-
12,
58-
],
59-
]);
53+
$this->analyse([__DIR__ . '/../Arrays/data/bug-6000.php'], []);
6054
}
6155

6256
}

0 commit comments

Comments
 (0)