Skip to content

Report impure methods overriding @pure-unless-parameter-passed methods - #6666

Merged
staabm merged 2 commits into
phpstan:2.3.xfrom
zonuexe:feature/pure-unless-parameter-passed-required
Oct 3, 2026
Merged

staabm merged 2 commits into
phpstan:2.3.xfrom
zonuexe:feature/pure-unless-parameter-passed-required

Conversation

@zonuexe

@zonuexe zonuexe commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #6018. A method marked @pure-unless-parameter-passed tells callers it is pure as long as the flagged out parameter is omitted, but an override marked @phpstan-impure can break that without any error. @pure-unless-callable-is-impure already has this check (method.impureOverridePureUnlessCallable); this adds the same for the new tag.

Changes

  • MethodSignatureRule reports Impure method %s::%s() overrides method %s::%s() marked @pure-unless-parameter-passed. with the identifier method.impureOverridePureUnlessParameterPassed.
  • Like the existing check, it only runs with reportMethodPurityOverride (bleeding edge) and only for an override that is explicitly impure; an override without a purity tag or one marked @phpstan-pure is not reported.
  • When the parent carries both tags, only the @pure-unless-callable-is-impure error is reported, so each parent method still yields at most one error.

Not in this PR: the signature checks in FunctionPurityCheck (e.g. a non-optional parameter marked @pure-unless-parameter-passed) only run for methods with a body, so interface and abstract methods aren't checked. That applies to the existing @phpstan-pure checks as well, so I'd handle it separately.

@VincentLanglet
VincentLanglet requested a review from staabm October 3, 2026 13:44
@staabm

staabm commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Please add another test with @phpstan-all-methods-pure

@zonuexe zonuexe mentioned this pull request Oct 3, 2026
3 tasks done
@zonuexe

zonuexe commented Oct 3, 2026

Copy link
Copy Markdown
Contributor Author

I added this in 6fa0be6. PHPStan reports an implementation in a @phpstan-all-methods-impure class the same way as one marked @phpstan-impure, and leaves one in a @phpstan-all-methods-pure class alone.

I left out the other direction, a @phpstan-all-methods-pure class that declares the @pure-unless-parameter-passed method itself, because PHPStan gets that case wrong: it lets the class-level tag override the method's own tag and treats the method as unconditionally pure. It then misses a caller that passes $count, and reports an impure override as method.impure ("overrides pure method") instead of the new error. @pure-unless-callable-is-impure on 2.3.x has the same problem: in such a class, PHPStan misses an impure callback too. I'll fix both tags in a separate PR.

@staabm
staabm merged commit b0e7a99 into phpstan:2.3.x Oct 3, 2026
909 of 924 checks passed
@zonuexe
zonuexe deleted the feature/pure-unless-parameter-passed-required branch October 3, 2026 17:57
@staabm

staabm commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Thank you

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.

3 participants