use_arrow_functions: constant-expression protection misses defaults and constants

Author: fzlzjerryCreated Sep 11, 2026Updated Sep 11, 2026

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

bash
php php-cs-fixer fix --rules=use_arrow_functions --allow-risky=yes --using-cache=no example.php
php -l example.php

Minimal reproducer code snippet

php
<?php
const CALLBACK = static function () { return 1; };

The fixer writes:

php
<?php
const CALLBACK = static fn () => 1;

These inputs also reproduce the problem:

php
<?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