Skip to content

Call operator type specifying extensions for bitwise and arithmetic operators#5226

Open
Firehed wants to merge 2 commits intophpstan:2.1.xfrom
Firehed:operator-extension-resolver-fix
Open

Call operator type specifying extensions for bitwise and arithmetic operators#5226
Firehed wants to merge 2 commits intophpstan:2.1.xfrom
Firehed:operator-extension-resolver-fix

Conversation

@Firehed
Copy link
Contributor

@Firehed Firehed commented Mar 15, 2026

Summary

This PR ensures OperatorTypeSpecifyingExtension implementations are called consistently for all supported binary operators:

  • Add extension calls to getBitwiseAndType, getBitwiseOrType, getBitwiseXorType
  • Move extension call to the top of resolveCommonMath (before integer range optimization)
  • Remove the duplicate extension call that was later in resolveCommonMath

This is prerequisite work for phpstan/phpstan#14288 (GMP operator type inference), split out per review feedback on #5223.

Testing approach

Per @ondrejmirtes' feedback:

"Please introduce the changes to InitializerExprTypeResolver in a separate PR - this will force you to create synthetic extensions just for test purposes... Without this, if we once removed the GMP extensions then this feature would become untested."

This PR creates synthetic test extensions independent of any specific type (like GMP):

  1. TestBitwiseOperand - A dummy fixture class
  2. TestBitwiseOperatorTypeSpecifyingExtension - Returns TestBitwiseOperand for &, |, ^ operators
  3. Uses existing TestDecimal + TestDecimalOperatorTypeSpecifyingExtension for arithmetic operators

The test verifies the resolver correctly invokes extensions for both bitwise and arithmetic operators. This ensures the resolver infrastructure remains tested even if specific extensions (like a future GMP extension) are removed.

Test plan

  • Added OperatorTypeSpecifyingExtensionTypeInferenceTest with 8 assertions
  • All existing tests pass (11634 tests, 78899 assertions)

Generated with Claude Code

…perators

- Add extension calls to getBitwiseAndType, getBitwiseOrType, getBitwiseXorType
- Move extension call to top of resolveCommonMath (before integer range optimization)
- Remove duplicate extension call later in resolveCommonMath
- Add TestBitwiseOperatorTypeSpecifyingExtension for testing bitwise extension calls
- Add OperatorTypeSpecifyingExtensionTypeInferenceTest with tests for both
  bitwise (TestBitwiseOperand) and arithmetic (TestDecimal) operators

This ensures operator type specifying extensions are called consistently
for all supported operators, allowing custom types to specify operator
return types.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@Firehed
Copy link
Contributor Author

Firehed commented Mar 15, 2026

I believe the two failing tests are unrelated to this change based on other PRs I'm seeing and their associated error messages.

@VincentLanglet VincentLanglet requested a review from staabm March 17, 2026 22:33
$leftType = $getTypeCallback($left);
$rightType = $getTypeCallback($right);

$specifiedTypes = $this->operatorTypeSpecifyingExtensionRegistryProvider->getRegistry()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this change only makes sense when getBitwiseAndTypeFromTypes is no longer public because otherwise you can by-pass extensions.

but it seems like getBitwiseAndTypeFromTypes is not called from anywhere outside this class and since InitializerExprTypeResolver is not @api-annotated, I think we can reduce visibility for such methods to private.

affects multiple methods in this class

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don’t change this, I’m pretty sure I use these in my refactoring at #5224

use PHPStan\Fixture\TestDecimal;
use function PHPStan\Testing\assertType;

// =============================================================================
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

misses tests for shift left/right

@Firehed
Copy link
Contributor Author

Firehed commented Mar 18, 2026

I can get some extra tests added for bit-shifting.

@staabm & @ondrejmirtes Just to make sure I'm following your comments correctly, should the logic in InitializerExprTypeResolver stay as-is? Sounds like changing method visibility per the original suggestion is out.

@staabm
Copy link
Contributor

staabm commented Mar 18, 2026

Leave the visibility as is , right

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.

4 participants