ord() returns int<0, 255>ord('A') to int<0, 255> is valid only when the call is typed
as the range rather than as plain int (int is not a subtype of
int<0, 255>). Passing it to a disjoint range is the rejection probe.
Source: vimeo/psalm#10676 (5.22.0).
References:
- psalm#10676
- phpdoc_advanced_fallback_int_range for the spelling itself| Analyzer | Version | Result | Diagnostics |
|---|---|---|---|
| phan | 6.0.11Phan 6.0.11 php-ast version 1.1.3 PHP version used to run Phan: 8.5.11 | Not enforced | No diagnostics reported.
|
| phpstan | 2.3.5PHPStan - PHP Static Analysis Tool 2.3.5 | Enforced reported Lv.5+ | native_types_ord_range.php:36: Parameter #1 $value of function Conformance\Tests\NativeTypesOrdRange\takesAboveByte expects int<256, max>, int<0, 255> given. [reported-from-level=5] With strict-rulesnative_types_ord_range.php:36: Parameter #1 $value of function Conformance\Tests\NativeTypesOrdRange\takesAboveByte expects int<256, max>, int<0, 255> given.
|
| psalm | 6.20.9Psalm 6.20.9@f67170ac3c3b931f5088681e21d6c8babc601c08 next: 7.0.4 |
Enforced | native_types_ord_range.php:36: Argument 1 of Conformance\Tests\NativeTypesOrdRange\takesAboveByte expects int<256, max>, but int<0, 255> provided [InvalidArgument]
|
| mago | 1.59.0mago 1.59.0 | Enforced | native_types_ord_range.php:36: Invalid argument type for argument #1 of `Conformance\Tests\NativeTypesOrdRange\takesAboveByte`: expected `int<256, max>`, but found `int<0, 255>`. [invalid-argument]
|
| mir | 0.91.0mir 0.91.0 | Enforced | native_types_ord_range.php:36: InvalidArgument: Argument $value of takesAboveByte() expects 'int<256, max>', got 'int<0, 255>' [MIR0201]
|
| phpantom | 0.11.1phpantom_lsp 0.11.1 | Enforced | native_types_ord_range.php:36: Argument 1 ($value) expects int<256, max>, got int<0, 255> [type_mismatch_argument]
|
| intelephense | 1.18.5intelephense 1.18.5 | Unrecognized | native_types_ord_range.php:29: PHPDoc undefined type 'Conformance\Tests\NativeTypesOrdRange\max'. [P1133]
|
| phpactor | 2026.10.07.0Phpactor 2026.10.07.0 | Not enforced | No diagnostics reported.
|
| phpy | 1.0.19490phpy 1.0.19490 | Not enforced | No diagnostics reported.
|
| qodana | 262.11879.104PhpStorm 262.11879.104 | Enforced | native_types_ord_range.php:36: Value ranges mismatch. Expected: <256, 2147483647>, Actual: <0, 255> [PhpParamsInspection]
|
| noverify | 0.5.5NoVerify, version 0.5.5: built on: 2025.04.22 14:36:46 OS: r-kuchinskas arm64 Commit: 4774b82f8adc53fbef38f95e97af4b953b4d1529 | Not enforced | No diagnostics reported.
|
| steins | 0.1.8steins 0.1.8 (2026-09-21 revision 76306a9) | Not enforced | No diagnostics reported.
|
| phpstan-strict | 2.3.5PHPStan - PHP Static Analysis Tool 2.3.5 | Enforced | native_types_ord_range.php:36: Parameter #1 $value of function Conformance\Tests\NativeTypesOrdRange\takesAboveByte expects int<256, max>, int<0, 255> given.
|
| psalm-next | 7.0.4Psalm 7.0.4@fa5b1f6e665cb743838ffd865b8fc96207f9409f | Enforced | native_types_ord_range.php:36: Argument 1 of Conformance\Tests\NativeTypesOrdRange\takesAboveByte expects int<256, max>, but int<0, 255> provided [InvalidArgument]
|
<?php
declare(strict_types=1);
namespace Conformance\Tests\NativeTypesOrdRange;
/**
* `ord()` returns `int<0, 255>`.
*
* Passing `ord('A')` to `int<0, 255>` is valid only when the call is typed
* as the range rather than as plain `int` (`int` is not a subtype of
* `int<0, 255>`). Passing it to a disjoint range is the rejection probe.
*
* Source: vimeo/psalm#10676 (5.22.0).
*
* References:
* - https://github.com/vimeo/psalm/pull/10676
* - phpdoc_advanced_fallback_int_range for the spelling itself
*/
/**
* @param int<0, 255> $value
*/
function takesByte($value): void // T: int<0, 255>
{
}
/**
* @param int<256, max> $value
*/
function takesAboveByte($value): void // T: int<256, max>
{
}
takesByte(ord('A')); // V: ord() is int<0, 255>
takesAboveByte(ord('A')); // E?: 65 is not in int<256, max>