diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php index 1e76ec575..40d369e43 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/Fetch/ArrayFetchAnalyzer.php @@ -797,9 +797,16 @@ class ArrayFetchAnalyzer $statements_analyzer ); } + $has_valid_offset = true; + } elseif (count($key_values) === 1 + && is_int($key_values[0]) + && $key_values[0] < 0 + ) { + $expected_offset_types[] = Type::getPositiveInt(); + $has_valid_offset = false; + } else { + $has_valid_offset = true; } - - $has_valid_offset = true; } if ($in_assignment && $type instanceof Type\Atomic\TNonEmptyList && $type->count !== null) { diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index 6d2610e98..4133858a8 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -1270,6 +1270,19 @@ class ArrayAccessTest extends TestCase [$width, $height, $depth] = size();', 'error_message' => 'InvalidArrayOffset', ], + 'negativeListAccess' => [ + ' 'InvalidArrayOffset' + ] ]; } }