Feature request
ksort() on a list is always a no-op with the default SORT_REGULAR flags: a list's keys are 0..n-1 in ascending order already. The same is true for arrays PHPStan knows are empty or have a single element.
This is the same class of dead call that ArrayValuesRule already reports:
I hit this in the wild: shipmonk/dead-code-detector builds a list of tips and then calls ksort() on it, clearly intending sort(). Because the ksort() silently did nothing, the tip order followed hash-map insertion order instead, which varies between parallel runs — so the tool's output was non-deterministic. A rule would have caught it immediately.
<?php declare(strict_types = 1);
/** @param list<string> $list */
function doFoo(array $list): void
{
ksort($list); // no-op, keys are already 0..n-1 ascending
}
function doBar(): void
{
$tips = [];
$tips[] = 'a';
$tips[] = 'b';
ksort($tips); // no-op, same reason
}
Neither is reported at level 10 today.
Things the rule needs to be careful about:
- Only the default flags qualify.
ksort($list, SORT_STRING) is not a no-op — string comparison orders "10" before "2". SORT_REGULAR, SORT_NUMERIC, and no argument at all are safe; anything unknown should be skipped. SORT_NATURAL/SORT_FLAG_CASE also reorder nothing on a list, but there's no need to be exhaustive — bailing out whenever the flags aren't a known-safe constant is fine.
krsort() is not a no-op on a list — it reverses it. Only ksort() should be reported.
ksort() on an array with at most one element is a no-op regardless of whether it's a list, mirroring arrayValues.empty.
Suggested identifiers, following the existing naming: ksort.list and ksort.empty.
asort()/arsort()/sort()/rsort() sort by value, so they're outside the scope of this request.
Did PHPStan help you today? Did it make you happy in any way?
It found a real non-determinism bug in a third-party extension for me today — just not this particular one, which is why I'm asking for it :)
Feature request
ksort()on alistis always a no-op with the defaultSORT_REGULARflags: a list's keys are0..n-1in ascending order already. The same is true for arrays PHPStan knows are empty or have a single element.This is the same class of dead call that
ArrayValuesRulealready reports:arrayValues.list— "Parameter Require nette/di 2.3.6 for PHP7 typehints support #1 $array (...) of array_values is already a list, call has no effect."arrayValues.empty— "Parameter Require nette/di 2.3.6 for PHP7 typehints support #1 $array (...) to function array_values is empty, call has no effect."I hit this in the wild: shipmonk/dead-code-detector builds a list of tips and then calls
ksort()on it, clearly intendingsort(). Because theksort()silently did nothing, the tip order followed hash-map insertion order instead, which varies between parallel runs — so the tool's output was non-deterministic. A rule would have caught it immediately.Neither is reported at level 10 today.
Things the rule needs to be careful about:
ksort($list, SORT_STRING)is not a no-op — string comparison orders"10"before"2".SORT_REGULAR,SORT_NUMERIC, and no argument at all are safe; anything unknown should be skipped.SORT_NATURAL/SORT_FLAG_CASEalso reorder nothing on a list, but there's no need to be exhaustive — bailing out whenever the flags aren't a known-safe constant is fine.krsort()is not a no-op on a list — it reverses it. Onlyksort()should be reported.ksort()on an array with at most one element is a no-op regardless of whether it's a list, mirroringarrayValues.empty.Suggested identifiers, following the existing naming:
ksort.listandksort.empty.asort()/arsort()/sort()/rsort()sort by value, so they're outside the scope of this request.Did PHPStan help you today? Did it make you happy in any way?
It found a real non-determinism bug in a third-party extension for me today — just not this particular one, which is why I'm asking for it :)