Skip to content

Preserve maybe in BitwiseFlagHelper for bitwise-or with dynamic operands - #6080

Merged
staabm merged 1 commit into
phpstan:2.2.xfrom
vrana:bitwise-or
Jul 21, 2026
Merged

Preserve maybe in BitwiseFlagHelper for bitwise-or with dynamic operands#6080
staabm merged 1 commit into
phpstan:2.2.xfrom
vrana:bitwise-or

Conversation

@vrana

@vrana vrana commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

The BitwiseOr branch of bitwiseOrContainsConstant() returned createFromBoolean(left->yes() || right->yes()), collapsing "maybe" to "no". For an expression like SOME_CONST | $dynamicInt it answered a definite "no" for a flag the dynamic operand may well contain. The correct trinary is left->or(right): yes if either side definitely contains the flag, no only if both sides definitely don't, maybe otherwise.

Callers acting on ->no() were affected:

  • JsonThrowTypeExtension no longer reports a false-positive "Dead catch - JsonException" for json_encode()/json_decode() called with JSON_X | $dynamicFlags, and correctly attributes a possible JsonException throw type to such calls.
  • PregSplitDynamicReturnTypeExtension now keeps the array{string, int<0, max>} element shape in the return type when PREG_SPLIT_OFFSET_CAPTURE may be present in dynamic flags.

Callers acting only on ->yes() are unaffected.

The BitwiseOr branch of bitwiseOrContainsConstant() returned
createFromBoolean(left->yes() || right->yes()), collapsing "maybe" to
"no". For an expression like SOME_CONST | $dynamicInt it answered a
definite "no" for a flag the dynamic operand may well contain. The
correct trinary is left->or(right): yes if either side definitely
contains the flag, no only if both sides definitely don't, maybe
otherwise.

Callers acting on ->no() were affected:
- JsonThrowTypeExtension no longer reports a false-positive
  "Dead catch - JsonException" for json_encode()/json_decode() called
  with JSON_X | $dynamicFlags, and correctly attributes a possible
  JsonException throw type to such calls.
- PregSplitDynamicReturnTypeExtension now keeps the
  array{string, int<0, max>} element shape in the return type when
  PREG_SPLIT_OFFSET_CAPTURE may be present in dynamic flags.

Callers acting only on ->yes() are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@staabm
staabm requested a review from VincentLanglet July 21, 2026 19:12
@staabm
staabm merged commit 1671b81 into phpstan:2.2.x Jul 21, 2026
814 of 817 checks passed
@staabm

staabm commented Jul 21, 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