Skip to content

Conversation

DanielEScherzer
Copy link

No description provided.

@DanielEScherzer
Copy link
Author

Wasn't able to figure out instance methods or static methods, I'll work on those separately later

@DanielEScherzer DanielEScherzer force-pushed the polyfill-NoDiscard-function branch from 0b700c1 to 24db3f7 Compare August 21, 2025 07:00
@DanielEScherzer
Copy link
Author

DanielEScherzer commented Aug 21, 2025

PHP 8.5 linting failure is unrelated, caused by yours truly in php/php-src@c416191 // php/php-src#19154

@ondrejmirtes
Copy link
Member

This is a wrong approach. We don't need a new rule but instead:

  1. Add a new method on FunctionReflection and ExtendedMethodReflection that would reflect this. Maybe something like mustUseReturnValue(): TrinaryLogic or mustNotDiscardReturnValue(): TrinaryLogic although I don't like double negatives.
  2. Add a check in FunctionCallParametersCheck that would ask about this. There's already a similar check for pure functions.
  3. Do not forget about (void) and add proper support for this. This means support in MutatingScope::resolveType and also NodeScopeResolver (if not already covered by the common Cast parent node type).
  4. Flag NoDiscard attribute as an error above a void function.

@DanielEScherzer
Copy link
Author

This is a wrong approach. We don't need a new rule but instead:

  1. Add a new method on FunctionReflection and ExtendedMethodReflection that would reflect this. Maybe something like mustUseReturnValue(): TrinaryLogic or mustNotDiscardReturnValue(): TrinaryLogic although I don't like double negatives.

Per the docs https://phpstan.org/developing-extensions/backward-compatibility-promise

Interfaces with @api in their PHPDoc can be implemented and extended

so can this be added to FunctionReflection?

  1. Add a check in FunctionCallParametersCheck that would ask about this. There's already a similar check for pure functions.

FunctionCallParametersCheck doesn't include pure anywhere in the file?

  1. Do not forget about (void) and add proper support for this. This means support in MutatingScope::resolveType and also NodeScopeResolver (if not already covered by the common Cast parent node type).

Is this necessary? The (void) is for runtime suppression, and a comment can be used for suppressing the phpstan issue

  1. Flag NoDiscard attribute as an error above a void function.

Is that necessary? That means a whole other rule for something that PHP would complain about at compile time anyway

@DanielEScherzer DanielEScherzer force-pushed the polyfill-NoDiscard-function branch from d3dc3d4 to 131caa6 Compare August 28, 2025 21:01
@ondrejmirtes
Copy link
Member

so can this be added to FunctionReflection?

Yes, some interfaces cannot be extended. If you try that you get an error: https://phpstan.org/r/847a20b4-ce41-4763-b7f4-aa088ea30bca

FunctionCallParametersCheck doesn't include pure anywhere in the file?

I'm sorry, I was mistaken. I had these lines in mind (

if (
!$funcCall instanceof Node\Expr\New_
&& !$scope->isInFirstLevelStatement()
&& $scope->getKeepVoidType($funcCall)->isVoid()->yes()
) {
$errors[] = RuleErrorBuilder::message($voidReturnTypeUsed)
->identifier(sprintf('%s.void', $nodeType))
->line($funcCall->getStartLine())
->build();
}
). They produce errors like "Result of method X (void) is used." We actually need to check the opposite here.

Call to pure functions without using their result is covered by these rules:

  • CallToFunctionStatementWithoutSideEffectsRule
  • CallToMethodStatementWithoutSideEffectsRule
  • CallToStaticMethodStatementWithoutSideEffectsRule

But I think we first should try to report this in FunctionCallParametersCheck. $scope->isInFirstLevelStatement() is great for that.

Is this necessary? The (void) is for runtime suppression

The user already expresses their intention with (void). So PHPStan should not produce this message. If you'd ask $scope->isInFirstLevelStatement() it'd be taken care of automatically.

Is that necessary? That means a whole other rule for something that PHP would complain about at compile time anyway

Yes. PHPStan users expect this to be reported. We should report all the situations from the "Constraints" section in the RFC (https://wiki.php.net/rfc/marking_return_value_as_important).

@DanielEScherzer
Copy link
Author

So PHPStan should not produce this message. If you'd ask $scope->isInFirstLevelStatement() it'd be taken care of automatically.

I couldn't figure out using the scope, so I added a visitor to indicate method calls that use (void)
A few e2e tests are now failing, I think because of #[\NoDiscard] attributes that are now being complained about, I should be able to address that tomorrow

Yes. PHPStan users expect this to be reported. We should report all the situations from the "Constraints" section in the RFC (https://wiki.php.net/rfc/marking_return_value_as_important).

What I mean is, is this necessary for this patch? Errors about when the attribute is applied are different from errors about when the methods with the attribute are called

@ondrejmirtes
Copy link
Member

 What I mean is, is this necessary for this patch?

@DanielEScherzer My process for adding support for new PHP features is that I read the whole RFC and I update PHPStan with everything that should be added about the feature.

If you don't do that, then I'd have to keep in mind to do it myself.

@ondrejmirtes
Copy link
Member

Another important thing from the RFC:

As the result of a (void) cast is not defined, the (void) cast is a statement, not an expression. Using it within an expression will result in a syntax error.

Another rule checking the (void) cast with isInFirstLevelStatement would be great for that.

@DanielEScherzer DanielEScherzer deleted the polyfill-NoDiscard-function branch August 30, 2025 15:13
@DanielEScherzer DanielEScherzer restored the polyfill-NoDiscard-function branch August 30, 2025 15:14
@DanielEScherzer
Copy link
Author

Sorry, tried to rename the branch but didn't realize that that closes the PR :(

@DanielEScherzer
Copy link
Author

Okay, I have

  • added a rule to complain about (void) in expressions
  • added a case to the existing attribute.target issues for using NoDiscard on property hooks
  • fixed the handling of instance and method calls to address the false positives

@DanielEScherzer DanielEScherzer changed the title Add support for PHP 8.5 #[\NoDiscard] on functions Add support for PHP 8.5 #[\NoDiscard] Aug 30, 2025
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.

2 participants