diff --git a/src/Analyser/MutatingScope.php b/src/Analyser/MutatingScope.php index f1dfb1f0da..d8b2f5524b 100644 --- a/src/Analyser/MutatingScope.php +++ b/src/Analyser/MutatingScope.php @@ -1043,7 +1043,24 @@ private function resolveType(string $exprString, Expr $node): Type && !$node instanceof Expr\ArrowFunction && $this->hasExpressionType($node)->yes() ) { - return $this->expressionTypes[$exprString]->getType(); + $type = $this->expressionTypes[$exprString]->getType(); + + if ($node instanceof Expr\ArrayDimFetch && $node->dim !== null) { + $dimType = $this->getType($node->dim); + if ($dimType->isConstantScalarValue()->yes()) { + $arrayType = $this->getType($node->var); + $offsetValueType = $arrayType->getOffsetValueType($dimType); + if ( + !$offsetValueType instanceof ErrorType + && $type->isSuperTypeOf($offsetValueType)->yes() + && !$offsetValueType->isSuperTypeOf($type)->yes() + ) { + $type = $offsetValueType; + } + } + } + + return $type; } /** @var ExprHandler $exprHandler */ diff --git a/tests/PHPStan/Analyser/nsrt/bug-11705.php b/tests/PHPStan/Analyser/nsrt/bug-11705.php new file mode 100644 index 0000000000..5e29e27fc0 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/bug-11705.php @@ -0,0 +1,31 @@ +} $theInput + * @param array $theTags + */ +function example(array $theInput, array $theTags): void +{ + foreach ($theTags as $tag) { + if (!array_key_exists($tag, $theInput)) { + continue; + } + switch ($tag) { + case 'name': + assertType("'name'", $tag); + assertType('string', $theInput[$tag]); + if ($tag === 'name') { + echo "Of course it is..."; + } + assertType("'name'", $tag); + assertType('string', $theInput[$tag]); + break; + default: + // fall out + } + } +}