Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 13.7k
error on variables that are used but never initialized#55887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
ecf36a78416f9854183fdff025b37bb240f8d814cde8971985fbd69de1262a62942ade23be1058e4e266d32f696b3edbf0775670c158d0f36bfa97066f221044ce876f9a820746b735c1aabd4945c0011f0b637fbf4bb5110e2cf86c85362b930faaFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -29504,7 +29504,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| node.kind === SyntaxKind.PropertyDeclaration)!; | ||
| } | ||
| // Check if a parameter or catch variable is assigned anywhere | ||
| // Check if a parameter, catch variable, or mutable local variable is assigned anywhere definitely | ||
gabritto marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| function isSymbolAssignedDefinitely(symbol: Symbol) { | ||
| if (symbol.lastAssignmentPos !== undefined) { | ||
| return symbol.lastAssignmentPos < 0; | ||
| } | ||
| return isSymbolAssigned(symbol) && symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0; | ||
| } | ||
| // Check if a parameter, catch variable, or mutable local variable is assigned anywhere | ||
| function isSymbolAssigned(symbol: Symbol) { | ||
| return !isPastLastAssignment(symbol, /*location*/ undefined); | ||
| } | ||
| @@ -29523,7 +29531,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| markNodeAssignments(parent); | ||
| } | ||
| } | ||
| return !symbol.lastAssignmentPos || location && symbol.lastAssignmentPos < location.pos; | ||
| return !symbol.lastAssignmentPos || location && Math.abs(symbol.lastAssignmentPos) < location.pos; | ||
| } | ||
| // Check if a parameter or catch variable (or their bindings elements) is assigned anywhere | ||
| @@ -29557,12 +29565,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| function markNodeAssignments(node: Node) { | ||
| switch (node.kind) { | ||
| case SyntaxKind.Identifier: | ||
| if (isAssignmentTarget(node)) { | ||
| const assigmentTarget = getAssignmentTargetKind(node); | ||
| if (assigmentTarget !== AssignmentKind.None) { | ||
| const symbol = getResolvedSymbol(node as Identifier); | ||
| if (isParameterOrMutableLocalVariable(symbol) && symbol.lastAssignmentPos !== Number.MAX_VALUE) { | ||
| const referencingFunction = findAncestor(node, isFunctionOrSourceFile); | ||
| const declaringFunction = findAncestor(symbol.valueDeclaration, isFunctionOrSourceFile); | ||
| symbol.lastAssignmentPos = referencingFunction === declaringFunction ? extendAssignmentPosition(node, symbol.valueDeclaration!) : Number.MAX_VALUE; | ||
| const hasDefiniteAssignment = assigmentTarget === AssignmentKind.Definite || (symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0); | ||
| if (isParameterOrMutableLocalVariable(symbol)) { | ||
| if (symbol.lastAssignmentPos === undefined || Math.abs(symbol.lastAssignmentPos) !== Number.MAX_VALUE) { | ||
| const referencingFunction = findAncestor(node, isFunctionOrSourceFile); | ||
| const declaringFunction = findAncestor(symbol.valueDeclaration, isFunctionOrSourceFile); | ||
| symbol.lastAssignmentPos = referencingFunction === declaringFunction ? extendAssignmentPosition(node, symbol.valueDeclaration!) : Number.MAX_VALUE; | ||
gabritto marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| if (hasDefiniteAssignment && symbol.lastAssignmentPos > 0) { | ||
| symbol.lastAssignmentPos *= -1; | ||
gabritto marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| } | ||
| return; | ||
| @@ -29572,7 +29587,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| if (!(node as ExportSpecifier).isTypeOnly && !exportDeclaration.isTypeOnly && !exportDeclaration.moduleSpecifier && name.kind !== SyntaxKind.StringLiteral) { | ||
| const symbol = resolveEntityName(name, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ true); | ||
| if (symbol && isParameterOrMutableLocalVariable(symbol)) { | ||
| symbol.lastAssignmentPos = Number.MAX_VALUE; | ||
| const sign = symbol.lastAssignmentPos !== undefined && symbol.lastAssignmentPos < 0 ? -1 : 1; | ||
| symbol.lastAssignmentPos = sign * Number.MAX_VALUE; | ||
| } | ||
| } | ||
| return; | ||
| @@ -30316,6 +30332,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| const localOrExportSymbol = getExportSymbolOfValueSymbolIfExported(symbol); | ||
| let declaration = localOrExportSymbol.valueDeclaration; | ||
| const immediateDeclaration = declaration; | ||
| // If the identifier is declared in a binding pattern for which we're currently computing the implied type and the | ||
| // reference occurs with the same binding pattern, return the non-inferrable any type. This for example occurs in | ||
| @@ -30405,7 +30422,10 @@ 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 assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) || | ||
| const isNeverInitialized = immediateDeclaration && isVariableDeclaration(immediateDeclaration) && !immediateDeclaration.initializer && !immediateDeclaration.exclamationToken && isMutableLocalVariableDeclaration(immediateDeclaration) && !isSymbolAssignedDefinitely(symbol); | ||
| const assumeInitialized = isParameter || isAlias || | ||
gabritto marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| (isOuterVariable && !isNeverInitialized) || | ||
| isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) || | ||
| type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 || | ||
| isInTypeQuery(node) || isInAmbientOrTypeNode(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || | ||
| node.parent.kind === SyntaxKind.NonNullExpression || | ||
| @@ -43264,7 +43284,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { | ||
| case SyntaxKind.MethodDeclaration: | ||
| case SyntaxKind.GetAccessor: | ||
| case SyntaxKind.SetAccessor: | ||
| if (node.body) { // Don't report unused parameters in overloads | ||
| // Only report unused parameters on the implementation, not overloads. | ||
| if (node.body) { | ||
| checkUnusedLocalsAndParameters(node, addDiagnostic); | ||
| } | ||
| checkUnusedTypeParameters(node, addDiagnostic); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -13,7 +13,7 @@ | ||
| // for (<|var { [|property1|]: p1 } of elems|>) { | ||
| // } | ||
| // var p2; | ||
| // for (<|{ [|{| isWriteAccess: true |}property1|] : p2 } of elems|>) { | ||
| // for (<|{ [|property1|] : p2 } of elems|>) { | ||
Zzzen marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| // } | ||
| // === Definitions === | ||
| @@ -94,7 +94,7 @@ | ||
| // for (<|var { [|property1|]: p1 } of elems|>) { | ||
| // } | ||
| // var p2; | ||
| // for (<|{ [|{| isWriteAccess: true |}property1|] : p2 } of elems|>) { | ||
| // for (<|{ [|property1|] : p2 } of elems|>) { | ||
| // } | ||
| // === Definitions === | ||
| @@ -180,7 +180,7 @@ | ||
| // for (<|var { /*FIND ALL REFS*/[|property1|]: p1 } of elems|>) { | ||
| // } | ||
| // var p2; | ||
| // for (<|{ [|{| isWriteAccess: true |}property1|] : p2 } of elems|>) { | ||
| // for (<|{ [|property1|] : p2 } of elems|>) { | ||
| // } | ||
| // === Definitions === | ||
| @@ -270,7 +270,7 @@ | ||
| // for (<|var { [|property1|]: p1 } of elems|>) { | ||
| // } | ||
| // var p2; | ||
| // for (<|{ /*FIND ALL REFS*/[|{| isWriteAccess: true, isDefinition: true |}property1|] : p2 } of elems|>) { | ||
| // for (<|{ /*FIND ALL REFS*/[|{| isDefinition: true |}property1|] : p2 } of elems|>) { | ||
| // } | ||
| // === Definitions === | ||
| @@ -358,7 +358,7 @@ | ||
| // for (<|var { [|{| defId: 0 |}property1|]: p1 } of elems|>) { | ||
| // } | ||
| // var p2; | ||
| // for (<|{ [|{| defId: 0, isWriteAccess: true |}property1|] : p2 } of elems|>) { | ||
| // for (<|{ [|{| defId: 0 |}property1|] : p2 } of elems|>) { | ||
| // } | ||
| // === Definitions === | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,9 @@ | ||
| narrowingPastLastAssignment.ts(88,9): error TS7034: Variable 'x' implicitly has type 'any' in some locations where its type cannot be determined. | ||
| narrowingPastLastAssignment.ts(90,20): error TS7005: Variable 'x' implicitly has an 'any' type. | ||
| narrowingPastLastAssignment.ts(161,9): error TS18048: 'foo' is possibly 'undefined'. | ||
| ==== narrowingPastLastAssignment.ts (2 errors) ==== | ||
| ==== narrowingPastLastAssignment.ts (3 errors) ==== | ||
| function action(f: Function) {} | ||
| // Narrowings are preserved in closures created past last assignment | ||
| @@ -160,4 +161,15 @@ narrowingPastLastAssignment.ts(90,20): error TS7005: Variable 'x' implicitly has | ||
| } | ||
| values.forEach(v => foo.push(v)); | ||
| } | ||
| function f13() { | ||
| // Test for captured 'var' declaration (as opposed to parameters, let, const). | ||
| var foo: string | undefined; | ||
gabritto marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| foo = ''; | ||
| return () => { | ||
| foo.toLocaleLowerCase(); | ||
| ~~~ | ||
| !!! error TS18048: 'foo' is possibly 'undefined'. | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.