feat(variance)!: adopt Kotlin-style out/in variance markers#22
Merged
Conversation
Replace the Scala/Hack variance markers `+T` (covariant) / `-T` (contravariant) with `out T` / `in T`, matching the syntax selected for PHP's generics. `out`/`in` are contextual keywords: a plain identifier acts as a marker only when immediately followed by the parameter name (`out T`, never `outT`), so names that merely start with `out`/`in` stay ordinary parameters. `out` and `in` are reserved as markers and cannot name a type parameter (checked at the name slot, so `class Box<out>`, `class Box<out out>`, and `class Pair<in, out>` all fail with one clear diagnostic). The old `+T` / `-T` glyphs now raise an explicit migration error instead of an opaque downstream parse failure. Variance semantics, the `Variance` enum, and every downstream soundness pass are unchanged; only the surface spelling moves. Fixtures and parser tests migrated accordingly. BREAKING CHANGE: `+T` / `-T` variance syntax is no longer accepted; write `out T` / `in T`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The variance-position, unprovable-edge, and inner-variance diagnostics built their parameter display from the enum with the old `+`/`-` sigil, so a program written with `out T` / `in T` would be told its error is on `+T`. Render the marker as `out`/`in` to match the source syntax. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Update the syntax reference, comparison guide, ADRs, caveats, error catalogue, and changelog for the `out T` / `in T` spelling. Also correct the error catalogue's "verbatim" method-variance message (it had drifted to a paraphrase and said "not yet supported" for what is a permanent, by-design boundary) and fix the article agreement in the variance-position entry. Released changelog history is left as written. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the Scala/Hack-style declaration-site variance markers
+T(covariant) /-T(contravariant) with the Kotlin/C#-styleout T/in T, aligning xphp'ssurface syntax with the spelling chosen for PHP's generics. This is a hard swap:
+T/-Tare no longer accepted.Variance semantics are unchanged — the subtyping lift, position validation, edge
emission, and registry are identical. Only the surface spelling and the diagnostic
wording move; emitted PHP is byte-for-byte the same.
Details
out/inact as a marker only when immediately followedby the parameter name (
out T, neveroutT). Ordinary parameters whose names merelystart with those letters (
outer,input,outT) are unaffected.out/incannot themselves name a type parameter, soclass Box<out>,class Box<out out>, andclass Pair<in, out>fail with a singleclear diagnostic.
+T/-Tsource now raises an explicit error pointing atthe new spelling instead of an opaque downstream parse failure.
xphp.variance_position, unprovable-edge warnings, inner-variancecomposition) now render
out T/in Tto match what the user wrote.