Bug Report
| Subject |
Details |
| Rector version |
2.5.4 |
| Responsible rules |
InnerFunctionToPrivateMethodRector, aggravated by RemoveUnusedPrivateMethodRector |
| PHP version |
8.x |
Minimal PHP Code Causing Issue
<?php
class Demo
{
public static function getOptions()
{
function sortByOrder(array $a, array $b): int
{
return strcmp((string) $a['label'], (string) $b['label']);
}
$options = [
['value' => 'b', 'label' => 'Bravo'],
['value' => 'a', 'label' => 'Alpha'],
];
usort($options, 'sortByOrder');
return $options;
}
}
Config
<?php
use Rector\CodeQuality\Rector\Class_\InnerFunctionToPrivateMethodRector;
use Rector\DeadCode\Rector\ClassMethod\RemoveUnusedPrivateMethodRector;
use Rector\Config\RectorConfig;
return RectorConfig::configure()
->withPaths([__DIR__ . '/src'])
->withRules([
InnerFunctionToPrivateMethodRector::class,
RemoveUnusedPrivateMethodRector::class,
]);
Actual output (both rules — function is deleted entirely, call site untouched)
{
public static function getOptions()
{
- function sortByOrder(array $a, array $b): int
- {
- return strcmp((string) $a['label'], (string) $b['label']);
- }
-
$options = [
With only InnerFunctionToPrivateMethodRector enabled, the private method is created, but the
string callable is not rewritten, so the result is still broken:
usort($options, 'sortByOrder');
return $options;
+ }
+ private static function sortByOrder(array $a, array $b): int
+ {
+ return strcmp((string) $a['label'], (string) $b['label']);
}
}
https://getrector.com/demo/61afb5ea-efc3-4014-96d6-2de5dbb5b774
Expected Behaviour
Either:
InnerFunctionToPrivateMethodRector rewrites string-callable usages to reference the new private
method (e.g. usort($options, self::sortByOrder(...)) or [self::class, 'sortByOrder']), or
- the rule skips the transformation when the inner function is referenced by name as a string
callable, since the rename cannot be applied safely.
Rewriting to a real reference (option 1) would also stop RemoveUnusedPrivateMethodRector from
considering the new method dead code.
Bug Report
InnerFunctionToPrivateMethodRector, aggravated byRemoveUnusedPrivateMethodRectorMinimal PHP Code Causing Issue
Config
Actual output (both rules — function is deleted entirely, call site untouched)
{ public static function getOptions() { - function sortByOrder(array $a, array $b): int - { - return strcmp((string) $a['label'], (string) $b['label']); - } - $options = [With only
InnerFunctionToPrivateMethodRectorenabled, the private method is created, but thestring callable is not rewritten, so the result is still broken:
usort($options, 'sortByOrder'); return $options; + } + private static function sortByOrder(array $a, array $b): int + { + return strcmp((string) $a['label'], (string) $b['label']); } }https://getrector.com/demo/61afb5ea-efc3-4014-96d6-2de5dbb5b774
Expected Behaviour
Either:
InnerFunctionToPrivateMethodRectorrewrites string-callable usages to reference the new privatemethod (e.g.
usort($options, self::sortByOrder(...))or[self::class, 'sortByOrder']), orcallable, since the rename cannot be applied safely.
Rewriting to a real reference (option 1) would also stop
RemoveUnusedPrivateMethodRectorfromconsidering the new method dead code.