From 4d28d70489a6a7701c0a7ee2f87192924f010e75 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 26 Jun 2018 09:32:12 -0700 Subject: [PATCH 1/2] Fix control flow loop in yield expression Yet again, the fix is to stop using checkExpressionCached. --- src/compiler/checker.ts | 2 +- .../yieldExpressionInControlFlow.errors.txt | 27 +++++++++++++ .../yieldExpressionInControlFlow.symbols | 29 ++++++++++++++ .../yieldExpressionInControlFlow.types | 38 +++++++++++++++++++ .../yieldExpressionInControlFlow.ts | 20 ++++++++++ 5 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/yieldExpressionInControlFlow.errors.txt create mode 100644 tests/baselines/reference/yieldExpressionInControlFlow.symbols create mode 100644 tests/baselines/reference/yieldExpressionInControlFlow.types create mode 100644 tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 27e1b8117f441..9388827b85f64 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19618,7 +19618,7 @@ namespace ts { function getYieldedTypeOfYieldExpression(node: YieldExpression, isAsync: boolean, checkMode?: CheckMode): Type | undefined { const errorNode = node.expression || node; - const expressionType = node.expression ? checkExpressionCached(node.expression, checkMode) : undefinedWideningType; + const expressionType = node.expression ? checkExpression(node.expression, checkMode) : undefinedWideningType; // A `yield*` expression effectively yields everything that its operand yields const yieldedType = node.asteriskToken ? checkIteratedTypeOrElementType(expressionType, errorNode, /*allowStringInput*/ false, isAsync) : expressionType; return !isAsync ? yieldedType : getAwaitedType(yieldedType, errorNode, node.asteriskToken diff --git a/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt b/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt new file mode 100644 index 0000000000000..2e320065f0c88 --- /dev/null +++ b/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt @@ -0,0 +1,27 @@ +error TS2318: Cannot find global type 'IterableIterator'. +tests/cases/conformance/es6/yieldExpressions/alsoFails.ts(3,9): error TS7034: Variable 'o' implicitly has type 'any[]' in some locations where its type cannot be determined. +tests/cases/conformance/es6/yieldExpressions/alsoFails.ts(5,20): error TS7005: Variable 'o' implicitly has an 'any[]' type. + + +!!! error TS2318: Cannot find global type 'IterableIterator'. +==== tests/cases/conformance/es6/yieldExpressions/bug25149.js (0 errors) ==== + function* f() { + var o + while (true) { + o = yield o + } + } + +==== tests/cases/conformance/es6/yieldExpressions/alsoFails.ts (2 errors) ==== + // fails in Typescript too + function* g() { + var o = [] + ~ +!!! error TS7034: Variable 'o' implicitly has type 'any[]' in some locations where its type cannot be determined. + while (true) { + o = yield* o + ~ +!!! error TS7005: Variable 'o' implicitly has an 'any[]' type. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/yieldExpressionInControlFlow.symbols b/tests/baselines/reference/yieldExpressionInControlFlow.symbols new file mode 100644 index 0000000000000..1a0a2968dccfc --- /dev/null +++ b/tests/baselines/reference/yieldExpressionInControlFlow.symbols @@ -0,0 +1,29 @@ +=== tests/cases/conformance/es6/yieldExpressions/bug25149.js === +function* f() { +>f : Symbol(f, Decl(bug25149.js, 0, 0)) + + var o +>o : Symbol(o, Decl(bug25149.js, 1, 7)) + + while (true) { + o = yield o +>o : Symbol(o, Decl(bug25149.js, 1, 7)) +>o : Symbol(o, Decl(bug25149.js, 1, 7)) + } +} + +=== tests/cases/conformance/es6/yieldExpressions/alsoFails.ts === +// fails in Typescript too +function* g() { +>g : Symbol(g, Decl(alsoFails.ts, 0, 0)) + + var o = [] +>o : Symbol(o, Decl(alsoFails.ts, 2, 7)) + + while (true) { + o = yield* o +>o : Symbol(o, Decl(alsoFails.ts, 2, 7)) +>o : Symbol(o, Decl(alsoFails.ts, 2, 7)) + } +} + diff --git a/tests/baselines/reference/yieldExpressionInControlFlow.types b/tests/baselines/reference/yieldExpressionInControlFlow.types new file mode 100644 index 0000000000000..cae31ee8577a2 --- /dev/null +++ b/tests/baselines/reference/yieldExpressionInControlFlow.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/es6/yieldExpressions/bug25149.js === +function* f() { +>f : () => {} + + var o +>o : any + + while (true) { +>true : true + + o = yield o +>o = yield o : any +>o : any +>yield o : any +>o : any + } +} + +=== tests/cases/conformance/es6/yieldExpressions/alsoFails.ts === +// fails in Typescript too +function* g() { +>g : () => {} + + var o = [] +>o : any[] +>[] : undefined[] + + while (true) { +>true : true + + o = yield* o +>o = yield* o : any +>o : any[] +>yield* o : any +>o : any + } +} + diff --git a/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts b/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts new file mode 100644 index 0000000000000..5a9ac421d8d4c --- /dev/null +++ b/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts @@ -0,0 +1,20 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true +// @noImplicitAny: true +// @Filename: bug25149.js +function* f() { + var o + while (true) { + o = yield o + } +} + +// @Filename: alsoFails.ts +// fails in Typescript too +function* g() { + var o = [] + while (true) { + o = yield* o + } +} From 452a24f15c5519141832c4267594e20630466dfc Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Tue, 26 Jun 2018 09:34:30 -0700 Subject: [PATCH 2/2] Update lib in test to reduce number of errors --- .../reference/yieldExpressionInControlFlow.errors.txt | 2 -- tests/baselines/reference/yieldExpressionInControlFlow.types | 4 ++-- .../es6/yieldExpressions/yieldExpressionInControlFlow.ts | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt b/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt index 2e320065f0c88..b571231172d53 100644 --- a/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt +++ b/tests/baselines/reference/yieldExpressionInControlFlow.errors.txt @@ -1,9 +1,7 @@ -error TS2318: Cannot find global type 'IterableIterator'. tests/cases/conformance/es6/yieldExpressions/alsoFails.ts(3,9): error TS7034: Variable 'o' implicitly has type 'any[]' in some locations where its type cannot be determined. tests/cases/conformance/es6/yieldExpressions/alsoFails.ts(5,20): error TS7005: Variable 'o' implicitly has an 'any[]' type. -!!! error TS2318: Cannot find global type 'IterableIterator'. ==== tests/cases/conformance/es6/yieldExpressions/bug25149.js (0 errors) ==== function* f() { var o diff --git a/tests/baselines/reference/yieldExpressionInControlFlow.types b/tests/baselines/reference/yieldExpressionInControlFlow.types index cae31ee8577a2..14650ef05829c 100644 --- a/tests/baselines/reference/yieldExpressionInControlFlow.types +++ b/tests/baselines/reference/yieldExpressionInControlFlow.types @@ -1,6 +1,6 @@ === tests/cases/conformance/es6/yieldExpressions/bug25149.js === function* f() { ->f : () => {} +>f : () => IterableIterator var o >o : any @@ -19,7 +19,7 @@ function* f() { === tests/cases/conformance/es6/yieldExpressions/alsoFails.ts === // fails in Typescript too function* g() { ->g : () => {} +>g : () => IterableIterator var o = [] >o : any[] diff --git a/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts b/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts index 5a9ac421d8d4c..fbabcbebce4ff 100644 --- a/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts +++ b/tests/cases/conformance/es6/yieldExpressions/yieldExpressionInControlFlow.ts @@ -2,6 +2,7 @@ // @allowJs: true // @checkJs: true // @noImplicitAny: true +// @lib: esnext // @Filename: bug25149.js function* f() { var o