diff --git a/NOTICE b/NOTICE index 6b4450d592..6226bc34ab 100644 --- a/NOTICE +++ b/NOTICE @@ -42,6 +42,7 @@ under the licensing terms detailed in LICENSE: * Roman F. <70765447+romdotdog@users.noreply.github.com> * Joe Pea * Felipe Gasper +* Congcong Cai <77575210+HerrCai0907@users.noreply.github.com> Portions of this software are derived from third-party works licensed under the following terms: diff --git a/src/compiler.ts b/src/compiler.ts index a0dd74d9e6..e035cab8ca 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -3030,7 +3030,7 @@ export class Compiler extends DiagnosticEmitter { if (initializerNode) { let pendingElements = this.pendingElements; - let dummy = flow.addScopedDummyLocal(name, type); // pending dummy + let dummy = flow.addScopedDummyLocal(name, type, statement); // pending dummy pendingElements.add(dummy); initExpr = this.compileExpression(initializerNode, type, // reports Constraints.CONV_IMPLICIT @@ -3042,7 +3042,7 @@ export class Compiler extends DiagnosticEmitter { // Otherwise infer type from initializer } else if (initializerNode) { let pendingElements = this.pendingElements; - let temp = flow.addScopedDummyLocal(name, Type.auto); // pending dummy + let temp = flow.addScopedDummyLocal(name, Type.auto, statement); // pending dummy pendingElements.add(temp); initExpr = this.compileExpression(initializerNode, Type.auto); // reports pendingElements.delete(temp); diff --git a/src/diagnosticMessages.generated.ts b/src/diagnosticMessages.generated.ts index 0f0f3a00d1..77d2012864 100644 --- a/src/diagnosticMessages.generated.ts +++ b/src/diagnosticMessages.generated.ts @@ -151,6 +151,7 @@ export enum DiagnosticCode { A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged = 2434, Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses = 2445, Variable_0_used_before_its_declaration = 2448, + Cannot_redeclare_block_scoped_variable_0 = 2451, The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly = 2453, Type_0_has_no_property_1 = 2460, The_0_operator_cannot_be_applied_to_type_1 = 2469, @@ -333,6 +334,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string { case 2434: return "A namespace declaration cannot be located prior to a class or function with which it is merged."; case 2445: return "Property '{0}' is protected and only accessible within class '{1}' and its subclasses."; case 2448: return "Variable '{0}' used before its declaration."; + case 2451: return "Cannot redeclare block-scoped variable '{0}'"; case 2453: return "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly."; case 2460: return "Type '{0}' has no property '{1}'."; case 2469: return "The '{0}' operator cannot be applied to type '{1}'."; diff --git a/src/diagnosticMessages.json b/src/diagnosticMessages.json index 8a76e1eb12..7975f441d2 100644 --- a/src/diagnosticMessages.json +++ b/src/diagnosticMessages.json @@ -149,6 +149,7 @@ "A namespace declaration cannot be located prior to a class or function with which it is merged.": 2434, "Property '{0}' is protected and only accessible within class '{1}' and its subclasses.": 2445, "Variable '{0}' used before its declaration.": 2448, + "Cannot redeclare block-scoped variable '{0}'" : 2451, "The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly.": 2453, "Type '{0}' has no property '{1}'.": 2460, "The '{0}' operator cannot be applied to type '{1}'.": 2469, diff --git a/src/flow.ts b/src/flow.ts index 100d97ac8e..ee8671ee8f 100644 --- a/src/flow.ts +++ b/src/flow.ts @@ -444,11 +444,16 @@ export class Flow { } /** Adds a new scoped dummy local of the specified name. */ - addScopedDummyLocal(name: string, type: Type): Local { + addScopedDummyLocal(name: string, type: Type, declarationNode: Node): Local { var scopedDummy = new Local(name, -1, type, this.parentFunction); var scopedLocals = this.scopedLocals; if (!scopedLocals) this.scopedLocals = scopedLocals = new Map(); - else assert(!scopedLocals.has(name)); + else if (scopedLocals.has(name)) { + this.parentFunction.program.error( + DiagnosticCode.Cannot_redeclare_block_scoped_variable_0, + declarationNode.range, name + ); + } scopedDummy.set(CommonFlags.SCOPED); scopedLocals.set(name, scopedDummy); return scopedDummy;