mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Fixed an issue causing spurious "used before being assigned" errors in for of/in loops (#61376)
Co-authored-by: Ryan Cavanaugh <RyanCavanaugh@users.noreply.github.com>
This commit is contained in:
parent
9d364978d3
commit
632479f28d
@ -31113,7 +31113,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
|
||||
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
|
||||
// declaration container are the same).
|
||||
const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
|
||||
const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !isForInOrOfStatement(immediateDeclaration.parent.parent) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol);
|
||||
const assumeInitialized = isParameter || isAlias ||
|
||||
(isOuterVariable && !isNeverInitialized) ||
|
||||
isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) ||
|
||||
|
||||
@ -0,0 +1,84 @@
|
||||
unusedLocalsInForInOrOf1.ts(2,12): error TS6133: 'f' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(8,7): error TS6133: 'f' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(14,12): error TS6133: 'g' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(20,12): error TS6133: 'f2' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(26,7): error TS6133: 'f2' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(32,12): error TS6133: 'g2' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(38,12): error TS6133: 'f3' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(44,7): error TS6133: 'f3' is declared but its value is never read.
|
||||
unusedLocalsInForInOrOf1.ts(50,12): error TS6133: 'g3' is declared but its value is never read.
|
||||
|
||||
|
||||
==== unusedLocalsInForInOrOf1.ts (9 errors) ====
|
||||
for (let x of [1, 2]) {
|
||||
function f() {
|
||||
~
|
||||
!!! error TS6133: 'f' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x of [1, 2]) {
|
||||
let f = () => {
|
||||
~
|
||||
!!! error TS6133: 'f' is declared but its value is never read.
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const x of [1, 2]) {
|
||||
function g() {
|
||||
~
|
||||
!!! error TS6133: 'g' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
function f2() {
|
||||
~~
|
||||
!!! error TS6133: 'f2' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
let f2 = () => {
|
||||
~~
|
||||
!!! error TS6133: 'f2' is declared but its value is never read.
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const x in { a: 1, b: 2 }) {
|
||||
function g2() {
|
||||
~~
|
||||
!!! error TS6133: 'g2' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
function f3() {
|
||||
~~
|
||||
!!! error TS6133: 'f3' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
let f3 = () => {
|
||||
~~
|
||||
!!! error TS6133: 'f3' is declared but its value is never read.
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
function g3() {
|
||||
~~
|
||||
!!! error TS6133: 'g3' is declared but its value is never read.
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
117
tests/baselines/reference/unusedLocalsInForInOrOf1.symbols
Normal file
117
tests/baselines/reference/unusedLocalsInForInOrOf1.symbols
Normal file
@ -0,0 +1,117 @@
|
||||
//// [tests/cases/compiler/unusedLocalsInForInOrOf1.ts] ////
|
||||
|
||||
=== unusedLocalsInForInOrOf1.ts ===
|
||||
for (let x of [1, 2]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 0, 8))
|
||||
|
||||
function f() {
|
||||
>f : Symbol(f, Decl(unusedLocalsInForInOrOf1.ts, 0, 23))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 0, 8))
|
||||
}
|
||||
}
|
||||
|
||||
for (let x of [1, 2]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 6, 8))
|
||||
|
||||
let f = () => {
|
||||
>f : Symbol(f, Decl(unusedLocalsInForInOrOf1.ts, 7, 5))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 6, 8))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const x of [1, 2]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 12, 10))
|
||||
|
||||
function g() {
|
||||
>g : Symbol(g, Decl(unusedLocalsInForInOrOf1.ts, 12, 25))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 12, 10))
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 18, 8))
|
||||
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 18, 15))
|
||||
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 18, 21))
|
||||
|
||||
function f2() {
|
||||
>f2 : Symbol(f2, Decl(unusedLocalsInForInOrOf1.ts, 18, 31))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 18, 8))
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 24, 8))
|
||||
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 24, 15))
|
||||
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 24, 21))
|
||||
|
||||
let f2 = () => {
|
||||
>f2 : Symbol(f2, Decl(unusedLocalsInForInOrOf1.ts, 25, 5))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 24, 8))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const x in { a: 1, b: 2 }) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 30, 10))
|
||||
>a : Symbol(a, Decl(unusedLocalsInForInOrOf1.ts, 30, 17))
|
||||
>b : Symbol(b, Decl(unusedLocalsInForInOrOf1.ts, 30, 23))
|
||||
|
||||
function g2() {
|
||||
>g2 : Symbol(g2, Decl(unusedLocalsInForInOrOf1.ts, 30, 33))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 30, 10))
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 10))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 20))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 30))
|
||||
|
||||
function f3() {
|
||||
>f3 : Symbol(f3, Decl(unusedLocalsInForInOrOf1.ts, 36, 41))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 36, 10))
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 10))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 20))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 30))
|
||||
|
||||
let f3 = () => {
|
||||
>f3 : Symbol(f3, Decl(unusedLocalsInForInOrOf1.ts, 43, 5))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 42, 10))
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 12))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 22))
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 32))
|
||||
|
||||
function g3() {
|
||||
>g3 : Symbol(g3, Decl(unusedLocalsInForInOrOf1.ts, 48, 43))
|
||||
|
||||
x;
|
||||
>x : Symbol(x, Decl(unusedLocalsInForInOrOf1.ts, 48, 12))
|
||||
}
|
||||
}
|
||||
|
||||
228
tests/baselines/reference/unusedLocalsInForInOrOf1.types
Normal file
228
tests/baselines/reference/unusedLocalsInForInOrOf1.types
Normal file
@ -0,0 +1,228 @@
|
||||
//// [tests/cases/compiler/unusedLocalsInForInOrOf1.ts] ////
|
||||
|
||||
=== unusedLocalsInForInOrOf1.ts ===
|
||||
for (let x of [1, 2]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[1, 2] : number[]
|
||||
> : ^^^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function f() {
|
||||
>f : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
for (let x of [1, 2]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[1, 2] : number[]
|
||||
> : ^^^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
let f = () => {
|
||||
>f : () => void
|
||||
> : ^^^^^^^^^^
|
||||
>() => { x; } : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const x of [1, 2]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[1, 2] : number[]
|
||||
> : ^^^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function g() {
|
||||
>g : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>a : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>b : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function f2() {
|
||||
>f2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>a : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>b : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
let f2 = () => {
|
||||
>f2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
>() => { x; } : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const x in { a: 1, b: 2 }) {
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
>{ a: 1, b: 2 } : { a: number; b: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>a : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>b : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function g2() {
|
||||
>g2 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : string
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[{ x: 1 }, { x: 2 }] : { x: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>{ x: 1 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>{ x: 2 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function f3() {
|
||||
>f3 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[{ x: 1 }, { x: 2 }] : { x: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>{ x: 1 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>{ x: 2 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
let f3 = () => {
|
||||
>f3 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
>() => { x; } : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
for (const { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>[{ x: 1 }, { x: 2 }] : { x: number; }[]
|
||||
> : ^^^^^^^^^^^^^^^^
|
||||
>{ x: 1 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>1 : 1
|
||||
> : ^
|
||||
>{ x: 2 } : { x: number; }
|
||||
> : ^^^^^^^^^^^^^^
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
>2 : 2
|
||||
> : ^
|
||||
|
||||
function g3() {
|
||||
>g3 : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
x;
|
||||
>x : number
|
||||
> : ^^^^^^
|
||||
}
|
||||
}
|
||||
|
||||
59
tests/cases/compiler/unusedLocalsInForInOrOf1.ts
Normal file
59
tests/cases/compiler/unusedLocalsInForInOrOf1.ts
Normal file
@ -0,0 +1,59 @@
|
||||
// @strict: true
|
||||
// @target: esnext
|
||||
// @noEmit: true
|
||||
// @noUnusedLocals: true
|
||||
// @noUnusedParameters: true
|
||||
|
||||
for (let x of [1, 2]) {
|
||||
function f() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x of [1, 2]) {
|
||||
let f = () => {
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const x of [1, 2]) {
|
||||
function g() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
function f2() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let x in { a: 1, b: 2 }) {
|
||||
let f2 = () => {
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const x in { a: 1, b: 2 }) {
|
||||
function g2() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
function f3() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
|
||||
for (let { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
let f3 = () => {
|
||||
x;
|
||||
};
|
||||
}
|
||||
|
||||
for (const { x } of [{ x: 1 }, { x: 2 }]) {
|
||||
function g3() {
|
||||
x;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user