Skip to content

Commit 89497fc

Browse files
committed
Don’t use checkExpressionCached when checking spread element inside a loop
1 parent 48f0380 commit 89497fc

File tree

6 files changed

+73
-5
lines changed

6 files changed

+73
-5
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20708,7 +20708,7 @@ namespace ts {
2070820708
// of the argument is a tuple type, spread the tuple elements into the argument list. We can
2070920709
// call checkExpressionCached because spread expressions never have a contextual type.
2071020710
const spreadArgument = <SpreadElement>args[length - 1];
20711-
const type = checkExpressionCached(spreadArgument.expression);
20711+
const type = flowLoopCount ? checkExpression(spreadArgument.expression) : checkExpressionCached(spreadArgument.expression);
2071220712
if (isTupleType(type)) {
2071320713
const typeArguments = (<TypeReference>type).typeArguments || emptyArray;
2071420714
const restIndex = type.target.hasRestElement ? typeArguments.length - 1 : -1;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,16): error TS2556: Expected 0 arguments, but got 1 or more.
2+
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'number' is not an array type.
3+
tests/cases/compiler/noImplicitAnyLoopCrash.ts(4,19): error TS2461: Type 'undefined' is not an array type.
4+
5+
6+
==== tests/cases/compiler/noImplicitAnyLoopCrash.ts (3 errors) ====
7+
let foo = () => {};
8+
let bar;
9+
while (1) {
10+
bar = ~foo(...bar);
11+
~~~~~~
12+
!!! error TS2556: Expected 0 arguments, but got 1 or more.
13+
~~~
14+
!!! error TS2461: Type 'number' is not an array type.
15+
~~~
16+
!!! error TS2461: Type 'undefined' is not an array type.
17+
}
18+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//// [noImplicitAnyLoopCrash.ts]
2+
let foo = () => {};
3+
let bar;
4+
while (1) {
5+
bar = ~foo(...bar);
6+
}
7+
8+
9+
//// [noImplicitAnyLoopCrash.js]
10+
var foo = function () { };
11+
var bar;
12+
while (1) {
13+
bar = ~foo.apply(void 0, bar);
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/compiler/noImplicitAnyLoopCrash.ts ===
2+
let foo = () => {};
3+
>foo : Symbol(foo, Decl(noImplicitAnyLoopCrash.ts, 0, 3))
4+
5+
let bar;
6+
>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3))
7+
8+
while (1) {
9+
bar = ~foo(...bar);
10+
>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3))
11+
>foo : Symbol(foo, Decl(noImplicitAnyLoopCrash.ts, 0, 3))
12+
>bar : Symbol(bar, Decl(noImplicitAnyLoopCrash.ts, 1, 3))
13+
}
14+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
=== tests/cases/compiler/noImplicitAnyLoopCrash.ts ===
2+
let foo = () => {};
3+
>foo : () => void
4+
>() => {} : () => void
5+
6+
let bar;
7+
>bar : any
8+
9+
while (1) {
10+
>1 : 1
11+
12+
bar = ~foo(...bar);
13+
>bar = ~foo(...bar) : number
14+
>bar : any
15+
>~foo(...bar) : number
16+
>foo(...bar) : void
17+
>foo : () => void
18+
>...bar : any
19+
>bar : number
20+
}
21+
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @noImplicitAny: true
2-
let foo = () => {}; // if you remove or change foo definition to not a function, bug disappears
3-
let bar; // if you add type annotation here, bug disappears
4-
while (1) // if you remove while, bug disappears
5-
bar = ~foo(...bar); // if you remove unary or spread operator, bug disappears
2+
let foo = () => {};
3+
let bar;
4+
while (1) {
5+
bar = ~foo(...bar);
6+
}

0 commit comments

Comments
 (0)