Skip to content

Commit e68fa65

Browse files
authored
Report iteration errors on all error nodes (#1061)
1 parent bc8ac16 commit e68fa65

File tree

7 files changed

+30
-82
lines changed

7 files changed

+30
-82
lines changed

internal/checker/checker.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,6 @@ const (
470470
IterationUseSpreadFlag IterationUse = 1 << 5
471471
IterationUseDestructuringFlag IterationUse = 1 << 6
472472
IterationUsePossiblyOutOfBounds IterationUse = 1 << 7
473-
IterationUseReportError IterationUse = 1 << 8
474473
// Spread, Destructuring, Array element assignment
475474
IterationUseElement = IterationUseAllowsSyncIterablesFlag
476475
IterationUseSpread = IterationUseAllowsSyncIterablesFlag | IterationUseSpreadFlag
@@ -481,7 +480,7 @@ const (
481480
IterationUseAsyncYieldStar = IterationUseAllowsSyncIterablesFlag | IterationUseAllowsAsyncIterablesFlag | IterationUseYieldStarFlag
482481
IterationUseGeneratorReturnType = IterationUseAllowsSyncIterablesFlag
483482
IterationUseAsyncGeneratorReturnType = IterationUseAllowsAsyncIterablesFlag
484-
IterationUseCacheFlags = IterationUseAllowsSyncIterablesFlag | IterationUseAllowsAsyncIterablesFlag | IterationUseForOfFlag | IterationUseReportError
483+
IterationUseCacheFlags = IterationUseAllowsSyncIterablesFlag | IterationUseAllowsAsyncIterablesFlag | IterationUseForOfFlag
485484
)
486485

487486
type IterationTypes struct {
@@ -5907,18 +5906,26 @@ func (c *Checker) getIterationTypesOfIterable(t *Type, use IterationUse, errorNo
59075906
if IsTypeAny(t) {
59085907
return IterationTypes{c.anyType, c.anyType, c.anyType}
59095908
}
5910-
key := IterationTypesKey{typeId: t.id, use: use&IterationUseCacheFlags | core.IfElse(errorNode != nil, IterationUseReportError, 0)}
5909+
key := IterationTypesKey{typeId: t.id, use: use & IterationUseCacheFlags}
5910+
// If we are reporting errors and encounter a cached `noIterationTypes`, we should ignore the cached value and continue as if nothing was cached.
5911+
// In addition, we should not cache any new results for this call.
5912+
noCache := false
59115913
if cached, ok := c.iterationTypesCache[key]; ok {
5912-
return cached
5914+
if errorNode == nil || cached.hasTypes() {
5915+
return cached
5916+
}
5917+
noCache = true
5918+
}
5919+
result := c.getIterationTypesOfIterableWorker(t, use, errorNode, noCache)
5920+
if !noCache {
5921+
c.iterationTypesCache[key] = result
59135922
}
5914-
result := c.getIterationTypesOfIterableWorker(t, use, errorNode)
5915-
c.iterationTypesCache[key] = result
59165923
return result
59175924
}
59185925

5919-
func (c *Checker) getIterationTypesOfIterableWorker(t *Type, use IterationUse, errorNode *ast.Node) IterationTypes {
5926+
func (c *Checker) getIterationTypesOfIterableWorker(t *Type, use IterationUse, errorNode *ast.Node, noCache bool) IterationTypes {
59205927
if t.flags&TypeFlagsUnion != 0 {
5921-
return c.combineIterationTypes(core.Map(t.Types(), func(t *Type) IterationTypes { return c.getIterationTypesOfIterableWorker(t, use, errorNode) }))
5928+
return c.combineIterationTypes(core.Map(t.Types(), func(t *Type) IterationTypes { return c.getIterationTypesOfIterableWorker(t, use, errorNode, noCache) }))
59225929
}
59235930
if use&IterationUseAllowsAsyncIterablesFlag != 0 {
59245931
iterationTypes := c.getIterationTypesOfIterableFast(t, c.asyncIterationTypesResolver)

testdata/baselines/reference/submodule/compiler/omittedExpressionForOfLoop.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
omittedExpressionForOfLoop.ts(1,19): error TS2304: Cannot find name 'doesNotExist'.
22
omittedExpressionForOfLoop.ts(4,19): error TS18050: The value 'undefined' cannot be used here.
33
omittedExpressionForOfLoop.ts(7,12): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
4+
omittedExpressionForOfLoop.ts(10,12): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
45

56

6-
==== omittedExpressionForOfLoop.ts (3 errors) ====
7+
==== omittedExpressionForOfLoop.ts (4 errors) ====
78
for (const [,] of doesNotExist) {
89
~~~~~~~~~~~~
910
!!! error TS2304: Cannot find name 'doesNotExist'.
@@ -20,4 +21,6 @@ omittedExpressionForOfLoop.ts(7,12): error TS2488: Type 'never' must have a '[Sy
2021
}
2122

2223
for (const [] of []) {
24+
~~
25+
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
2326
}

testdata/baselines/reference/submodule/compiler/omittedExpressionForOfLoop.errors.txt.diff

Lines changed: 0 additions & 23 deletions
This file was deleted.

testdata/baselines/reference/submodule/conformance/for-of16.errors.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
for-of16.ts(8,11): error TS2488: Type 'MyStringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
2+
for-of16.ts(10,11): error TS2488: Type 'MyStringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
23

34

4-
==== for-of16.ts (1 errors) ====
5+
==== for-of16.ts (2 errors) ====
56
class MyStringIterator {
67
[Symbol.iterator]() {
78
return this;
@@ -14,4 +15,7 @@ for-of16.ts(8,11): error TS2488: Type 'MyStringIterator' must have a '[Symbol.it
1415
!!! error TS2488: Type 'MyStringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
1516
!!! related TS2489 for-of16.ts:8:11: An iterator must have a 'next()' method.
1617

17-
for (v of new MyStringIterator) { } // Should still fail (related errors should still be shown even though type is cached).
18+
for (v of new MyStringIterator) { } // Should still fail (related errors should still be shown even though type is cached).
19+
~~~~~~~~~~~~~~~~~~~~
20+
!!! error TS2488: Type 'MyStringIterator' must have a '[Symbol.iterator]()' method that returns an iterator.
21+
!!! related TS2489 for-of16.ts:10:11: An iterator must have a 'next()' method.

testdata/baselines/reference/submodule/conformance/for-of16.errors.txt.diff

Lines changed: 0 additions & 21 deletions
This file was deleted.

testdata/baselines/reference/submodule/conformance/types.forAwait.es2018.2.errors.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ types.forAwait.es2018.2.ts(8,21): error TS2504: Type '{}' must have a '[Symbol.a
33
types.forAwait.es2018.2.ts(10,16): error TS2322: Type 'number' is not assignable to type 'string'.
44
types.forAwait.es2018.2.ts(12,16): error TS2322: Type 'number' is not assignable to type 'string'.
55
types.forAwait.es2018.2.ts(14,21): error TS2488: Type 'AsyncIterable<number>' must have a '[Symbol.iterator]()' method that returns an iterator.
6+
types.forAwait.es2018.2.ts(16,15): error TS2488: Type 'AsyncIterable<number>' must have a '[Symbol.iterator]()' method that returns an iterator.
67

78

8-
==== types.forAwait.es2018.2.ts (5 errors) ====
9+
==== types.forAwait.es2018.2.ts (6 errors) ====
910
declare const asyncIterable: AsyncIterable<number>;
1011
declare const iterable: Iterable<number>;
1112
async function f() {
@@ -33,6 +34,9 @@ types.forAwait.es2018.2.ts(14,21): error TS2488: Type 'AsyncIterable<number>' mu
3334
!!! related TS2773 types.forAwait.es2018.2.ts:14:21: Did you forget to use 'await'?
3435
}
3536
for (y of asyncIterable) {
37+
~~~~~~~~~~~~~
38+
!!! error TS2488: Type 'AsyncIterable<number>' must have a '[Symbol.iterator]()' method that returns an iterator.
39+
!!! related TS2773 types.forAwait.es2018.2.ts:16:15: Did you forget to use 'await'?
3640
}
3741
}
3842

testdata/baselines/reference/submodule/conformance/types.forAwait.es2018.2.errors.txt.diff

Lines changed: 0 additions & 26 deletions
This file was deleted.

0 commit comments

Comments
 (0)