Re: [RFC] [Discussion] Bound-Erased Generic Types

From: Date: Sat, 16 May 2026 19:24:04 +0000
Subject: Re: [RFC] [Discussion] Bound-Erased Generic Types
References: 1 2 3 4 5 6 7 8 9 10  Groups: php.internals 
Request: Send a blank email to internals+get-130915@lists.php.net to get a copy of this message
Le sam. 16 mai 2026 à 20:08, Seifeddine Gmati <azjezz@carthage.software> a écrit : > Hi Nicolas, > > I'd like to push back on the inheritance-BC framing. The claim that > bounded types have no sensible default or wildcard is not quite accurate; > defaults can be any type expression that satisfies the bound, including the > bound itself. > > For example, consider this docblock: > > ``` > /** > * @template Id of string|object > * @template T of UserInterface > */ > interface UserProvider { > /** > * @param Id $id > * @return T|null > */ > public function load(string|object $id): null|UserInterface; > } > ``` > > Under this RFC, the migration would be: > > ``` > interface UserProvider< > Id : string|object = string|object, > T : UserInterface = UserInterface, > > { > public function load(Id $id): T|null; > } > ``` > > By using the bounds themselves as defaults, every existing implementer > continues to work unchanged: > > ``` > class DummyProvider implements UserProvider { > public function load(string|object $x): ?UserInterface { > return null; > } > } > ``` > > This is the general pattern: for any bounded type parameter, the widest > legal default is the bound itself. There is no shape of generic declaration > where a library cannot supply a default that satisfies its own bound. > > The migration story for adding generics to existing classes is to declare > parameters with the bound as the default. Every existing subclass continues > to compile and run, while downstream code can specialize on its own > schedule. > > Consequently, the deprecation-window proposal addresses a problem that > doesn't exist if defaults are used correctly. If a library declares > defaults equal to its bounds, missing arguments resolve to those defaults, > maintaining existing behavior. A deprecation window would only be necessary > if an author chooses not to provide sensible defaults. > > I don't see a need to bake a deprecation window into the RFC. The existing > mechanism (using defaults equal to bounds), already covers the migration > path for zero-BC adoption. > Ah I didn't get this at first, thanks for bringing my attention there. I was focused on clarifying an adoption path and it looks like there is one already. I think this is worth a new section in the RFC; telling the community how the adoption can be made smooth (or not - aka no defaults). Then we might need a way to deprecate relying on a default. Likely not for this iteration. I think you answered all my concerns. Thanks! Nicolas

« previous php.internals (#130915) next »