diff --git a/src/Psalm/Checker/Statements/Expression/Fetch/ArrayFetchChecker.php b/src/Psalm/Checker/Statements/Expression/Fetch/ArrayFetchChecker.php index e7cc03cb5..61a3a5a5d 100644 --- a/src/Psalm/Checker/Statements/Expression/Fetch/ArrayFetchChecker.php +++ b/src/Psalm/Checker/Statements/Expression/Fetch/ArrayFetchChecker.php @@ -380,10 +380,12 @@ class ArrayFetchChecker $type->type_params[0] = $offset_type; } } elseif (!$type->type_params[0]->isEmpty()) { - if (!TypeChecker::isContainedBy( + if ((!TypeChecker::isContainedBy( $project_checker->codebase, $offset_type, - $type->type_params[0], + $type->type_params[0]->isMixed() + ? new Type\Union([ new TInt, new TString ]) + : $type->type_params[0], true, $offset_type->ignore_falsable_issues, $has_scalar_match, @@ -391,7 +393,8 @@ class ArrayFetchChecker $type_coerced_from_mixed, $to_string_cast, $type_coerced_from_scalar - ) && !$type_coerced_from_scalar + ) && !$type_coerced_from_scalar) + || $to_string_cast ) { $expected_offset_types[] = $type->type_params[0]->getId(); } else { diff --git a/tests/ArrayAccessTest.php b/tests/ArrayAccessTest.php index 79e2cfbf7..c12133bc7 100644 --- a/tests/ArrayAccessTest.php +++ b/tests/ArrayAccessTest.php @@ -149,6 +149,14 @@ class ArrayAccessTest extends TestCase 'assertions' => [], 'error_levels' => ['MixedArgument'], ], + 'mixedKeyMixedOffset' => [ + ' [], + 'error_levels' => ['MixedArgument', 'MixedArrayOffset', 'MissingParamType'], + ], ]; } @@ -250,6 +258,13 @@ class ArrayAccessTest extends TestCase }', 'error_message' => 'InvalidArrayOffset', ], + 'mixedKeyStdClassOffset' => [ + ' 'InvalidArrayOffset', + ], ]; } }