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

From: Date: Thu, 04 Jun 2026 15:08:04 +0000
Subject: Re: [RFC] [Discussion] Bound-Erased Generic Types
References: 1 2 3 4  Groups: php.internals 
Request: Send a blank email to internals+get-131141@lists.php.net to get a copy of this message
On 4 June 2026 11:58:46 BST, "Ondřej Mirtes" <ondrej@mirtes.cz> wrote: > On 4. 6. 2026 at 12:29:42, Ondřej Mirtes <ondrej@mirtes.cz> wrote: > >> ’d also like to point out a few places in currently shipping PHP version >> where you can put types in native syntax and they are not checked at >> runtime, meaning completely wrong and non-existent types are silently being >> accepted or skipped. >> > >I just remembered one more place: attributes. Interestingly, all of these examples effectively make the *opposite* check to what Seifeddine is proposing: the *name* is unchecked, but the *value* compared to it is always rejected as not matching. In "function foo(Nonesuch $x) {}", there is no complaint that "Nonesuch" is not a valid class, but the function can't be called because no parameter matches. In the proposed "function foo(Container<Nonesuch> $x)", the bounds checking will require Nonesuch to exist, but the function can be called with any instance of Collection. The function would be callable even if an instance of Nonesuch was impossible to create (an interface with no implementations, or a final private constructor, etc). None of your examples breaks the invariant "if I mark a value as requiring a particular type, I can be sure that reading that value will give me a value of that type". The only marginal case would be parameters to attributes, which can be read through reflection without running the constructor, and therefore without validating the types specified in that constructor. But that's in keeping with the power of reflection to bypass the language's normal invariants, e.g. newInstanceWithoutConstructor, setAccessible, etc So I do think what Seifeddine is proposing is unprecedented in that sense. Rowan Tommins [IMSoP]

« previous php.internals (#131141) next »