Skip to content

Fix #7317: Return type of SimpleXMLElement::current() is not tentative#5086

Open
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-7olywkl
Open

Fix #7317: Return type of SimpleXMLElement::current() is not tentative#5086
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-7olywkl

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

SimpleXMLElement::current() has a tentative return type (?static) in PHP 8.1+, but PHPStan was not reporting it as a tentative return type violation when a subclass overrides it with an incompatible return type. Instead, no error was reported at all, while SimpleXMLElement::valid() correctly showed the tentative return type error.

Changes

  • Modified src/Rules/Methods/OverridingMethodRule.php to also check the parent class method's own tentative return type, not just the deepest prototype in the chain
  • Updated the $reportReturnType logic to suppress regular return type errors when either the deepest prototype or the parent class method has a tentative return type
  • Added TypehintHelper import for converting reflection types to PHPStan types
  • Added regression test in tests/PHPStan/Rules/Methods/data/bug-7317.php and tests/PHPStan/Rules/Methods/OverridingMethodRuleTest.php

Root cause

When checking tentative return types, OverridingMethodRule uses $method->getPrototype() which follows BetterReflection's prototype chain to the deepest ancestor. For MySimpleXMLElement::current(), this resolves to Iterator::current() which has a tentative return type of mixed. Since bool is covariant with mixed, the tentative check passes and no error is reported.

However, the intermediate class SimpleXMLElement::current() has its own tentative return type of ?static (i.e., SimpleXMLElement|null), which bool is NOT covariant with. The fix adds an additional check that examines the parent class method's tentative return type via $prototypeDeclaringClass->getNativeReflection()->getMethod(), catching cases where an intermediate prototype in the chain has a more restrictive tentative return type than the deepest prototype.

Test

Added tests/PHPStan/Rules/Methods/data/bug-7317.php with a MySimpleXMLElement class that extends SimpleXMLElement and overrides both current() (returning bool) and valid() (returning int). The test verifies that both methods now correctly produce tentative return type errors on PHP 8.1+.

Fixes phpstan/phpstan#7317

…ate prototypes

- OverridingMethodRule now also checks the parent class method's own tentative return type, not just the deepest prototype's
- This fixes the case where SimpleXMLElement::current() has tentative return type ?static but the check only saw Iterator::current() with tentative type mixed
- Updated $reportReturnType logic to suppress regular return type errors when the parent class method has a tentative return type
- Added regression test for phpstan/phpstan#7317

Closes phpstan/phpstan#7317
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