From c9a3ea6fe0fdbcb1dfe2d413c136feaf9cb774fb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 May 2016 12:49:42 -0700 Subject: [PATCH 1/2] Stop analyzing loop branches when declared type is seen --- src/compiler/checker.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 85e78324cc7..fa8004a5d91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7780,16 +7780,15 @@ namespace ts { if (cache[key]) { return cache[key]; } - // If the type at a particular antecedent path is the declared type and the - // reference is known to always be assigned (i.e. when declared and initial types - // are the same), there is no reason to process more antecedents since the only - // possible outcome is subtypes that will be removed in the final union type anyway. - if (type === declaredType && declaredType === initialType) { - return cache[key] = type; - } if (!contains(antecedentTypes, type)) { antecedentTypes.push(type); } + // If the type at a particular antecedent path is the declared type there is no + // reason to process more antecedents since the only possible outcome is subtypes + // that will be removed in the final union type anyway. + if (type === declaredType) { + break; + } } return cache[key] = getUnionType(antecedentTypes); } From 43691b10a86b4406322c9578d2f610363a298e62 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 11 May 2016 13:03:47 -0700 Subject: [PATCH 2/2] Adding test --- .../controlFlowLoopAnalysis.errors.txt | 19 +++++++++++ .../reference/controlFlowLoopAnalysis.js | 33 +++++++++++++++++++ .../cases/compiler/controlFlowLoopAnalysis.ts | 20 +++++++++++ 3 files changed, 72 insertions(+) diff --git a/tests/baselines/reference/controlFlowLoopAnalysis.errors.txt b/tests/baselines/reference/controlFlowLoopAnalysis.errors.txt index 21bf6b1c19a..0d08f93a8a8 100644 --- a/tests/baselines/reference/controlFlowLoopAnalysis.errors.txt +++ b/tests/baselines/reference/controlFlowLoopAnalysis.errors.txt @@ -36,4 +36,23 @@ tests/cases/compiler/controlFlowLoopAnalysis.ts(13,25): error TS2345: Argument o } } } + + // Repro from #8511 + + function mapUntilCant( + values: a[], + canTake: (value: a, index: number) => boolean, + mapping: (value: a, index: number) => b + ): b[] { + let result: b[] = []; + for (let index = 0, length = values.length; index < length; index++) { + let value = values[index]; + if (canTake(value, index)) { + result.push(mapping(value, index)); + } else { + return result; + } + } + return result; + } \ No newline at end of file diff --git a/tests/baselines/reference/controlFlowLoopAnalysis.js b/tests/baselines/reference/controlFlowLoopAnalysis.js index 3cf2ce2caac..77384ddedcf 100644 --- a/tests/baselines/reference/controlFlowLoopAnalysis.js +++ b/tests/baselines/reference/controlFlowLoopAnalysis.js @@ -29,6 +29,25 @@ function test2() { } } } + +// Repro from #8511 + +function mapUntilCant( + values: a[], + canTake: (value: a, index: number) => boolean, + mapping: (value: a, index: number) => b +): b[] { + let result: b[] = []; + for (let index = 0, length = values.length; index < length; index++) { + let value = values[index]; + if (canTake(value, index)) { + result.push(mapping(value, index)); + } else { + return result; + } + } + return result; +} //// [controlFlowLoopAnalysis.js] @@ -56,3 +75,17 @@ function test2() { } } } +// Repro from #8511 +function mapUntilCant(values, canTake, mapping) { + var result = []; + for (var index = 0, length = values.length; index < length; index++) { + var value = values[index]; + if (canTake(value, index)) { + result.push(mapping(value, index)); + } + else { + return result; + } + } + return result; +} diff --git a/tests/cases/compiler/controlFlowLoopAnalysis.ts b/tests/cases/compiler/controlFlowLoopAnalysis.ts index 60cb9436006..e4fb2f91f7e 100644 --- a/tests/cases/compiler/controlFlowLoopAnalysis.ts +++ b/tests/cases/compiler/controlFlowLoopAnalysis.ts @@ -1,4 +1,5 @@ // @strictNullChecks: true +// @noImplicitAny: true // Repro from #8418 @@ -29,3 +30,22 @@ function test2() { } } } + +// Repro from #8511 + +function mapUntilCant( + values: a[], + canTake: (value: a, index: number) => boolean, + mapping: (value: a, index: number) => b +): b[] { + let result: b[] = []; + for (let index = 0, length = values.length; index < length; index++) { + let value = values[index]; + if (canTake(value, index)) { + result.push(mapping(value, index)); + } else { + return result; + } + } + return result; +}