Skip to content

Commit

Permalink
Don’t use checkExpressionCached when checking spread element inside a…
Browse files Browse the repository at this point in the history
… loop
  • Loading branch information
andrewbranch committed Apr 24, 2019
1 parent 48f0380 commit 89497fc
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/compiler/checker.ts
Expand Up @@ -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 = <SpreadElement>args[length - 1];
const type = checkExpressionCached(spreadArgument.expression);
const type = flowLoopCount ? checkExpression(spreadArgument.expression) : checkExpressionCached(spreadArgument.expression);
if (isTupleType(type)) {
const typeArguments = (<TypeReference>type).typeArguments || emptyArray;
const restIndex = type.target.hasRestElement ? typeArguments.length - 1 : -1;
Expand Down
18 changes: 18 additions & 0 deletions 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.
}

14 changes: 14 additions & 0 deletions 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);
}
14 changes: 14 additions & 0 deletions 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))
}

21 changes: 21 additions & 0 deletions 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
}

9 changes: 5 additions & 4 deletions 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
let foo = () => {};
let bar;
while (1) {
bar = ~foo(...bar);
}

0 comments on commit 89497fc

Please sign in to comment.