Skip to content

Do not report maybe in RandomIntParametersRule when either argument is an unbounded IntegerRangeType#5622

Merged
staabm merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-2ipg1d6
May 10, 2026
Merged

Do not report maybe in RandomIntParametersRule when either argument is an unbounded IntegerRangeType#5622
staabm merged 2 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-2ipg1d6

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Summary

RandomIntParametersRule was reporting false-positive maybe errors for random_int() calls where one or both arguments had unbounded integer range types (e.g. int<0, max>). This happened because the rule already skips plain int (IntegerType) but treated unbounded IntegerRangeType values differently, even though they carry the same level of uncertainty about the relationship between min and max.

Changes

  • Modified src/Rules/Functions/RandomIntParametersRule.php to suppress maybe reports when either the min or max argument type is an IntegerRangeType with an unbounded end (null min or null max). Definite (yes) errors are still reported even for unbounded ranges.
  • Added regression test in tests/PHPStan/Rules/Functions/data/bug-14468.php covering:
    • The original issue: random_int() inside a while ($min < $max) loop with strlen-based max
    • Both arguments with unbounded max (int<0, max>)
    • Both arguments with unbounded min (int<min, 0>)
    • Unbounded min arg with bounded max arg
    • Bounded min arg with unbounded max arg
    • Unbounded ranges where the result is definitely wrong (int<5, max> vs int<min, 3>) — still correctly reported

Root cause

The rule checks $maxType->isSmallerThan($minType) and reports when the result is maybe (with reportMaybes enabled). For unbounded ranges like int<0, max>, isSmallerThan trivially returns maybe because unbounded ranges overlap with almost everything. The rule already had a bail-out for plain int (IntegerType) at lines 59-63, but IntegerRangeType with one null bound was not covered by that bail-out.

The fix extends the maybe suppression to also cover unbounded IntegerRangeType, making it consistent with the existing IntegerType handling.

Searched for analogous rules using isSmallerThanRandomIntParametersRule is the only consumer, so no other rules are affected.

Test

  • testBug14468 in RandomIntParametersRuleTest — verifies no errors for unbounded range combinations and still reports errors for definitely-wrong unbounded combinations.
  • All existing tests (testFile, testBug6361) continue to pass unchanged.

Fixes phpstan/phpstan#14468

staabm and others added 2 commits May 9, 2026 14:49
…nt is an unbounded `IntegerRangeType`

- The rule already skips plain `int` (IntegerType) since the comparison is inherently uncertain, but it was reporting `maybe` errors for unbounded IntegerRangeType values like `int<0, max>` or `int<min, 0>`, which are equally uncertain.
- When `isSmallerThan` returns `maybe`, now also skip if either argument's type is an IntegerRangeType with a null min or null max bound.
- Definite (`yes`) errors with unbounded ranges are still reported correctly (e.g. `random_int(int<5, max>, int<min, 3>)` where max <= 3 < 5 <= min).
- No analogous rules exist — `RandomIntParametersRule` is the only rule using `isSmallerThan`.
@staabm staabm requested a review from VincentLanglet May 9, 2026 15:02
Copy link
Copy Markdown
Contributor

@VincentLanglet VincentLanglet left a comment

Choose a reason for hiding this comment

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

Dunno if we should confirm this with ondrej...

@staabm
Copy link
Copy Markdown
Contributor

staabm commented May 10, 2026

I remember we did similar thibgs somewhere else

@staabm staabm merged commit 7896148 into phpstan:2.1.x May 10, 2026
660 of 661 checks passed
@staabm staabm deleted the create-pull-request/patch-2ipg1d6 branch May 10, 2026 09:23
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