diff --git a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php index 2ecd14aaf..d8a11d59c 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Expression/ArrayAnalyzer.php @@ -126,14 +126,17 @@ class ArrayAnalyzer } if ($item_key_type) { + $bad_types = []; + $good_types = []; + foreach ($item_key_type->getAtomicTypes() as $atomic_key_type) { - if (!$atomic_key_type instanceof Type\Atomic\TString && - !$atomic_key_type instanceof Type\Atomic\TInt && - !$atomic_key_type instanceof Type\Atomic\TArrayKey && - !$atomic_key_type instanceof Type\Atomic\TMixed && - !( - $atomic_key_type instanceof Type\Atomic\TObjectWithProperties && - isset($atomic_key_type->methods['__toString']) + if (!$atomic_key_type instanceof Type\Atomic\TString + && !$atomic_key_type instanceof Type\Atomic\TInt + && !$atomic_key_type instanceof Type\Atomic\TArrayKey + && !$atomic_key_type instanceof Type\Atomic\TMixed + && !( + $atomic_key_type instanceof Type\Atomic\TObjectWithProperties + && isset($atomic_key_type->methods['__toString']) ) ) { if (IssueBuffer::accepts( @@ -143,10 +146,30 @@ class ArrayAnalyzer ), $statements_analyzer->getSuppressedIssues() )) { - $item_key_type = Type::getArrayKey(); + $bad_types[] = $atomic_key_type; + + if ($atomic_key_type instanceof Type\Atomic\TFalse) { + $good_types[] = new Type\Atomic\TLiteralInt(0); + } elseif ($atomic_key_type instanceof Type\Atomic\TTrue) { + $good_types[] = new Type\Atomic\TLiteralInt(1); + } elseif ($atomic_key_type instanceof Type\Atomic\TBool) { + $good_types[] = new Type\Atomic\TLiteralInt(0); + $good_types[] = new Type\Atomic\TLiteralInt(1); + } elseif ($atomic_key_type instanceof Type\Atomic\TFloat) { + $good_types[] = new Type\Atomic\TInt; + } else { + $good_types[] = new Type\Atomic\TArrayKey; + } } } } + + if ($bad_types && $good_types) { + $item_key_type->substitute( + TypeCombiner::combine($bad_types, $codebase), + TypeCombiner::combine($good_types, $codebase) + ); + } } $array_type = new Type\Atomic\TNonEmptyArray([