Skip to content

[DowngradePhp81] Handle ArrowFunction in DowngradeNeverTypeDeclarationRector - #397

Merged
samsonasik merged 1 commit into
rectorphp:mainfrom
roxblnfk:feature/never-arrow-function
Sep 8, 2026
Merged

samsonasik merged 1 commit into
rectorphp:mainfrom
roxblnfk:feature/never-arrow-function

Conversation

@roxblnfk

@roxblnfk roxblnfk commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

🔍 What was changed

DowngradeNeverTypeDeclarationRector now also strips the never return type from arrow functions, not just Function_, ClassMethod and Closure.

Why?

A never return type is invalid on an arrow function below PHP 8.1 — semantically an arrow function always "returns" its expression. When downgrading e.g. fn (): never => throw ... from 8.2, the rule left the never in place, producing code that does not parse on the target version. The decorator (PhpDocFromTypeDeclarationDecorator) already accepted ArrowFunction, so only the subscribed node types needed the addition.

Checklist

  • How was this tested:
    • Unit tests added

Added Fixture/arrow_function_never.php.inc; the rule's test suite passes (7/7). PHPStan and ECS pass on the changed rule.

…nRector

A "never" return type on an arrow function is invalid below PHP 8.1, yet the rule only subscribed to Function_, ClassMethod and Closure, so fn(): never => ... was left untouched. Add ArrowFunction to the subscribed node types; the decorator already accepts it.

Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@samsonasik

Copy link
Copy Markdown
Member

Looks good to me 👍

@samsonasik

Copy link
Copy Markdown
Member

Thank you @roxblnfk

@samsonasik
samsonasik merged commit ad2e1bb into rectorphp:main Sep 8, 2026
9 checks passed
roxblnfk added a commit to php-testo/testo that referenced this pull request Sep 8, 2026
test(output): restore the never-returning arrow-fn helpers

The downgrade path now carries Rector rules for both `ReflectionMethod::hasPrototype()` and `fn(): never => throw ...` (rectorphp/rector-downgrade-php#397, #398), so these hand-written 8.1 workarounds are redundant and the source returns to its plain 8.2 form. The memory_reset_peak_usage() guard and the memory-comparison skip stay — no Rector rule covers those.

Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
roxblnfk added a commit to php-testo/testo that referenced this pull request Sep 11, 2026
test(output): restore the never-returning arrow-fn helpers

The downgrade path now carries Rector rules for both `ReflectionMethod::hasPrototype()` and `fn(): never => throw ...` (rectorphp/rector-downgrade-php#397, #398), so these hand-written 8.1 workarounds are redundant and the source returns to its plain 8.2 form. The memory_reset_peak_usage() guard and the memory-comparison skip stay — no Rector rule covers those.

Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
roxblnfk added a commit to php-testo/testo that referenced this pull request Sep 11, 2026
test(output): restore the never-returning arrow-fn helpers

The downgrade path now carries Rector rules for both `ReflectionMethod::hasPrototype()` and `fn(): never => throw ...` (rectorphp/rector-downgrade-php#397, #398), so these hand-written 8.1 workarounds are redundant and the source returns to its plain 8.2 form. The memory_reset_peak_usage() guard and the memory-comparison skip stay — no Rector rule covers those.

Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
roxblnfk added a commit to php-testo/testo that referenced this pull request Sep 14, 2026
test(output): restore the never-returning arrow-fn helpers

The downgrade path now carries Rector rules for both `ReflectionMethod::hasPrototype()` and `fn(): never => throw ...` (rectorphp/rector-downgrade-php#397, #398), so these hand-written 8.1 workarounds are redundant and the source returns to its plain 8.2 form. The memory_reset_peak_usage() guard and the memory-comparison skip stay — no Rector rule covers those.

Assisted-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
samsonasik pushed a commit that referenced this pull request Sep 21, 2026
PHP 8.1 accepts the "never" return type on functions, methods and closures, but rejects it on arrow functions: the implicit return of the body expression trips "A never-returning function must not return" at compile time (php/php-src#7900, fixed in 8.2). #397 taught DowngradeNeverTypeDeclarationRector to strip it from arrow functions, but that rule sits in the 8.1 set, which removes 8.1 features when downgrading *from* 8.1 to 8.0. Code downgraded *to* 8.1 never reaches it, so `fn (): never => throw ...` survived and still failed to compile on 8.1. The arrow-function case is an 8.2 feature and belongs in the 8.2 set; this rule puts it there and leaves every other function-like to the 8.1 set.

Assisted-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants