From 708d9383325a623b49518be7c759b6fd480cc30c Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 11 Aug 2024 01:12:35 +0200 Subject: [PATCH] Fix array_intersect_key --- src/Type/ArrayType.php | 4 +-- .../Analyser/nsrt/array-intersect-key.php | 4 +-- .../IfConstantConditionRuleTest.php | 6 ++++ .../Rules/Comparison/data/bug-10561.php | 33 +++++++++++++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 tests/PHPStan/Rules/Comparison/data/bug-10561.php diff --git a/src/Type/ArrayType.php b/src/Type/ArrayType.php index c58bcf951a..6040f0ee06 100644 --- a/src/Type/ArrayType.php +++ b/src/Type/ArrayType.php @@ -541,9 +541,7 @@ public function intersectKeyArray(Type $otherArraysType): Type } if ($isKeySuperType->yes()) { - return $otherArraysType->isIterableAtLeastOnce()->yes() - ? TypeCombinator::intersect($this, new NonEmptyArrayType()) - : $this; + return $this; } return new self($otherArraysType->getIterableKeyType(), $this->getIterableValueType()); diff --git a/tests/PHPStan/Analyser/nsrt/array-intersect-key.php b/tests/PHPStan/Analyser/nsrt/array-intersect-key.php index 5d17736266..bf620b508b 100644 --- a/tests/PHPStan/Analyser/nsrt/array-intersect-key.php +++ b/tests/PHPStan/Analyser/nsrt/array-intersect-key.php @@ -15,9 +15,9 @@ class Foo public function nonEmpty(array $arr, array $arr2): void { assertType('non-empty-array', array_intersect_key($arr)); - assertType('non-empty-array', array_intersect_key($arr, $arr)); + assertType('array', array_intersect_key($arr, $arr)); assertType('array', array_intersect_key($arr, $arr2)); - assertType('non-empty-array', array_intersect_key($arr2, $arr)); + assertType('array', array_intersect_key($arr2, $arr)); assertType('array{}', array_intersect_key($arr, [])); assertType("array<'foo', string>", array_intersect_key($arr, ['foo' => 17])); } diff --git a/tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php b/tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php index 979af0dc12..a7c2629d16 100644 --- a/tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/IfConstantConditionRuleTest.php @@ -162,4 +162,10 @@ public function testBug2499(): void $this->analyse([__DIR__ . '/data/bug-2499.php'], []); } + public function testBug10561(): void + { + $this->treatPhpDocTypesAsCertain = true; + $this->analyse([__DIR__ . '/data/bug-10561.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-10561.php b/tests/PHPStan/Rules/Comparison/data/bug-10561.php new file mode 100644 index 0000000000..71f7bf9d4c --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-10561.php @@ -0,0 +1,33 @@ + $inner_arr1 */ + $inner_arr1 = $arr1['inner_arr']; + /** @var array $inner_arr2 */ + $inner_arr2 = $arr2['inner_arr']; + + if (!$inner_arr1) { + return; + } + if (!$inner_arr2) { + return; + } + + $arr_intersect = array_intersect_key($inner_arr1, $inner_arr2); + if ($arr_intersect) { + echo "not empty\n"; + } else { + echo "empty\n"; + } +} + +$arr1 = ['inner_arr' => ['a' => 'b']]; +$arr2 = ['inner_arr' => ['c' => 'd']]; +func($arr1, $arr2); // Outputs "empty"