diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 41514cc01a9..239812a9de5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8214,15 +8214,14 @@ module ts { // declaration. the problem is if the declaration has an initializer. this will act as a write to the // block declared value. this is fine for let, but not const. // Only consider declarations with initializers, uninitialized var declarations will not - // step on a let\const variable. + // step on a let/const variable. // Do not consider let and const declarations, as duplicate block-scoped declarations // are handled by the binder. // We are only looking for var declarations that step on let\const declarations from a // different scope. e.g.: - // var x = 0; // { - // const x = 0; - // var x = 0; + // const x = 0; // localDeclarationSymbol obtained after name resolution will correspond to this declaration + // var x = 0; // symbol for this declaration will be 'symbol' // } if (node.initializer && (getCombinedNodeFlags(node) & NodeFlags.BlockScoped) === 0) { var symbol = getSymbolOfNode(node); @@ -8232,26 +8231,26 @@ module ts { localDeclarationSymbol !== symbol && localDeclarationSymbol.flags & SymbolFlags.BlockScopedVariable) { if (getDeclarationFlagsFromSymbol(localDeclarationSymbol) & NodeFlags.BlockScoped) { - // here we know that function scoped variable is shadowed by block scoped one - // if they are defined in the same scope - binder has already reported redeclaration error - // otherwise if variable has an initializer - show error that initialization will fail - // since LHS will be block scoped name instead of function scoped - var localVarDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList); - var localContainer = - localVarDeclList.parent.kind === SyntaxKind.VariableStatement && - localVarDeclList.parent.parent; + var varDeclList = getAncestor(localDeclarationSymbol.valueDeclaration, SyntaxKind.VariableDeclarationList); + var container = + varDeclList.parent.kind === SyntaxKind.VariableStatement && + varDeclList.parent.parent; // names of block-scoped and function scoped variables can collide only // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting) var namesShareScope = - localContainer && - (localContainer.kind === SyntaxKind.Block && isAnyFunction(localContainer.parent) || - (localContainer.kind === SyntaxKind.ModuleBlock && localContainer.kind === SyntaxKind.ModuleDeclaration) || - localContainer.kind === SyntaxKind.SourceFile); + container && + (container.kind === SyntaxKind.Block && isAnyFunction(container.parent) || + (container.kind === SyntaxKind.ModuleBlock && container.kind === SyntaxKind.ModuleDeclaration) || + container.kind === SyntaxKind.SourceFile); + // here we know that function scoped variable is shadowed by block scoped one + // if they are defined in the same scope - binder has already reported redeclaration error + // otherwise if variable has an initializer - show error that initialization will fail + // since LHS will be block scoped name instead of function scoped if (!namesShareScope) { - error(getErrorSpanForNode(node), Diagnostics.Cannot_initialize_outer_scope_variable_0_when_having_block_scoped_variable_with_the_same_name, symbolToString(localDeclarationSymbol)); + error(getErrorSpanForNode(node), Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, symbolToString(localDeclarationSymbol)); } } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 06ee032a498..c6061e3570a 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -381,7 +381,7 @@ module ts { const_enum_member_initializer_was_evaluated_to_disallowed_value_NaN: { code: 4087, category: DiagnosticCategory.Error, key: "'const' enum member initializer was evaluated to disallowed value 'NaN'." }, Property_0_does_not_exist_on_const_enum_1: { code: 4088, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on 'const' enum '{1}'." }, let_is_not_allowed_to_be_used_as_a_name_in_let_or_const_declarations: { code: 4089, category: DiagnosticCategory.Error, key: "'let' is not allowed to be used as a name in 'let' or 'const' declarations." }, - Cannot_initialize_outer_scope_variable_0_when_having_block_scoped_variable_with_the_same_name: { code: 4090, category: DiagnosticCategory.Error, key: "Cannot initialize outer scope variable '{0}' when having block-scoped variable with the same name." }, + Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1: { code: 4090, category: DiagnosticCategory.Error, key: "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'." }, The_current_host_does_not_support_the_0_option: { code: 5001, category: DiagnosticCategory.Error, key: "The current host does not support the '{0}' option." }, Cannot_find_the_common_subdirectory_path_for_the_input_files: { code: 5009, category: DiagnosticCategory.Error, key: "Cannot find the common subdirectory path for the input files." }, Cannot_read_file_0_Colon_1: { code: 5012, category: DiagnosticCategory.Error, key: "Cannot read file '{0}': {1}" }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index efe2a63f911..fdeec58a705 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1517,7 +1517,7 @@ "category": "Error", "code": 4089 }, - "Cannot initialize outer scope variable '{0}' when having block-scoped variable with the same name.": { + "Cannot initialize outer scoped variable '{0}' in the same scope as block scoped declaration '{1}'.": { "category": "Error", "code": 4090 }, diff --git a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt index 529964a6a85..99c02d87f45 100644 --- a/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt +++ b/tests/baselines/reference/constDeclarationShadowedByVarDeclaration.errors.txt @@ -1,6 +1,6 @@ -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(7,9): error TS4090: Cannot initialize outer scope variable 'x' when having block-scoped variable with the same name. -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(15,13): error TS4090: Cannot initialize outer scope variable 'y' when having block-scoped variable with the same name. -tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS4090: Cannot initialize outer scope variable 'z' when having block-scoped variable with the same name. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(7,9): error TS4090: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(15,13): error TS4090: Cannot initialize outer scoped variable 'y' in the same scope as block scoped declaration 'y'. +tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS4090: Cannot initialize outer scoped variable 'z' in the same scope as block scoped declaration 'z'. ==== tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts (3 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS var x = 0; ~ -!!! error TS4090: Cannot initialize outer scope variable 'x' when having block-scoped variable with the same name. +!!! error TS4090: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'. } @@ -22,7 +22,7 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS { var y = 0; ~ -!!! error TS4090: Cannot initialize outer scope variable 'y' when having block-scoped variable with the same name. +!!! error TS4090: Cannot initialize outer scoped variable 'y' in the same scope as block scoped declaration 'y'. } } @@ -31,5 +31,5 @@ tests/cases/compiler/constDeclarationShadowedByVarDeclaration.ts(22,7): error TS const z = 0; var z = 0 ~ -!!! error TS4090: Cannot initialize outer scope variable 'z' when having block-scoped variable with the same name. +!!! error TS4090: Cannot initialize outer scoped variable 'z' in the same scope as block scoped declaration 'z'. } \ No newline at end of file diff --git a/tests/baselines/reference/shadowingViaLocalValue.errors.txt b/tests/baselines/reference/shadowingViaLocalValue.errors.txt index a4a8d9a05d2..2a585ba8b7d 100644 --- a/tests/baselines/reference/shadowingViaLocalValue.errors.txt +++ b/tests/baselines/reference/shadowingViaLocalValue.errors.txt @@ -1,7 +1,7 @@ tests/cases/compiler/shadowingViaLocalValue.ts(2,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/shadowingViaLocalValue.ts(4,13): error TS4090: Cannot initialize outer scope variable 'x' when having block-scoped variable with the same name. +tests/cases/compiler/shadowingViaLocalValue.ts(4,13): error TS4090: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'. tests/cases/compiler/shadowingViaLocalValue.ts(9,5): error TS1153: 'let' declarations are only available when targeting ECMAScript 6 and higher. -tests/cases/compiler/shadowingViaLocalValue.ts(11,18): error TS4090: Cannot initialize outer scope variable 'x1' when having block-scoped variable with the same name. +tests/cases/compiler/shadowingViaLocalValue.ts(11,18): error TS4090: Cannot initialize outer scoped variable 'x1' in the same scope as block scoped declaration 'x1'. ==== tests/cases/compiler/shadowingViaLocalValue.ts (4 errors) ==== @@ -12,7 +12,7 @@ tests/cases/compiler/shadowingViaLocalValue.ts(11,18): error TS4090: Cannot init { var x = 1; ~ -!!! error TS4090: Cannot initialize outer scope variable 'x' when having block-scoped variable with the same name. +!!! error TS4090: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'. } } @@ -23,7 +23,7 @@ tests/cases/compiler/shadowingViaLocalValue.ts(11,18): error TS4090: Cannot init { for (var x1 = 0; ;); ~~ -!!! error TS4090: Cannot initialize outer scope variable 'x1' when having block-scoped variable with the same name. +!!! error TS4090: Cannot initialize outer scoped variable 'x1' in the same scope as block scoped declaration 'x1'. } }