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

From: Date: Fri, 15 May 2026 11:10:45 +0000
Subject: Re: [RFC] [Discussion] Bound-Erased Generic Types
References: 1 2 3  Groups: php.internals 
Request: Send a blank email to internals+get-130886@lists.php.net to get a copy of this message
On 15 May 2026 00:32:05 BST, Seifeddine Gmati <azjezz@carthage.software> wrote: >Generic type information currently lives in optional levels because it >lives in optional syntax (docblocks). This is, quite frankly, nonsense. If you write a function with no native type information, but an "@return int" docblock, PHPStan will report an error for a missing return statement at Level 0, and for an incorrect return statement on Level 3. There's no relationship between the syntax needed and the types of analysis performed. > That's the point: native syntax means the language >did the work, and tools surface violations at whatever strictness the >user already has configured. As Daniil pointed out, SA tools analyse code with offline parsers, not by loading and reflecting it; so the native enforcement of arity etc will still need to be reimplemented in each tool. The RFC will act as a standardisation of what tools *should* enforce around those things; but that could equally be done by agreeing a set of conformance tests based on the existing docblock syntax. In fact, those conformance tests would be needed whatever the syntax, if the goal is to eliminate different handling in different tools. >The actual situation is that PHP has a runtime-checked layer (what the >engine validates) and an SA-checked layer (what tools verify). The two >layers complement each other. Native generics formalize a part of the >SA-checked layer that the engine can partially absorb. I can agree with this framing. I think where we differ is that you see unifying those layers in one syntax as a good thing, but I see it as a bad thing: I think it is useful to be able to look at the code, and understand which parts are definitely going to be enforced by the runtime-checked layer. I think the ideal is to somehow create a standardised syntax for the SA-checked layer, but still keep it separate from the syntax for the runtime-checked layer. If neither docblocks nor attributes are a good basis for that, maybe there's some other primitive we can add so that users can mark both the "runtime type" and the "SA type". Straw man example: class Foo ~~Foo<T> extends Bar ~~Bar<int,T> { public function foo(string ~~non-empty-string $in): array ~~list<T> { .. Maybe PHP would process the syntax, but not the semantics, of the extra type information; SA tools would then be free to invent new pseudotypes within that framework, without needing to wait for a full PHP release cycle every time. Rowan Tommins [IMSoP]

« previous php.internals (#130886) next »