On Mon, Jun 15, 2026, at 20:22, Matthew Brown wrote: > On Mon, 15 Jun 2026 at 12:28, Levi Morrison <[email protected]> > wrote: >> > Voting is now open on the Bound-Erased Generic Types RFC, as announced >> > in the Intent to Vote message earlier this week. >> > >> > 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 >> >> To my own surprise, I am voting yes on this proposal. >> >> I still believe that refied generics should be the goal. To that end, >> I think we should be able to merge this and in minor versions, fix >> "soundness" and implementation holes as "bug" fixes on that route. If >> internals can agree on this, and then the community can communicate >> this through education, promotion, documentation, etc, then this RFC >> is simply a useful stepping stone. >> >> This is based on my own experience playing with the RFC, which >> included reporting 2 bugs in the implementation on the RFC. To be >> honest, it's not too useful to me. I very quickly run up against some >> limitation when trying to build useful things. Most notably, we need >> to be able to define lower bounds (syntax pending, obviously): >> >> class Option<+A> >> { >> // B >: A means B is an ancestor of A >> // Since all As are Bs, you can return the A here >> function get_or_default<B >: A>(Option $option, B $default): B >> { >> return $option->has_some() >> ? $option->get() >> : $default; >> } >> // todo: the rest of the implementation >> } >> >> You can't take `A $default` and return `A` because this violates the >> variance laws: a covariant type A cannot be used in parameter >> position. So alternatively you could solve this with `inout A >> $default` or similar. > > Presumably this would work with the current proposal: > > class Option<+A> { > public function getOrDefault<B>(B $default): A|B { > return $this->hasSome() ? $this->get() : $default; > } > } > > Hack also has `super` type constraints: > https://hhvm.com/blog/9215/covariance-contravariance-and-super-type-constraints
It wouldn’t actually do anything though… — Rob
