diff --git a/src/program.ts b/src/program.ts index febeb1227c..1db22d6855 100644 --- a/src/program.ts +++ b/src/program.ts @@ -5058,6 +5058,9 @@ function tryMerge(older: Element, newer: Element): DeclaredElement | null { /** Copies the members of `src` to `dest`. */ function copyMembers(src: Element, dest: Element): void { + let program = src.program; + assert(program == dest.program); + let srcMembers = src.members; if (srcMembers) { let destMembers = dest.members; @@ -5065,8 +5068,21 @@ function copyMembers(src: Element, dest: Element): void { // TODO: for (let [memberName, member] of srcMembers) { for (let _keys = Map_keys(srcMembers), i = 0, k = _keys.length; i < k; ++i) { let memberName = unchecked(_keys[i]); - let member = assert(srcMembers.get(memberName)); - destMembers.set(memberName, member); + let srcMember = assert(srcMembers.get(memberName)); + // This isn't TS compatible in every case, but the logic involved in + // merging, scoping, and making internal names is not currently able to + // handle duplicates well. + if (destMembers.has(memberName)) { + let destMember = assert(destMembers.get(memberName)); + program.errorRelated( + DiagnosticCode.Duplicate_identifier_0, + srcMember.declaration.name.range, destMember.declaration.name.range, + memberName + ); + continue; + } + + destMembers.set(memberName, srcMember); } } } diff --git a/tests/compiler/issues/2793.json b/tests/compiler/issues/2793.json new file mode 100644 index 0000000000..8f275f6155 --- /dev/null +++ b/tests/compiler/issues/2793.json @@ -0,0 +1,13 @@ +{ + "stderr": [ + "Duplicate identifier 'bar'.", + "in issues/2793.ts(8,14)", + "in issues/2793.ts(2,10)", + "Duplicate identifier 'baz'.", + "in issues/2793.ts(9,7)", + "in issues/2793.ts(3,10)", + "Duplicate identifier 'qux'.", + "in issues/2793.ts(10,14)", + "in issues/2793.ts(4,18)" + ] +} \ No newline at end of file diff --git a/tests/compiler/issues/2793.ts b/tests/compiler/issues/2793.ts new file mode 100644 index 0000000000..b9f966bc43 --- /dev/null +++ b/tests/compiler/issues/2793.ts @@ -0,0 +1,12 @@ +class Foo { + static bar: i32 = 2; // errors in TS + static baz: i32 = 2; // does not error in TS + private static qux: i32 = 2; // errors in TS +} + +namespace Foo { + export let bar: i32 = 1; + let baz: string = "baz"; + export let qux: i32 = 1; + let hi: i32 = 1; +}