Skip to content

Commit eac8907

Browse files
committed
Fixed a crash coming from hitting the instantiation depth limit
1 parent cdc205d commit eac8907

File tree

5 files changed

+141
-0
lines changed

5 files changed

+141
-0
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21027,6 +21027,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2102721027
// that perpetually generate new type identities, so we stop the recursion here by yielding the error type.
2102821028
tracing?.instant(tracing.Phase.CheckTypes, "instantiateType_DepthLimit", { typeId: type.id, instantiationDepth, instantiationCount });
2102921029
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
21030+
// set this to a max value to "propagate" the error through any further instantiations within the currently checked node
21031+
// this can skip a bunch of redundant work in the case of hitting the depth limit
21032+
instantiationCount = 5000000;
2103021033
return errorType;
2103121034
}
2103221035
const index = findActiveMapper(mapper);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
recursiveConditionalCrash5.ts(13,6): error TS2589: Type instantiation is excessively deep and possibly infinite.
2+
3+
4+
==== recursiveConditionalCrash5.ts (1 errors) ====
5+
// https://github.com/microsoft/TypeScript/issues/62966
6+
7+
type Prepend<Elm, T extends unknown[]> = T extends unknown
8+
? ((arg: Elm, ...rest: T) => void) extends (...args: infer T2) => void
9+
? T2
10+
: never
11+
: never;
12+
13+
type ExactExtract<T, U> = (T extends U ? U extends T ? T : never : never) & string;
14+
15+
type Conv<T, U = T> = {
16+
0: [T];
17+
1: Prepend<T, Conv<ExactExtract<U, T>>>;
18+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19+
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
20+
}[U extends T ? 0 : 1];
21+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//// [tests/cases/compiler/recursiveConditionalCrash5.ts] ////
2+
3+
=== recursiveConditionalCrash5.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/62966
5+
6+
type Prepend<Elm, T extends unknown[]> = T extends unknown
7+
>Prepend : Symbol(Prepend, Decl(recursiveConditionalCrash5.ts, 0, 0))
8+
>Elm : Symbol(Elm, Decl(recursiveConditionalCrash5.ts, 2, 13))
9+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 2, 17))
10+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 2, 17))
11+
12+
? ((arg: Elm, ...rest: T) => void) extends (...args: infer T2) => void
13+
>arg : Symbol(arg, Decl(recursiveConditionalCrash5.ts, 3, 6))
14+
>Elm : Symbol(Elm, Decl(recursiveConditionalCrash5.ts, 2, 13))
15+
>rest : Symbol(rest, Decl(recursiveConditionalCrash5.ts, 3, 15))
16+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 2, 17))
17+
>args : Symbol(args, Decl(recursiveConditionalCrash5.ts, 3, 46))
18+
>T2 : Symbol(T2, Decl(recursiveConditionalCrash5.ts, 3, 60))
19+
20+
? T2
21+
>T2 : Symbol(T2, Decl(recursiveConditionalCrash5.ts, 3, 60))
22+
23+
: never
24+
: never;
25+
26+
type ExactExtract<T, U> = (T extends U ? U extends T ? T : never : never) & string;
27+
>ExactExtract : Symbol(ExactExtract, Decl(recursiveConditionalCrash5.ts, 6, 10))
28+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 8, 18))
29+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 8, 20))
30+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 8, 18))
31+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 8, 20))
32+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 8, 20))
33+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 8, 18))
34+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 8, 18))
35+
36+
type Conv<T, U = T> = {
37+
>Conv : Symbol(Conv, Decl(recursiveConditionalCrash5.ts, 8, 83))
38+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
39+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 10, 12))
40+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
41+
42+
0: [T];
43+
>0 : Symbol(0, Decl(recursiveConditionalCrash5.ts, 10, 23))
44+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
45+
46+
1: Prepend<T, Conv<ExactExtract<U, T>>>;
47+
>1 : Symbol(1, Decl(recursiveConditionalCrash5.ts, 11, 9))
48+
>Prepend : Symbol(Prepend, Decl(recursiveConditionalCrash5.ts, 0, 0))
49+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
50+
>Conv : Symbol(Conv, Decl(recursiveConditionalCrash5.ts, 8, 83))
51+
>ExactExtract : Symbol(ExactExtract, Decl(recursiveConditionalCrash5.ts, 6, 10))
52+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 10, 12))
53+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
54+
55+
}[U extends T ? 0 : 1];
56+
>U : Symbol(U, Decl(recursiveConditionalCrash5.ts, 10, 12))
57+
>T : Symbol(T, Decl(recursiveConditionalCrash5.ts, 10, 10))
58+
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
//// [tests/cases/compiler/recursiveConditionalCrash5.ts] ////
2+
3+
=== Performance Stats ===
4+
Instantiation count: 5,000
5+
6+
=== recursiveConditionalCrash5.ts ===
7+
// https://github.com/microsoft/TypeScript/issues/62966
8+
9+
type Prepend<Elm, T extends unknown[]> = T extends unknown
10+
>Prepend : Prepend<Elm, T>
11+
> : ^^^^^^^^^^^^^^^
12+
13+
? ((arg: Elm, ...rest: T) => void) extends (...args: infer T2) => void
14+
>arg : Elm
15+
> : ^^^
16+
>rest : T
17+
> : ^
18+
>args : T2
19+
> : ^^
20+
21+
? T2
22+
: never
23+
: never;
24+
25+
type ExactExtract<T, U> = (T extends U ? U extends T ? T : never : never) & string;
26+
>ExactExtract : ExactExtract<T, U>
27+
> : ^^^^^^^^^^^^^^^^^^
28+
29+
type Conv<T, U = T> = {
30+
>Conv : Conv<T, U>
31+
> : ^^^^^^^^^^
32+
33+
0: [T];
34+
>0 : [T]
35+
> : ^^^
36+
37+
1: Prepend<T, Conv<ExactExtract<U, T>>>;
38+
>1 : Prepend<T, Conv<ExactExtract<U, T>, ExactExtract<U, T>>>
39+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
40+
41+
}[U extends T ? 0 : 1];
42+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/62966
5+
6+
type Prepend<Elm, T extends unknown[]> = T extends unknown
7+
? ((arg: Elm, ...rest: T) => void) extends (...args: infer T2) => void
8+
? T2
9+
: never
10+
: never;
11+
12+
type ExactExtract<T, U> = (T extends U ? U extends T ? T : never : never) & string;
13+
14+
type Conv<T, U = T> = {
15+
0: [T];
16+
1: Prepend<T, Conv<ExactExtract<U, T>>>;
17+
}[U extends T ? 0 : 1];

0 commit comments

Comments
 (0)