Skip to content

Resolve bitwise not on constant integer#4437

Merged
ondrejmirtes merged 3 commits intophpstan:2.1.xfrom
VincentLanglet:bitwiseNot
Feb 5, 2026
Merged

Resolve bitwise not on constant integer#4437
ondrejmirtes merged 3 commits intophpstan:2.1.xfrom
VincentLanglet:bitwiseNot

Conversation

@VincentLanglet
Copy link
Contributor

While working on #4435 I discovered the issue phpstan/phpstan#9384 was almost solve except for the operation with the bitwise operator not ~.

This one generalize constant integer into integer while we could compute the value.

A comment is saying it depends on PHP_INT_SIZE but we could consider that

@VincentLanglet
Copy link
Contributor Author

WDYT of this small fix @staabm @ondrejmirtes ?
I'll need it to fix #4435 after

@staabm
Copy link
Contributor

staabm commented Feb 2, 2026

  • 99% operation ~ are on small number

I am not sure this argument makes sense, since as far as I understand it ~1 already returns a different result on 64 bit vs. 32 bit PHP.


I think we need to either judge whether...

  • 32 bit php is still worth supporting (maybe worth dropping with PHPStan 3.x)
  • whether this more precise types should be bleeding edge only (or otherwise feature flagged)

@VincentLanglet
Copy link
Contributor Author

  • 99% operation ~ are on small number

I am not sure this argument makes sense, since as far as I understand it ~1 already returns a different result on 64 bit vs. 32 bit PHP.

When I tried I got ~n = -(n+1) and it does not depends on the PHP bit size (for small numbers).
You can try, ~1 returns -2 in both 32 and 64 bit PHP.

@ondrejmirtes ondrejmirtes merged commit 8430e21 into phpstan:2.1.x Feb 5, 2026
634 of 639 checks passed
@ondrejmirtes
Copy link
Member

Thank you.

@ondrejmirtes
Copy link
Member

Either this or #4435 is a reason for a new error:

				$previousErrorHandler = set_error_handler(
					function (int $severity, string $message, string $file, int $line) use ($item, $columnIndex, $rowIndex, $startRowIndex, &$previousErrorHandler): mixed {
						if (($severity & E_WARNING | E_NOTICE) > 0) {
							$this->throwInvalidValueException($item, $this->columns[$columnIndex], $rowIndex - $startRowIndex, $columnIndex);
						} elseif ($previousErrorHandler !== null) {
							return $previousErrorHandler($severity, $message, $file, $line);
						}

						throw new ShouldNotHappenException(sprintf('Unexpected error %s: %s', $severity, $message));
					},
				);

  117    Comparison operation ">" between 8|9|10 and 0 is always true.  
         🪪  greater.alwaysTrue                                         
  123    Unreachable statement - code above always terminates.          
         🪪  deadCode.unreachable                                       

Do you think it's valid or not? I suspect the code should be parenthesized like this $severity & (E_WARNING | E_NOTICE) but not sure.

@VincentLanglet
Copy link
Contributor Author

Were does come from this error ? I don't see such code in phpstan codebase.

Do you think it's valid or not? I suspect the code should be parenthesized like this $severity & (E_WARNING | E_NOTICE) but not sure.

This seems valid to me, I think it should be $severity & (E_WARNING | E_NOTICE)

@ondrejmirtes
Copy link
Member

Each commit to PHPStan is analysed on four private projects only I have access to.

@staabm
Copy link
Contributor

staabm commented Feb 9, 2026

I think it should be $severity & (E_WARNING | E_NOTICE)

agree

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