Skip to content

Commit 5b84512

Browse files
authored
Fix infinite recursion in control flow analyzer inlining logic (#45845)
* Move inlineLevel counter to main type checker scope * Add regression test
1 parent e03600f commit 5b84512

File tree

6 files changed

+91
-2
lines changed

6 files changed

+91
-2
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ namespace ts {
333333
let totalInstantiationCount = 0;
334334
let instantiationCount = 0;
335335
let instantiationDepth = 0;
336+
let inlineLevel = 0;
336337
let currentNode: Node | undefined;
337338

338339
const emptySymbols = createSymbolTable();
@@ -23247,7 +23248,6 @@ namespace ts {
2324723248
let key: string | undefined;
2324823249
let isKeySet = false;
2324923250
let flowDepth = 0;
23250-
let inlineLevel = 0;
2325123251
if (flowAnalysisDisabled) {
2325223252
return errorType;
2325323253
}

tests/baselines/reference/controlFlowAliasing.errors.txt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ tests/cases/conformance/controlFlow/controlFlowAliasing.ts(267,13): error TS2322
3232
Type 'number' is not assignable to type 'string'.
3333
tests/cases/conformance/controlFlow/controlFlowAliasing.ts(270,13): error TS2322: Type 'string | number' is not assignable to type 'number'.
3434
Type 'string' is not assignable to type 'number'.
35+
tests/cases/conformance/controlFlow/controlFlowAliasing.ts(280,5): error TS2448: Block-scoped variable 'a' used before its declaration.
36+
tests/cases/conformance/controlFlow/controlFlowAliasing.ts(280,5): error TS2454: Variable 'a' is used before being assigned.
3537

3638

37-
==== tests/cases/conformance/controlFlow/controlFlowAliasing.ts (17 errors) ====
39+
==== tests/cases/conformance/controlFlow/controlFlowAliasing.ts (19 errors) ====
3840
// Narrowing by aliased conditional expressions
3941

4042
function f10(x: string | number) {
@@ -358,4 +360,19 @@ tests/cases/conformance/controlFlow/controlFlowAliasing.ts(270,13): error TS2322
358360
!!! error TS2322: Type 'string' is not assignable to type 'number'.
359361
}
360362
}
363+
364+
// Repro from #45830
365+
366+
const obj = {
367+
fn: () => true
368+
};
369+
370+
if (a) { }
371+
~
372+
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
373+
!!! related TS2728 tests/cases/conformance/controlFlow/controlFlowAliasing.ts:282:7: 'a' is declared here.
374+
~
375+
!!! error TS2454: Variable 'a' is used before being assigned.
376+
377+
const a = obj.fn();
361378

tests/baselines/reference/controlFlowAliasing.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,16 @@ function foo({ kind, payload }: Data) {
271271
let t: number = payload;
272272
}
273273
}
274+
275+
// Repro from #45830
276+
277+
const obj = {
278+
fn: () => true
279+
};
280+
281+
if (a) { }
282+
283+
const a = obj.fn();
274284

275285

276286
//// [controlFlowAliasing.js]
@@ -522,6 +532,12 @@ function foo(_a) {
522532
var t = payload;
523533
}
524534
}
535+
// Repro from #45830
536+
var obj = {
537+
fn: function () { return true; }
538+
};
539+
if (a) { }
540+
var a = obj.fn();
525541

526542

527543
//// [controlFlowAliasing.d.ts]
@@ -657,3 +673,7 @@ declare type Data = {
657673
};
658674
declare function gg2(obj: Data): void;
659675
declare function foo({ kind, payload }: Data): void;
676+
declare const obj: {
677+
fn: () => boolean;
678+
};
679+
declare const a: boolean;

tests/baselines/reference/controlFlowAliasing.symbols

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,3 +772,22 @@ function foo({ kind, payload }: Data) {
772772
}
773773
}
774774

775+
// Repro from #45830
776+
777+
const obj = {
778+
>obj : Symbol(obj, Decl(controlFlowAliasing.ts, 275, 5))
779+
780+
fn: () => true
781+
>fn : Symbol(fn, Decl(controlFlowAliasing.ts, 275, 13))
782+
783+
};
784+
785+
if (a) { }
786+
>a : Symbol(a, Decl(controlFlowAliasing.ts, 281, 5))
787+
788+
const a = obj.fn();
789+
>a : Symbol(a, Decl(controlFlowAliasing.ts, 281, 5))
790+
>obj.fn : Symbol(fn, Decl(controlFlowAliasing.ts, 275, 13))
791+
>obj : Symbol(obj, Decl(controlFlowAliasing.ts, 275, 5))
792+
>fn : Symbol(fn, Decl(controlFlowAliasing.ts, 275, 13))
793+

tests/baselines/reference/controlFlowAliasing.types

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,3 +897,26 @@ function foo({ kind, payload }: Data) {
897897
}
898898
}
899899

900+
// Repro from #45830
901+
902+
const obj = {
903+
>obj : { fn: () => boolean; }
904+
>{ fn: () => true} : { fn: () => boolean; }
905+
906+
fn: () => true
907+
>fn : () => boolean
908+
>() => true : () => boolean
909+
>true : true
910+
911+
};
912+
913+
if (a) { }
914+
>a : boolean
915+
916+
const a = obj.fn();
917+
>a : boolean
918+
>obj.fn() : boolean
919+
>obj.fn : () => boolean
920+
>obj : { fn: () => boolean; }
921+
>fn : () => boolean
922+

tests/cases/conformance/controlFlow/controlFlowAliasing.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,3 +273,13 @@ function foo({ kind, payload }: Data) {
273273
let t: number = payload;
274274
}
275275
}
276+
277+
// Repro from #45830
278+
279+
const obj = {
280+
fn: () => true
281+
};
282+
283+
if (a) { }
284+
285+
const a = obj.fn();

0 commit comments

Comments
 (0)