From ba154ee82f48a3d43bccf97e80dd02b16ad30c69 Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Tue, 4 Feb 2025 10:55:50 +0100 Subject: [PATCH 1/5] Add generic typings to array_uintersect --- stubs/arrayFunctions.stub | 12 ++++++ .../CallToFunctionParametersRuleTest.php | 26 +++++++++++++ .../Rules/Functions/data/array_uintersect.php | 39 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/PHPStan/Rules/Functions/data/array_uintersect.php diff --git a/stubs/arrayFunctions.stub b/stubs/arrayFunctions.stub index 9b29ddff0b..0aa353042b 100644 --- a/stubs/arrayFunctions.stub +++ b/stubs/arrayFunctions.stub @@ -70,6 +70,18 @@ function array_udiff( callable $three ): int {} +/** + * @template T + * @param array $one + * @param array $two + * @param callable(T, T): int $three + */ +function array_uintersect( + array $one, + array $two, + callable $three +): int {} + /** * @param array $value * @return ($value is list ? true : false) diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index 4eb95d8449..b48bd016e2 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -663,6 +663,32 @@ public function testArrayUdiffCallback(): void ]); } + public function testArrayUintersectCallback(): void + { + $this->analyse([__DIR__ . '/data/array_uintersect.php'], [ + [ + 'Parameter #3 $data_compare_func of function array_uintersect expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(string, string): string given.', + 6, + ], + [ + 'Parameter #3 $data_compare_func of function array_uintersect expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(int, int): (literal-string&lowercase-string&non-falsy-string&numeric-string&uppercase-string) given.', + 14, + ], + [ + 'Parameter #1 $arr1 of function array_uintersect expects array, null given.', + 20, + ], + [ + 'Parameter #2 $arr2 of function array_uintersect expects array, null given.', + 21, + ], + [ + 'Parameter #3 $data_compare_func of function array_uintersect expects callable(string, string): int, Closure(string, int): non-empty-string given.', + 22, + ], + ]); + } + public function testPregReplaceCallback(): void { $this->analyse([__DIR__ . '/data/preg_replace_callback.php'], [ diff --git a/tests/PHPStan/Rules/Functions/data/array_uintersect.php b/tests/PHPStan/Rules/Functions/data/array_uintersect.php new file mode 100644 index 0000000000..f3d8b74834 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/array_uintersect.php @@ -0,0 +1,39 @@ + $b; + }, +); + +array_uintersect( + ["25","26"], + ["26","27"], + 'strcasecmp', +); From c0f7d1d5793d8b33ee6030f0dd7c2959e5762c0c Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Tue, 4 Feb 2025 15:00:37 +0100 Subject: [PATCH 2/5] Allow comparisons between arrays of different types --- stubs/arrayFunctions.stub | 13 +++++++------ .../CallToFunctionParametersRuleTest.php | 16 ++++++++-------- .../PHPStan/Rules/Functions/data/array_udiff.php | 8 ++++++++ .../Rules/Functions/data/array_uintersect.php | 8 ++++++++ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/stubs/arrayFunctions.stub b/stubs/arrayFunctions.stub index 0aa353042b..d2d37e4edf 100644 --- a/stubs/arrayFunctions.stub +++ b/stubs/arrayFunctions.stub @@ -58,11 +58,11 @@ function uksort(array &$array, callable $callback): bool } /** - * @template T of mixed - * + * @template T + * @template U * @param array $one - * @param array $two - * @param callable(T, T): int $three + * @param array $two + * @param callable(T, U): int $three */ function array_udiff( array $one, @@ -72,9 +72,10 @@ function array_udiff( /** * @template T + * @template U * @param array $one - * @param array $two - * @param callable(T, T): int $three + * @param array $two + * @param callable(T, U): int $three */ function array_uintersect( array $one, diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index b48bd016e2..348fa5bffe 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -641,11 +641,11 @@ public function testArrayUdiffCallback(): void { $this->analyse([__DIR__ . '/data/array_udiff.php'], [ [ - 'Parameter #3 $data_comp_func of function array_udiff expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(string, string): string given.', + 'Parameter #3 $data_comp_func of function array_udiff expects callable(1|2|3, 4|5|6): int, Closure(string, string): string given.', 6, ], [ - 'Parameter #3 $data_comp_func of function array_udiff expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(int, int): (literal-string&lowercase-string&non-falsy-string&numeric-string&uppercase-string) given.', + "Parameter #3 \$data_comp_func of function array_udiff expects callable(1|2|3, 4|5|6): int, Closure(int, int): ('14'|'15'|'16'|'24'|'25'|'26'|'34'|'35'|'36') given.", 14, ], [ @@ -653,11 +653,11 @@ public function testArrayUdiffCallback(): void 20, ], [ - 'Parameter #2 $arr2 of function array_udiff expects array, null given.', + 'Parameter #2 $arr2 of function array_udiff expects array, null given.', 21, ], [ - 'Parameter #3 $data_comp_func of function array_udiff expects callable(string, string): int, Closure(string, int): non-empty-string given.', + 'Parameter #3 $data_comp_func of function array_udiff expects callable(string, int): int, Closure(string, int): non-empty-string given.', 22, ], ]); @@ -667,11 +667,11 @@ public function testArrayUintersectCallback(): void { $this->analyse([__DIR__ . '/data/array_uintersect.php'], [ [ - 'Parameter #3 $data_compare_func of function array_uintersect expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(string, string): string given.', + 'Parameter #3 $data_compare_func of function array_uintersect expects callable(1|2|3, 4|5|6): int, Closure(string, string): string given.', 6, ], [ - 'Parameter #3 $data_compare_func of function array_uintersect expects callable(1|2|3|4|5|6, 1|2|3|4|5|6): int, Closure(int, int): (literal-string&lowercase-string&non-falsy-string&numeric-string&uppercase-string) given.', + "Parameter #3 \$data_compare_func of function array_uintersect expects callable(1|2|3, 4|5|6): int, Closure(int, int): ('14'|'15'|'16'|'24'|'25'|'26'|'34'|'35'|'36') given.", 14, ], [ @@ -679,11 +679,11 @@ public function testArrayUintersectCallback(): void 20, ], [ - 'Parameter #2 $arr2 of function array_uintersect expects array, null given.', + 'Parameter #2 $arr2 of function array_uintersect expects array, null given.', 21, ], [ - 'Parameter #3 $data_compare_func of function array_uintersect expects callable(string, string): int, Closure(string, int): non-empty-string given.', + 'Parameter #3 $data_compare_func of function array_uintersect expects callable(string, int): int, Closure(string, int): non-empty-string given.', 22, ], ]); diff --git a/tests/PHPStan/Rules/Functions/data/array_udiff.php b/tests/PHPStan/Rules/Functions/data/array_udiff.php index 23af63ccef..06b1d4c179 100644 --- a/tests/PHPStan/Rules/Functions/data/array_udiff.php +++ b/tests/PHPStan/Rules/Functions/data/array_udiff.php @@ -37,3 +37,11 @@ static function(int $a, int $b): int { ["26","27"], 'strcasecmp', ); + +array_udiff( + [100, 200, 300], + ['200', '300', '400'], + function(int $a, string $b): int { + return (string) $a <=> $b; + }, +); diff --git a/tests/PHPStan/Rules/Functions/data/array_uintersect.php b/tests/PHPStan/Rules/Functions/data/array_uintersect.php index f3d8b74834..047c7585b5 100644 --- a/tests/PHPStan/Rules/Functions/data/array_uintersect.php +++ b/tests/PHPStan/Rules/Functions/data/array_uintersect.php @@ -37,3 +37,11 @@ static function(int $a, int $b): int { ["26","27"], 'strcasecmp', ); + +array_uintersect( + [100, 200, 300], + ['200', '300', '400'], + function(int $a, string $b): int { + return (string) $a <=> $b; + }, +); From dc87eb0f59494a07b43ada2da03b76bb50f34d5c Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Tue, 25 Feb 2025 19:00:33 +0100 Subject: [PATCH 3/5] (WIP) --- ...gumentBasedFunctionReturnTypeExtension.php | 2 - stubs/arrayFunctions.stub | 26 +++---- tests/PHPStan/Analyser/nsrt/array_udiff.php | 71 +++++++++++++++++++ .../Analyser/nsrt/array_uintersect.php | 71 +++++++++++++++++++ 4 files changed, 156 insertions(+), 14 deletions(-) create mode 100644 tests/PHPStan/Analyser/nsrt/array_udiff.php create mode 100644 tests/PHPStan/Analyser/nsrt/array_uintersect.php diff --git a/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php b/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php index 6e3c75b9a1..4579041f70 100644 --- a/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php +++ b/src/Type/Php/ArgumentBasedFunctionReturnTypeExtension.php @@ -25,14 +25,12 @@ final class ArgumentBasedFunctionReturnTypeExtension implements DynamicFunctionR 'array_diff' => 0, 'array_udiff_assoc' => 0, 'array_udiff_uassoc' => 0, - 'array_udiff' => 0, 'array_intersect_assoc' => 0, 'array_intersect_uassoc' => 0, 'array_intersect_ukey' => 0, 'array_intersect' => 0, 'array_uintersect_assoc' => 0, 'array_uintersect_uassoc' => 0, - 'array_uintersect' => 0, ]; public function isFunctionSupported(FunctionReflection $functionReflection): bool diff --git a/stubs/arrayFunctions.stub b/stubs/arrayFunctions.stub index d2d37e4edf..ed826ba627 100644 --- a/stubs/arrayFunctions.stub +++ b/stubs/arrayFunctions.stub @@ -58,30 +58,32 @@ function uksort(array &$array, callable $callback): bool } /** - * @template T - * @template U - * @param array $one - * @param array $two - * @param callable(T, U): int $three + * @template T of array + * @template U of array + * @param T $one + * @param U $two + * @param callable(value-of, value-of): int $three + * @return array, value-of> */ function array_udiff( array $one, array $two, callable $three -): int {} +): array {} /** - * @template T - * @template U - * @param array $one - * @param array $two - * @param callable(T, U): int $three + * @template T of array + * @template U of array + * @param T $one + * @param U $two + * @param callable(value-of, value-of): int $three + * @return array, value-of> */ function array_uintersect( array $one, array $two, callable $three -): int {} +): array {} /** * @param array $value diff --git a/tests/PHPStan/Analyser/nsrt/array_udiff.php b/tests/PHPStan/Analyser/nsrt/array_udiff.php new file mode 100644 index 0000000000..7f82671558 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/array_udiff.php @@ -0,0 +1,71 @@ + $array1 + * @param array $array2 + * @param array $array3 + * @param list $list + * @param non-empty-array $nonEmptyArray + */ +function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray): void +{ + assertType('array', array_udiff($array1, $array2, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('string', $b); + + return strcasecmp((string) $a, $b); + })); + + assertType('array', array_udiff($array2, $array1, static function (mixed $a, mixed $b) { + assertType('string', $a); + assertType('int', $b); + + return strcasecmp($a, (string) $b); + })); + + assertType('array', array_udiff($array1, $array3, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_udiff($array3, $array1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_udiff($array1, $list, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('string', $b); + + return strcasecmp((string) $a, $b); + })); + + assertType('array', array_udiff($list, $array1, static function (mixed $a, mixed $b) { + assertType('string', $a); + assertType('int', $b); + + return strcasecmp($a, (string) $b); + })); + + assertType('array', array_udiff($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_udiff($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); +} diff --git a/tests/PHPStan/Analyser/nsrt/array_uintersect.php b/tests/PHPStan/Analyser/nsrt/array_uintersect.php new file mode 100644 index 0000000000..45a4b93467 --- /dev/null +++ b/tests/PHPStan/Analyser/nsrt/array_uintersect.php @@ -0,0 +1,71 @@ + $array1 + * @param array $array2 + * @param array $array3 + * @param list $list + * @param non-empty-array $nonEmptyArray + */ +function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray): void +{ + assertType('array', array_uintersect($array1, $array2, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('string', $b); + + return strcasecmp((string) $a, $b); + })); + + assertType('array', array_uintersect($array2, $array1, static function (mixed $a, mixed $b) { + assertType('string', $a); + assertType('int', $b); + + return strcasecmp($a, (string) $b); + })); + + assertType('array', array_uintersect($array1, $array3, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_uintersect($array3, $array1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_uintersect($array1, $list, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('string', $b); + + return strcasecmp((string) $a, $b); + })); + + assertType('array', array_uintersect($list, $array1, static function (mixed $a, mixed $b) { + assertType('string', $a); + assertType('int', $b); + + return strcasecmp($a, (string) $b); + })); + + assertType('array', array_uintersect($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType('array', array_uintersect($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int', $b); + + return $a <=> $b; + })); +} From ce77fbfe57260b630169c4a54b1972f620b22a6d Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Tue, 25 Feb 2025 19:00:56 +0100 Subject: [PATCH 4/5] Add failing tests --- tests/PHPStan/Analyser/nsrt/array_udiff.php | 25 ++++++++++++++++++- .../Analyser/nsrt/array_uintersect.php | 25 ++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/tests/PHPStan/Analyser/nsrt/array_udiff.php b/tests/PHPStan/Analyser/nsrt/array_udiff.php index 7f82671558..505a748b5c 100644 --- a/tests/PHPStan/Analyser/nsrt/array_udiff.php +++ b/tests/PHPStan/Analyser/nsrt/array_udiff.php @@ -10,8 +10,10 @@ * @param array $array3 * @param list $list * @param non-empty-array $nonEmptyArray + * @param array{foo: string, 0?: int} $arrayShape1 + * @param array{foo: string, bar?: int} $arrayShape2 */ -function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray): void +function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray, array $arrayShape1, array $arrayShape2): void { assertType('array', array_udiff($array1, $array2, static function (mixed $a, mixed $b) { assertType('int', $a); @@ -68,4 +70,25 @@ function test(array $array1, array $array2, array $array3, array $list, array $n return $a <=> $b; })); + + assertType('array', array_udiff($array1, $arrayShape1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int|string', $b); + + return $a <=> $b; + })); + + assertType("array<'foo'|0, int|string>", array_udiff($arrayShape1, $array1, static function (mixed $a, mixed $b) { + assertType('int|string', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType("array<'bar'|'foo', string>", array_udiff($arrayShape2, $array1, static function (mixed $a, mixed $b) { + assertType('int|string', $a); + assertType('int', $b); + + return $a <=> $b; + })); } diff --git a/tests/PHPStan/Analyser/nsrt/array_uintersect.php b/tests/PHPStan/Analyser/nsrt/array_uintersect.php index 45a4b93467..7d0ff1b7fd 100644 --- a/tests/PHPStan/Analyser/nsrt/array_uintersect.php +++ b/tests/PHPStan/Analyser/nsrt/array_uintersect.php @@ -10,8 +10,10 @@ * @param array $array3 * @param list $list * @param non-empty-array $nonEmptyArray + * @param array{foo: string, 0?: int} $arrayShape1 + * @param array{foo: string, bar?: int} $arrayShape2 */ -function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray): void +function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray, array $arrayShape1, array $arrayShape2): void { assertType('array', array_uintersect($array1, $array2, static function (mixed $a, mixed $b) { assertType('int', $a); @@ -68,4 +70,25 @@ function test(array $array1, array $array2, array $array3, array $list, array $n return $a <=> $b; })); + + assertType('array', array_uintersect($array1, $arrayShape1, static function (mixed $a, mixed $b) { + assertType('int', $a); + assertType('int|string', $b); + + return $a <=> $b; + })); + + assertType("array<'foo'|0, int|string>", array_uintersect($arrayShape1, $array1, static function (mixed $a, mixed $b) { + assertType('int|string', $a); + assertType('int', $b); + + return $a <=> $b; + })); + + assertType("array<'bar'|'foo', string>", array_uintersect($arrayShape2, $array1, static function (mixed $a, mixed $b) { + assertType('int|string', $a); + assertType('int', $b); + + return $a <=> $b; + })); } From bfeb553e03a59a3eaf2d62630b8fb5393c9c331c Mon Sep 17 00:00:00 2001 From: Choraimy Kroonstuiver <3661474+axlon@users.noreply.github.com> Date: Tue, 25 Feb 2025 19:57:29 +0100 Subject: [PATCH 5/5] Fix failing tests --- stubs/arrayFunctions.stub | 26 ++++++++++--------- tests/PHPStan/Analyser/nsrt/array_udiff.php | 20 +++++++------- .../Analyser/nsrt/array_uintersect.php | 20 +++++++------- .../CallToFunctionParametersRuleTest.php | 4 +-- 4 files changed, 36 insertions(+), 34 deletions(-) diff --git a/stubs/arrayFunctions.stub b/stubs/arrayFunctions.stub index ed826ba627..670bf00d68 100644 --- a/stubs/arrayFunctions.stub +++ b/stubs/arrayFunctions.stub @@ -58,12 +58,13 @@ function uksort(array &$array, callable $callback): bool } /** - * @template T of array - * @template U of array - * @param T $one - * @param U $two - * @param callable(value-of, value-of): int $three - * @return array, value-of> + * @template TKey of array-key + * @template TValue + * @template UValue + * @param array $one + * @param array $two + * @param callable(TValue, UValue): int $three + * @return array */ function array_udiff( array $one, @@ -72,12 +73,13 @@ function array_udiff( ): array {} /** - * @template T of array - * @template U of array - * @param T $one - * @param U $two - * @param callable(value-of, value-of): int $three - * @return array, value-of> + * @template TKey of array-key + * @template TValue + * @template UValue + * @param array $one + * @param array $two + * @param callable(TValue, UValue): int $three + * @return array */ function array_uintersect( array $one, diff --git a/tests/PHPStan/Analyser/nsrt/array_udiff.php b/tests/PHPStan/Analyser/nsrt/array_udiff.php index 505a748b5c..389e214a92 100644 --- a/tests/PHPStan/Analyser/nsrt/array_udiff.php +++ b/tests/PHPStan/Analyser/nsrt/array_udiff.php @@ -15,21 +15,21 @@ */ function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray, array $arrayShape1, array $arrayShape2): void { - assertType('array', array_udiff($array1, $array2, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array1, $array2, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('string', $b); return strcasecmp((string) $a, $b); })); - assertType('array', array_udiff($array2, $array1, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array2, $array1, static function (mixed $a, mixed $b) { assertType('string', $a); assertType('int', $b); return strcasecmp($a, (string) $b); })); - assertType('array', array_udiff($array1, $array3, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array1, $array3, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); @@ -43,49 +43,49 @@ function test(array $array1, array $array2, array $array3, array $list, array $n return $a <=> $b; })); - assertType('array', array_udiff($array1, $list, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array1, $list, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('string', $b); return strcasecmp((string) $a, $b); })); - assertType('array', array_udiff($list, $array1, static function (mixed $a, mixed $b) { + assertType('array, string>', array_udiff($list, $array1, static function (mixed $a, mixed $b) { assertType('string', $a); assertType('int', $b); return strcasecmp($a, (string) $b); })); - assertType('array', array_udiff($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); return $a <=> $b; })); - assertType('array', array_udiff($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); return $a <=> $b; })); - assertType('array', array_udiff($array1, $arrayShape1, static function (mixed $a, mixed $b) { + assertType('array', array_udiff($array1, $arrayShape1, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int|string', $b); return $a <=> $b; })); - assertType("array<'foo'|0, int|string>", array_udiff($arrayShape1, $array1, static function (mixed $a, mixed $b) { + assertType("array<0|'foo', int|string>", array_udiff($arrayShape1, $array1, static function (mixed $a, mixed $b) { assertType('int|string', $a); assertType('int', $b); return $a <=> $b; })); - assertType("array<'bar'|'foo', string>", array_udiff($arrayShape2, $array1, static function (mixed $a, mixed $b) { + assertType("array<'bar'|'foo', int|string>", array_udiff($arrayShape2, $array1, static function (mixed $a, mixed $b) { assertType('int|string', $a); assertType('int', $b); diff --git a/tests/PHPStan/Analyser/nsrt/array_uintersect.php b/tests/PHPStan/Analyser/nsrt/array_uintersect.php index 7d0ff1b7fd..aec27b814e 100644 --- a/tests/PHPStan/Analyser/nsrt/array_uintersect.php +++ b/tests/PHPStan/Analyser/nsrt/array_uintersect.php @@ -15,21 +15,21 @@ */ function test(array $array1, array $array2, array $array3, array $list, array $nonEmptyArray, array $arrayShape1, array $arrayShape2): void { - assertType('array', array_uintersect($array1, $array2, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array1, $array2, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('string', $b); return strcasecmp((string) $a, $b); })); - assertType('array', array_uintersect($array2, $array1, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array2, $array1, static function (mixed $a, mixed $b) { assertType('string', $a); assertType('int', $b); return strcasecmp($a, (string) $b); })); - assertType('array', array_uintersect($array1, $array3, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array1, $array3, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); @@ -43,49 +43,49 @@ function test(array $array1, array $array2, array $array3, array $list, array $n return $a <=> $b; })); - assertType('array', array_uintersect($array1, $list, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array1, $list, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('string', $b); return strcasecmp((string) $a, $b); })); - assertType('array', array_uintersect($list, $array1, static function (mixed $a, mixed $b) { + assertType('array, string>', array_uintersect($list, $array1, static function (mixed $a, mixed $b) { assertType('string', $a); assertType('int', $b); return strcasecmp($a, (string) $b); })); - assertType('array', array_uintersect($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($nonEmptyArray, $array1, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); return $a <=> $b; })); - assertType('array', array_uintersect($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array1, $nonEmptyArray, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int', $b); return $a <=> $b; })); - assertType('array', array_uintersect($array1, $arrayShape1, static function (mixed $a, mixed $b) { + assertType('array', array_uintersect($array1, $arrayShape1, static function (mixed $a, mixed $b) { assertType('int', $a); assertType('int|string', $b); return $a <=> $b; })); - assertType("array<'foo'|0, int|string>", array_uintersect($arrayShape1, $array1, static function (mixed $a, mixed $b) { + assertType("array<0|'foo', int|string>", array_uintersect($arrayShape1, $array1, static function (mixed $a, mixed $b) { assertType('int|string', $a); assertType('int', $b); return $a <=> $b; })); - assertType("array<'bar'|'foo', string>", array_uintersect($arrayShape2, $array1, static function (mixed $a, mixed $b) { + assertType("array<'bar'|'foo', int|string>", array_uintersect($arrayShape2, $array1, static function (mixed $a, mixed $b) { assertType('int|string', $a); assertType('int', $b); diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index 348fa5bffe..9fc8bb2ec5 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -649,7 +649,7 @@ public function testArrayUdiffCallback(): void 14, ], [ - 'Parameter #1 $arr1 of function array_udiff expects array, null given.', + 'Parameter #1 $arr1 of function array_udiff expects array, null given.', 20, ], [ @@ -675,7 +675,7 @@ public function testArrayUintersectCallback(): void 14, ], [ - 'Parameter #1 $arr1 of function array_uintersect expects array, null given.', + 'Parameter #1 $arr1 of function array_uintersect expects array, null given.', 20, ], [