diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index b07a0a075080e..c83e11fc2a4a0 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1536,13 +1536,16 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { function bindForStatement(node: ForStatement): void { 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); currentFlow = finishFlowLabel(preBodyLabel); - bindIterativeStatement(node.statement, postLoopLabel, preLoopLabel); + bindIterativeStatement(node.statement, postLoopLabel, preIncrementorLabel); + addAntecedent(preIncrementorLabel, currentFlow); + currentFlow = finishFlowLabel(preIncrementorLabel); bind(node.incrementor); addAntecedent(preLoopLabel, currentFlow); currentFlow = finishFlowLabel(postLoopLabel); diff --git a/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.errors.txt b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.errors.txt new file mode 100644 index 0000000000000..01465c856fd43 --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.errors.txt @@ -0,0 +1,45 @@ +controlFlowForStatementContinueIntoIncrementor1.ts(8,5): error TS2322: Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. +controlFlowForStatementContinueIntoIncrementor1.ts(23,5): error TS2322: Type 'string | number' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. + + +==== controlFlowForStatementContinueIntoIncrementor1.ts (2 errors) ==== + // https://github.com/microsoft/TypeScript/issues/60945 + + { + let iNext; + for ( + let i = 0; + i < 10; + i = iNext // error + ~ +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + ) { + if (i == 5) { + iNext = "bad"; + continue; + } + iNext = i + 1; + } + } + + { + let iNext: string | number = ""; + for ( + let i = 0; + i < 10; + i = iNext // error + ~ +!!! error TS2322: Type 'string | number' is not assignable to type 'number'. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + ) { + if (i == 5) { + iNext = "bad"; + continue; + } + iNext = i + 1; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.symbols b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.symbols new file mode 100644 index 0000000000000..2ef70777fa4d7 --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.symbols @@ -0,0 +1,65 @@ +//// [tests/cases/compiler/controlFlowForStatementContinueIntoIncrementor1.ts] //// + +=== controlFlowForStatementContinueIntoIncrementor1.ts === +// https://github.com/microsoft/TypeScript/issues/60945 + +{ + let iNext; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 3, 5)) + + for ( + let i = 0; +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 5, 7)) + + i < 10; +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 5, 7)) + + i = iNext // error +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 5, 7)) +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 3, 5)) + + ) { + if (i == 5) { +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 5, 7)) + + iNext = "bad"; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 3, 5)) + + continue; + } + iNext = i + 1; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 3, 5)) +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 5, 7)) + } +} + +{ + let iNext: string | number = ""; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 18, 5)) + + for ( + let i = 0; +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 20, 7)) + + i < 10; +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 20, 7)) + + i = iNext // error +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 20, 7)) +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 18, 5)) + + ) { + if (i == 5) { +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 20, 7)) + + iNext = "bad"; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 18, 5)) + + continue; + } + iNext = i + 1; +>iNext : Symbol(iNext, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 18, 5)) +>i : Symbol(i, Decl(controlFlowForStatementContinueIntoIncrementor1.ts, 20, 7)) + } +} + diff --git a/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.types b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.types new file mode 100644 index 0000000000000..cb632f36c5192 --- /dev/null +++ b/tests/baselines/reference/controlFlowForStatementContinueIntoIncrementor1.types @@ -0,0 +1,129 @@ +//// [tests/cases/compiler/controlFlowForStatementContinueIntoIncrementor1.ts] //// + +=== controlFlowForStatementContinueIntoIncrementor1.ts === +// https://github.com/microsoft/TypeScript/issues/60945 + +{ + let iNext; +>iNext : any +> : ^^^ + + for ( + let i = 0; +>i : number +> : ^^^^^^ +>0 : 0 +> : ^ + + i < 10; +>i < 10 : boolean +> : ^^^^^^^ +>i : number +> : ^^^^^^ +>10 : 10 +> : ^^ + + i = iNext // error +>i = iNext : string | number +> : ^^^^^^^^^^^^^^^ +>i : number +> : ^^^^^^ +>iNext : string | number +> : ^^^^^^^^^^^^^^^ + + ) { + if (i == 5) { +>i == 5 : boolean +> : ^^^^^^^ +>i : number +> : ^^^^^^ +>5 : 5 +> : ^ + + iNext = "bad"; +>iNext = "bad" : "bad" +> : ^^^^^ +>iNext : any +> : ^^^ +>"bad" : "bad" +> : ^^^^^ + + continue; + } + iNext = i + 1; +>iNext = i + 1 : number +> : ^^^^^^ +>iNext : any +> : ^^^ +>i + 1 : number +> : ^^^^^^ +>i : number +> : ^^^^^^ +>1 : 1 +> : ^ + } +} + +{ + let iNext: string | number = ""; +>iNext : string | number +> : ^^^^^^^^^^^^^^^ +>"" : "" +> : ^^ + + for ( + let i = 0; +>i : number +> : ^^^^^^ +>0 : 0 +> : ^ + + i < 10; +>i < 10 : boolean +> : ^^^^^^^ +>i : number +> : ^^^^^^ +>10 : 10 +> : ^^ + + i = iNext // error +>i = iNext : string | number +> : ^^^^^^^^^^^^^^^ +>i : number +> : ^^^^^^ +>iNext : string | number +> : ^^^^^^^^^^^^^^^ + + ) { + if (i == 5) { +>i == 5 : boolean +> : ^^^^^^^ +>i : number +> : ^^^^^^ +>5 : 5 +> : ^ + + iNext = "bad"; +>iNext = "bad" : "bad" +> : ^^^^^ +>iNext : string | number +> : ^^^^^^^^^^^^^^^ +>"bad" : "bad" +> : ^^^^^ + + continue; + } + iNext = i + 1; +>iNext = i + 1 : number +> : ^^^^^^ +>iNext : string | number +> : ^^^^^^^^^^^^^^^ +>i + 1 : number +> : ^^^^^^ +>i : number +> : ^^^^^^ +>1 : 1 +> : ^ + } +} + diff --git a/tests/cases/compiler/controlFlowForStatementContinueIntoIncrementor1.ts b/tests/cases/compiler/controlFlowForStatementContinueIntoIncrementor1.ts new file mode 100644 index 0000000000000..2b791d271d086 --- /dev/null +++ b/tests/cases/compiler/controlFlowForStatementContinueIntoIncrementor1.ts @@ -0,0 +1,34 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/60945 + +{ + let iNext; + for ( + let i = 0; + i < 10; + i = iNext // error + ) { + if (i == 5) { + iNext = "bad"; + continue; + } + iNext = i + 1; + } +} + +{ + let iNext: string | number = ""; + for ( + let i = 0; + i < 10; + i = iNext // error + ) { + if (i == 5) { + iNext = "bad"; + continue; + } + iNext = i + 1; + } +}