From b160808cfda4f9df9f0e14e1e269f48ccb74cacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 3 Jul 2023 17:15:52 +0200 Subject: [PATCH] Fixed variance measurement in type aliases of generic functions --- src/compiler/checker.ts | 9 ++++- .../complexRecursiveCollections.errors.txt | 9 ++++- .../complexRecursiveCollections.types | 2 +- .../reference/varianceAnnotations.errors.txt | 37 ++++++++++++++++++- .../reference/varianceAnnotations.js | 11 +++++- .../reference/varianceAnnotations.symbols | 34 +++++++++++++++++ .../reference/varianceAnnotations.types | 18 +++++++++ .../typeParameterLists/varianceAnnotations.ts | 6 +++ 8 files changed, 120 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0b67afefbb9d8..bca8fea0f0605 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1915,6 +1915,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var wildcardType = createIntrinsicType(TypeFlags.Any, "any"); var errorType = createIntrinsicType(TypeFlags.Any, "error"); var unresolvedType = createIntrinsicType(TypeFlags.Any, "unresolved"); + var erasedType = createIntrinsicType(TypeFlags.Any, "erased"); var nonInferrableAnyType = createIntrinsicType(TypeFlags.Any, "any", ObjectFlags.ContainsWideningType); var intrinsicMarkerType = createIntrinsicType(TypeFlags.Any, "intrinsic"); var unknownType = createIntrinsicType(TypeFlags.Unknown, "unknown"); @@ -16288,6 +16289,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { + if (type === erasedType) { + return includes; + } const flags = type.flags; // We ignore 'never' types in unions if (!(flags & TypeFlags.Never)) { @@ -16621,6 +16625,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function addTypeToIntersection(typeSet: Map, includes: TypeFlags, type: Type) { + if (type === erasedType) { + return includes; + } const flags = type.flags; if (flags & TypeFlags.Intersection) { return addTypesToIntersection(typeSet, includes, (type as IntersectionType).types); @@ -18681,7 +18688,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function createTypeEraser(sources: readonly TypeParameter[]): TypeMapper { - return createTypeMapper(sources, /*targets*/ undefined); + return createTypeMapper(sources, sources.map(() => erasedType)); } /** diff --git a/tests/baselines/reference/complexRecursiveCollections.errors.txt b/tests/baselines/reference/complexRecursiveCollections.errors.txt index 3f51359243a8f..bc52fbfe7d2e7 100644 --- a/tests/baselines/reference/complexRecursiveCollections.errors.txt +++ b/tests/baselines/reference/complexRecursiveCollections.errors.txt @@ -1,3 +1,6 @@ +immutable.ts(189,20): error TS2430: Interface 'Stack' incorrectly extends interface 'Indexed'. + The types returned by 'concat(...).filter(...)' are incompatible between these types. + Type 'Set' is not assignable to type 'Indexed'. immutable.ts(341,22): error TS2430: Interface 'Keyed' incorrectly extends interface 'Collection'. The types returned by 'toSeq()' are incompatible between these types. Type 'Keyed' is not assignable to type 'this'. @@ -33,7 +36,7 @@ immutable.ts(391,22): error TS2430: Interface 'Set' incorrectly extends inter flatMap(mapper: (value: T, key: void, iter: this) => Ara, context?: any): N2; toSeq(): N2; } -==== immutable.ts (3 errors) ==== +==== immutable.ts (4 errors) ==== // Test that complex recursive collections can pass the `extends` assignability check without // running out of memory. This bug was exposed in Typescript 2.4 when more generic signatures // started being checked. @@ -223,6 +226,10 @@ immutable.ts(391,22): error TS2430: Interface 'Set' incorrectly extends inter export function Stack(): Stack; export function Stack(collection: Iterable): Stack; export interface Stack extends Collection.Indexed { + ~~~~~ +!!! error TS2430: Interface 'Stack' incorrectly extends interface 'Indexed'. +!!! error TS2430: The types returned by 'concat(...).filter(...)' are incompatible between these types. +!!! error TS2430: Type 'Set' is not assignable to type 'Indexed'. // Reading values peek(): T | undefined; // Persistent changes diff --git a/tests/baselines/reference/complexRecursiveCollections.types b/tests/baselines/reference/complexRecursiveCollections.types index 0aa394d46b370..2a6a5c12d81a7 100644 --- a/tests/baselines/reference/complexRecursiveCollections.types +++ b/tests/baselines/reference/complexRecursiveCollections.types @@ -1139,7 +1139,7 @@ declare module Immutable { >Seq : typeof Seq function isSeq(maybeSeq: any): maybeSeq is Seq.Indexed | Seq.Keyed; ->isSeq : (maybeSeq: any) => maybeSeq is Indexed | Keyed +>isSeq : (maybeSeq: any) => maybeSeq is Keyed | Indexed >maybeSeq : any >Seq : any >Seq : any diff --git a/tests/baselines/reference/varianceAnnotations.errors.txt b/tests/baselines/reference/varianceAnnotations.errors.txt index d34477cce47d0..a5f78e6515e8d 100644 --- a/tests/baselines/reference/varianceAnnotations.errors.txt +++ b/tests/baselines/reference/varianceAnnotations.errors.txt @@ -64,9 +64,21 @@ varianceAnnotations.ts(160,68): error TS2345: Argument of type 'ActionObject<{ t Types of property '_storedEvent' are incompatible. Type '{ type: "PLAY"; value: number; } | { type: "RESET"; }' is not assignable to type '{ type: "PLAY"; value: number; }'. Type '{ type: "RESET"; }' is not assignable to type '{ type: "PLAY"; value: number; }'. +varianceAnnotations.ts(177,15): error TS2636: Type 'F1_53210' is not assignable to type 'F1_53210' as implied by variance annotation. + Types of parameters 'v' and 'v' are incompatible. + Type 'super-A' is not assignable to type 'sub-A'. +varianceAnnotations.ts(178,15): error TS2636: Type 'F2_53210' is not assignable to type 'F2_53210' as implied by variance annotation. + Types of parameters 'v2' and 'v2' are incompatible. + Type 'super-A' is not assignable to type 'sub-A'. +varianceAnnotations.ts(179,15): error TS2636: Type 'F3_53210' is not assignable to type 'F3_53210' as implied by variance annotation. + Types of parameters 'v2' and 'v2' are incompatible. + Type 'super-A' is not assignable to type 'sub-A'. +varianceAnnotations.ts(180,15): error TS2636: Type 'F4_53210' is not assignable to type 'F4_53210' as implied by variance annotation. + Types of parameters 'v' and 'v' are incompatible. + Type 'super-A' is not assignable to type 'sub-A'. -==== varianceAnnotations.ts (31 errors) ==== +==== varianceAnnotations.ts (35 errors) ==== type Covariant = { x: T; } @@ -338,4 +350,25 @@ varianceAnnotations.ts(160,68): error TS2345: Argument of type 'ActionObject<{ t return this; } } - \ No newline at end of file + + // https://github.com/microsoft/TypeScript/issues/53210#issuecomment-1468551245 + type F1_53210 = (v: X & A) => unknown; + ~~~~~ +!!! error TS2636: Type 'F1_53210' is not assignable to type 'F1_53210' as implied by variance annotation. +!!! error TS2636: Types of parameters 'v' and 'v' are incompatible. +!!! error TS2636: Type 'super-A' is not assignable to type 'sub-A'. + type F2_53210 = (v1: X, v2: A) => unknown; + ~~~~~ +!!! error TS2636: Type 'F2_53210' is not assignable to type 'F2_53210' as implied by variance annotation. +!!! error TS2636: Types of parameters 'v2' and 'v2' are incompatible. +!!! error TS2636: Type 'super-A' is not assignable to type 'sub-A'. + type F3_53210 = (v2: A) => X; + ~~~~~ +!!! error TS2636: Type 'F3_53210' is not assignable to type 'F3_53210' as implied by variance annotation. +!!! error TS2636: Types of parameters 'v2' and 'v2' are incompatible. +!!! error TS2636: Type 'super-A' is not assignable to type 'sub-A'. + type F4_53210 = (v: X | A) => unknown; + ~~~~~ +!!! error TS2636: Type 'F4_53210' is not assignable to type 'F4_53210' as implied by variance annotation. +!!! error TS2636: Types of parameters 'v' and 'v' are incompatible. +!!! error TS2636: Type 'super-A' is not assignable to type 'sub-A'. \ No newline at end of file diff --git a/tests/baselines/reference/varianceAnnotations.js b/tests/baselines/reference/varianceAnnotations.js index 558080cadc332..d8cca8239ebb7 100644 --- a/tests/baselines/reference/varianceAnnotations.js +++ b/tests/baselines/reference/varianceAnnotations.js @@ -175,7 +175,12 @@ let OuterC = class C { return this; } } - + +// https://github.com/microsoft/TypeScript/issues/53210#issuecomment-1468551245 +type F1_53210 = (v: X & A) => unknown; +type F2_53210 = (v1: X, v2: A) => unknown; +type F3_53210 = (v2: A) => X; +type F4_53210 = (v: X | A) => unknown; //// [varianceAnnotations.js] "use strict"; @@ -336,3 +341,7 @@ declare let OuterC: { foo(): any; }; }; +type F1_53210 = (v: X & A) => unknown; +type F2_53210 = (v1: X, v2: A) => unknown; +type F3_53210 = (v2: A) => X; +type F4_53210 = (v: X | A) => unknown; diff --git a/tests/baselines/reference/varianceAnnotations.symbols b/tests/baselines/reference/varianceAnnotations.symbols index 694821619912d..bbb7012c37714 100644 --- a/tests/baselines/reference/varianceAnnotations.symbols +++ b/tests/baselines/reference/varianceAnnotations.symbols @@ -482,3 +482,37 @@ let OuterC = class C { } } +// https://github.com/microsoft/TypeScript/issues/53210#issuecomment-1468551245 +type F1_53210 = (v: X & A) => unknown; +>F1_53210 : Symbol(F1_53210, Decl(varianceAnnotations.ts, 173, 1)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 176, 14)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 176, 24)) +>v : Symbol(v, Decl(varianceAnnotations.ts, 176, 27)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 176, 24)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 176, 14)) + +type F2_53210 = (v1: X, v2: A) => unknown; +>F2_53210 : Symbol(F2_53210, Decl(varianceAnnotations.ts, 176, 48)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 177, 14)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 177, 24)) +>v1 : Symbol(v1, Decl(varianceAnnotations.ts, 177, 27)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 177, 24)) +>v2 : Symbol(v2, Decl(varianceAnnotations.ts, 177, 33)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 177, 14)) + +type F3_53210 = (v2: A) => X; +>F3_53210 : Symbol(F3_53210, Decl(varianceAnnotations.ts, 177, 52)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 178, 14)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 178, 24)) +>v2 : Symbol(v2, Decl(varianceAnnotations.ts, 178, 27)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 178, 14)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 178, 24)) + +type F4_53210 = (v: X | A) => unknown; +>F4_53210 : Symbol(F4_53210, Decl(varianceAnnotations.ts, 178, 39)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 179, 14)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 179, 24)) +>v : Symbol(v, Decl(varianceAnnotations.ts, 179, 27)) +>X : Symbol(X, Decl(varianceAnnotations.ts, 179, 24)) +>A : Symbol(A, Decl(varianceAnnotations.ts, 179, 14)) + diff --git a/tests/baselines/reference/varianceAnnotations.types b/tests/baselines/reference/varianceAnnotations.types index 44fb8af0d7c8f..f9a3b77d5332d 100644 --- a/tests/baselines/reference/varianceAnnotations.types +++ b/tests/baselines/reference/varianceAnnotations.types @@ -371,3 +371,21 @@ let OuterC = class C { } } +// https://github.com/microsoft/TypeScript/issues/53210#issuecomment-1468551245 +type F1_53210 = (v: X & A) => unknown; +>F1_53210 : F1_53210 +>v : X & A + +type F2_53210 = (v1: X, v2: A) => unknown; +>F2_53210 : F2_53210 +>v1 : X +>v2 : A + +type F3_53210 = (v2: A) => X; +>F3_53210 : F3_53210 +>v2 : A + +type F4_53210 = (v: X | A) => unknown; +>F4_53210 : F4_53210 +>v : A | X + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts index d2abd84ce6963..c22850c2422db 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/varianceAnnotations.ts @@ -175,3 +175,9 @@ let OuterC = class C { return this; } } + +// https://github.com/microsoft/TypeScript/issues/53210#issuecomment-1468551245 +type F1_53210 = (v: X & A) => unknown; +type F2_53210 = (v1: X, v2: A) => unknown; +type F3_53210 = (v2: A) => X; +type F4_53210 = (v: X | A) => unknown; \ No newline at end of file