Skip to content

Commit

Permalink
skip param castable to X on non-arrays
Browse files Browse the repository at this point in the history
Fixes bug 12146
  • Loading branch information
schlndh authored and ondrejmirtes committed Nov 30, 2024
1 parent 7070346 commit bd44528
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 7 deletions.
8 changes: 5 additions & 3 deletions src/Rules/ParameterCastableToStringCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,13 @@ public function checkParameter(
$scope,
$parameter->value,
'',
static fn (Type $type): bool => !$castFn($type->getIterableValueType()) instanceof ErrorType,
static fn (Type $type): bool => $type->isArray()->yes() && !$castFn($type->getIterableValueType()) instanceof ErrorType,
);

if ($typeResult->getType() instanceof ErrorType
|| !$castFn($typeResult->getType()->getIterableValueType()) instanceof ErrorType) {
if (
! $typeResult->getType()->isArray()->yes()
|| !$castFn($typeResult->getType()->getIterableValueType()) instanceof ErrorType
) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ImplodeParameterCastableToStringRuleTest extends RuleTestCase
protected function getRule(): Rule
{
$broker = $this->createReflectionProvider();
return new ImplodeParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, false, false, false)));
return new ImplodeParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, true, true, false)));
}

public function testNamedArguments(): void
Expand Down Expand Up @@ -100,4 +100,14 @@ public function testBug8467a(): void
$this->analyse([__DIR__ . '/../Arrays/data/bug-8467a.php'], []);
}

public function testBug12146(): void
{
$this->analyse([__DIR__ . '/data/bug-12146.php'], [
[
'Parameter #2 $array of function implode expects array<string>, array<int|stdClass> given.',
28,
],
]);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ParameterCastableToNumberRuleTest extends RuleTestCase
protected function getRule(): Rule
{
$broker = $this->createReflectionProvider();
return new ParameterCastableToNumberRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, false, false, false)));
return new ParameterCastableToNumberRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, true, true, false)));
}

public function testRule(): void
Expand Down Expand Up @@ -130,6 +130,20 @@ public function testBug11883(): void
]);
}

public function testBug12146(): void
{
$this->analyse([__DIR__ . '/data/bug-12146.php'], $this->hackPhp74ErrorMessages([
[
'Parameter #1 $array of function array_sum expects an array of values castable to number, array<int|stdClass> given.',
16,
],
[
'Parameter #1 $array of function array_product expects an array of values castable to number, array<int|stdClass> given.',
22,
],
]));
}

/**
* @param list<array{0: string, 1: int, 2?: string|null}> $errors
* @return list<array{0: string, 1: int, 2?: string|null}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ParameterCastableToStringRuleTest extends RuleTestCase
protected function getRule(): Rule
{
$broker = $this->createReflectionProvider();
return new ParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, false, false, false)));
return new ParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, true, true, false)));
}

public function testRule(): void
Expand Down Expand Up @@ -196,6 +196,20 @@ public function testBug11141(): void
]);
}

public function testBug12146(): void
{
$this->analyse([__DIR__ . '/data/bug-12146.php'], $this->hackParameterNames([
[
'Parameter #1 $array of function array_intersect expects an array of values castable to string, array<int|stdClass> given.',
34,
],
[
'Parameter #1 $keys of function array_fill_keys expects an array of values castable to string, array<int|stdClass> given.',
40,
],
]));
}

/**
* @param list<array{0: string, 1: int, 2?: string|null}> $errors
* @return list<array{0: string, 1: int, 2?: string|null}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class SortParameterCastableToStringRuleTest extends RuleTestCase
protected function getRule(): Rule
{
$broker = $this->createReflectionProvider();
return new SortParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, false, false, false)));
return new SortParameterCastableToStringRule($broker, new ParameterCastableToStringCheck(new RuleLevelHelper($broker, true, false, true, true, true, false)));
}

public function testRule(): void
Expand Down Expand Up @@ -145,6 +145,16 @@ public function testBug11167(): void
$this->analyse([__DIR__ . '/data/bug-11167.php'], []);
}

public function testBug12146(): void
{
$this->analyse([__DIR__ . '/data/bug-12146.php'], $this->hackParameterNames([
[
'Parameter #1 $array of function array_unique expects an array of values castable to string, array<int|stdClass> given.',
46,
],
]));
}

/**
* @param list<array{0: string, 1: int, 2?: string|null}> $errors
* @return list<array{0: string, 1: int, 2?: string|null}>
Expand Down
49 changes: 49 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-12146.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php declare(strict_types = 1);

namespace Bug12146;

/**
* @param mixed $mixed invalid, but don't report because it's reported by CallToFunctionParametersRule
* @param array<int>|array<float> $validArrayUnion valid
* @param array<int>|array<\stdClass> $invalidArrayUnion invalid, report
* @param ?array<\stdClass> $nullableInvalidArray invalid, but don't report because it's reported by CallToFunctionParametersRule
* @param array<\stdClass>|\SplFixedArray<int> $arrayOrSplArray invalid, but don't report because it's reported by CallToFunctionParametersRule
* @return void
*/
function foo($mixed, $validArrayUnion, $invalidArrayUnion, $nullableInvalidArray, $arrayOrSplArray) {
var_dump(array_sum($mixed));
var_dump(array_sum($validArrayUnion));
var_dump(array_sum($invalidArrayUnion));
var_dump(array_sum($nullableInvalidArray));
var_dump(array_sum($arrayOrSplArray));

var_dump(array_product($mixed));
var_dump(array_product($validArrayUnion));
var_dump(array_product($invalidArrayUnion));
var_dump(array_product($nullableInvalidArray));
var_dump(array_product($arrayOrSplArray));

var_dump(implode(',', $mixed));
var_dump(implode(',', $validArrayUnion));
var_dump(implode(',', $invalidArrayUnion));
var_dump(implode(',', $nullableInvalidArray));
var_dump(implode(',', $arrayOrSplArray));

var_dump(array_intersect($mixed, [5]));
var_dump(array_intersect($validArrayUnion, [5]));
var_dump(array_intersect($invalidArrayUnion, [5]));
var_dump(array_intersect($nullableInvalidArray, [5]));
var_dump(array_intersect($arrayOrSplArray, [5]));

var_dump(array_fill_keys($mixed, 1));
var_dump(array_fill_keys($validArrayUnion, 1));
var_dump(array_fill_keys($invalidArrayUnion, 1));
var_dump(array_fill_keys($nullableInvalidArray, 1));
var_dump(array_fill_keys($arrayOrSplArray, 1));

var_dump(array_unique($mixed));
var_dump(array_unique($validArrayUnion));
var_dump(array_unique($invalidArrayUnion));
var_dump(array_unique($nullableInvalidArray));
var_dump(array_unique($arrayOrSplArray));
}

0 comments on commit bd44528

Please sign in to comment.