Skip to content

[TypeDeclarationDocblocks] Skip ClassMethodArrayDocblockParamFromLocalCallsRector on methods overriding parent/interface - #8357

Merged
TomasVotruba merged 1 commit into
mainfrom
fix-9835-skip-parent-interface-param-docblock
Aug 20, 2026
Merged

[TypeDeclarationDocblocks] Skip ClassMethodArrayDocblockParamFromLocalCallsRector on methods overriding parent/interface#8357
TomasVotruba merged 1 commit into
mainfrom
fix-9835-skip-parent-interface-param-docblock

Conversation

@TomasVotruba

Copy link
Copy Markdown
Member

Fixes rectorphp/rector#9835

ClassMethodArrayDocblockParamFromLocalCallsRector added a @param docblock inferred from local calls, even when the method overrides a parent/interface method whose contract is wider. This narrowed the type below the parent contract and broke LSP.

Before

Interface declares a wide array shape:

interface SomeSearchInterface
{
    /** @param array{alias?: string, id?: string} \$criteria */
    public function findOneMatching(array \$criteria): ?object;
}

Implementation only calls it locally with ['id' => ...], so the rule wrongly narrowed the docblock:

 final class SomeSearch implements SomeSearchInterface
 {
+    /**
+     * @param array<string, string> \$criteria
+     */
     public function findOneMatching(array \$criteria): ?object
     {
         return null;
     }
 }

After

The rule now skips a method when a parent class or interface already declares it (ClassMethodManipulator::hasParentMethodOrInterfaceMethod()), keeping the wider contract intact.

…lCallsRector on methods overriding parent/interface (#9835)
@TomasVotruba
TomasVotruba merged commit 83496b5 into main Aug 20, 2026
55 of 59 checks passed
@TomasVotruba
TomasVotruba deleted the fix-9835-skip-parent-interface-param-docblock branch August 20, 2026 16:50
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.

Incorrect behavior of ClassMethodArrayDocblockParamFromLocalCallsRector

1 participant