Skip to content

Check the purity declarations of methods without a body - #6668

Open
zonuexe wants to merge 1 commit into
phpstan:2.3.xfrom
zonuexe:feature/purity-checks-without-body
Open

zonuexe wants to merge 1 commit into
phpstan:2.3.xfrom
zonuexe:feature/purity-checks-without-body

Conversation

@zonuexe

@zonuexe zonuexe commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #6018 (comment). PureMethodRule runs on MethodReturnStatementsNode, which only methods with a body get, so PHPStan never checked the purity declarations of abstract and interface methods:

interface Foo
{
	/** @phpstan-pure */
	public function pureByRef(int &$p): int; // not reported

	/**
	 * @param-out int $count
	 * @pure-unless-parameter-passed $count
	 */
	public function replace(string $subject, int &$count): string; // not reported
}

PHPStan reports the same declarations on a method with a body as pureMethod.parameterByRef and pureMethod.nonOptionalParameterPassed.

Changes

  • FunctionPurityCheck::checkSignature() holds the checks that need only the signature: parameterByRef and void for @phpstan-pure, redundantUnlessCallable for @pure-unless-callable-is-impure, and nonOptionalParameterPassed / parameterPassedNotByRef for @pure-unless-parameter-passed. check() calls it first, so PureFunctionRule, PureMethodRule and PurePropertyHookRule report the same errors as before.
  • The new PureAbstractMethodRule runs checkSignature() on InClassMethodNode for methods without a body, with the same pureMethod.* identifiers.
  • The rule can report existing @phpstan-pure interface methods, so I registered it on level 2 (like PureMethodRule) behind the reportAbstractMethodPurity bleeding-edge toggle.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant