From 6f4057467163a3625b5c591209bfb7989250ab64 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Jun 2025 19:45:10 +0000 Subject: [PATCH 1/4] Initial plan From eaccac269f40a1f544d5ea48eb03d0bc4645af4e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Jun 2025 20:03:11 +0000 Subject: [PATCH 2/4] Add CFA regression test for while loop with continue statements Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com> --- .../controlFlowWhileLoopWithContinue.symbols | 106 ++++++++++++++++ .../controlFlowWhileLoopWithContinue.types | 116 ++++++++++++++++++ .../controlFlowWhileLoopWithContinue.ts | 41 +++++++ 3 files changed, 263 insertions(+) create mode 100644 testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols create mode 100644 testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types create mode 100644 testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts diff --git a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols b/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols new file mode 100644 index 0000000000..d29fb4587d --- /dev/null +++ b/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols @@ -0,0 +1,106 @@ +//// [tests/cases/compiler/controlFlowWhileLoopWithContinue.ts] //// + +=== controlFlowWhileLoopWithContinue.ts === +class A { +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) + + next: A | null = null; +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) + + constructor(readonly children: (A | null)[]) {} +>children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) +} + +function getNodes(): A[] { +>getNodes : Symbol(getNodes, Decl(controlFlowWhileLoopWithContinue.ts, 4, 1)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) + + const out: A[] = []; +>out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) + + let current: A | null = new A([]); +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) +>A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) + + while (current !== null) { +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) + + let firstChild = null; +>firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) + + // If the following if block is commented out, then current TS also shows an error + if (out.length) { +>out.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) + + current = current.next; +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) + + continue; + } + + for (let i = 0; i < current.children.length; i++) { +>i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) +>i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) +>current.children.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>current.children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) + + const child = current.children[i]; +>child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) +>current.children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) +>i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) + + if (child) { +>child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) + + if (!firstChild) { +>firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) + + firstChild = child; +>firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) +>child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) + + firstChild.next = current.next; +>firstChild.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) + } + + child.next = current.next; +>child.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) + } + } + + current = firstChild || current.next; +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) +>current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) +>current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) +>next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) + } + + return out; +>out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) +} diff --git a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types b/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types new file mode 100644 index 0000000000..46dd4a2ea3 --- /dev/null +++ b/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types @@ -0,0 +1,116 @@ +//// [tests/cases/compiler/controlFlowWhileLoopWithContinue.ts] //// + +=== controlFlowWhileLoopWithContinue.ts === +class A { +>A : A + + next: A | null = null; +>next : A | null + + constructor(readonly children: (A | null)[]) {} +>children : (A | null)[] +} + +function getNodes(): A[] { +>getNodes : () => A[] + + const out: A[] = []; +>out : A[] +>[] : never[] + + let current: A | null = new A([]); +>current : A | null +>new A([]) : A +>A : typeof A +>[] : never[] + + while (current !== null) { +>current !== null : boolean +>current : A | null + + let firstChild = null; +>firstChild : any + + // If the following if block is commented out, then current TS also shows an error + if (out.length) { +>out.length : number +>out : A[] +>length : number + + current = current.next; +>current = current.next : A | null +>current : A | null +>current.next : A | null +>current : A +>next : A | null + + continue; + } + + for (let i = 0; i < current.children.length; i++) { +>i : number +>0 : 0 +>i < current.children.length : boolean +>i : number +>current.children.length : number +>current.children : (A | null)[] +>current : A +>children : (A | null)[] +>length : number +>i++ : number +>i : number + + const child = current.children[i]; +>child : A | null +>current.children[i] : A | null +>current.children : (A | null)[] +>current : A +>children : (A | null)[] +>i : number + + if (child) { +>child : A | null + + if (!firstChild) { +>!firstChild : boolean +>firstChild : A | null + + firstChild = child; +>firstChild = child : A +>firstChild : any +>child : A + + firstChild.next = current.next; +>firstChild.next = current.next : A | null +>firstChild.next : A | null +>firstChild : A +>next : A | null +>current.next : A | null +>current : A +>next : A | null + } + + child.next = current.next; +>child.next = current.next : A | null +>child.next : A | null +>child : A +>next : A | null +>current.next : A | null +>current : A +>next : A | null + } + } + + current = firstChild || current.next; +>current = firstChild || current.next : A | null +>current : A | null +>firstChild || current.next : A | null +>firstChild : A | null +>current.next : A | null +>current : A +>next : A | null + } + + return out; +>out : A[] +} diff --git a/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts b/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts new file mode 100644 index 0000000000..b19ec60656 --- /dev/null +++ b/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts @@ -0,0 +1,41 @@ +// @strict: true +// @noEmit: true + +class A { + next: A | null = null; + + constructor(readonly children: (A | null)[]) {} +} + +function getNodes(): A[] { + const out: A[] = []; + + let current: A | null = new A([]); + + while (current !== null) { + let firstChild = null; + + // If the following if block is commented out, then current TS also shows an error + if (out.length) { + current = current.next; + continue; + } + + for (let i = 0; i < current.children.length; i++) { + const child = current.children[i]; + + if (child) { + if (!firstChild) { + firstChild = child; + firstChild.next = current.next; + } + + child.next = current.next; + } + } + + current = firstChild || current.next; + } + + return out; +} \ No newline at end of file From 4b463995b111806a1a895f71e1341fab94f86c83 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 30 Jun 2025 15:28:21 -0700 Subject: [PATCH 3/4] Apply suggestions from code review --- .../tests/cases/compiler/controlFlowWhileLoopWithContinue.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts b/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts index b19ec60656..50d2917404 100644 --- a/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts +++ b/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts @@ -15,7 +15,6 @@ function getNodes(): A[] { while (current !== null) { let firstChild = null; - // If the following if block is commented out, then current TS also shows an error if (out.length) { current = current.next; continue; From 28f6ee2d6c2983c50ef3f8477996c3cd755441e2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 30 Jun 2025 22:46:33 +0000 Subject: [PATCH 4/4] Rename test file to circularControlFlowNarrowingWithCurrentElement01.ts and accept baselines Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com> --- ...lFlowNarrowingWithCurrentElement01.symbols | 105 +++++++++++++++++ ...olFlowNarrowingWithCurrentElement01.types} | 5 +- .../controlFlowWhileLoopWithContinue.symbols | 106 ------------------ ...ntrolFlowNarrowingWithCurrentElement01.ts} | 0 4 files changed, 107 insertions(+), 109 deletions(-) create mode 100644 testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols rename testdata/baselines/reference/compiler/{controlFlowWhileLoopWithContinue.types => circularControlFlowNarrowingWithCurrentElement01.types} (86%) delete mode 100644 testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols rename testdata/tests/cases/compiler/{controlFlowWhileLoopWithContinue.ts => circularControlFlowNarrowingWithCurrentElement01.ts} (100%) diff --git a/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols new file mode 100644 index 0000000000..8b47e8ef22 --- /dev/null +++ b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.symbols @@ -0,0 +1,105 @@ +//// [tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts] //// + +=== circularControlFlowNarrowingWithCurrentElement01.ts === +class A { +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + next: A | null = null; +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + constructor(readonly children: (A | null)[]) {} +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) +} + +function getNodes(): A[] { +>getNodes : Symbol(getNodes, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 4, 1)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + const out: A[] = []; +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + let current: A | null = new A([]); +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) +>A : Symbol(A, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 0)) + + while (current !== null) { +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) + + let firstChild = null; +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) + + if (out.length) { +>out.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) + + current = current.next; +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + + continue; + } + + for (let i = 0; i < current.children.length; i++) { +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) +>current.children.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>current.children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>length : Symbol(length, Decl(lib.es5.d.ts, --, --)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) + + const child = current.children[i]; +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) +>current.children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>children : Symbol(children, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 3, 14)) +>i : Symbol(i, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 19, 12)) + + if (child) { +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) + + if (!firstChild) { +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) + + firstChild = child; +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) + + firstChild.next = current.next; +>firstChild.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + + child.next = current.next; +>child.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>child : Symbol(child, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 20, 11)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + } + + current = firstChild || current.next; +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>firstChild : Symbol(firstChild, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 12, 7)) +>current.next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) +>current : Symbol(current, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 9, 5)) +>next : Symbol(next, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 0, 9)) + } + + return out; +>out : Symbol(out, Decl(circularControlFlowNarrowingWithCurrentElement01.ts, 7, 7)) +} diff --git a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types similarity index 86% rename from testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types rename to testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types index 46dd4a2ea3..09a5ecd958 100644 --- a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.types +++ b/testdata/baselines/reference/compiler/circularControlFlowNarrowingWithCurrentElement01.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/controlFlowWhileLoopWithContinue.ts] //// +//// [tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts] //// -=== controlFlowWhileLoopWithContinue.ts === +=== circularControlFlowNarrowingWithCurrentElement01.ts === class A { >A : A @@ -31,7 +31,6 @@ function getNodes(): A[] { let firstChild = null; >firstChild : any - // If the following if block is commented out, then current TS also shows an error if (out.length) { >out.length : number >out : A[] diff --git a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols b/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols deleted file mode 100644 index d29fb4587d..0000000000 --- a/testdata/baselines/reference/compiler/controlFlowWhileLoopWithContinue.symbols +++ /dev/null @@ -1,106 +0,0 @@ -//// [tests/cases/compiler/controlFlowWhileLoopWithContinue.ts] //// - -=== controlFlowWhileLoopWithContinue.ts === -class A { ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) - - next: A | null = null; ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) - - constructor(readonly children: (A | null)[]) {} ->children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) -} - -function getNodes(): A[] { ->getNodes : Symbol(getNodes, Decl(controlFlowWhileLoopWithContinue.ts, 4, 1)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) - - const out: A[] = []; ->out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) - - let current: A | null = new A([]); ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) ->A : Symbol(A, Decl(controlFlowWhileLoopWithContinue.ts, 0, 0)) - - while (current !== null) { ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) - - let firstChild = null; ->firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) - - // If the following if block is commented out, then current TS also shows an error - if (out.length) { ->out.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) ->out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) ->length : Symbol(length, Decl(lib.es5.d.ts, --, --)) - - current = current.next; ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) - - continue; - } - - for (let i = 0; i < current.children.length; i++) { ->i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) ->i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) ->current.children.length : Symbol(length, Decl(lib.es5.d.ts, --, --)) ->current.children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) ->length : Symbol(length, Decl(lib.es5.d.ts, --, --)) ->i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) - - const child = current.children[i]; ->child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) ->current.children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->children : Symbol(children, Decl(controlFlowWhileLoopWithContinue.ts, 3, 14)) ->i : Symbol(i, Decl(controlFlowWhileLoopWithContinue.ts, 20, 12)) - - if (child) { ->child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) - - if (!firstChild) { ->firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) - - firstChild = child; ->firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) ->child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) - - firstChild.next = current.next; ->firstChild.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) - } - - child.next = current.next; ->child.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->child : Symbol(child, Decl(controlFlowWhileLoopWithContinue.ts, 21, 11)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) - } - } - - current = firstChild || current.next; ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->firstChild : Symbol(firstChild, Decl(controlFlowWhileLoopWithContinue.ts, 12, 7)) ->current.next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) ->current : Symbol(current, Decl(controlFlowWhileLoopWithContinue.ts, 9, 5)) ->next : Symbol(next, Decl(controlFlowWhileLoopWithContinue.ts, 0, 9)) - } - - return out; ->out : Symbol(out, Decl(controlFlowWhileLoopWithContinue.ts, 7, 7)) -} diff --git a/testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts b/testdata/tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts similarity index 100% rename from testdata/tests/cases/compiler/controlFlowWhileLoopWithContinue.ts rename to testdata/tests/cases/compiler/circularControlFlowNarrowingWithCurrentElement01.ts