{"record":{"id":"48fd23dc2c36a6e6","repo":"rectorphp/rector","slug":"s-rule-is-deprecated-as-a-function-call-can-ra","errorCode":null,"errorMessage":"\"%s\" rule is deprecated, as a function call can rarely be turned to a method call without breaking the code; use a custom rule for the exact project case instead","messagePattern":"\"(.+?)\" rule is deprecated, as a function call can rarely be turned to a method call without breaking the code; use a custom rule for the exact project case instead","errorType":"exception","errorClass":"ShouldNotHappenException","httpStatus":null,"severity":"error","filePath":"rules/Transform/Rector/FuncCall/FuncCallToMethodCallRector.php","lineNumber":64,"sourceCode":"        $this->someRenderer->view('...');\n    }\n}\nCODE_SAMPLE\n, [new FuncCallToMethodCall('view', 'Namespaced\\SomeRenderer', 'render')])]);\n    }\n    /**\n     * @return array<class-string<Node>>\n     */\n    public function getNodeTypes(): array\n    {\n        return [Class_::class];\n    }\n    /**\n     * @param Class_ $node\n     */\n    public function refactor(Node $node): ?Node\n    {\n        throw new ShouldNotHappenException(sprintf('\"%s\" rule is deprecated, as a function call can rarely be turned to a method call without breaking the code; use a custom rule for the exact project case instead', self::class));\n    }\n    /**\n     * @param mixed[] $configuration\n     */\n    public function configure(array $configuration): void\n    {\n    }\n}\n","sourceCodeStart":46,"sourceCodeEnd":73,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/rules/Transform/Rector/FuncCall/FuncCallToMethodCallRector.php#L46-L73","documentation":"Rector\\Transform\\Rector\\FuncCall\\FuncCallToMethodCallRector is deprecated: refactor() throws Rector\\Exception\\ShouldNotHappenException on the first Class_ node. The rule turned configured global function calls (e.g. some_helper()) into static or service method calls, but a function call can rarely be swapped for a method call without breaking code - the target object may not exist, names collide, and call semantics differ. configure() is a no-op now, so previously passed mappings are ignored.","triggerScenarios":"The rule remains in rector.php (withRules() or withConfiguredRule() with an old function=>method map) and rector visits any class; refactor() throws on the first Class_ node.","commonSituations":"Old configs migrating helper functions to a service class; projects that wired e.g. env() or trans() helpers to method calls; CI failing after a rector upgrade that emptied the implementation.","solutions":["Remove FuncCallToMethodCallRector from rector.php.","Do the function-to-method migration by hand per call site, verifying the receiver object is actually available there.","If it is a standing project convention, write a custom rule scoped to the exact function/method pair."],"exampleFix":"// before (rector.php)\n->withConfiguredRule(FuncCallToMethodCallRector::class, [\n    'some_helper' => [SomeService::class, 'helper'],\n])\n\n// after (rector.php) - removed; migrate call sites by hand\n\n// before                 // after\n$value = some_helper();    $value = $this->someService->helper();","handlingStrategy":"validation","validationCode":"use Rector\\Transform\\Rector\\FuncCall\\FuncCallToMethodCallRector;\n\n$rules = [/* your list */ FuncCallToMethodCallRector::class];\nif (in_array(FuncCallToMethodCallRector::class, $rules, true)) {\n    throw new InvalidArgumentException('Rule deprecated; migrate function calls manually or via a custom project rule');\n}","typeGuard":null,"tryCatchPattern":"try {\n    exit($rectorApplication->run());\n} catch (\\Rector\\Exception\\ShouldNotHappenException $e) {\n    if (str_contains($e->getMessage(), 'FuncCallToMethodCallRector')) {\n        fwrite(STDERR, 'Remove the rule; function-to-method swaps need per-call-site verification.' . PHP_EOL);\n        exit(1);\n    }\n    throw $e;\n}","preventionTips":["Migrate helper functions to service methods in reviewed commits where receiver availability is checked at each call site.","Keep a shortlist of sanctioned custom rules in the repo instead of relying on generic Transform rules for API-shape changes.","Drop deprecated Transform rules from rector.php during upgrade PRs rather than leaving them for CI to trip over."],"tags":["rector","php","refactor","function-call","transform","deprecated-rule"],"backgroundTag":"deprecated-api-invoked","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}