On 9 June 2026 08:26:12 BST, Brent Roose <[email protected]> wrote:
>To reiterate what I've said before: generics aren't a runtime tool.
Generics are as much a runtime tool - or as little - as any other type
declaration. If it is useful to enforce "function foo(int $bar): int" at
runtime, it is equally useful to enforce "function foo<T>(T $bar): T" at
runtime.
A mode which erases all runtime checks which can be proven statically would be
a valuable addition. Again, we're into "ship a native analyser" territory,
though, because you have to know which types can be trusted, and which are
still unchecked.
Importantly, you can't rely on static analysis outside of a closed system - a
library can't choose to erase all types, and still make assumptions in code
based on users not passing other types.
PHPStan has a specific setting to account for this:
> PHPStan by default doesn’t differentiate between PHPDoc and native types. It
> considers them both as certain.
>
> This might not be what you want in case you’re writing a library whose users
> might pass a wrong argument type to a function. Setting
> treatPhpDocTypesAsCertain to false relaxes some of the rules around
> type-checking.
Replace "PHPDoc" with "erased" and the statement applies to the current
discussion. For example:
```
interface Foo<T: int|string> {
public function bar(): T;
}
function test(Foo<int> $foo): void {
$bar = $foo->bar();
if ( ! is_int($bar) ) {
throw new \TypeError('Expected an int');
}
}
```
If the generic type can be trusted, then the is_int() check is redundant and
can safely be removed. If generics are checked at runtime, it can be trusted;
if the final running system has been successfully analysed and proven correct,
it can be trusted. But analysing this code in isolation *can't* make it
trusted; and analyzing the final running system may find cases which can't be
proven until runtime.
As I understand it, the "partial erasure" approach, where the static analyser
decides which runtime checks are needed, is used by Dart:
https://dart.dev/language/type-system
Rowan Tommins
[IMSoP]