Skip to content

Commit 632479f

Browse files
Fixed an issue causing spurious "used before being assigned" errors in for of/in loops (#61376)
Co-authored-by: Ryan Cavanaugh <[email protected]>
1 parent 9d36497 commit 632479f

File tree

5 files changed

+489
-1
lines changed

5 files changed

+489
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31113,7 +31113,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3111331113
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
3111431114
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
3111531115
// declaration container are the same).
31116-
const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
31116+
const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !isForInOrOfStatement(immediateDeclaration.parent.parent) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
3111731117
const assumeInitialized = isParameter || isAlias ||
3111831118
(isOuterVariable && !isNeverInitialized) ||
3111931119
isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
unusedLocalsInForInOrOf1.ts(2,12): error TS6133: 'f' is declared but its value is never read.
2+
unusedLocalsInForInOrOf1.ts(8,7): error TS6133: 'f' is declared but its value is never read.
3+
unusedLocalsInForInOrOf1.ts(14,12): error TS6133: 'g' is declared but its value is never read.
4+
unusedLocalsInForInOrOf1.ts(20,12): error TS6133: 'f2' is declared but its value is never read.
5+
unusedLocalsInForInOrOf1.ts(26,7): error TS6133: 'f2' is declared but its value is never read.
6+
unusedLocalsInForInOrOf1.ts(32,12): error TS6133: 'g2' is declared but its value is never read.
7+
unusedLocalsInForInOrOf1.ts(38,12): error TS6133: 'f3' is declared but its value is never read.
8+
unusedLocalsInForInOrOf1.ts(44,7): error TS6133: 'f3' is declared but its value is never read.
9+
unusedLocalsInForInOrOf1.ts(50,12): error TS6133: 'g3' is declared but its value is never read.
10+
11+
12+
==== unusedLocalsInForInOrOf1.ts (9 errors) ====
13+
for (let x of [1, 2]) {
14+
function f() {
15+
~
16+
!!! error TS6133: 'f' is declared but its value is never read.
17+
x;
18+
}
19+
}
20+
21+
for (let x of [1, 2]) {
22+
let f = () => {
23+
~
24+
!!! error TS6133: 'f' is declared but its value is never read.
25+
x;
26+
};
27+
}
28+
29+
for (const x of [1, 2]) {
30+
function g() {
31+
~
32+
!!! error TS6133: 'g' is declared but its value is never read.
33+
x;
34+
}
35+
}
36+
37+
for (let x in { a: 1, b: 2 }) {
38+
function f2() {
39+
~~
40+
!!! error TS6133: 'f2' is declared but its value is never read.
41+
x;
42+
}
43+
}
44+
45+
for (let x in { a: 1, b: 2 }) {
46+
let f2 = () => {
47+
~~
48+
!!! error TS6133: 'f2' is declared but its value is never read.
49+
x;
50+
};
51+
}
52+
53+
for (const x in { a: 1, b: 2 }) {
54+
function g2() {
55+
~~
56+
!!! error TS6133: 'g2' is declared but its value is never read.
57+
x;
58+
}
59+
}
60+
61+
for (let { x } of [{ x: 1 }, { x: 2 }]) {
62+
function f3() {
63+
~~
64+
!!! error TS6133: 'f3' is declared but its value is never read.
65+
x;
66+
}
67+
}
68+
69+
for (let { x } of [{ x: 1 }, { x: 2 }]) {
70+
let f3 = () => {
71+
~~
72+
!!! error TS6133: 'f3' is declared but its value is never read.
73+
x;
74+
};
75+
}
76+
77+
for (const { x } of [{ x: 1 }, { x: 2 }]) {
78+
function g3() {
79+
~~
80+
!!! error TS6133: 'g3' is declared but its value is never read.
81+
x;
82+
}
83+
}
84+
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//// [tests/cases/compiler/unusedLocalsInForInOrOf1.ts] ////
2+
3+
=== unusedLocalsInForInOrOf1.ts ===
4+
for (let x of [1, 2]) {
5+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 0, 8))
6+
7+
function f() {
8+
>f : Symbol(f, Decl(unusedLocalsInForInOrOf1.ts, 0, 23))
9+
10+
x;
11+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 0, 8))
12+
}
13+
}
14+
15+
for (let x of [1, 2]) {
16+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 6, 8))
17+
18+
let f = () => {
19+
>f : Symbol(f, Decl(unusedLocalsInForInOrOf1.ts, 7, 5))
20+
21+
x;
22+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 6, 8))
23+
24+
};
25+
}
26+
27+
for (const x of [1, 2]) {
28+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 12, 10))
29+
30+
function g() {
31+
>g : Symbol(g, Decl(unusedLocalsInForInOrOf1.ts, 12, 25))
32+
33+
x;
34+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 12, 10))
35+
}
36+
}
37+
38+
for (let x in { a: 1, b: 2 }) {
39+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 18, 8))
40+
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 18, 15))
41+
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 18, 21))
42+
43+
function f2() {
44+
>f2 : Symbol(f2, Decl(unusedLocalsInForInOrOf1.ts, 18, 31))
45+
46+
x;
47+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 18, 8))
48+
}
49+
}
50+
51+
for (let x in { a: 1, b: 2 }) {
52+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 24, 8))
53+
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 24, 15))
54+
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 24, 21))
55+
56+
let f2 = () => {
57+
>f2 : Symbol(f2, Decl(unusedLocalsInForInOrOf1.ts, 25, 5))
58+
59+
x;
60+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 24, 8))
61+
62+
};
63+
}
64+
65+
for (const x in { a: 1, b: 2 }) {
66+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 30, 10))
67+
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 30, 17))
68+
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 30, 23))
69+
70+
function g2() {
71+
>g2 : Symbol(g2, Decl(unusedLocalsInForInOrOf1.ts, 30, 33))
72+
73+
x;
74+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 30, 10))
75+
}
76+
}
77+
78+
for (let { x } of [{ x: 1 }, { x: 2 }]) {
79+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 10))
80+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 20))
81+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 30))
82+
83+
function f3() {
84+
>f3 : Symbol(f3, Decl(unusedLocalsInForInOrOf1.ts, 36, 41))
85+
86+
x;
87+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 10))
88+
}
89+
}
90+
91+
for (let { x } of [{ x: 1 }, { x: 2 }]) {
92+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 10))
93+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 20))
94+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 30))
95+
96+
let f3 = () => {
97+
>f3 : Symbol(f3, Decl(unusedLocalsInForInOrOf1.ts, 43, 5))
98+
99+
x;
100+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 10))
101+
102+
};
103+
}
104+
105+
for (const { x } of [{ x: 1 }, { x: 2 }]) {
106+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 12))
107+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 22))
108+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 32))
109+
110+
function g3() {
111+
>g3 : Symbol(g3, Decl(unusedLocalsInForInOrOf1.ts, 48, 43))
112+
113+
x;
114+
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 12))
115+
}
116+
}
117+

0 commit comments

Comments
 (0)