diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index caab75c99fa8a..5c1f4593aa251 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30452,7 +30452,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) || diff --git a/tests/baselines/reference/unusedLocalsInForInOrOf1.errors.txt b/tests/baselines/reference/unusedLocalsInForInOrOf1.errors.txt new file mode 100644 index 0000000000000..2b0a014ec961b --- /dev/null +++ b/tests/baselines/reference/unusedLocalsInForInOrOf1.errors.txt @@ -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; + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsInForInOrOf1.symbols b/tests/baselines/reference/unusedLocalsInForInOrOf1.symbols new file mode 100644 index 0000000000000..c4c2381baff5d --- /dev/null +++ b/tests/baselines/reference/unusedLocalsInForInOrOf1.symbols @@ -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)) + } +} + diff --git a/tests/baselines/reference/unusedLocalsInForInOrOf1.types b/tests/baselines/reference/unusedLocalsInForInOrOf1.types new file mode 100644 index 0000000000000..cf2e52be73799 --- /dev/null +++ b/tests/baselines/reference/unusedLocalsInForInOrOf1.types @@ -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 +> : ^^^^^^ + } +} + diff --git a/tests/cases/compiler/unusedLocalsInForInOrOf1.ts b/tests/cases/compiler/unusedLocalsInForInOrOf1.ts new file mode 100644 index 0000000000000..edbdad5c59069 --- /dev/null +++ b/tests/cases/compiler/unusedLocalsInForInOrOf1.ts @@ -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; + } +}