Hello internals,
Voting is now open on the Bound-Erased Generic Types RFC, as announced
in the Intent to Vote message earlier this week.
There are two votes on the RFC page:
- Primary vote, requires a 2/3 majority: accept the RFC as proposed.
- Secondary vote, simple majority, conditional on the primary
passing: variance marker syntax,+T/-T(Hack, Scala) vsin T/
out T(C#, Kotlin). Semantically identical; only the surface syntax
differs.
The vote started on 2026-06-14 at 16:50 UTC and ends on 2026-06-28 at 17:00 UTC.
RFC: https://wiki.php.net/rfc/bound_erased_generic_types
Discussion thread: https://news-web.php.net/php.internals/130816
Implementation: https://github.com/php/php-src/pull/21969
Cheers::<>,
Seifeddine.
Voting is now open on the Bound-Erased Generic Types RFC, as announced
in the Intent to Vote message earlier this week.RFC: https://wiki.php.net/rfc/bound_erased_generic_types
Discussion thread: https://news-web.php.net/php.internals/130816
Implementation: https://github.com/php/php-src/pull/21969
It will come as no surprise to those who followed the discussion that I
have voted "No".
For those who did not, my position in a nutshell is: I want PHP to have
generic types; but I want to be able to trust those types. This RFC does
not deliver that.
This is not a technical argument about "erased" vs "reified" vs
"monomorphized"; it's more philosophical: if there's native syntax,
there should be native enforcement of some kind.
There are several versions of this RFC I could have supported, for example:
- Separating out the parts which are enforced, at compile and link
time, and leaving more to Future Scope - An official tool which proved types statically, then erased them at
run-time - A new syntax for "untrusted" types, as a structured replacement to
docblocks
In its current form, I think it would be a step backwards for the
language's type system.
Currently, a reader seeing a native parameter, return, or property type
can trust that it will be enforced.
Additional unenforced types can be included in docblock annotations,
where human readers and tools can choose how much to trust them. For
example, the author of a library may document that users should pass
correct types, but still write defensive code for if they fail to do so.
As a quick example, in the below, the language guarantees that the
is_int() check is redundant:
function foo(int $bar) {
if ( ! is_int($bar) ) {
throw new \TypeError('Expected an int');
}
}
This RFC proposes to remove that guarantee, and use native syntax for
unenforced types.
In the code below, the is_int() call will not be redundant, because
the language will only guarantee a type of "int|string", despite the
native syntax indicating more:
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');
}
}
I would like to thank Seifeddine for the hard work, and although I hope
this RFC is not accepted, I also hope that others build on its
foundations to deliver much-needed generic types to the language.
Regards,
--
Rowan Tommins
[IMSoP]
- Secondary vote, simple majority, conditional on the primary
passing: variance marker syntax,+T/-T(Hack, Scala) vsin T/
out T(C#, Kotlin). Semantically identical; only the surface syntax
differs.
The second one is missing the Abstain option.
cheers
Derick