Skip to content

[phpstan] Add PHPStan rule to flag same class-type union in param and return - #8585

Merged
TomasVotruba merged 2 commits into
mainfrom
generics-same-union-template-rule
Oct 10, 2026
Merged

TomasVotruba merged 2 commits into
mainfrom
generics-same-union-template-rule

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Adds PreferGenericTemplateOnSameUnionTypeRule under utils/phpstan, registered in phpstan.neon, to catch the shape generalized in #8584: a method whose single param and return share the same class-type union, e.g.

private function processNullableInstance(BooleanAnd|BooleanOr $node): null|BooleanAnd|BooleanOr

Such a method almost always returns the node it was passed, so a @template generic narrows the return to the concrete passed type and lets callers drop /** @var ... */ hacks.

The rule only fires when every union member is a class type (a Name node). Scalar unions like int|float and mixed unions like Node|array are skipped, since there the return is usually a fresh value, not the input - adding a template would be unsound. Methods that already carry @template are skipped too.

Covered by PreferGenericTemplateOnSameUnionTypeRuleTest with a failing fixture (bare union) and a passing one (already generic, scalar union, mismatched union).

Also applies the @template to the 13 existing matches across the tree, so a full composer phpstan run reports no hits outside the rule test fixtures.

Flags methods like (A|B $node): A|B|null that should use a @template generic to narrow the return to the passed type. Applies the template to the 13 existing matches.
@TomasVotruba TomasVotruba changed the title Add PHPStan rule to flag same class-type union in param and return [phpstan] Add PHPStan rule to flag same class-type union in param and return Oct 10, 2026
@TomasVotruba
TomasVotruba merged commit bcaae98 into main Oct 10, 2026
49 checks passed
@TomasVotruba
TomasVotruba deleted the generics-same-union-template-rule branch October 10, 2026 09:49
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.

1 participant