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

From: Date: Sat, 16 May 2026 18:07:50 +0000
Subject: Re: [RFC] [Discussion] Bound-Erased Generic Types
References: 1 2 3 4 5 6 7 8 9  Groups: php.internals 
Request: Send a blank email to internals+get-130913@lists.php.net to get a copy of this message
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. Cheers, Seifeddine >

« previous php.internals (#130913) next »