diff --git a/config.xsd b/config.xsd index b6fccc015..c3b111fb4 100644 --- a/config.xsd +++ b/config.xsd @@ -139,6 +139,7 @@ + @@ -150,6 +151,7 @@ + diff --git a/src/Psalm/Checker/Statements/Block/ForeachChecker.php b/src/Psalm/Checker/Statements/Block/ForeachChecker.php index fd18cc7d7..aac0a9e66 100644 --- a/src/Psalm/Checker/Statements/Block/ForeachChecker.php +++ b/src/Psalm/Checker/Statements/Block/ForeachChecker.php @@ -13,6 +13,9 @@ use Psalm\CodeLocation; use Psalm\Context; use Psalm\Issue\InvalidIterator; use Psalm\IssueBuffer; +use Psalm\Issue\NullIterator; +use Psalm\Issue\NullReference; +use Psalm\Issue\PossiblyNullIterator; use Psalm\Type; class ForeachChecker @@ -54,12 +57,38 @@ class ForeachChecker } if ($iterator_type) { + if ($iterator_type->isNull()) { + if (IssueBuffer::accepts( + new NullIterator( + 'Cannot iterate over null', + new CodeLocation($statements_checker->getSource(), $stmt->expr) + ), + $statements_checker->getSuppressedIssues() + )) { + return false; + } + } elseif ($iterator_type->isNullable() && !$iterator_type->ignore_nullable_issues) { + if (IssueBuffer::accepts( + new PossiblyNullIterator( + 'Cannot iterate over nullable var ' . $iterator_type, + new CodeLocation($statements_checker->getSource(), $stmt->expr) + ), + $statements_checker->getSuppressedIssues() + )) { + return false; + } + } + foreach ($iterator_type->types as $iterator_type) { // if it's an empty array, we cannot iterate over it if ((string) $iterator_type === 'array') { continue; } + if ($iterator_type instanceof Type\Atomic\TNull) { + continue; + } + if ($iterator_type instanceof Type\Atomic\TArray) { if (!$value_type) { $value_type = $iterator_type->type_params[1]; @@ -78,7 +107,6 @@ class ForeachChecker } if ($iterator_type instanceof Type\Atomic\Scalar || - $iterator_type instanceof Type\Atomic\TNull || $iterator_type instanceof Type\Atomic\TVoid ) { if (IssueBuffer::accepts( diff --git a/src/Psalm/Issue/NullIterator.php b/src/Psalm/Issue/NullIterator.php new file mode 100644 index 000000000..0eda60471 --- /dev/null +++ b/src/Psalm/Issue/NullIterator.php @@ -0,0 +1,6 @@ +