diff --git a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php index d1d387d4b..ecfec7205 100644 --- a/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php +++ b/src/Psalm/Internal/Analyzer/Statements/Block/ForeachAnalyzer.php @@ -629,6 +629,28 @@ class ForeachAnalyzer $has_valid_iterator = true; + if ($iterator_atomic_type instanceof Type\Atomic\TNamedObject + && strtolower($iterator_atomic_type->value) === 'simplexmlelement' + ) { + if ($value_type) { + $value_type = Type::combineUnionTypes( + $value_type, + new Type\Union([clone $iterator_atomic_type]) + ); + } else { + $value_type = new Type\Union([clone $iterator_atomic_type]); + } + + if ($key_type) { + $key_type = Type::combineUnionTypes( + $key_type, + Type::getString() + ); + } else { + $key_type = Type::getString(); + } + } + if ($iterator_atomic_type instanceof Type\Atomic\TIterable || (strtolower($iterator_atomic_type->value) === 'traversable' || $codebase->classImplements( diff --git a/tests/Loop/ForeachTest.php b/tests/Loop/ForeachTest.php index 37033b3f7..11e578fe3 100644 --- a/tests/Loop/ForeachTest.php +++ b/tests/Loop/ForeachTest.php @@ -961,6 +961,14 @@ class ForeachTest extends \Psalm\Tests\TestCase } }', ], + 'simpleXmlIterator' => [ + '