On Fri, May 15, 2026, at 7:09 AM, Nicolas Grekas wrote:
> Hi all,
>
> Thanks Seifeddine for putting this together. This is an impressive
> piece of work, and the general approach is sound to me. Looking forward
> to where this discussion lands; I hope we'll reach enough consensus to
> merge.
>
> Le ven. 15 mai 2026 à 13:13, Rowan Tommins [IMSoP]
> <[email protected]> a écrit :
>> On 15 May 2026 00:32:05 BST, Seifeddine Gmati <[email protected]>
>> 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'd like to put a syntax proposal on the table that may address Rowan's
> concern, and that also addresses something I'm worried about
> independently: the migration path for existing libraries.
>
> How does a library that uses @template docblocks today migrate to
> native syntax without forcing a BC break on its consumers? Multiplied
> across the libraries out there, this is a major point of tension for
> the ecosystem we need to anticipate.
> Existing @template annotations were adoptable gradually *because*
> they're invisible to the engine.
> Native <T> syntax, as the RFC proposes it, doesn't have that property:
> a library cannot adopt it without bumping its minimum PHP version and
> pulling all its consumers with it.
>
> We've solved this exact problem once before for attributes. The #[...]
> syntax was deliberately designed so older PHP versions would parse it
> as a # line comment, which is what made the adoption across the
> ecosystem so smooth.
Though recall that was an after-passage change; the original attribute syntax
was << >>, which everyone apparently hated, so we changed it twice in rapid
succession. (I am very very glad we did switch to the Rust-inspired syntax,
but just making sure the history is clear.)
> The same trick is available for generics if we pick the right
> delimiter. Concretely, write #<...> everywhere <...> appears in the
> current RFC: declarations, inheritance clauses, type uses in
> signatures, call-site arguments. One syntax, used uniformly.
>
> Three benefits, beyond the migration story:
>
> 1. FC for free. A library can adopt native generics in source today and
> continue running on older PHP versions, because the engine just sees
> comments. No need to coordinate with the min-PHP bump.
> 2. The turbofish goes away. No need to disambiguate < from less-than
> comparison. With #<...>, the token is unique and unambiguous
> everywhere: at declaration, use, and call site. We get to drop a whole
> grammar mechanism rather than introduce one.
> 3. Rowan's concern is addressed typographically. Anything inside #<...>
> is the erased, SA-enforced layer; everything outside follows the
> engine's normal runtime-checked rules.
>
> For codebases that want to adopt native generics while still supporting
> earlier PHP versions, #<...> would need to sit at the end of a line so
> older parsers consume it as a # line comment. Code targeting only
> generics-aware PHP can write it inline. The line-break constraint is a
> transitional code-style cost, not a permanent property of the syntax,
> and it's bounded by however long libraries support pre-generics
> versions.
>
> WDYT? I expect Seifeddine has good reasons to prefer the current
> syntax. I'd like to put this on the table because the FC story it
> unlocks, combined with the turbofish simplification, might be worth the
> trade-off and might help gather a broader consensus.
>
> Cheers,
> Nicolas
I'm not a huge fan of this approach. With attributes, most use cases already
had a natural line-break built in. The only one that didn't was parameter
attributes, and that was easy enough to work around by veritcalizing the
parameter list, which is already common practice when it gets long.
In this case, what you're proposing is I'd need to write something like this:
class Foo
#<Bar>
implements Baz
#<Beep>
{
public do(
#Bar
$bar) : List
#<string>
)
}
That's just disgusting. :-) I'm never going to do that. I'll just write it
properly, but now I have comment tags floating around my code forever that
aren't actually comments. Please, no.
Really, Attributes' FC-friendliness was a one-off. Pretty much any other new
syntax we've added has always been a "upgrade or get a parse error, deal", like
any other language. I realize Symfony and its BC policy puts it in a position
where a hard-cut to the new syntax would be harder than for most projects, but
the cost is just way too high.
--Larry Garfield