Skip to content

Commit 3a7a4d4

Browse files
authored
Error on shadowed var declarations without initializers (#55228)
1 parent e624827 commit 3a7a4d4

6 files changed

+194
-8
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41020,12 +41020,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4102041020
return;
4102141021
}
4102241022

41023-
// skip variable declarations that don't have initializers
4102441023
// NOTE: in ES6 spec initializer is required in variable declarations where name is binding pattern
4102541024
// so we'll always treat binding elements as initialized
41026-
if (node.kind === SyntaxKind.VariableDeclaration && !node.initializer) {
41027-
return;
41028-
}
4102941025

4103041026
const symbol = getSymbolOfDeclaration(node);
4103141027
if (symbol.flags & SymbolFlags.FunctionScopedVariable) {
@@ -41050,10 +41046,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
4105041046
container.kind === SyntaxKind.ModuleDeclaration ||
4105141047
container.kind === SyntaxKind.SourceFile);
4105241048

41053-
// here we know that function scoped variable is shadowed by block scoped one
41054-
// if they are defined in the same scope - binder has already reported redeclaration error
41055-
// otherwise if variable has an initializer - show error that initialization will fail
41056-
// since LHS will be block scoped name instead of function scoped
41049+
// here we know that function scoped variable is "shadowed" by block scoped one
41050+
// a var declatation can't hoist past a lexical declaration and it results in a SyntaxError at runtime
4105741051
if (!namesShareScope) {
4105841052
const name = symbolToString(localDeclarationSymbol);
4105941053
error(node, Diagnostics.Cannot_initialize_outer_scoped_variable_0_in_the_same_scope_as_block_scoped_declaration_1, name, name);
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
for-of53.ts(2,9): error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
2+
3+
4+
==== for-of53.ts (1 errors) ====
5+
for (let v of []) {
6+
var v;
7+
~
8+
!!! error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
9+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
shadowedFunctionScopedVariablesByBlockScopedOnes.ts(4,27): error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
2+
shadowedFunctionScopedVariablesByBlockScopedOnes.ts(7,29): error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
3+
shadowedFunctionScopedVariablesByBlockScopedOnes.ts(10,29): error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
4+
shadowedFunctionScopedVariablesByBlockScopedOnes.ts(16,17): error TS2481: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'.
5+
shadowedFunctionScopedVariablesByBlockScopedOnes.ts(23,17): error TS2481: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'.
6+
7+
8+
==== shadowedFunctionScopedVariablesByBlockScopedOnes.ts (5 errors) ====
9+
// https://github.com/microsoft/TypeScript/issues/2185
10+
11+
function test1() {
12+
for (let v; ; ) { var v; }
13+
~
14+
!!! error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
15+
}
16+
function test2() {
17+
for (let v in []) { var v; }
18+
~
19+
!!! error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
20+
}
21+
function test3() {
22+
for (let v of []) { var v; }
23+
~
24+
!!! error TS2481: Cannot initialize outer scoped variable 'v' in the same scope as block scoped declaration 'v'.
25+
}
26+
function test4() {
27+
{
28+
let x;
29+
{
30+
var x;
31+
~
32+
!!! error TS2481: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'.
33+
}
34+
}
35+
}
36+
function test5() {
37+
{
38+
{
39+
var x;
40+
~
41+
!!! error TS2481: Cannot initialize outer scoped variable 'x' in the same scope as block scoped declaration 'x'.
42+
}
43+
let x;
44+
}
45+
}
46+
47+
48+
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//// [tests/cases/compiler/shadowedFunctionScopedVariablesByBlockScopedOnes.ts] ////
2+
3+
=== shadowedFunctionScopedVariablesByBlockScopedOnes.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/2185
5+
6+
function test1() {
7+
>test1 : Symbol(test1, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 0, 0))
8+
9+
for (let v; ; ) { var v; }
10+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 3, 12))
11+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 3, 25))
12+
}
13+
function test2() {
14+
>test2 : Symbol(test2, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 4, 1))
15+
16+
for (let v in []) { var v; }
17+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 6, 12))
18+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 6, 27))
19+
}
20+
function test3() {
21+
>test3 : Symbol(test3, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 7, 1))
22+
23+
for (let v of []) { var v; }
24+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 9, 12))
25+
>v : Symbol(v, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 9, 27))
26+
}
27+
function test4() {
28+
>test4 : Symbol(test4, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 10, 1))
29+
{
30+
let x;
31+
>x : Symbol(x, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 13, 11))
32+
{
33+
var x;
34+
>x : Symbol(x, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 15, 15))
35+
}
36+
}
37+
}
38+
function test5() {
39+
>test5 : Symbol(test5, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 18, 1))
40+
{
41+
{
42+
var x;
43+
>x : Symbol(x, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 22, 15))
44+
}
45+
let x;
46+
>x : Symbol(x, Decl(shadowedFunctionScopedVariablesByBlockScopedOnes.ts, 24, 11))
47+
}
48+
}
49+
50+
51+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
//// [tests/cases/compiler/shadowedFunctionScopedVariablesByBlockScopedOnes.ts] ////
2+
3+
=== shadowedFunctionScopedVariablesByBlockScopedOnes.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/2185
5+
6+
function test1() {
7+
>test1 : () => void
8+
9+
for (let v; ; ) { var v; }
10+
>v : any
11+
>v : any
12+
}
13+
function test2() {
14+
>test2 : () => void
15+
16+
for (let v in []) { var v; }
17+
>v : string
18+
>[] : undefined[]
19+
>v : any
20+
}
21+
function test3() {
22+
>test3 : () => void
23+
24+
for (let v of []) { var v; }
25+
>v : any
26+
>[] : undefined[]
27+
>v : any
28+
}
29+
function test4() {
30+
>test4 : () => void
31+
{
32+
let x;
33+
>x : any
34+
{
35+
var x;
36+
>x : any
37+
}
38+
}
39+
}
40+
function test5() {
41+
>test5 : () => void
42+
{
43+
{
44+
var x;
45+
>x : any
46+
}
47+
let x;
48+
>x : any
49+
}
50+
}
51+
52+
53+
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// @noEmit: true
2+
3+
// https://github.com/microsoft/TypeScript/issues/2185
4+
5+
function test1() {
6+
for (let v; ; ) { var v; }
7+
}
8+
function test2() {
9+
for (let v in []) { var v; }
10+
}
11+
function test3() {
12+
for (let v of []) { var v; }
13+
}
14+
function test4() {
15+
{
16+
let x;
17+
{
18+
var x;
19+
}
20+
}
21+
}
22+
function test5() {
23+
{
24+
{
25+
var x;
26+
}
27+
let x;
28+
}
29+
}
30+
31+

0 commit comments

Comments
 (0)