Skip to content

Commit c290ea1

Browse files
Avoid duplicates
1 parent 2417411 commit c290ea1

File tree

2 files changed

+20
-15
lines changed

2 files changed

+20
-15
lines changed

src/Rules/Arrays/NonexistentOffsetInArrayDimFetchCheck.php

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
use PHPStan\Rules\RuleLevelHelper;
1313
use PHPStan\Type\BenevolentUnionType;
1414
use PHPStan\Type\ErrorType;
15+
use PHPStan\Type\MixedType;
16+
use PHPStan\Type\NeverType;
1517
use PHPStan\Type\Type;
18+
use PHPStan\Type\TypeCombinator;
1619
use PHPStan\Type\TypeUtils;
1720
use PHPStan\Type\VerbosityLevel;
1821
use function count;
@@ -44,11 +47,21 @@ public function check(
4447
Type $dimType,
4548
): array
4649
{
50+
if ($dimType instanceof MixedType) {
51+
$dimToCheck = $dimType;
52+
} else {
53+
// Non allowed array keys are already reported by InvalidKeyInArrayItemRule
54+
$dimToCheck = TypeCombinator::intersect($dimType, AllowedArrayKeysTypes::getType());
55+
if ($dimToCheck instanceof NeverType) {
56+
return [];
57+
}
58+
}
59+
4760
$typeResult = $this->ruleLevelHelper->findTypeToCheck(
4861
$scope,
4962
NullsafeOperatorHelper::getNullsafeShortcircuitedExprRespectingScope($scope, $var),
5063
$unknownClassPattern,
51-
static fn (Type $type): bool => $type->hasOffsetValueType($dimType)->yes(),
64+
static fn (Type $type): bool => $type->hasOffsetValueType($dimToCheck)->yes(),
5265
);
5366
$type = $typeResult->getType();
5467
if ($type instanceof ErrorType) {
@@ -59,7 +72,7 @@ public function check(
5972
return [];
6073
}
6174

62-
if ($type->hasOffsetValueType($dimType)->no()) {
75+
if ($type->hasOffsetValueType($dimToCheck)->no()) {
6376
return [
6477
RuleErrorBuilder::message(sprintf('Offset %s does not exist on %s.', $dimType->describe(count($dimType->getConstantStrings()) > 0 ? VerbosityLevel::precise() : VerbosityLevel::value()), $type->describe(VerbosityLevel::value())))
6578
->identifier('offsetAccess.notFound')
@@ -81,23 +94,23 @@ public function check(
8194
$this->reportPossiblyNonexistentGeneralArrayOffset
8295
&& $innerType->isArray()->yes()
8396
&& !$innerType->isConstantArray()->yes()
84-
&& !$innerType->hasOffsetValueType($dimType)->yes()
97+
&& !$innerType->hasOffsetValueType($dimToCheck)->yes()
8598
) {
8699
$report = true;
87100
break;
88101
}
89102
if (
90103
$this->reportPossiblyNonexistentConstantArrayOffset
91104
&& $innerType->isConstantArray()->yes()
92-
&& !$innerType->hasOffsetValueType($dimType)->yes()
105+
&& !$innerType->hasOffsetValueType($dimToCheck)->yes()
93106
) {
94107
$report = true;
95108
break;
96109
}
97-
if ($dimType instanceof BenevolentUnionType) {
98-
$flattenedInnerTypes = [$dimType];
110+
if ($dimToCheck instanceof BenevolentUnionType) {
111+
$flattenedInnerTypes = [$dimToCheck];
99112
} else {
100-
$flattenedInnerTypes = TypeUtils::flattenTypes($dimType);
113+
$flattenedInnerTypes = TypeUtils::flattenTypes($dimToCheck);
101114
}
102115
foreach ($flattenedInnerTypes as $innerDimType) {
103116
if (

tests/PHPStan/Rules/Arrays/NonexistentOffsetInArrayDimFetchRuleTest.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,6 @@ public function testStrings(): void
193193
'Offset 12.34 does not exist on \'foo\'.',
194194
13,
195195
],
196-
[
197-
'Offset int|object might not exist on \'foo\'.',
198-
16,
199-
],
200196
[
201197
'Offset \'foo\' might not exist on array|string.',
202198
24,
@@ -205,10 +201,6 @@ public function testStrings(): void
205201
'Offset 12.34 might not exist on array|string.',
206202
28,
207203
],
208-
[
209-
'Offset int|object might not exist on array|string.',
210-
32,
211-
],
212204
]);
213205
}
214206

0 commit comments

Comments
 (0)