Skip to content

Elide in/out variance modifiers from emitted JS#4156

Merged
jakebailey merged 2 commits into
mainfrom
copilot/fix-in-out-variance-modifiers
Jun 1, 2026
Merged

Elide in/out variance modifiers from emitted JS#4156
jakebailey merged 2 commits into
mainfrom
copilot/fix-in-out-variance-modifiers

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 1, 2026

in/out variance modifiers are only valid on type parameters, but when written (a grammar error) on a class member they were copied verbatim into the emitted JavaScript:

class C {
  in x = 1;
}
// before          // after
class C {          class C {
    in x = 1;          x = 1;
}                  }

Changes

  • internal/transformers/tstransforms/typeeraser.go: TypeEraserTransformer now elides KindInKeyword/KindOutKeyword modifier tokens alongside the other TypeScript-only modifiers. Since KindInKeyword is shared with the in binary operator, the token is only elided when its parent is not a BinaryExpression, so a in b and for…in are left untouched.
  • testdata/tests/cases/compiler/varianceModifiersOnClassMembers.ts (+ baselines): covers variance modifiers on class members together with the in operator and for…in to guard against over-elision.

The grammar diagnostic (TS1274) is unaffected and still reported.

Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix in/out variance modifiers leaking into emitted JS Elide in/out variance modifiers from emitted JS Jun 1, 2026
Copilot AI requested a review from jakebailey June 1, 2026 18:31
@jakebailey jakebailey marked this pull request as ready for review June 1, 2026 19:33
Copilot AI review requested due to automatic review settings June 1, 2026 19:33
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a regression where in/out variance modifiers (grammar errors when placed on class members rather than type parameters) were copied verbatim into emitted JavaScript. The TypeEraserTransformer now elides these tokens while preserving the in binary operator and for…in semantics.

Changes:

  • Add an InKeyword/OutKeyword case in TypeEraserTransformer.visit that elides the token unless its parent is a BinaryExpression.
  • Add a compiler test case (with .js, .types, .symbols, .errors.txt baselines) covering misplaced variance modifiers alongside in/for…in usage.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

File Description
internal/transformers/tstransforms/typeeraser.go Elides KindInKeyword/KindOutKeyword modifier tokens, guarded against the in binary operator via parent-node check.
testdata/tests/cases/compiler/varianceModifiersOnClassMembers.ts New test covering elision plus in operator/for…in preservation.
testdata/baselines/reference/compiler/varianceModifiersOnClassMembers.js Baseline showing variance modifiers stripped, in/for…in retained.
testdata/baselines/reference/compiler/varianceModifiersOnClassMembers.{types,symbols,errors.txt} Type/symbol/diagnostic baselines (TS1274 still reported).

@RyanCavanaugh
Copy link
Copy Markdown
Member

RyanCavanaugh commented Jun 1, 2026

Seems fine but I don't think we guarantee syntactic validity of output JS in the presence of malformed TS, which this is? I would have punted the original bug

Same category as

const q = ;

which emits as-is (syntax error in, syntax error out)

@jakebailey
Copy link
Copy Markdown
Member

A while back I added something to our test harness that verified that all output code parses, and it does; I think surprisingly it was an invariant, we just were lacking many tests.

@jakebailey jakebailey added this pull request to the merge queue Jun 1, 2026
@RyanCavanaugh
Copy link
Copy Markdown
Member

Yeah seems like a desirable property to have, even if Strada didn't have it

Merged via the queue into main with commit a980d86 Jun 1, 2026
22 checks passed
@jakebailey jakebailey deleted the copilot/fix-in-out-variance-modifiers branch June 1, 2026 20:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

in/out variance modifiers on a class member leak into the emitted JS

4 participants