Skip to content

Remove reportErrors check in relateVariances #55222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
10 changes: 8 additions & 2 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22810,6 +22810,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
tracing?.pop();
}

// if (entry !== undefined) {
// // If the previous entry and the result disagree, then something has gone wrong.
// const entrySucceeded = !!(entry & RelationComparisonResult.Succeeded);
// const resultSucceeded = result !== Ternary.False;
// Debug.assertEqual(entrySucceeded, resultSucceeded, "Cached relationship does not match recalculated result");
// }

if (outofbandVarianceMarkerHandler) {
outofbandVarianceMarkerHandler = originalHandler;
}
Expand Down Expand Up @@ -23522,9 +23529,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// types are invariant, if any of the type parameters are invariant we reset the reported
// errors and instead force a structural comparison (which will include elaborations that
// reveal the reason).
// We can switch on `reportErrors` here, since varianceCheckFailed guarantees we return `False`,
// we can return `False` early here to skip calculating the structural error message we don't need.
if (varianceCheckFailed && !(reportErrors && some(variances, v => (v & VarianceFlags.VarianceMask) === VarianceFlags.Invariant))) {
if (varianceCheckFailed && !some(variances, v => (v & VarianceFlags.VarianceMask) === VarianceFlags.Invariant)) {
return Ternary.False;
}
// We remember the original error information so we can restore it in case the structural
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//// [tests/cases/compiler/conditionalTypeDoesntSpinForever.ts] ////

=== Performance Stats ===
Type Count: 1,000
Instantiation count: 2,500 -> 5,000
Assignability cache: 1,000
Type Count: 2,500
Instantiation count: 5,000

=== conditionalTypeDoesntSpinForever.ts ===
// A *self-contained* demonstration of the problem follows...
Expand Down
45 changes: 45 additions & 0 deletions tests/baselines/reference/issue55217.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//// [tests/cases/compiler/issue55217.ts] ////

//// [types.ts]
export type ProductName = 'a' | 'b'

export type SubproductNameForProductName<P extends ProductName> = P extends unknown
? keyof EntitiesByProductName[P]
: never

type EntitiesByProductName = {
a: { a1: { value: 'a-a1' } }
b: { b1: { value: 'b-b1' } }
}

export type DiscriminatedUnion<
P extends ProductName = ProductName,
E extends SubproductNameForProductName<P> = SubproductNameForProductName<P>,
> = P extends ProductName
? E extends SubproductNameForProductName<P>
// ? E extends unknown // With unknown, the exception doesn't happen.
? EntitiesByProductName[P][E]
: never
: never

//// [app.ts]
import { SubproductNameForProductName, DiscriminatedUnion, ProductName } from './types'

export const bug = <P extends ProductName>() => {
const subproducts: DiscriminatedUnion<P, SubproductNameForProductName<P>>[] = []
subproducts.map((_: DiscriminatedUnion) => null)
}


//// [types.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//// [app.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.bug = void 0;
var bug = function () {
var subproducts = [];
subproducts.map(function (_) { return null; });
};
exports.bug = bug;
91 changes: 91 additions & 0 deletions tests/baselines/reference/issue55217.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//// [tests/cases/compiler/issue55217.ts] ////

=== types.ts ===
export type ProductName = 'a' | 'b'
>ProductName : Symbol(ProductName, Decl(types.ts, 0, 0))

export type SubproductNameForProductName<P extends ProductName> = P extends unknown
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(types.ts, 0, 35))
>P : Symbol(P, Decl(types.ts, 2, 41))
>ProductName : Symbol(ProductName, Decl(types.ts, 0, 0))
>P : Symbol(P, Decl(types.ts, 2, 41))

? keyof EntitiesByProductName[P]
>EntitiesByProductName : Symbol(EntitiesByProductName, Decl(types.ts, 4, 9))
>P : Symbol(P, Decl(types.ts, 2, 41))

: never

