use_arrow_functions: constant-expression protection misses defaults and constants
Problem description
Follow-up to #9414 and #9416: use_arrow_functions now leaves closures in attribute arguments alone, but still converts closures in the other PHP 8.5 constant-expression positions into arrow functions. PHP does not allow arrow functions in these positions.
Confirmed on current master (c544875308be1b26ca4a5e649a01e48d35c6d6e7), with PHP 8.5.9:
- global constants;
- class constants;
- property defaults;
- parameter defaults.
The fix command exits successfully and writes the arrow function. Running php -l on that output then fails with Constant expression contains invalid operations. The original input passes php -l.
Minimal reproducer CLI command
php php-cs-fixer fix --rules=use_arrow_functions --allow-risky=yes --using-cache=no example.php
php -l example.phpMinimal reproducer code snippet
<?php
const CALLBACK = static function () { return 1; };The fixer writes:
<?php
const CALLBACK = static fn () => 1;These inputs also reproduce the problem:
<?php
class Holder {
public $callback = static function () { return 1; };
const CALLBACK = static function () { return 1; };
}
function take($callback = static function () { return 1; }) {}Expected behaviour
Preserve closures that are themselves constant expressions. Ordinary closures in executable code should still be converted, including closures inside the body of a constant-expression closure; avoiding an entire containing class or declaration would hide valid conversions.
The PHP 8.5 RFC constraints apply to all these positions, not just attributes. I found this while investigating #9372; this report is about the existing invalid-code conversion, not adding no-op conversion or changing PER-CS rulesets. I will work on a focused guard and regression coverage for these remaining contexts.
Fixer version
3.95.26-DEV, current master
PHP version
8.5.9
How do you run Fixer?
Composer package and CLI
Contribution Checks
- I searched existing open issues and PRs; #9414/#9416 cover the attribute case, and I found no active implementation for these remaining positions.
- I read
feature-or-bug.rst; this produces invalid output from valid input.
Source: PHP-CS-Fixer/PHP-CS-Fixer