diff --git a/src/Mutator/Removal/ArrayItemRemoval.php b/src/Mutator/Removal/ArrayItemRemoval.php index 7d24f9101..a23225f10 100644 --- a/src/Mutator/Removal/ArrayItemRemoval.php +++ b/src/Mutator/Removal/ArrayItemRemoval.php @@ -46,7 +46,6 @@ use PhpParser\Node; use PhpParser\Node\Expr\ArrayItem; use function range; -use Webmozart\Assert\Assert; /** * @internal @@ -116,8 +115,6 @@ public static function getDefinition(): ?Definition */ public function mutate(Node $node): iterable { - Assert::allNotNull($node->items); - foreach ($this->getItemsIndexes($node->items) as $indexToRemove) { $newArrayNode = clone $node; unset($newArrayNode->items[$indexToRemove]); @@ -147,13 +144,18 @@ public function canMutate(Node $node): bool return false; } + // Don't mutate destructured values in foreach loops + if ($parent instanceof Node\Stmt\Foreach_ && $parent->valueVar === $node) { + return false; + } + return true; } /** * @psalm-mutation-free * - * @param ArrayItem[] $items + * @param array $items * * @return int[] */ diff --git a/tests/phpunit/Mutator/Removal/ArrayItemRemovalTest.php b/tests/phpunit/Mutator/Removal/ArrayItemRemovalTest.php index 5801f604a..d560b4461 100644 --- a/tests/phpunit/Mutator/Removal/ArrayItemRemovalTest.php +++ b/tests/phpunit/Mutator/Removal/ArrayItemRemovalTest.php @@ -122,5 +122,9 @@ public function mutationsProvider(): iterable yield 'It does not mutate arrays as an attribute argument' => [ MutatorFixturesProvider::getFixtureFileContent($this, 'does-not-mutate-array-in-attribute.php'), ]; + + yield 'It does not mutate destructured array values in foreach loops' => [ + '