type EntitiesByProductName = {
>EntitiesByProductName : Symbol(EntitiesByProductName, Decl(types.ts, 4, 9))

a: { a1: { value: 'a-a1' } }
>a : Symbol(a, Decl(types.ts, 6, 30))
>a1 : Symbol(a1, Decl(types.ts, 7, 6))
>value : Symbol(value, Decl(types.ts, 7, 12))

b: { b1: { value: 'b-b1' } }
>b : Symbol(b, Decl(types.ts, 7, 30))
>b1 : Symbol(b1, Decl(types.ts, 8, 6))
>value : Symbol(value, Decl(types.ts, 8, 12))
}

export type DiscriminatedUnion<
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(types.ts, 9, 1))

P extends ProductName = ProductName,
>P : Symbol(P, Decl(types.ts, 11, 31))
>ProductName : Symbol(ProductName, Decl(types.ts, 0, 0))
>ProductName : Symbol(ProductName, Decl(types.ts, 0, 0))

E extends SubproductNameForProductName<P> = SubproductNameForProductName<P>,
>E : Symbol(E, Decl(types.ts, 12, 38))
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(types.ts, 0, 35))
>P : Symbol(P, Decl(types.ts, 11, 31))
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(types.ts, 0, 35))
>P : Symbol(P, Decl(types.ts, 11, 31))

> = P extends ProductName
>P : Symbol(P, Decl(types.ts, 11, 31))
>ProductName : Symbol(ProductName, Decl(types.ts, 0, 0))

? E extends SubproductNameForProductName<P>
>E : Symbol(E, Decl(types.ts, 12, 38))
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(types.ts, 0, 35))
>P : Symbol(P, Decl(types.ts, 11, 31))

// ? E extends unknown // With unknown, the exception doesn't happen.
? EntitiesByProductName[P][E]
>EntitiesByProductName : Symbol(EntitiesByProductName, Decl(types.ts, 4, 9))
>P : Symbol(P, Decl(types.ts, 11, 31))
>E : Symbol(E, Decl(types.ts, 12, 38))

: never
: never

=== app.ts ===
import { SubproductNameForProductName, DiscriminatedUnion, ProductName } from './types'
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(app.ts, 0, 8))
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(app.ts, 0, 38))
>ProductName : Symbol(ProductName, Decl(app.ts, 0, 58))

export const bug = <P extends ProductName>() => {
>bug : Symbol(bug, Decl(app.ts, 2, 12))
>P : Symbol(P, Decl(app.ts, 2, 20))
>ProductName : Symbol(ProductName, Decl(app.ts, 0, 58))

const subproducts: DiscriminatedUnion<P, SubproductNameForProductName<P>>[] = []
>subproducts : Symbol(subproducts, Decl(app.ts, 3, 7))
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(app.ts, 0, 38))
>P : Symbol(P, Decl(app.ts, 2, 20))
>SubproductNameForProductName : Symbol(SubproductNameForProductName, Decl(app.ts, 0, 8))
>P : Symbol(P, Decl(app.ts, 2, 20))

subproducts.map((_: DiscriminatedUnion) => null)
>subproducts.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
>subproducts : Symbol(subproducts, Decl(app.ts, 3, 7))
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
>_ : Symbol(_, Decl(app.ts, 4, 19))
>DiscriminatedUnion : Symbol(DiscriminatedUnion, Decl(app.ts, 0, 38))
}

84 changes: 84 additions & 0 deletions tests/baselines/reference/issue55217.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//// [tests/cases/compiler/issue55217.ts] ////

=== types.ts ===
export type ProductName = 'a' | 'b'
>ProductName : ProductName
> : ^^^^^^^^^^^

export type SubproductNameForProductName<P extends ProductName> = P extends unknown
>SubproductNameForProductName : SubproductNameForProductName<P>
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

? keyof EntitiesByProductName[P]
: never

type EntitiesByProductName = {
>EntitiesByProductName : EntitiesByProductName
> : ^^^^^^^^^^^^^^^^^^^^^

a: { a1: { value: 'a-a1' } }
>a : { a1: { value: "a-a1"; }; }
> : ^^^^^^ ^^^
>a1 : { value: "a-a1"; }
> : ^^^^^^^^^ ^^^
>value : "a-a1"
> : ^^^^^^

b: { b1: { value: 'b-b1' } }
>b : { b1: { value: "b-b1"; }; }
> : ^^^^^^ ^^^
>b1 : { value: "b-b1"; }
> : ^^^^^^^^^ ^^^
>value : "b-b1"
> : ^^^^^^
}

