From 629847d3923eb521356c9b1871a3e4b0ab8bdc77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 14:39:52 +0100 Subject: [PATCH 1/6] add tests --- ...ad1(allowunreachablecode=false).errors.txt | 16 +++++++ ...rHead1(allowunreachablecode=false).symbols | 15 ++++++ ...ForHead1(allowunreachablecode=false).types | 45 +++++++++++++++++ ...ead1(allowunreachablecode=true).errors.txt | 16 +++++++ ...orHead1(allowunreachablecode=true).symbols | 15 ++++++ ...gForHead1(allowunreachablecode=true).types | 45 +++++++++++++++++ ...rHead2(allowunreachablecode=false).symbols | 28 +++++++++++ ...ForHead2(allowunreachablecode=false).types | 48 +++++++++++++++++++ ...orHead2(allowunreachablecode=true).symbols | 28 +++++++++++ ...gForHead2(allowunreachablecode=true).types | 48 +++++++++++++++++++ .../unreachableFlowAfterThrowingForHead1.ts | 13 +++++ .../unreachableFlowAfterThrowingForHead2.ts | 16 +++++++ 12 files changed, 333 insertions(+) create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types create mode 100644 tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts create mode 100644 tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt new file mode 100644 index 0000000000000..159778a61b4eb --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt @@ -0,0 +1,16 @@ +unreachableFlowAfterThrowingForHead1.ts(9,2): error TS2304: Cannot find name 'as'. + + +==== unreachableFlowAfterThrowingForHead1.ts (1 errors) ==== + try { + for ( + (function () { throw "1"; })(); + (function* () { throw "2"; })(); + (function* () { throw "3"; })() + ) { } + } + catch (e) { } + as ; + ~~ +!!! error TS2304: Cannot find name 'as'. + \ No newline at end of file diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols new file mode 100644 index 0000000000000..a05962805deb7 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts] //// + +=== unreachableFlowAfterThrowingForHead1.ts === +try { + for ( + (function () { throw "1"; })(); + (function* () { throw "2"; })(); + (function* () { throw "3"; })() + ) { } +} +catch (e) { } +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 7, 7)) + + as ; + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types new file mode 100644 index 0000000000000..c8cee6fd0ddd1 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts] //// + +=== unreachableFlowAfterThrowingForHead1.ts === +try { + for ( + (function () { throw "1"; })(); +>(function () { throw "1"; })() : never +> : ^^^^^ +>(function () { throw "1"; }) : () => never +> : ^^^^^^^^^^^ +>function () { throw "1"; } : () => never +> : ^^^^^^^^^^^ +>"1" : "1" +> : ^^^ + + (function* () { throw "2"; })(); +>(function* () { throw "2"; })() : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(function* () { throw "2"; }) : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { throw "2"; } : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"2" : "2" +> : ^^^ + + (function* () { throw "3"; })() +>(function* () { throw "3"; })() : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(function* () { throw "3"; }) : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { throw "3"; } : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"3" : "3" +> : ^^^ + + ) { } +} +catch (e) { } +>e : unknown +> : ^^^^^^^ + + as ; +>as : any +> : ^^^ + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt new file mode 100644 index 0000000000000..159778a61b4eb --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt @@ -0,0 +1,16 @@ +unreachableFlowAfterThrowingForHead1.ts(9,2): error TS2304: Cannot find name 'as'. + + +==== unreachableFlowAfterThrowingForHead1.ts (1 errors) ==== + try { + for ( + (function () { throw "1"; })(); + (function* () { throw "2"; })(); + (function* () { throw "3"; })() + ) { } + } + catch (e) { } + as ; + ~~ +!!! error TS2304: Cannot find name 'as'. + \ No newline at end of file diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols new file mode 100644 index 0000000000000..a05962805deb7 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols @@ -0,0 +1,15 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts] //// + +=== unreachableFlowAfterThrowingForHead1.ts === +try { + for ( + (function () { throw "1"; })(); + (function* () { throw "2"; })(); + (function* () { throw "3"; })() + ) { } +} +catch (e) { } +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 7, 7)) + + as ; + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types new file mode 100644 index 0000000000000..c8cee6fd0ddd1 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts] //// + +=== unreachableFlowAfterThrowingForHead1.ts === +try { + for ( + (function () { throw "1"; })(); +>(function () { throw "1"; })() : never +> : ^^^^^ +>(function () { throw "1"; }) : () => never +> : ^^^^^^^^^^^ +>function () { throw "1"; } : () => never +> : ^^^^^^^^^^^ +>"1" : "1" +> : ^^^ + + (function* () { throw "2"; })(); +>(function* () { throw "2"; })() : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(function* () { throw "2"; }) : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { throw "2"; } : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"2" : "2" +> : ^^^ + + (function* () { throw "3"; })() +>(function* () { throw "3"; })() : Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>(function* () { throw "3"; }) : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>function* () { throw "3"; } : () => Generator +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>"3" : "3" +> : ^^^ + + ) { } +} +catch (e) { } +>e : unknown +> : ^^^^^^^ + + as ; +>as : any +> : ^^^ + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols new file mode 100644 index 0000000000000..fba242427f5cc --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts] //// + +=== unreachableFlowAfterThrowingForHead2.ts === +function test1(v: 0 | 1 | 2) { +>test1 : Symbol(test1, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 0)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + try { + for ( + (function () { + throw new Error(""); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + })(); + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + v++ +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + ) {} + } catch (e) {} +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 9, 11)) + + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +} + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types new file mode 100644 index 0000000000000..214a38e0cf074 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts] //// + +=== unreachableFlowAfterThrowingForHead2.ts === +function test1(v: 0 | 1 | 2) { +>test1 : (v: 0 | 1 | 2) => void +> : ^ ^^ ^^^^^^^^^ +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + try { + for ( + (function () { +>(function () { throw new Error(""); })() : never +> : ^^^^^ +>(function () { throw new Error(""); }) : () => never +> : ^^^^^^^^^^^ +>function () { throw new Error(""); } : () => never +> : ^^^^^^^^^^^ + + throw new Error(""); +>new Error("") : Error +> : ^^^^^ +>Error : ErrorConstructor +> : ^^^^^^^^^^^^^^^^ +>"" : "" +> : ^^ + + })(); + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + v++ +>v++ : number +> : ^^^^^^ +>v : number +> : ^^^^^^ + + ) {} + } catch (e) {} +>e : unknown +> : ^^^^^^^ + + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ +} + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols new file mode 100644 index 0000000000000..fba242427f5cc --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols @@ -0,0 +1,28 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts] //// + +=== unreachableFlowAfterThrowingForHead2.ts === +function test1(v: 0 | 1 | 2) { +>test1 : Symbol(test1, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 0)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + try { + for ( + (function () { + throw new Error(""); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + })(); + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + v++ +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + ) {} + } catch (e) {} +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 9, 11)) + + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +} + diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types new file mode 100644 index 0000000000000..214a38e0cf074 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types @@ -0,0 +1,48 @@ +//// [tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts] //// + +=== unreachableFlowAfterThrowingForHead2.ts === +function test1(v: 0 | 1 | 2) { +>test1 : (v: 0 | 1 | 2) => void +> : ^ ^^ ^^^^^^^^^ +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + try { + for ( + (function () { +>(function () { throw new Error(""); })() : never +> : ^^^^^ +>(function () { throw new Error(""); }) : () => never +> : ^^^^^^^^^^^ +>function () { throw new Error(""); } : () => never +> : ^^^^^^^^^^^ + + throw new Error(""); +>new Error("") : Error +> : ^^^^^ +>Error : ErrorConstructor +> : ^^^^^^^^^^^^^^^^ +>"" : "" +> : ^^ + + })(); + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + v++ +>v++ : number +> : ^^^^^^ +>v : number +> : ^^^^^^ + + ) {} + } catch (e) {} +>e : unknown +> : ^^^^^^^ + + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ +} + diff --git a/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts b/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts new file mode 100644 index 0000000000000..ba69a7a5ace20 --- /dev/null +++ b/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts @@ -0,0 +1,13 @@ +// @strict: true +// @noEmit: true +// @allowUnreachableCode: true, false + +try { + for ( + (function () { throw "1"; })(); + (function* () { throw "2"; })(); + (function* () { throw "3"; })() + ) { } +} +catch (e) { } + as ; diff --git a/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts new file mode 100644 index 0000000000000..53db43d7b83ea --- /dev/null +++ b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts @@ -0,0 +1,16 @@ +// @strict: true +// @noEmit: true +// @allowUnreachableCode: true, false + +function test1(v: 0 | 1 | 2) { + try { + for ( + (function () { + throw new Error(""); + })(); + v; + v++ + ) {} + } catch (e) {} + v; +} From f0aeeeb417b03623ff01dea147bb25dc7cc6a337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 14:40:23 +0100 Subject: [PATCH 2/6] add reentry mitigation --- src/compiler/checker.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 348d6051831a2..fff9282ff4adf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28800,7 +28800,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!noCacheCheck) { const id = getFlowNodeId(flow); const reachable = flowNodeReachable[id]; - return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true)); + if (reachable !== undefined) { + return reachable; + } + flowNodeReachable[id] = false; + return flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true); } noCacheCheck = false; } From aa5b116885d7bae82edeb12757cabecff394b767 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 14:59:35 +0100 Subject: [PATCH 3/6] update tests --- ...ad1(allowunreachablecode=false).errors.txt | 11 +++++++--- ...rHead1(allowunreachablecode=false).symbols | 9 ++++++-- ...ForHead1(allowunreachablecode=false).types | 14 ++++++++++++- ...ead1(allowunreachablecode=true).errors.txt | 6 ++++-- ...orHead1(allowunreachablecode=true).symbols | 9 ++++++-- ...gForHead1(allowunreachablecode=true).types | 14 ++++++++++++- ...ad2(allowunreachablecode=false).errors.txt | 21 +++++++++++++++++++ ...rHead2(allowunreachablecode=false).symbols | 9 ++++++-- ...ForHead2(allowunreachablecode=false).types | 14 ++++++++++++- ...orHead2(allowunreachablecode=true).symbols | 9 ++++++-- ...gForHead2(allowunreachablecode=true).types | 14 ++++++++++++- .../unreachableFlowAfterThrowingForHead1.ts | 4 +++- .../unreachableFlowAfterThrowingForHead2.ts | 4 +++- 13 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt index 159778a61b4eb..cb03cfb21752f 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).errors.txt @@ -1,13 +1,18 @@ -unreachableFlowAfterThrowingForHead1.ts(9,2): error TS2304: Cannot find name 'as'. +unreachableFlowAfterThrowingForHead1.ts(7,9): error TS7027: Unreachable code detected. +unreachableFlowAfterThrowingForHead1.ts(11,2): error TS2304: Cannot find name 'as'. -==== unreachableFlowAfterThrowingForHead1.ts (1 errors) ==== +==== unreachableFlowAfterThrowingForHead1.ts (2 errors) ==== try { for ( (function () { throw "1"; })(); (function* () { throw "2"; })(); (function* () { throw "3"; })() - ) { } + ) { + console.log("1"); + ~~~~~~~~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + } } catch (e) { } as ; diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols index a05962805deb7..cb6fd0af391ce 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).symbols @@ -6,10 +6,15 @@ try { (function () { throw "1"; })(); (function* () { throw "2"; })(); (function* () { throw "3"; })() - ) { } + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } } catch (e) { } ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 7, 7)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 9, 7)) as ; diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types index c8cee6fd0ddd1..f74ba48799043 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=false).types @@ -33,7 +33,19 @@ try { >"3" : "3" > : ^^^ - ) { } + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } } catch (e) { } >e : unknown diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt index 159778a61b4eb..4836a580a5e6d 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).errors.txt @@ -1,4 +1,4 @@ -unreachableFlowAfterThrowingForHead1.ts(9,2): error TS2304: Cannot find name 'as'. +unreachableFlowAfterThrowingForHead1.ts(11,2): error TS2304: Cannot find name 'as'. ==== unreachableFlowAfterThrowingForHead1.ts (1 errors) ==== @@ -7,7 +7,9 @@ unreachableFlowAfterThrowingForHead1.ts(9,2): error TS2304: Cannot find name 'as (function () { throw "1"; })(); (function* () { throw "2"; })(); (function* () { throw "3"; })() - ) { } + ) { + console.log("1"); + } } catch (e) { } as ; diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols index a05962805deb7..cb6fd0af391ce 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).symbols @@ -6,10 +6,15 @@ try { (function () { throw "1"; })(); (function* () { throw "2"; })(); (function* () { throw "3"; })() - ) { } + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } } catch (e) { } ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 7, 7)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead1.ts, 9, 7)) as ; diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types index c8cee6fd0ddd1..f74ba48799043 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead1(allowunreachablecode=true).types @@ -33,7 +33,19 @@ try { >"3" : "3" > : ^^^ - ) { } + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } } catch (e) { } >e : unknown diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt new file mode 100644 index 0000000000000..3539097fbd062 --- /dev/null +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt @@ -0,0 +1,21 @@ +unreachableFlowAfterThrowingForHead2.ts(10,7): error TS7027: Unreachable code detected. + + +==== unreachableFlowAfterThrowingForHead2.ts (1 errors) ==== + function test1(v: 0 | 1 | 2) { + try { + for ( + (function () { + throw new Error(""); + })(); + v; + v++ + ) { + console.log("1"); + ~~~~~~~~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + } + } catch (e) {} + v; + } + \ No newline at end of file diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols index fba242427f5cc..f4bbb6433c281 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols @@ -18,9 +18,14 @@ function test1(v: 0 | 1 | 2) { v++ >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) - ) {} + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } } catch (e) {} ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 9, 11)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 11, 11)) v; >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types index 214a38e0cf074..c5380ee40a46e 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types @@ -36,7 +36,19 @@ function test1(v: 0 | 1 | 2) { >v : number > : ^^^^^^ - ) {} + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } } catch (e) {} >e : unknown > : ^^^^^^^ diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols index fba242427f5cc..f4bbb6433c281 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols @@ -18,9 +18,14 @@ function test1(v: 0 | 1 | 2) { v++ >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) - ) {} + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } } catch (e) {} ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 9, 11)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 11, 11)) v; >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types index 214a38e0cf074..c5380ee40a46e 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types @@ -36,7 +36,19 @@ function test1(v: 0 | 1 | 2) { >v : number > : ^^^^^^ - ) {} + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } } catch (e) {} >e : unknown > : ^^^^^^^ diff --git a/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts b/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts index ba69a7a5ace20..4d73e8cadeb4a 100644 --- a/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts +++ b/tests/cases/compiler/unreachableFlowAfterThrowingForHead1.ts @@ -7,7 +7,9 @@ try { (function () { throw "1"; })(); (function* () { throw "2"; })(); (function* () { throw "3"; })() - ) { } + ) { + console.log("1"); + } } catch (e) { } as ; diff --git a/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts index 53db43d7b83ea..ade3597146fc7 100644 --- a/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts +++ b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts @@ -10,7 +10,9 @@ function test1(v: 0 | 1 | 2) { })(); v; v++ - ) {} + ) { + console.log("1"); + } } catch (e) {} v; } From 1ed689063597de0332ef54a3e689638a78b89ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 20:47:32 +0100 Subject: [PATCH 4/6] target fix in the binder --- src/compiler/binder.ts | 10 +++++++++- src/compiler/checker.ts | 6 +----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 9ea90805fb51e..879eebd4669eb 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1539,11 +1539,19 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } function bindForStatement(node: ForStatement): void { + bind(node.initializer); + if (currentFlow === unreachableFlow) { + // follow what `bindChildren` already does for `unreachableFlow` + // given `node.initializer` was already bound we have to manually bind the rest of the statement instead of relying on `bindEach` + bind(node.condition); + bind(node.statement); + bind(node.incrementor); + return; + } const preLoopLabel = setContinueTarget(node, createLoopLabel()); const preBodyLabel = createBranchLabel(); const preIncrementorLabel = createBranchLabel(); const postLoopLabel = createBranchLabel(); - bind(node.initializer); addAntecedent(preLoopLabel, currentFlow); currentFlow = preLoopLabel; bindCondition(node.condition, preBodyLabel, postLoopLabel); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fff9282ff4adf..348d6051831a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -28800,11 +28800,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!noCacheCheck) { const id = getFlowNodeId(flow); const reachable = flowNodeReachable[id]; - if (reachable !== undefined) { - return reachable; - } - flowNodeReachable[id] = false; - return flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true); + return reachable !== undefined ? reachable : (flowNodeReachable[id] = isReachableFlowNodeWorker(flow, /*noCacheCheck*/ true)); } noCacheCheck = false; } From 805972dcd43c4366214d548fcb6748a59cf0e293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 20:50:52 +0100 Subject: [PATCH 5/6] improve comment --- src/compiler/binder.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 879eebd4669eb..2453fc859ebc9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1541,8 +1541,11 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { function bindForStatement(node: ForStatement): void { bind(node.initializer); if (currentFlow === unreachableFlow) { - // follow what `bindChildren` already does for `unreachableFlow` - // given `node.initializer` was already bound we have to manually bind the rest of the statement instead of relying on `bindEach` + // Unlike while/do, the for-loop initializer is bound inside this function before the loop's + // flow graph is constructed. If it makes flow unreachable (e.g. a throwing IIFE), addAntecedent + // will filter out the unreachable entry to preLoopLabel, leaving only the back-edge from the + // incrementor. This creates a cycle with no exit that crashes isReachableFlowNodeWorker. + // Bail out early and just bind the remaining children with unreachable flow. bind(node.condition); bind(node.statement); bind(node.incrementor); From 76f2f2fdc52bf1a4dd9f27cc85bac1745d5d030c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Thu, 5 Feb 2026 21:11:22 +0100 Subject: [PATCH 6/6] add test --- ...ad2(allowunreachablecode=false).errors.txt | 19 ++++++- ...rHead2(allowunreachablecode=false).symbols | 32 ++++++++++-- ...ForHead2(allowunreachablecode=false).types | 49 +++++++++++++++++++ ...orHead2(allowunreachablecode=true).symbols | 32 ++++++++++-- ...gForHead2(allowunreachablecode=true).types | 49 +++++++++++++++++++ .../unreachableFlowAfterThrowingForHead2.ts | 12 +++++ 6 files changed, 183 insertions(+), 10 deletions(-) diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt index 3539097fbd062..09c4cbf7e26d1 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).errors.txt @@ -1,8 +1,23 @@ -unreachableFlowAfterThrowingForHead2.ts(10,7): error TS7027: Unreachable code detected. +unreachableFlowAfterThrowingForHead2.ts(9,5): error TS7027: Unreachable code detected. +unreachableFlowAfterThrowingForHead2.ts(22,7): error TS7027: Unreachable code detected. -==== unreachableFlowAfterThrowingForHead2.ts (1 errors) ==== +==== unreachableFlowAfterThrowingForHead2.ts (2 errors) ==== function test1(v: 0 | 1 | 2) { + for ( + (function () { + throw new Error(""); + })(); + v; + v++ + ) { + console.log("1"); + ~~~~~~~~~~~~~~~~~ +!!! error TS7027: Unreachable code detected. + } + } + + function test2(v: 0 | 1 | 2) { try { for ( (function () { diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols index f4bbb6433c281..983d0945225ef 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).symbols @@ -5,6 +5,30 @@ function test1(v: 0 | 1 | 2) { >test1 : Symbol(test1, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 0)) >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + for ( + (function () { + throw new Error(""); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + })(); + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + v++ +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } +} + +function test2(v: 0 | 1 | 2) { +>test2 : Symbol(test2, Decl(unreachableFlowAfterThrowingForHead2.ts, 10, 1)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) + try { for ( (function () { @@ -13,10 +37,10 @@ function test1(v: 0 | 1 | 2) { })(); v; ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) v++ ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) ) { console.log("1"); @@ -25,9 +49,9 @@ function test1(v: 0 | 1 | 2) { >log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) } } catch (e) {} ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 11, 11)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 23, 11)) v; ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) } diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types index c5380ee40a46e..6e09766d64115 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=false).types @@ -5,6 +5,55 @@ function test1(v: 0 | 1 | 2) { >test1 : (v: 0 | 1 | 2) => void > : ^ ^^ ^^^^^^^^^ >v : 0 | 1 | 2 +> : ^^^^^^^^^ + + for ( + (function () { +>(function () { throw new Error(""); })() : never +> : ^^^^^ +>(function () { throw new Error(""); }) : () => never +> : ^^^^^^^^^^^ +>function () { throw new Error(""); } : () => never +> : ^^^^^^^^^^^ + + throw new Error(""); +>new Error("") : Error +> : ^^^^^ +>Error : ErrorConstructor +> : ^^^^^^^^^^^^^^^^ +>"" : "" +> : ^^ + + })(); + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + v++ +>v++ : number +> : ^^^^^^ +>v : number +> : ^^^^^^ + + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } +} + +function test2(v: 0 | 1 | 2) { +>test2 : (v: 0 | 1 | 2) => void +> : ^ ^^ ^^^^^^^^^ +>v : 0 | 1 | 2 > : ^^^^^^^^^ try { diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols index f4bbb6433c281..983d0945225ef 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).symbols @@ -5,6 +5,30 @@ function test1(v: 0 | 1 | 2) { >test1 : Symbol(test1, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 0)) >v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + for ( + (function () { + throw new Error(""); +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) + + })(); + v; +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + v++ +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) + + ) { + console.log("1"); +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) + } +} + +function test2(v: 0 | 1 | 2) { +>test2 : Symbol(test2, Decl(unreachableFlowAfterThrowingForHead2.ts, 10, 1)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) + try { for ( (function () { @@ -13,10 +37,10 @@ function test1(v: 0 | 1 | 2) { })(); v; ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) v++ ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) ) { console.log("1"); @@ -25,9 +49,9 @@ function test1(v: 0 | 1 | 2) { >log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) } } catch (e) {} ->e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 11, 11)) +>e : Symbol(e, Decl(unreachableFlowAfterThrowingForHead2.ts, 23, 11)) v; ->v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 0, 15)) +>v : Symbol(v, Decl(unreachableFlowAfterThrowingForHead2.ts, 12, 15)) } diff --git a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types index c5380ee40a46e..6e09766d64115 100644 --- a/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types +++ b/tests/baselines/reference/unreachableFlowAfterThrowingForHead2(allowunreachablecode=true).types @@ -5,6 +5,55 @@ function test1(v: 0 | 1 | 2) { >test1 : (v: 0 | 1 | 2) => void > : ^ ^^ ^^^^^^^^^ >v : 0 | 1 | 2 +> : ^^^^^^^^^ + + for ( + (function () { +>(function () { throw new Error(""); })() : never +> : ^^^^^ +>(function () { throw new Error(""); }) : () => never +> : ^^^^^^^^^^^ +>function () { throw new Error(""); } : () => never +> : ^^^^^^^^^^^ + + throw new Error(""); +>new Error("") : Error +> : ^^^^^ +>Error : ErrorConstructor +> : ^^^^^^^^^^^^^^^^ +>"" : "" +> : ^^ + + })(); + v; +>v : 0 | 1 | 2 +> : ^^^^^^^^^ + + v++ +>v++ : number +> : ^^^^^^ +>v : number +> : ^^^^^^ + + ) { + console.log("1"); +>console.log("1") : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>"1" : "1" +> : ^^^ + } +} + +function test2(v: 0 | 1 | 2) { +>test2 : (v: 0 | 1 | 2) => void +> : ^ ^^ ^^^^^^^^^ +>v : 0 | 1 | 2 > : ^^^^^^^^^ try { diff --git a/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts index ade3597146fc7..dabb66f51a6d5 100644 --- a/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts +++ b/tests/cases/compiler/unreachableFlowAfterThrowingForHead2.ts @@ -3,6 +3,18 @@ // @allowUnreachableCode: true, false function test1(v: 0 | 1 | 2) { + for ( + (function () { + throw new Error(""); + })(); + v; + v++ + ) { + console.log("1"); + } +} + +function test2(v: 0 | 1 | 2) { try { for ( (function () {