From 89497fcac9bc5fddda798f31c052695e84fa58da Mon Sep 17 00:00:00 2001 From: Andrew Branch Date: Wed, 24 Apr 2019 14:15:58 -0700 Subject: [PATCH] =?UTF-8?q?Don=E2=80=99t=20use=20checkExpressionCached=20w?= =?UTF-8?q?hen=20checking=20spread=20element=20inside=20a=20loop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/compiler/checker.ts | 2 +- .../noImplicitAnyLoopCrash.errors.txt | 18 ++++++++++++++++ .../reference/noImplicitAnyLoopCrash.js | 14 +++++++++++++ .../reference/noImplicitAnyLoopCrash.symbols | 14 +++++++++++++ .../reference/noImplicitAnyLoopCrash.types | 21 +++++++++++++++++++ .../cases/compiler/noImplicitAnyLoopCrash.ts | 9 ++++---- 6 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/noImplicitAnyLoopCrash.errors.txt create mode 100644 tests/baselines/reference/noImplicitAnyLoopCrash.js create mode 100644 tests/baselines/reference/noImplicitAnyLoopCrash.symbols create mode 100644 tests/baselines/reference/noImplicitAnyLoopCrash.types diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 22a658a0f7ab3..d53253e655841 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20708,7 +20708,7 @@ namespace ts { // of the argument is a tuple type, spread the tuple elements into the argument list. We can // call checkExpressionCached because spread expressions never have a contextual type. const spreadArgument = args[length - 1]; - const type = checkExpressionCached(spreadArgument.expression); + const type = flowLoopCount ? checkExpression(spreadArgument.expression) : checkExpressionCached(spreadArgument.expression); if (isTupleType(type)) { const typeArguments = (type).typeArguments || emptyArray; const restIndex = type.target.hasRestElement ? typeArguments.length - 1 : -1; diff --git a/tests/baselines/reference/noImplicitAnyLoopCrash.errors.txt b/tests/baselines/reference/noImplicitAnyLoopCrash.errors.txt new file mode 100644 index 0000000000000..2937f133749d7 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyLoopCrash.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,16): error TS2556: Expected 0 arguments, but got 1 or more. +tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'number' is not an array type. +tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'undefined' is not an array type. + + +==== tests/cases/compiler/noImplicitAnyLoopCrash.ts (3 errors) ==== + let foo = () => {}; + let bar; + while (1) { + bar = ~foo(...bar); + ~~~~~~ +!!! error TS2556: Expected 0 arguments, but got 1 or more. + ~~~ +!!! error TS2461: Type 'number' is not an array type. + ~~~ +!!! error TS2461: Type 'undefined' is not an array type. + } + \ No newline at end of file diff --git a/tests/baselines/reference/noImplicitAnyLoopCrash.js b/tests/baselines/reference/noImplicitAnyLoopCrash.js new file mode 100644 index 0000000000000..36f8a7470b221 --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyLoopCrash.js @@ -0,0 +1,14 @@ +//// [noImplicitAnyLoopCrash.ts] +let foo = () => {}; +let bar; +while (1) { + bar = ~foo(...bar); +} + + +//// [noImplicitAnyLoopCrash.js] +var foo = function () { }; +var bar; +while (1) { + bar = ~foo.apply(void 0, bar); +} diff --git a/tests/baselines/reference/noImplicitAnyLoopCrash.symbols b/tests/baselines/reference/noImplicitAnyLoopCrash.symbols new file mode 100644 index 0000000000000..1bac6fac5ab4b --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyLoopCrash.symbols @@ -0,0 +1,14 @@ +=== tests/cases/compiler/noImplicitAnyLoopCrash.ts === +let foo = () => {}; +>foo : Symbol(foo, Decl(noImplicitAnyLoopCrash.ts, 0, 3)) + +let bar; +>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3)) + +while (1) { + bar = ~foo(...bar); +>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3)) +>foo : Symbol(foo, Decl(noImplicitAnyLoopCrash.ts, 0, 3)) +>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3)) +} + diff --git a/tests/baselines/reference/noImplicitAnyLoopCrash.types b/tests/baselines/reference/noImplicitAnyLoopCrash.types new file mode 100644 index 0000000000000..2e698c0673eba --- /dev/null +++ b/tests/baselines/reference/noImplicitAnyLoopCrash.types @@ -0,0 +1,21 @@ +=== tests/cases/compiler/noImplicitAnyLoopCrash.ts === +let foo = () => {}; +>foo : () => void +>() => {} : () => void + +let bar; +>bar : any + +while (1) { +>1 : 1 + + bar = ~foo(...bar); +>bar = ~foo(...bar) : number +>bar : any +>~foo(...bar) : number +>foo(...bar) : void +>foo : () => void +>...bar : any +>bar : number +} + diff --git a/tests/cases/compiler/noImplicitAnyLoopCrash.ts b/tests/cases/compiler/noImplicitAnyLoopCrash.ts index d43802765065e..1df8a27a92df6 100644 --- a/tests/cases/compiler/noImplicitAnyLoopCrash.ts +++ b/tests/cases/compiler/noImplicitAnyLoopCrash.ts @@ -1,5 +1,6 @@ // @noImplicitAny: true -let foo = () => {}; // if you remove or change foo definition to not a function, bug disappears -let bar; // if you add type annotation here, bug disappears -while (1) // if you remove while, bug disappears - bar = ~foo(...bar); // if you remove unary or spread operator, bug disappears \ No newline at end of file +let foo = () => {}; +let bar; +while (1) { + bar = ~foo(...bar); +}