Merge pull request #15011 from Microsoft/limitDeepInstantiations

Limit deep generic type instantiations
This commit is contained in:
Anders Hejlsberg 2017-04-04 20:28:33 -07:00 committed by GitHub
commit 9d2b57ad9e
5 changed files with 53 additions and 7 deletions

View File

@ -47,6 +47,7 @@ namespace ts {
let typeCount = 0;
let symbolCount = 0;
let symbolInstantiationDepth = 0;
const emptyArray: any[] = [];
const emptySymbols = createMap<Symbol>();
@ -4449,14 +4450,22 @@ namespace ts {
function getTypeOfInstantiatedSymbol(symbol: Symbol): Type {
const links = getSymbolLinks(symbol);
if (!links.type) {
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
return unknownType;
if (symbolInstantiationDepth === 100) {
error(symbol.valueDeclaration, Diagnostics.Generic_type_instantiation_is_excessively_deep_and_possibly_infinite);
links.type = unknownType;
}
let type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
if (!popTypeResolution()) {
type = reportCircularityError(symbol);
else {
if (!pushTypeResolution(symbol, TypeSystemPropertyName.Type)) {
return unknownType;
}
symbolInstantiationDepth++;
let type = instantiateType(getTypeOfSymbol(links.target), links.mapper);
symbolInstantiationDepth--;
if (!popTypeResolution()) {
type = reportCircularityError(symbol);
}
links.type = type;
}
links.type = type;
}
return links.type;
}
@ -7266,8 +7275,9 @@ namespace ts {
else {
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
}
return unknownType;
}
return unknownType;
return anyType;
}
function getIndexedAccessForMappedType(type: MappedType, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode) {

View File

@ -1827,6 +1827,10 @@
"category": "Error",
"code": 2549
},
"Generic type instantiation is excessively deep and possibly infinite.": {
"category": "Error",
"code": 2550
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600

View File

@ -0,0 +1,15 @@
tests/cases/compiler/limitDeepInstantiations.ts(3,35): error TS2550: Generic type instantiation is excessively deep and possibly infinite.
tests/cases/compiler/limitDeepInstantiations.ts(5,13): error TS2344: Type '"false"' does not satisfy the constraint '"true"'.
==== tests/cases/compiler/limitDeepInstantiations.ts (2 errors) ====
// Repro from #14837
type Foo<T extends "true", B> = { "true": Foo<T, Foo<T, B>> }[T];
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2550: Generic type instantiation is excessively deep and possibly infinite.
let f1: Foo<"true", {}>;
let f2: Foo<"false", {}>;
~~~~~~~
!!! error TS2344: Type '"false"' does not satisfy the constraint '"true"'.

View File

@ -0,0 +1,12 @@
//// [limitDeepInstantiations.ts]
// Repro from #14837
type Foo<T extends "true", B> = { "true": Foo<T, Foo<T, B>> }[T];
let f1: Foo<"true", {}>;
let f2: Foo<"false", {}>;
//// [limitDeepInstantiations.js]
// Repro from #14837
var f1;
var f2;

View File

@ -0,0 +1,5 @@
// Repro from #14837
type Foo<T extends "true", B> = { "true": Foo<T, Foo<T, B>> }[T];
let f1: Foo<"true", {}>;
let f2: Foo<"false", {}>;