export type DiscriminatedUnion<
>DiscriminatedUnion : DiscriminatedUnion<P, E>
> : ^^^^^^^^^^^^^^^^^^^^^^^^

P extends ProductName = ProductName,
E extends SubproductNameForProductName<P> = SubproductNameForProductName<P>,
> = P extends ProductName
? E extends SubproductNameForProductName<P>
// ? E extends unknown // With unknown, the exception doesn't happen.
? EntitiesByProductName[P][E]
: never
: never

=== app.ts ===
import { SubproductNameForProductName, DiscriminatedUnion, ProductName } from './types'
>SubproductNameForProductName : any
> : ^^^
>DiscriminatedUnion : any
> : ^^^
>ProductName : any
> : ^^^

export const bug = <P extends ProductName>() => {
>bug : <P extends ProductName>() => void
> : ^ ^^^^^^^^^ ^^^^^^^^^^^
><P extends ProductName>() => { const subproducts: DiscriminatedUnion<P, SubproductNameForProductName<P>>[] = [] subproducts.map((_: DiscriminatedUnion) => null)} : <P extends ProductName>() => void
> : ^ ^^^^^^^^^ ^^^^^^^^^^^

const subproducts: DiscriminatedUnion<P, SubproductNameForProductName<P>>[] = []
>subproducts : DiscriminatedUnion<P, SubproductNameForProductName<P>>[]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>[] : never[]
> : ^^^^^^^

subproducts.map((_: DiscriminatedUnion) => null)
>subproducts.map((_: DiscriminatedUnion) => null) : null[]
> : ^^^^^^
>subproducts.map : <U>(callbackfn: (value: DiscriminatedUnion<P, SubproductNameForProductName<P>>, index: number, array: DiscriminatedUnion<P, SubproductNameForProductName<P>>[]) => U, thisArg?: any) => U[]
> : ^ ^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^
>subproducts : DiscriminatedUnion<P, SubproductNameForProductName<P>>[]
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>map : <U>(callbackfn: (value: DiscriminatedUnion<P, SubproductNameForProductName<P>>, index: number, array: DiscriminatedUnion<P, SubproductNameForProductName<P>>[]) => U, thisArg?: any) => U[]
> : ^ ^^ ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^ ^^^^^^^^
>(_: DiscriminatedUnion) => null : (_: DiscriminatedUnion) => null
> : ^ ^^ ^^^^^^^^^
>_ : DiscriminatedUnion
> : ^^^^^^^^^^^^^^^^^^
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
=== Performance Stats ===
Assignability cache: 10,000
Type Count: 25,000
Instantiation count: 250,000 -> 500,000
Instantiation count: 500,000
Symbol count: 100,000

=== styledComponentsInstantiaionLimitNotReached.ts ===
Expand Down
31 changes: 31 additions & 0 deletions tests/cases/compiler/issue55217.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// @strict: true

// @filename: types.ts
export type ProductName = 'a' | 'b'

export type SubproductNameForProductName<P extends ProductName> = P extends unknown
? keyof EntitiesByProductName[P]
: never

type EntitiesByProductName = {
a: { a1: { value: 'a-a1' } }
b: { b1: { value: 'b-b1' } }
}

export type DiscriminatedUnion<
P extends ProductName = ProductName,
E extends SubproductNameForProductName<P> = SubproductNameForProductName<P>,
> = P extends ProductName
? E extends SubproductNameForProductName<P>
// ? E extends unknown // With unknown, the exception doesn't happen.
? EntitiesByProductName[P][E]
: never
: never

// @filename: app.ts
import { SubproductNameForProductName, DiscriminatedUnion, ProductName } from './types'

export const bug = <P extends ProductName>() => {
const subproducts: DiscriminatedUnion<P, SubproductNameForProductName<P>>[] = []
subproducts.map((_: DiscriminatedUnion) => null)
}