From 4b3c52bfb75b42f6705396e0d3b69d1b4202af91 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 30 Sep 2023 03:14:33 +0000 Subject: [PATCH 01/17] Add test for enum compatibility between string/number enums. --- tests/cases/compiler/enumAssignmentCompat6.ts | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/cases/compiler/enumAssignmentCompat6.ts diff --git a/tests/cases/compiler/enumAssignmentCompat6.ts b/tests/cases/compiler/enumAssignmentCompat6.ts new file mode 100644 index 0000000000000..3cdc28ab91d21 --- /dev/null +++ b/tests/cases/compiler/enumAssignmentCompat6.ts @@ -0,0 +1,59 @@ +// @filename a.ts +namespace a { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } + + export enum DiagnosticCategory2 { + Warning, + Error, + Suggestion, + Message, + } +} + +namespace b { + export enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } +} + +function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { + x = y; + y = x; +} + +function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { + x = y; + y = x; +} + + +// @filename: f.ts +export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, +} + +export let x: DiagnosticCategory; + +{ + enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } + function f(y: DiagnosticCategory) { + x = y; + y = x; + } +} \ No newline at end of file From 26aa2dcfb29df162015da923f2e0589a56f84860 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 30 Sep 2023 03:14:56 +0000 Subject: [PATCH 02/17] Accepted baselines. --- .../enumAssignmentCompat6.errors.txt | 70 ++++++++ .../reference/enumAssignmentCompat6.js | 122 ++++++++++++++ .../reference/enumAssignmentCompat6.symbols | 147 +++++++++++++++++ .../reference/enumAssignmentCompat6.types | 155 ++++++++++++++++++ 4 files changed, 494 insertions(+) create mode 100644 tests/baselines/reference/enumAssignmentCompat6.errors.txt create mode 100644 tests/baselines/reference/enumAssignmentCompat6.js create mode 100644 tests/baselines/reference/enumAssignmentCompat6.symbols create mode 100644 tests/baselines/reference/enumAssignmentCompat6.types diff --git a/tests/baselines/reference/enumAssignmentCompat6.errors.txt b/tests/baselines/reference/enumAssignmentCompat6.errors.txt new file mode 100644 index 0000000000000..a39063ee85e50 --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat6.errors.txt @@ -0,0 +1,70 @@ +f.ts(33,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. +f.ts(34,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. +f.ts(54,14): error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. + + +==== f.ts (3 errors) ==== + // @filename a.ts + namespace a { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } + + export enum DiagnosticCategory2 { + Warning, + Error, + Suggestion, + Message, + } + } + + namespace b { + export enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } + } + + function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { + x = y; + y = x; + } + + function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { + x = y; + ~ +!!! error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. + y = x; + ~ +!!! error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. + } + + + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } + + export let x: DiagnosticCategory; + + { + enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } + function f(y: DiagnosticCategory) { + ~ +!!! error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. + x = y; + y = x; + } + } \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat6.js b/tests/baselines/reference/enumAssignmentCompat6.js new file mode 100644 index 0000000000000..a974a6d25787d --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat6.js @@ -0,0 +1,122 @@ +//// [tests/cases/compiler/enumAssignmentCompat6.ts] //// + +//// [f.ts] +// @filename a.ts +namespace a { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } + + export enum DiagnosticCategory2 { + Warning, + Error, + Suggestion, + Message, + } +} + +namespace b { + export enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } +} + +function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { + x = y; + y = x; +} + +function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { + x = y; + y = x; +} + + +export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, +} + +export let x: DiagnosticCategory; + +{ + enum DiagnosticCategory { + Warning = "Warning", + Error = "Error", + Suggestion = "Suggestion", + Message = "Message", + } + function f(y: DiagnosticCategory) { + x = y; + y = x; + } +} + +//// [f.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.x = exports.DiagnosticCategory = void 0; +// @filename a.ts +var a; +(function (a) { + var DiagnosticCategory; + (function (DiagnosticCategory) { + DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning"; + DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error"; + DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion"; + DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message"; + })(DiagnosticCategory = a.DiagnosticCategory || (a.DiagnosticCategory = {})); + var DiagnosticCategory2; + (function (DiagnosticCategory2) { + DiagnosticCategory2[DiagnosticCategory2["Warning"] = 0] = "Warning"; + DiagnosticCategory2[DiagnosticCategory2["Error"] = 1] = "Error"; + DiagnosticCategory2[DiagnosticCategory2["Suggestion"] = 2] = "Suggestion"; + DiagnosticCategory2[DiagnosticCategory2["Message"] = 3] = "Message"; + })(DiagnosticCategory2 = a.DiagnosticCategory2 || (a.DiagnosticCategory2 = {})); +})(a || (a = {})); +var b; +(function (b) { + var DiagnosticCategory; + (function (DiagnosticCategory) { + DiagnosticCategory["Warning"] = "Warning"; + DiagnosticCategory["Error"] = "Error"; + DiagnosticCategory["Suggestion"] = "Suggestion"; + DiagnosticCategory["Message"] = "Message"; + })(DiagnosticCategory = b.DiagnosticCategory || (b.DiagnosticCategory = {})); +})(b || (b = {})); +function f(x, y) { + x = y; + y = x; +} +function g(x, y) { + x = y; + y = x; +} +var DiagnosticCategory; +(function (DiagnosticCategory) { + DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning"; + DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error"; + DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion"; + DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message"; +})(DiagnosticCategory || (exports.DiagnosticCategory = DiagnosticCategory = {})); +{ + var DiagnosticCategory_1; + (function (DiagnosticCategory) { + DiagnosticCategory["Warning"] = "Warning"; + DiagnosticCategory["Error"] = "Error"; + DiagnosticCategory["Suggestion"] = "Suggestion"; + DiagnosticCategory["Message"] = "Message"; + })(DiagnosticCategory_1 || (DiagnosticCategory_1 = {})); + function f(y) { + exports.x = y; + y = exports.x; + } +} diff --git a/tests/baselines/reference/enumAssignmentCompat6.symbols b/tests/baselines/reference/enumAssignmentCompat6.symbols new file mode 100644 index 0000000000000..8083d8c79519b --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat6.symbols @@ -0,0 +1,147 @@ +//// [tests/cases/compiler/enumAssignmentCompat6.ts] //// + +=== f.ts === +// @filename a.ts +namespace a { +>a : Symbol(a, Decl(f.ts, 0, 0)) + + export enum DiagnosticCategory { +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 1, 13)) + + Warning, +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 2, 36)) + + Error, +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 3, 16)) + + Suggestion, +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 4, 14)) + + Message, +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 5, 19)) + } + + export enum DiagnosticCategory2 { +>DiagnosticCategory2 : Symbol(DiagnosticCategory2, Decl(f.ts, 7, 5)) + + Warning, +>Warning : Symbol(DiagnosticCategory2.Warning, Decl(f.ts, 9, 37)) + + Error, +>Error : Symbol(DiagnosticCategory2.Error, Decl(f.ts, 10, 16)) + + Suggestion, +>Suggestion : Symbol(DiagnosticCategory2.Suggestion, Decl(f.ts, 11, 14)) + + Message, +>Message : Symbol(DiagnosticCategory2.Message, Decl(f.ts, 12, 19)) + } +} + +namespace b { +>b : Symbol(b, Decl(f.ts, 15, 1)) + + export enum DiagnosticCategory { +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 17, 13)) + + Warning = "Warning", +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 18, 36)) + + Error = "Error", +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 19, 28)) + + Suggestion = "Suggestion", +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 20, 24)) + + Message = "Message", +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 21, 34)) + } +} + +function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { +>f : Symbol(f, Decl(f.ts, 24, 1)) +>x : Symbol(x, Decl(f.ts, 26, 11)) +>a : Symbol(a, Decl(f.ts, 0, 0)) +>DiagnosticCategory : Symbol(a.DiagnosticCategory, Decl(f.ts, 1, 13)) +>y : Symbol(y, Decl(f.ts, 26, 35)) +>b : Symbol(b, Decl(f.ts, 15, 1)) +>DiagnosticCategory : Symbol(b.DiagnosticCategory, Decl(f.ts, 17, 13)) + + x = y; +>x : Symbol(x, Decl(f.ts, 26, 11)) +>y : Symbol(y, Decl(f.ts, 26, 35)) + + y = x; +>y : Symbol(y, Decl(f.ts, 26, 35)) +>x : Symbol(x, Decl(f.ts, 26, 11)) +} + +function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { +>g : Symbol(g, Decl(f.ts, 29, 1)) +>x : Symbol(x, Decl(f.ts, 31, 11)) +>a : Symbol(a, Decl(f.ts, 0, 0)) +>DiagnosticCategory2 : Symbol(a.DiagnosticCategory2, Decl(f.ts, 7, 5)) +>y : Symbol(y, Decl(f.ts, 31, 36)) +>b : Symbol(b, Decl(f.ts, 15, 1)) +>DiagnosticCategory : Symbol(b.DiagnosticCategory, Decl(f.ts, 17, 13)) + + x = y; +>x : Symbol(x, Decl(f.ts, 31, 11)) +>y : Symbol(y, Decl(f.ts, 31, 36)) + + y = x; +>y : Symbol(y, Decl(f.ts, 31, 36)) +>x : Symbol(x, Decl(f.ts, 31, 11)) +} + + +export enum DiagnosticCategory { +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 34, 1)) + + Warning, +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 37, 32)) + + Error, +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 38, 12)) + + Suggestion, +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 39, 10)) + + Message, +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 40, 15)) +} + +export let x: DiagnosticCategory; +>x : Symbol(x, Decl(f.ts, 44, 10)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 34, 1)) + +{ + enum DiagnosticCategory { +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 1)) + + Warning = "Warning", +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 47, 29)) + + Error = "Error", +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 48, 28)) + + Suggestion = "Suggestion", +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 49, 24)) + + Message = "Message", +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 50, 34)) + } + function f(y: DiagnosticCategory) { +>f : Symbol(f, Decl(f.ts, 52, 5)) +>y : Symbol(y, Decl(f.ts, 53, 15)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 1)) + + x = y; +>x : Symbol(x, Decl(f.ts, 44, 10)) +>y : Symbol(y, Decl(f.ts, 53, 15)) + + y = x; +>y : Symbol(y, Decl(f.ts, 53, 15)) +>x : Symbol(x, Decl(f.ts, 44, 10)) + } +} diff --git a/tests/baselines/reference/enumAssignmentCompat6.types b/tests/baselines/reference/enumAssignmentCompat6.types new file mode 100644 index 0000000000000..da3b46034a94f --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat6.types @@ -0,0 +1,155 @@ +//// [tests/cases/compiler/enumAssignmentCompat6.ts] //// + +=== f.ts === +// @filename a.ts +namespace a { +>a : typeof a + + export enum DiagnosticCategory { +>DiagnosticCategory : DiagnosticCategory + + Warning, +>Warning : DiagnosticCategory.Warning + + Error, +>Error : DiagnosticCategory.Error + + Suggestion, +>Suggestion : DiagnosticCategory.Suggestion + + Message, +>Message : DiagnosticCategory.Message + } + + export enum DiagnosticCategory2 { +>DiagnosticCategory2 : DiagnosticCategory2 + + Warning, +>Warning : DiagnosticCategory2.Warning + + Error, +>Error : DiagnosticCategory2.Error + + Suggestion, +>Suggestion : DiagnosticCategory2.Suggestion + + Message, +>Message : DiagnosticCategory2.Message + } +} + +namespace b { +>b : typeof b + + export enum DiagnosticCategory { +>DiagnosticCategory : DiagnosticCategory + + Warning = "Warning", +>Warning : DiagnosticCategory.Warning +>"Warning" : "Warning" + + Error = "Error", +>Error : DiagnosticCategory.Error +>"Error" : "Error" + + Suggestion = "Suggestion", +>Suggestion : DiagnosticCategory.Suggestion +>"Suggestion" : "Suggestion" + + Message = "Message", +>Message : DiagnosticCategory.Message +>"Message" : "Message" + } +} + +function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { +>f : (x: a.DiagnosticCategory, y: b.DiagnosticCategory) => void +>x : a.DiagnosticCategory +>a : any +>y : b.DiagnosticCategory +>b : any + + x = y; +>x = y : b.DiagnosticCategory +>x : a.DiagnosticCategory +>y : b.DiagnosticCategory + + y = x; +>y = x : a.DiagnosticCategory +>y : b.DiagnosticCategory +>x : a.DiagnosticCategory +} + +function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { +>g : (x: a.DiagnosticCategory2, y: b.DiagnosticCategory) => void +>x : a.DiagnosticCategory2 +>a : any +>y : b.DiagnosticCategory +>b : any + + x = y; +>x = y : b.DiagnosticCategory +>x : a.DiagnosticCategory2 +>y : b.DiagnosticCategory + + y = x; +>y = x : a.DiagnosticCategory2 +>y : b.DiagnosticCategory +>x : a.DiagnosticCategory2 +} + + +export enum DiagnosticCategory { +>DiagnosticCategory : DiagnosticCategory + + Warning, +>Warning : DiagnosticCategory.Warning + + Error, +>Error : DiagnosticCategory.Error + + Suggestion, +>Suggestion : DiagnosticCategory.Suggestion + + Message, +>Message : DiagnosticCategory.Message +} + +export let x: DiagnosticCategory; +>x : DiagnosticCategory + +{ + enum DiagnosticCategory { +>DiagnosticCategory : DiagnosticCategory + + Warning = "Warning", +>Warning : DiagnosticCategory.Warning +>"Warning" : "Warning" + + Error = "Error", +>Error : DiagnosticCategory.Error +>"Error" : "Error" + + Suggestion = "Suggestion", +>Suggestion : DiagnosticCategory.Suggestion +>"Suggestion" : "Suggestion" + + Message = "Message", +>Message : DiagnosticCategory.Message +>"Message" : "Message" + } + function f(y: DiagnosticCategory) { +>f : (y: DiagnosticCategory) => void +>y : DiagnosticCategory + + x = y; +>x = y : DiagnosticCategory +>x : import("f").DiagnosticCategory +>y : DiagnosticCategory + + y = x; +>y = x : import("f").DiagnosticCategory +>y : DiagnosticCategory +>x : import("f").DiagnosticCategory + } +} From 35f3b9f129b74e3a3ac78565b799fb0469a72446 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 30 Sep 2023 03:15:25 +0000 Subject: [PATCH 03/17] Add error when enum values differ. --- src/compiler/checker.ts | 23 +++++++++++++++++++---- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 58d6a8b867e20..c5eb8db0a243c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20601,12 +20601,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return !!(entry & RelationComparisonResult.Succeeded); } const targetEnumType = getTypeOfSymbol(targetSymbol); - for (const property of getPropertiesOfType(getTypeOfSymbol(sourceSymbol))) { - if (property.flags & SymbolFlags.EnumMember) { - const targetProperty = getPropertyOfType(targetEnumType, property.escapedName); + for (const sourceProperty of getPropertiesOfType(getTypeOfSymbol(sourceSymbol))) { + if (sourceProperty.flags & SymbolFlags.EnumMember) { + const targetProperty = getPropertyOfType(targetEnumType, sourceProperty.escapedName); if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) { if (errorReporter) { - errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(property), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); + errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(sourceProperty), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType)); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + } + else { + enumRelation.set(id, RelationComparisonResult.Failed); + } + return false; + } + const sourceValue = getEnumMemberValue(getDeclarationOfKind(sourceProperty, SyntaxKind.EnumMember)!); + const targetValue = getEnumMemberValue(getDeclarationOfKind(targetProperty, SyntaxKind.EnumMember)!); + // TODO: Handle both 'undefined' + if (sourceValue !== undefined && targetValue !== undefined && sourceValue !== targetValue) { + if (errorReporter) { + const escapedSource = typeof sourceValue === "string" ? `"${escapeString(sourceValue)}"` : sourceValue; + const escapedTarget = typeof targetValue === "string" ? `"${escapeString(targetValue)}"` : targetValue; + errorReporter(Diagnostics.The_values_of_0_1_differ_in_their_declarations_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 31955155b0fc9..5a9c315fb20cd 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4132,6 +4132,10 @@ "category": "Error", "code": 4124 }, + "The values of '{0}.{1}' differ in their declarations, where '{2}' was expected but '{3}' was given.": { + "category": "Error", + "code": 4125 + }, "The current host does not support the '{0}' option.": { "category": "Error", From 41e7790e71d7242360ff740348c2d5fdaed3b178 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Sat, 30 Sep 2023 03:34:27 +0000 Subject: [PATCH 04/17] Accepted baselines. --- .../enumAssignmentCompat3.errors.txt | 25 +++++++++++++++---- .../enumAssignmentCompat6.errors.txt | 22 +++++++++++++++- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index efe726d5ddae1..e53f39996db97 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,20 +1,26 @@ enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. - Property 'd' is missing in type 'First.E'. + The values of 'E.c' differ in their declarations, where '2' was expected but '0' was given. enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. +enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. + The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. +enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. + The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. - Property 'd' is missing in type 'First.E'. + The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. +enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable to type 'Merged.E'. + The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. -==== enumAssignmentCompat3.ts (9 errors) ==== +==== enumAssignmentCompat3.ts (12 errors) ==== namespace First { export enum E { a, b, c, @@ -90,11 +96,14 @@ enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable abc = secondCd; // missing 'd' ~~~ !!! error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. -!!! error TS2322: Property 'd' is missing in type 'First.E'. +!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '0' was given. abc = nope; // nope! ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. abc = decl; // ok + ~~~ +!!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. +!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -109,6 +118,9 @@ enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable ~~~~ !!! error TS2322: Type 'E' is not assignable to type 'Nope'. decl = abc; // ok + ~~~~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. +!!! error TS2322: The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. // const is only assignable to itself k = k; @@ -123,7 +135,10 @@ enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable abc = merged; // missing 'd' ~~~ !!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. -!!! error TS2322: Property 'd' is missing in type 'First.E'. +!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. merged = abc; // ok + ~~~~~~ +!!! error TS2322: Type 'First.E' is not assignable to type 'Merged.E'. +!!! error TS2322: The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. abc = merged2; // ok merged2 = abc; // ok \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat6.errors.txt b/tests/baselines/reference/enumAssignmentCompat6.errors.txt index a39063ee85e50..1dec98ad237a6 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat6.errors.txt @@ -1,9 +1,17 @@ +f.ts(28,5): error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. + The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. +f.ts(29,5): error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. + The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. f.ts(33,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. f.ts(34,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. f.ts(54,14): error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. +f.ts(55,9): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. + The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. +f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. + The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. -==== f.ts (3 errors) ==== +==== f.ts (7 errors) ==== // @filename a.ts namespace a { export enum DiagnosticCategory { @@ -32,7 +40,13 @@ f.ts(54,14): error TS1252: Function declarations are not allowed inside blocks i function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { x = y; + ~ +!!! error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. +!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. y = x; + ~ +!!! error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. +!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. } function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { @@ -65,6 +79,12 @@ f.ts(54,14): error TS1252: Function declarations are not allowed inside blocks i ~ !!! error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. x = y; + ~ +!!! error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. +!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. y = x; + ~ +!!! error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. +!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. } } \ No newline at end of file From e4761579bf7f0324266a0933c4c85f6280b92d2d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Nov 2023 22:18:17 +0000 Subject: [PATCH 05/17] Rephrase error message. --- src/compiler/checker.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c5eb8db0a243c..e58638fcaeb5f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20621,7 +20621,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (errorReporter) { const escapedSource = typeof sourceValue === "string" ? `"${escapeString(sourceValue)}"` : sourceValue; const escapedTarget = typeof targetValue === "string" ? `"${escapeString(targetValue)}"` : targetValue; - errorReporter(Diagnostics.The_values_of_0_1_differ_in_their_declarations_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); + errorReporter(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); } else { diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5a9c315fb20cd..96fd26369f393 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4132,7 +4132,7 @@ "category": "Error", "code": 4124 }, - "The values of '{0}.{1}' differ in their declarations, where '{2}' was expected but '{3}' was given.": { + "Each declaration of '{0}.{1}' differs in its value, where '{2}' was expected but '{3}' was given.": { "category": "Error", "code": 4125 }, From 21f279480abf08d44e06d7b0c23009ecb85a2b6b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Nov 2023 22:35:08 +0000 Subject: [PATCH 06/17] Update tests. --- tests/cases/compiler/enumAssignmentCompat3.ts | 6 +++--- tests/cases/compiler/enumAssignmentCompat6.ts | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/cases/compiler/enumAssignmentCompat3.ts b/tests/cases/compiler/enumAssignmentCompat3.ts index 97a136468e3ee..a706be4ce2176 100644 --- a/tests/cases/compiler/enumAssignmentCompat3.ts +++ b/tests/cases/compiler/enumAssignmentCompat3.ts @@ -69,13 +69,13 @@ abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! -abc = decl; // ok +abc = decl; // bad - value of 'c' differs between these enums secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! -decl = abc; // ok +decl = abc; // bad - value of 'c' differs between these enums // const is only assignable to itself k = k; @@ -84,6 +84,6 @@ k = abc; // merged enums compare all their members abc = merged; // missing 'd' -merged = abc; // ok +merged = abc; // bad - value of 'c' differs between these enums abc = merged2; // ok merged2 = abc; // ok \ No newline at end of file diff --git a/tests/cases/compiler/enumAssignmentCompat6.ts b/tests/cases/compiler/enumAssignmentCompat6.ts index 3cdc28ab91d21..d6fb9165c6b6e 100644 --- a/tests/cases/compiler/enumAssignmentCompat6.ts +++ b/tests/cases/compiler/enumAssignmentCompat6.ts @@ -45,7 +45,7 @@ export enum DiagnosticCategory { export let x: DiagnosticCategory; -{ +(() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -56,4 +56,4 @@ export let x: DiagnosticCategory; x = y; y = x; } -} \ No newline at end of file +})() \ No newline at end of file From 2db27739d5b5615715dc77b352ceabb4d8d58155 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Nov 2023 22:35:14 +0000 Subject: [PATCH 07/17] Accept baselines. --- .../enumAssignmentCompat3.errors.txt | 26 +++++++++---------- .../reference/enumAssignmentCompat3.js | 12 ++++----- .../reference/enumAssignmentCompat3.symbols | 6 ++--- .../reference/enumAssignmentCompat3.types | 6 ++--- .../enumAssignmentCompat6.errors.txt | 25 ++++++++---------- .../reference/enumAssignmentCompat6.js | 12 ++++----- .../reference/enumAssignmentCompat6.symbols | 8 +++--- .../reference/enumAssignmentCompat6.types | 8 ++++-- 8 files changed, 52 insertions(+), 51 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index e53f39996db97..9c10fd6b13d95 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -1,23 +1,23 @@ enumAssignmentCompat3.ts(68,1): error TS2322: Type 'Abcd.E' is not assignable to type 'First.E'. Property 'd' is missing in type 'First.E'. enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. - The values of 'E.c' differ in their declarations, where '2' was expected but '0' was given. + Each declaration of 'E.c' differs in its value, where '2' was expected but '0' was given. enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. - The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. + Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. - The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. + Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. - The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. + Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable to type 'Merged.E'. - The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. + Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. ==== enumAssignmentCompat3.ts (12 errors) ==== @@ -96,14 +96,14 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t abc = secondCd; // missing 'd' ~~~ !!! error TS2322: Type 'Cd.E' is not assignable to type 'First.E'. -!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '0' was given. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '2' was expected but '0' was given. abc = nope; // nope! ~~~ !!! error TS2322: Type 'Nope' is not assignable to type 'E'. - abc = decl; // ok + abc = decl; // bad - value of 'c' differs between these enums ~~~ !!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. -!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -117,10 +117,10 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t nope = abc; // nope! ~~~~ !!! error TS2322: Type 'E' is not assignable to type 'Nope'. - decl = abc; // ok + decl = abc; // bad - value of 'c' differs between these enums ~~~~ !!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. -!!! error TS2322: The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. // const is only assignable to itself k = k; @@ -135,10 +135,10 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t abc = merged; // missing 'd' ~~~ !!! error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. -!!! error TS2322: The values of 'E.c' differ in their declarations, where '2' was expected but '3' was given. - merged = abc; // ok +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. + merged = abc; // bad - value of 'c' differs between these enums ~~~~~~ !!! error TS2322: Type 'First.E' is not assignable to type 'Merged.E'. -!!! error TS2322: The values of 'E.c' differ in their declarations, where '3' was expected but '2' was given. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. abc = merged2; // ok merged2 = abc; // ok \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat3.js b/tests/baselines/reference/enumAssignmentCompat3.js index ac83fb96c317a..755ddb169cfec 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.js +++ b/tests/baselines/reference/enumAssignmentCompat3.js @@ -72,13 +72,13 @@ abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! -abc = decl; // ok +abc = decl; // bad - value of 'c' differs between these enums secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! -decl = abc; // ok +decl = abc; // bad - value of 'c' differs between these enums // const is only assignable to itself k = k; @@ -87,7 +87,7 @@ k = abc; // merged enums compare all their members abc = merged; // missing 'd' -merged = abc; // ok +merged = abc; // bad - value of 'c' differs between these enums abc = merged2; // ok merged2 = abc; // ok @@ -184,19 +184,19 @@ abc = secondAbcd; // missing 'd' abc = secondAb; // ok abc = secondCd; // missing 'd' abc = nope; // nope! -abc = decl; // ok +abc = decl; // bad - value of 'c' differs between these enums secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' secondCd = abc; // missing 'a' and 'b' nope = abc; // nope! -decl = abc; // ok +decl = abc; // bad - value of 'c' differs between these enums // const is only assignable to itself k = k; abc = k; // error k = abc; // merged enums compare all their members abc = merged; // missing 'd' -merged = abc; // ok +merged = abc; // bad - value of 'c' differs between these enums abc = merged2; // ok merged2 = abc; // ok diff --git a/tests/baselines/reference/enumAssignmentCompat3.symbols b/tests/baselines/reference/enumAssignmentCompat3.symbols index 08b78e85f3a0d..00ee430fc60b3 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.symbols +++ b/tests/baselines/reference/enumAssignmentCompat3.symbols @@ -200,7 +200,7 @@ abc = nope; // nope! >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) >nope : Symbol(nope, Decl(enumAssignmentCompat3.ts, 61, 3)) -abc = decl; // ok +abc = decl; // bad - value of 'c' differs between these enums >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) >decl : Symbol(decl, Decl(enumAssignmentCompat3.ts, 63, 3)) @@ -224,7 +224,7 @@ nope = abc; // nope! >nope : Symbol(nope, Decl(enumAssignmentCompat3.ts, 61, 3)) >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) -decl = abc; // ok +decl = abc; // bad - value of 'c' differs between these enums >decl : Symbol(decl, Decl(enumAssignmentCompat3.ts, 63, 3)) >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) @@ -246,7 +246,7 @@ abc = merged; // missing 'd' >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) >merged : Symbol(merged, Decl(enumAssignmentCompat3.ts, 64, 3)) -merged = abc; // ok +merged = abc; // bad - value of 'c' differs between these enums >merged : Symbol(merged, Decl(enumAssignmentCompat3.ts, 64, 3)) >abc : Symbol(abc, Decl(enumAssignmentCompat3.ts, 56, 3)) diff --git a/tests/baselines/reference/enumAssignmentCompat3.types b/tests/baselines/reference/enumAssignmentCompat3.types index cc72b6777ba98..e1f98a739c8c9 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.types +++ b/tests/baselines/reference/enumAssignmentCompat3.types @@ -196,7 +196,7 @@ abc = nope; // nope! >abc : First.E >nope : Abc.Nope -abc = decl; // ok +abc = decl; // bad - value of 'c' differs between these enums >abc = decl : Decl.E >abc : First.E >decl : Decl.E @@ -226,7 +226,7 @@ nope = abc; // nope! >nope : Abc.Nope >abc : First.E -decl = abc; // ok +decl = abc; // bad - value of 'c' differs between these enums >decl = abc : First.E >decl : Decl.E >abc : First.E @@ -253,7 +253,7 @@ abc = merged; // missing 'd' >abc : First.E >merged : Merged.E -merged = abc; // ok +merged = abc; // bad - value of 'c' differs between these enums >merged = abc : First.E >merged : Merged.E >abc : First.E diff --git a/tests/baselines/reference/enumAssignmentCompat6.errors.txt b/tests/baselines/reference/enumAssignmentCompat6.errors.txt index 1dec98ad237a6..9a788385f03e6 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat6.errors.txt @@ -1,17 +1,16 @@ f.ts(28,5): error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. - The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. + Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. f.ts(29,5): error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. - The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. + Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. f.ts(33,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. f.ts(34,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. -f.ts(54,14): error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. f.ts(55,9): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. - The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. + Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. - The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. + Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. -==== f.ts (7 errors) ==== +==== f.ts (6 errors) ==== // @filename a.ts namespace a { export enum DiagnosticCategory { @@ -42,11 +41,11 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl x = y; ~ !!! error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. -!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. +!!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. y = x; ~ !!! error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. -!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. +!!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. } function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { @@ -68,7 +67,7 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl export let x: DiagnosticCategory; - { + (() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -76,15 +75,13 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl Message = "Message", } function f(y: DiagnosticCategory) { - ~ -!!! error TS1252: Function declarations are not allowed inside blocks in strict mode when targeting 'ES3' or 'ES5'. Modules are automatically in strict mode. x = y; ~ !!! error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. -!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '0' was expected but '"Warning"' was given. +!!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. y = x; ~ !!! error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. -!!! error TS2322: The values of 'DiagnosticCategory.Warning' differ in their declarations, where '"Warning"' was expected but '0' was given. +!!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. } - } \ No newline at end of file + })() \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat6.js b/tests/baselines/reference/enumAssignmentCompat6.js index a974a6d25787d..d54f5e755b677 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.js +++ b/tests/baselines/reference/enumAssignmentCompat6.js @@ -47,7 +47,7 @@ export enum DiagnosticCategory { export let x: DiagnosticCategory; -{ +(() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -58,7 +58,7 @@ export let x: DiagnosticCategory; x = y; y = x; } -} +})() //// [f.js] "use strict"; @@ -107,16 +107,16 @@ var DiagnosticCategory; DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion"; DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message"; })(DiagnosticCategory || (exports.DiagnosticCategory = DiagnosticCategory = {})); -{ - var DiagnosticCategory_1; +(function () { + var DiagnosticCategory; (function (DiagnosticCategory) { DiagnosticCategory["Warning"] = "Warning"; DiagnosticCategory["Error"] = "Error"; DiagnosticCategory["Suggestion"] = "Suggestion"; DiagnosticCategory["Message"] = "Message"; - })(DiagnosticCategory_1 || (DiagnosticCategory_1 = {})); + })(DiagnosticCategory || (DiagnosticCategory = {})); function f(y) { exports.x = y; y = exports.x; } -} +})(); diff --git a/tests/baselines/reference/enumAssignmentCompat6.symbols b/tests/baselines/reference/enumAssignmentCompat6.symbols index 8083d8c79519b..45d8fe4c70a8b 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.symbols +++ b/tests/baselines/reference/enumAssignmentCompat6.symbols @@ -115,9 +115,9 @@ export let x: DiagnosticCategory; >x : Symbol(x, Decl(f.ts, 44, 10)) >DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 34, 1)) -{ +(() => { enum DiagnosticCategory { ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 1)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 8)) Warning = "Warning", >Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 47, 29)) @@ -134,7 +134,7 @@ export let x: DiagnosticCategory; function f(y: DiagnosticCategory) { >f : Symbol(f, Decl(f.ts, 52, 5)) >y : Symbol(y, Decl(f.ts, 53, 15)) ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 1)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 8)) x = y; >x : Symbol(x, Decl(f.ts, 44, 10)) @@ -144,4 +144,4 @@ export let x: DiagnosticCategory; >y : Symbol(y, Decl(f.ts, 53, 15)) >x : Symbol(x, Decl(f.ts, 44, 10)) } -} +})() diff --git a/tests/baselines/reference/enumAssignmentCompat6.types b/tests/baselines/reference/enumAssignmentCompat6.types index da3b46034a94f..d9dea6d83d46a 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.types +++ b/tests/baselines/reference/enumAssignmentCompat6.types @@ -118,7 +118,11 @@ export enum DiagnosticCategory { export let x: DiagnosticCategory; >x : DiagnosticCategory -{ +(() => { +>(() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", Suggestion = "Suggestion", Message = "Message", } function f(y: DiagnosticCategory) { x = y; y = x; }})() : void +>(() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", Suggestion = "Suggestion", Message = "Message", } function f(y: DiagnosticCategory) { x = y; y = x; }}) : () => void +>() => { enum DiagnosticCategory { Warning = "Warning", Error = "Error", Suggestion = "Suggestion", Message = "Message", } function f(y: DiagnosticCategory) { x = y; y = x; }} : () => void + enum DiagnosticCategory { >DiagnosticCategory : DiagnosticCategory @@ -152,4 +156,4 @@ export let x: DiagnosticCategory; >y : DiagnosticCategory >x : import("f").DiagnosticCategory } -} +})() From e7da7024c62b8ea0e5ec11abc1766ad1bdcd53fa Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Nov 2023 23:10:57 +0000 Subject: [PATCH 08/17] Error on undefined values. --- src/compiler/checker.ts | 11 +++++++---- src/compiler/diagnosticMessages.json | 4 ++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e58638fcaeb5f..8660cbb70187a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20616,16 +20616,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const sourceValue = getEnumMemberValue(getDeclarationOfKind(sourceProperty, SyntaxKind.EnumMember)!); const targetValue = getEnumMemberValue(getDeclarationOfKind(targetProperty, SyntaxKind.EnumMember)!); - // TODO: Handle both 'undefined' - if (sourceValue !== undefined && targetValue !== undefined && sourceValue !== targetValue) { - if (errorReporter) { + if (sourceValue !== targetValue || sourceValue === undefined || targetValue === undefined) { + if (!errorReporter) { + enumRelation.set(id, RelationComparisonResult.Failed); + } + else if (sourceValue !== targetValue && sourceValue !== undefined && targetValue !== undefined) { const escapedSource = typeof sourceValue === "string" ? `"${escapeString(sourceValue)}"` : sourceValue; const escapedTarget = typeof targetValue === "string" ? `"${escapeString(targetValue)}"` : targetValue; errorReporter(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); } else { - enumRelation.set(id, RelationComparisonResult.Failed); + errorReporter(Diagnostics.Values_of_0_1_are_not_sufficiently_known, symbolName(targetSymbol), symbolName(targetProperty)); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); } return false; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 96fd26369f393..82d00ebfc5e5f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4136,6 +4136,10 @@ "category": "Error", "code": 4125 }, + "Values of '{0}.{1}' are not sufficiently known.": { + "category": "Error", + "code": 4126 + }, "The current host does not support the '{0}' option.": { "category": "Error", From b2033b37f3606e5392b8f22ebe1a4be417dd46e6 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Nov 2023 23:11:04 +0000 Subject: [PATCH 09/17] Accept baseline. --- .../baselines/reference/enumAssignmentCompat3.errors.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index 9c10fd6b13d95..59b2a2018a135 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -4,14 +4,14 @@ enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to t Each declaration of 'E.c' differs in its value, where '2' was expected but '0' was given. enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. - Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. + Values of 'E.a' are not sufficiently known. enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. - Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. + Values of 'E.a' are not sufficiently known. enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. @@ -103,7 +103,7 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t abc = decl; // bad - value of 'c' differs between these enums ~~~ !!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. -!!! error TS2322: Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. +!!! error TS2322: Values of 'E.a' are not sufficiently known. secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -120,7 +120,7 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t decl = abc; // bad - value of 'c' differs between these enums ~~~~ !!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. -!!! error TS2322: Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. +!!! error TS2322: Values of 'E.a' are not sufficiently known. // const is only assignable to itself k = k; From fad8d300411c9c950e14b59d4623fb3e7243d2ec Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 Dec 2023 00:54:24 +0000 Subject: [PATCH 10/17] Add test cases around ambient enum members. --- tests/cases/compiler/enumAssignmentCompat6.ts | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/cases/compiler/enumAssignmentCompat6.ts b/tests/cases/compiler/enumAssignmentCompat6.ts index d6fb9165c6b6e..b91300d37c537 100644 --- a/tests/cases/compiler/enumAssignmentCompat6.ts +++ b/tests/cases/compiler/enumAssignmentCompat6.ts @@ -1,5 +1,5 @@ // @filename a.ts -namespace a { +namespace numerics { export enum DiagnosticCategory { Warning, Error, @@ -15,7 +15,7 @@ namespace a { } } -namespace b { +namespace strings { export enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -24,16 +24,34 @@ namespace b { } } -function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { +declare namespace ambients { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } +} + +function f(x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) { x = y; y = x; } -function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { +function g(x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) { x = y; y = x; } +function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + y = x; +} + +function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + y = x; +} // @filename: f.ts export enum DiagnosticCategory { From 29b68f5d806614236fa6da4f181166532828f36c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 Dec 2023 00:55:28 +0000 Subject: [PATCH 11/17] Accepted baselines. --- .../enumAssignmentCompat6.errors.txt | 64 ++++++-- .../reference/enumAssignmentCompat6.js | 52 ++++-- .../reference/enumAssignmentCompat6.symbols | 153 ++++++++++++------ .../reference/enumAssignmentCompat6.types | 111 +++++++++---- 4 files changed, 277 insertions(+), 103 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat6.errors.txt b/tests/baselines/reference/enumAssignmentCompat6.errors.txt index 9a788385f03e6..3a15d0a224299 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat6.errors.txt @@ -1,18 +1,26 @@ -f.ts(28,5): error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. +f.ts(37,5): error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. -f.ts(29,5): error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. +f.ts(38,5): error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. -f.ts(33,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. -f.ts(34,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. -f.ts(55,9): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. +f.ts(42,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. +f.ts(43,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. +f.ts(47,5): error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. + Values of 'DiagnosticCategory.Warning' are not sufficiently known. +f.ts(48,5): error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. + Values of 'DiagnosticCategory.Warning' are not sufficiently known. +f.ts(52,5): error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. + Values of 'DiagnosticCategory.Warning' are not sufficiently known. +f.ts(53,5): error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. + Values of 'DiagnosticCategory.Warning' are not sufficiently known. +f.ts(73,9): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. -f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. +f.ts(74,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. -==== f.ts (6 errors) ==== +==== f.ts (10 errors) ==== // @filename a.ts - namespace a { + namespace numerics { export enum DiagnosticCategory { Warning, Error, @@ -28,7 +36,7 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl } } - namespace b { + namespace strings { export enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -37,18 +45,27 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl } } - function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { + declare namespace ambients { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } + } + + function f(x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) { x = y; ~ -!!! error TS2322: Type 'b.DiagnosticCategory' is not assignable to type 'a.DiagnosticCategory'. +!!! error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. !!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. y = x; ~ -!!! error TS2322: Type 'a.DiagnosticCategory' is not assignable to type 'b.DiagnosticCategory'. +!!! error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. !!! error TS2322: Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. } - function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { + function g(x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) { x = y; ~ !!! error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. @@ -57,6 +74,27 @@ f.ts(56,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl !!! error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. } + function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + ~ +!!! error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. +!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. + y = x; + ~ +!!! error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. +!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. + } + + function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + ~ +!!! error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. +!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. + y = x; + ~ +!!! error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. +!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. + } export enum DiagnosticCategory { Warning, diff --git a/tests/baselines/reference/enumAssignmentCompat6.js b/tests/baselines/reference/enumAssignmentCompat6.js index d54f5e755b677..a8cde20aacf69 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.js +++ b/tests/baselines/reference/enumAssignmentCompat6.js @@ -2,7 +2,7 @@ //// [f.ts] // @filename a.ts -namespace a { +namespace numerics { export enum DiagnosticCategory { Warning, Error, @@ -18,7 +18,7 @@ namespace a { } } -namespace b { +namespace strings { export enum DiagnosticCategory { Warning = "Warning", Error = "Error", @@ -27,16 +27,34 @@ namespace b { } } -function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { +declare namespace ambients { + export enum DiagnosticCategory { + Warning, + Error, + Suggestion, + Message, + } +} + +function f(x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) { x = y; y = x; } -function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { +function g(x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) { x = y; y = x; } +function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + y = x; +} + +function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { + x = y; + y = x; +} export enum DiagnosticCategory { Warning, @@ -65,33 +83,33 @@ export let x: DiagnosticCategory; Object.defineProperty(exports, "__esModule", { value: true }); exports.x = exports.DiagnosticCategory = void 0; // @filename a.ts -var a; -(function (a) { +var numerics; +(function (numerics) { var DiagnosticCategory; (function (DiagnosticCategory) { DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning"; DiagnosticCategory[DiagnosticCategory["Error"] = 1] = "Error"; DiagnosticCategory[DiagnosticCategory["Suggestion"] = 2] = "Suggestion"; DiagnosticCategory[DiagnosticCategory["Message"] = 3] = "Message"; - })(DiagnosticCategory = a.DiagnosticCategory || (a.DiagnosticCategory = {})); + })(DiagnosticCategory = numerics.DiagnosticCategory || (numerics.DiagnosticCategory = {})); var DiagnosticCategory2; (function (DiagnosticCategory2) { DiagnosticCategory2[DiagnosticCategory2["Warning"] = 0] = "Warning"; DiagnosticCategory2[DiagnosticCategory2["Error"] = 1] = "Error"; DiagnosticCategory2[DiagnosticCategory2["Suggestion"] = 2] = "Suggestion"; DiagnosticCategory2[DiagnosticCategory2["Message"] = 3] = "Message"; - })(DiagnosticCategory2 = a.DiagnosticCategory2 || (a.DiagnosticCategory2 = {})); -})(a || (a = {})); -var b; -(function (b) { + })(DiagnosticCategory2 = numerics.DiagnosticCategory2 || (numerics.DiagnosticCategory2 = {})); +})(numerics || (numerics = {})); +var strings; +(function (strings) { var DiagnosticCategory; (function (DiagnosticCategory) { DiagnosticCategory["Warning"] = "Warning"; DiagnosticCategory["Error"] = "Error"; DiagnosticCategory["Suggestion"] = "Suggestion"; DiagnosticCategory["Message"] = "Message"; - })(DiagnosticCategory = b.DiagnosticCategory || (b.DiagnosticCategory = {})); -})(b || (b = {})); + })(DiagnosticCategory = strings.DiagnosticCategory || (strings.DiagnosticCategory = {})); +})(strings || (strings = {})); function f(x, y) { x = y; y = x; @@ -100,6 +118,14 @@ function g(x, y) { x = y; y = x; } +function h(x, y) { + x = y; + y = x; +} +function i(x, y) { + x = y; + y = x; +} var DiagnosticCategory; (function (DiagnosticCategory) { DiagnosticCategory[DiagnosticCategory["Warning"] = 0] = "Warning"; diff --git a/tests/baselines/reference/enumAssignmentCompat6.symbols b/tests/baselines/reference/enumAssignmentCompat6.symbols index 45d8fe4c70a8b..fcf2c4f1637f5 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.symbols +++ b/tests/baselines/reference/enumAssignmentCompat6.symbols @@ -2,11 +2,11 @@ === f.ts === // @filename a.ts -namespace a { ->a : Symbol(a, Decl(f.ts, 0, 0)) +namespace numerics { +>numerics : Symbol(numerics, Decl(f.ts, 0, 0)) export enum DiagnosticCategory { ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 1, 13)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 1, 20)) Warning, >Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 2, 36)) @@ -38,11 +38,11 @@ namespace a { } } -namespace b { ->b : Symbol(b, Decl(f.ts, 15, 1)) +namespace strings { +>strings : Symbol(strings, Decl(f.ts, 15, 1)) export enum DiagnosticCategory { ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 17, 13)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 17, 19)) Warning = "Warning", >Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 18, 36)) @@ -58,90 +58,145 @@ namespace b { } } -function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { ->f : Symbol(f, Decl(f.ts, 24, 1)) ->x : Symbol(x, Decl(f.ts, 26, 11)) ->a : Symbol(a, Decl(f.ts, 0, 0)) ->DiagnosticCategory : Symbol(a.DiagnosticCategory, Decl(f.ts, 1, 13)) ->y : Symbol(y, Decl(f.ts, 26, 35)) ->b : Symbol(b, Decl(f.ts, 15, 1)) ->DiagnosticCategory : Symbol(b.DiagnosticCategory, Decl(f.ts, 17, 13)) +declare namespace ambients { +>ambients : Symbol(ambients, Decl(f.ts, 24, 1)) + + export enum DiagnosticCategory { +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 26, 28)) + + Warning, +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 27, 36)) + + Error, +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 28, 16)) + + Suggestion, +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 29, 14)) + + Message, +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 30, 19)) + } +} + +function f(x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) { +>f : Symbol(f, Decl(f.ts, 33, 1)) +>x : Symbol(x, Decl(f.ts, 35, 11)) +>numerics : Symbol(numerics, Decl(f.ts, 0, 0)) +>DiagnosticCategory : Symbol(numerics.DiagnosticCategory, Decl(f.ts, 1, 20)) +>y : Symbol(y, Decl(f.ts, 35, 42)) +>strings : Symbol(strings, Decl(f.ts, 15, 1)) +>DiagnosticCategory : Symbol(strings.DiagnosticCategory, Decl(f.ts, 17, 19)) + + x = y; +>x : Symbol(x, Decl(f.ts, 35, 11)) +>y : Symbol(y, Decl(f.ts, 35, 42)) + + y = x; +>y : Symbol(y, Decl(f.ts, 35, 42)) +>x : Symbol(x, Decl(f.ts, 35, 11)) +} + +function g(x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) { +>g : Symbol(g, Decl(f.ts, 38, 1)) +>x : Symbol(x, Decl(f.ts, 40, 11)) +>numerics : Symbol(numerics, Decl(f.ts, 0, 0)) +>DiagnosticCategory2 : Symbol(numerics.DiagnosticCategory2, Decl(f.ts, 7, 5)) +>y : Symbol(y, Decl(f.ts, 40, 43)) +>strings : Symbol(strings, Decl(f.ts, 15, 1)) +>DiagnosticCategory : Symbol(strings.DiagnosticCategory, Decl(f.ts, 17, 19)) x = y; ->x : Symbol(x, Decl(f.ts, 26, 11)) ->y : Symbol(y, Decl(f.ts, 26, 35)) +>x : Symbol(x, Decl(f.ts, 40, 11)) +>y : Symbol(y, Decl(f.ts, 40, 43)) y = x; ->y : Symbol(y, Decl(f.ts, 26, 35)) ->x : Symbol(x, Decl(f.ts, 26, 11)) +>y : Symbol(y, Decl(f.ts, 40, 43)) +>x : Symbol(x, Decl(f.ts, 40, 11)) } -function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { ->g : Symbol(g, Decl(f.ts, 29, 1)) ->x : Symbol(x, Decl(f.ts, 31, 11)) ->a : Symbol(a, Decl(f.ts, 0, 0)) ->DiagnosticCategory2 : Symbol(a.DiagnosticCategory2, Decl(f.ts, 7, 5)) ->y : Symbol(y, Decl(f.ts, 31, 36)) ->b : Symbol(b, Decl(f.ts, 15, 1)) ->DiagnosticCategory : Symbol(b.DiagnosticCategory, Decl(f.ts, 17, 13)) +function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { +>h : Symbol(h, Decl(f.ts, 43, 1)) +>x : Symbol(x, Decl(f.ts, 45, 11)) +>numerics : Symbol(numerics, Decl(f.ts, 0, 0)) +>DiagnosticCategory : Symbol(numerics.DiagnosticCategory, Decl(f.ts, 1, 20)) +>y : Symbol(y, Decl(f.ts, 45, 42)) +>ambients : Symbol(ambients, Decl(f.ts, 24, 1)) +>DiagnosticCategory : Symbol(ambients.DiagnosticCategory, Decl(f.ts, 26, 28)) x = y; ->x : Symbol(x, Decl(f.ts, 31, 11)) ->y : Symbol(y, Decl(f.ts, 31, 36)) +>x : Symbol(x, Decl(f.ts, 45, 11)) +>y : Symbol(y, Decl(f.ts, 45, 42)) y = x; ->y : Symbol(y, Decl(f.ts, 31, 36)) ->x : Symbol(x, Decl(f.ts, 31, 11)) +>y : Symbol(y, Decl(f.ts, 45, 42)) +>x : Symbol(x, Decl(f.ts, 45, 11)) } +function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { +>i : Symbol(i, Decl(f.ts, 48, 1)) +>x : Symbol(x, Decl(f.ts, 50, 11)) +>strings : Symbol(strings, Decl(f.ts, 15, 1)) +>DiagnosticCategory : Symbol(strings.DiagnosticCategory, Decl(f.ts, 17, 19)) +>y : Symbol(y, Decl(f.ts, 50, 41)) +>ambients : Symbol(ambients, Decl(f.ts, 24, 1)) +>DiagnosticCategory : Symbol(ambients.DiagnosticCategory, Decl(f.ts, 26, 28)) + + x = y; +>x : Symbol(x, Decl(f.ts, 50, 11)) +>y : Symbol(y, Decl(f.ts, 50, 41)) + + y = x; +>y : Symbol(y, Decl(f.ts, 50, 41)) +>x : Symbol(x, Decl(f.ts, 50, 11)) +} export enum DiagnosticCategory { ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 34, 1)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 53, 1)) Warning, ->Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 37, 32)) +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 55, 32)) Error, ->Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 38, 12)) +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 56, 12)) Suggestion, ->Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 39, 10)) +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 57, 10)) Message, ->Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 40, 15)) +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 58, 15)) } export let x: DiagnosticCategory; ->x : Symbol(x, Decl(f.ts, 44, 10)) ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 34, 1)) +>x : Symbol(x, Decl(f.ts, 62, 10)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 53, 1)) (() => { enum DiagnosticCategory { ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 8)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 64, 8)) Warning = "Warning", ->Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 47, 29)) +>Warning : Symbol(DiagnosticCategory.Warning, Decl(f.ts, 65, 29)) Error = "Error", ->Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 48, 28)) +>Error : Symbol(DiagnosticCategory.Error, Decl(f.ts, 66, 28)) Suggestion = "Suggestion", ->Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 49, 24)) +>Suggestion : Symbol(DiagnosticCategory.Suggestion, Decl(f.ts, 67, 24)) Message = "Message", ->Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 50, 34)) +>Message : Symbol(DiagnosticCategory.Message, Decl(f.ts, 68, 34)) } function f(y: DiagnosticCategory) { ->f : Symbol(f, Decl(f.ts, 52, 5)) ->y : Symbol(y, Decl(f.ts, 53, 15)) ->DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 46, 8)) +>f : Symbol(f, Decl(f.ts, 70, 5)) +>y : Symbol(y, Decl(f.ts, 71, 15)) +>DiagnosticCategory : Symbol(DiagnosticCategory, Decl(f.ts, 64, 8)) x = y; ->x : Symbol(x, Decl(f.ts, 44, 10)) ->y : Symbol(y, Decl(f.ts, 53, 15)) +>x : Symbol(x, Decl(f.ts, 62, 10)) +>y : Symbol(y, Decl(f.ts, 71, 15)) y = x; ->y : Symbol(y, Decl(f.ts, 53, 15)) ->x : Symbol(x, Decl(f.ts, 44, 10)) +>y : Symbol(y, Decl(f.ts, 71, 15)) +>x : Symbol(x, Decl(f.ts, 62, 10)) } })() diff --git a/tests/baselines/reference/enumAssignmentCompat6.types b/tests/baselines/reference/enumAssignmentCompat6.types index d9dea6d83d46a..ff464f41afb28 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.types +++ b/tests/baselines/reference/enumAssignmentCompat6.types @@ -2,8 +2,8 @@ === f.ts === // @filename a.ts -namespace a { ->a : typeof a +namespace numerics { +>numerics : typeof numerics export enum DiagnosticCategory { >DiagnosticCategory : DiagnosticCategory @@ -38,8 +38,8 @@ namespace a { } } -namespace b { ->b : typeof b +namespace strings { +>strings : typeof strings export enum DiagnosticCategory { >DiagnosticCategory : DiagnosticCategory @@ -62,42 +62,97 @@ namespace b { } } -function f(x: a.DiagnosticCategory, y: b.DiagnosticCategory) { ->f : (x: a.DiagnosticCategory, y: b.DiagnosticCategory) => void ->x : a.DiagnosticCategory ->a : any ->y : b.DiagnosticCategory ->b : any +declare namespace ambients { +>ambients : typeof ambients + + export enum DiagnosticCategory { +>DiagnosticCategory : DiagnosticCategory + + Warning, +>Warning : DiagnosticCategory.Warning + + Error, +>Error : DiagnosticCategory.Error + + Suggestion, +>Suggestion : DiagnosticCategory.Suggestion + + Message, +>Message : DiagnosticCategory.Message + } +} + +function f(x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) { +>f : (x: numerics.DiagnosticCategory, y: strings.DiagnosticCategory) => void +>x : numerics.DiagnosticCategory +>numerics : any +>y : strings.DiagnosticCategory +>strings : any + + x = y; +>x = y : strings.DiagnosticCategory +>x : numerics.DiagnosticCategory +>y : strings.DiagnosticCategory + + y = x; +>y = x : numerics.DiagnosticCategory +>y : strings.DiagnosticCategory +>x : numerics.DiagnosticCategory +} + +function g(x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) { +>g : (x: numerics.DiagnosticCategory2, y: strings.DiagnosticCategory) => void +>x : numerics.DiagnosticCategory2 +>numerics : any +>y : strings.DiagnosticCategory +>strings : any x = y; ->x = y : b.DiagnosticCategory ->x : a.DiagnosticCategory ->y : b.DiagnosticCategory +>x = y : strings.DiagnosticCategory +>x : numerics.DiagnosticCategory2 +>y : strings.DiagnosticCategory y = x; ->y = x : a.DiagnosticCategory ->y : b.DiagnosticCategory ->x : a.DiagnosticCategory +>y = x : numerics.DiagnosticCategory2 +>y : strings.DiagnosticCategory +>x : numerics.DiagnosticCategory2 } -function g(x: a.DiagnosticCategory2, y: b.DiagnosticCategory) { ->g : (x: a.DiagnosticCategory2, y: b.DiagnosticCategory) => void ->x : a.DiagnosticCategory2 ->a : any ->y : b.DiagnosticCategory ->b : any +function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { +>h : (x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) => void +>x : numerics.DiagnosticCategory +>numerics : any +>y : ambients.DiagnosticCategory +>ambients : any x = y; ->x = y : b.DiagnosticCategory ->x : a.DiagnosticCategory2 ->y : b.DiagnosticCategory +>x = y : ambients.DiagnosticCategory +>x : numerics.DiagnosticCategory +>y : ambients.DiagnosticCategory y = x; ->y = x : a.DiagnosticCategory2 ->y : b.DiagnosticCategory ->x : a.DiagnosticCategory2 +>y = x : numerics.DiagnosticCategory +>y : ambients.DiagnosticCategory +>x : numerics.DiagnosticCategory } +function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { +>i : (x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) => void +>x : strings.DiagnosticCategory +>strings : any +>y : ambients.DiagnosticCategory +>ambients : any + + x = y; +>x = y : ambients.DiagnosticCategory +>x : strings.DiagnosticCategory +>y : ambients.DiagnosticCategory + + y = x; +>y = x : strings.DiagnosticCategory +>y : ambients.DiagnosticCategory +>x : strings.DiagnosticCategory +} export enum DiagnosticCategory { >DiagnosticCategory : DiagnosticCategory From b5942810b2889d178b9552a4732853e563dcc13e Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 Dec 2023 00:15:06 +0000 Subject: [PATCH 12/17] Only error on undefined values when the other is a string. --- src/compiler/checker.ts | 40 +++++++++++++++++++--------- src/compiler/diagnosticMessages.json | 2 +- src/compiler/types.ts | 1 + 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8660cbb70187a..6402f3693312e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20616,21 +20616,35 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const sourceValue = getEnumMemberValue(getDeclarationOfKind(sourceProperty, SyntaxKind.EnumMember)!); const targetValue = getEnumMemberValue(getDeclarationOfKind(targetProperty, SyntaxKind.EnumMember)!); - if (sourceValue !== targetValue || sourceValue === undefined || targetValue === undefined) { - if (!errorReporter) { - enumRelation.set(id, RelationComparisonResult.Failed); - } - else if (sourceValue !== targetValue && sourceValue !== undefined && targetValue !== undefined) { - const escapedSource = typeof sourceValue === "string" ? `"${escapeString(sourceValue)}"` : sourceValue; - const escapedTarget = typeof targetValue === "string" ? `"${escapeString(targetValue)}"` : targetValue; - errorReporter(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); - enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + if (sourceValue !== targetValue) { + const sourceIsString = typeof sourceValue === "string"; + const targetIsString = typeof targetValue === "string"; + let errorFlags: RelationComparisonResult = errorReporter ? RelationComparisonResult.Reported : RelationComparisonResult.None; + + if (sourceValue !== undefined && targetValue !== undefined) { + // If we have 2 *known* values that differ, we should report an error. + const escapedSource = sourceIsString ? `"${escapeString(sourceValue)}"` : sourceValue; + const escapedTarget = targetIsString ? `"${escapeString(targetValue)}"` : targetValue; + errorReporter?.(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); + errorFlags |= RelationComparisonResult.Failed; + } + else if (sourceIsString || targetIsString) { + // At this point we know that at least one of the values is 'undefined'. + // This may mean that we have an opaque member from an ambient enum declaration, + // or that we were not able to calculate it (which is basically an error). + // + // Either way, we can assume that it's numeric. + // If we have a string, we report a mismatch in the types. + const knownStringValue = (sourceValue ?? targetValue) as string; + const escapedValue = `"${escapeString(knownStringValue)}"`; + errorReporter?.(Diagnostics.One_value_of_0_1_is_the_string_2_and_the_other_is_assumed_to_be_an_unknown_numeric_value, symbolName(targetSymbol), symbolName(targetProperty), escapedValue); + errorFlags |= RelationComparisonResult.Failed; } - else { - errorReporter(Diagnostics.Values_of_0_1_are_not_sufficiently_known, symbolName(targetSymbol), symbolName(targetProperty)); - enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + + if (errorFlags & RelationComparisonResult.Failed) { + enumRelation.set(id, errorFlags); + return false; } - return false; } } } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 82d00ebfc5e5f..98e9b85c5c56c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4136,7 +4136,7 @@ "category": "Error", "code": 4125 }, - "Values of '{0}.{1}' are not sufficiently known.": { + "One value of '{0}.{1}' is the string '{2}', and the other is assumed to be an unknown numeric value.": { "category": "Error", "code": 4126 }, diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d4860ec7621a8..b1c53f51191c2 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -896,6 +896,7 @@ export const enum JsxFlags { // dprint-ignore /** @internal */ export const enum RelationComparisonResult { + None = 0, Succeeded = 1 << 0, // Should be truthy Failed = 1 << 1, Reported = 1 << 2, From cd2d86e8bb9290b2a03080a92076c680f91fdfb7 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 Dec 2023 00:58:08 +0000 Subject: [PATCH 13/17] Accepted baselines. --- .../enumAssignmentCompat3.errors.txt | 8 ++++---- .../enumAssignmentCompat6.errors.txt | 20 +++++-------------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/tests/baselines/reference/enumAssignmentCompat3.errors.txt b/tests/baselines/reference/enumAssignmentCompat3.errors.txt index 59b2a2018a135..9c10fd6b13d95 100644 --- a/tests/baselines/reference/enumAssignmentCompat3.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat3.errors.txt @@ -4,14 +4,14 @@ enumAssignmentCompat3.ts(70,1): error TS2322: Type 'Cd.E' is not assignable to t Each declaration of 'E.c' differs in its value, where '2' was expected but '0' was given. enumAssignmentCompat3.ts(71,1): error TS2322: Type 'Nope' is not assignable to type 'E'. enumAssignmentCompat3.ts(72,1): error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. - Values of 'E.a' are not sufficiently known. + Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. enumAssignmentCompat3.ts(75,1): error TS2322: Type 'First.E' is not assignable to type 'Ab.E'. Property 'c' is missing in type 'Ab.E'. enumAssignmentCompat3.ts(76,1): error TS2322: Type 'First.E' is not assignable to type 'Cd.E'. Property 'a' is missing in type 'Cd.E'. enumAssignmentCompat3.ts(77,1): error TS2322: Type 'E' is not assignable to type 'Nope'. enumAssignmentCompat3.ts(78,1): error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. - Values of 'E.a' are not sufficiently known. + Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. enumAssignmentCompat3.ts(82,1): error TS2322: Type 'Const.E' is not assignable to type 'First.E'. enumAssignmentCompat3.ts(83,1): error TS2322: Type 'First.E' is not assignable to type 'Const.E'. enumAssignmentCompat3.ts(86,1): error TS2322: Type 'Merged.E' is not assignable to type 'First.E'. @@ -103,7 +103,7 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t abc = decl; // bad - value of 'c' differs between these enums ~~~ !!! error TS2322: Type 'Decl.E' is not assignable to type 'First.E'. -!!! error TS2322: Values of 'E.a' are not sufficiently known. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '2' was expected but '3' was given. secondAbc = abc; // ok secondAbcd = abc; // ok secondAb = abc; // missing 'c' @@ -120,7 +120,7 @@ enumAssignmentCompat3.ts(87,1): error TS2322: Type 'First.E' is not assignable t decl = abc; // bad - value of 'c' differs between these enums ~~~~ !!! error TS2322: Type 'First.E' is not assignable to type 'Decl.E'. -!!! error TS2322: Values of 'E.a' are not sufficiently known. +!!! error TS2322: Each declaration of 'E.c' differs in its value, where '3' was expected but '2' was given. // const is only assignable to itself k = k; diff --git a/tests/baselines/reference/enumAssignmentCompat6.errors.txt b/tests/baselines/reference/enumAssignmentCompat6.errors.txt index 3a15d0a224299..6fa72a1d05f16 100644 --- a/tests/baselines/reference/enumAssignmentCompat6.errors.txt +++ b/tests/baselines/reference/enumAssignmentCompat6.errors.txt @@ -4,21 +4,17 @@ f.ts(38,5): error TS2322: Type 'numerics.DiagnosticCategory' is not assignable t Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. f.ts(42,5): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'DiagnosticCategory2'. f.ts(43,5): error TS2322: Type 'DiagnosticCategory2' is not assignable to type 'DiagnosticCategory'. -f.ts(47,5): error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. - Values of 'DiagnosticCategory.Warning' are not sufficiently known. -f.ts(48,5): error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. - Values of 'DiagnosticCategory.Warning' are not sufficiently known. f.ts(52,5): error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. - Values of 'DiagnosticCategory.Warning' are not sufficiently known. + One value of 'DiagnosticCategory.Warning' is the string '"Warning"', and the other is assumed to be an unknown numeric value. f.ts(53,5): error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. - Values of 'DiagnosticCategory.Warning' are not sufficiently known. + One value of 'DiagnosticCategory.Warning' is the string '"Warning"', and the other is assumed to be an unknown numeric value. f.ts(73,9): error TS2322: Type 'DiagnosticCategory' is not assignable to type 'import("f").DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '0' was expected but '"Warning"' was given. f.ts(74,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignable to type 'DiagnosticCategory'. Each declaration of 'DiagnosticCategory.Warning' differs in its value, where '"Warning"' was expected but '0' was given. -==== f.ts (10 errors) ==== +==== f.ts (8 errors) ==== // @filename a.ts namespace numerics { export enum DiagnosticCategory { @@ -76,24 +72,18 @@ f.ts(74,9): error TS2322: Type 'import("f").DiagnosticCategory' is not assignabl function h(x: numerics.DiagnosticCategory, y: ambients.DiagnosticCategory) { x = y; - ~ -!!! error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'numerics.DiagnosticCategory'. -!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. y = x; - ~ -!!! error TS2322: Type 'numerics.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. -!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. } function i(x: strings.DiagnosticCategory, y: ambients.DiagnosticCategory) { x = y; ~ !!! error TS2322: Type 'ambients.DiagnosticCategory' is not assignable to type 'strings.DiagnosticCategory'. -!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. +!!! error TS2322: One value of 'DiagnosticCategory.Warning' is the string '"Warning"', and the other is assumed to be an unknown numeric value. y = x; ~ !!! error TS2322: Type 'strings.DiagnosticCategory' is not assignable to type 'ambients.DiagnosticCategory'. -!!! error TS2322: Values of 'DiagnosticCategory.Warning' are not sufficiently known. +!!! error TS2322: One value of 'DiagnosticCategory.Warning' is the string '"Warning"', and the other is assumed to be an unknown numeric value. } export enum DiagnosticCategory { From af7f5b8217322c773bd140111798869cfd3b344f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 7 Dec 2023 01:06:49 +0000 Subject: [PATCH 14/17] Only do work for error reporting if there's an error reporter. --- src/compiler/checker.ts | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6402f3693312e..a05913881e74e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20619,14 +20619,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (sourceValue !== targetValue) { const sourceIsString = typeof sourceValue === "string"; const targetIsString = typeof targetValue === "string"; - let errorFlags: RelationComparisonResult = errorReporter ? RelationComparisonResult.Reported : RelationComparisonResult.None; if (sourceValue !== undefined && targetValue !== undefined) { - // If we have 2 *known* values that differ, we should report an error. - const escapedSource = sourceIsString ? `"${escapeString(sourceValue)}"` : sourceValue; - const escapedTarget = targetIsString ? `"${escapeString(targetValue)}"` : targetValue; - errorReporter?.(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); - errorFlags |= RelationComparisonResult.Failed; + // If we have 2 enums with *known* values that differ, they are incompatible. + if (!errorReporter) { + enumRelation.set(id, RelationComparisonResult.Failed); + } + else { + const escapedSource = sourceIsString ? `"${escapeString(sourceValue)}"` : sourceValue; + const escapedTarget = targetIsString ? `"${escapeString(targetValue)}"` : targetValue; + errorReporter(Diagnostics.Each_declaration_of_0_1_differs_in_its_value_where_2_was_expected_but_3_was_given, symbolName(targetSymbol), symbolName(targetProperty), escapedTarget, escapedSource); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + } + return false; } else if (sourceIsString || targetIsString) { // At this point we know that at least one of the values is 'undefined'. @@ -20634,15 +20639,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // or that we were not able to calculate it (which is basically an error). // // Either way, we can assume that it's numeric. - // If we have a string, we report a mismatch in the types. - const knownStringValue = (sourceValue ?? targetValue) as string; - const escapedValue = `"${escapeString(knownStringValue)}"`; - errorReporter?.(Diagnostics.One_value_of_0_1_is_the_string_2_and_the_other_is_assumed_to_be_an_unknown_numeric_value, symbolName(targetSymbol), symbolName(targetProperty), escapedValue); - errorFlags |= RelationComparisonResult.Failed; - } - - if (errorFlags & RelationComparisonResult.Failed) { - enumRelation.set(id, errorFlags); + // If the other is a string, we have a mismatch in types. + if (!errorReporter) { + enumRelation.set(id, RelationComparisonResult.Failed); + } + else { + const knownStringValue = sourceValue ?? targetValue; + Debug.assert(typeof knownStringValue === "string"); + const escapedValue = `"${escapeString(knownStringValue)}"`; + errorReporter(Diagnostics.One_value_of_0_1_is_the_string_2_and_the_other_is_assumed_to_be_an_unknown_numeric_value, symbolName(targetSymbol), symbolName(targetProperty), escapedValue); + enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported); + } return false; } } From aeeb7da569d0d7af5d4f409b69bebcf1d0dfd7a4 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 19 Dec 2023 22:20:45 +0000 Subject: [PATCH 15/17] Move around comments. --- src/compiler/checker.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a05913881e74e..fa1b1b58a8208 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20620,8 +20620,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const sourceIsString = typeof sourceValue === "string"; const targetIsString = typeof targetValue === "string"; + // If we have 2 enums with *known* values that differ, they are incompatible. if (sourceValue !== undefined && targetValue !== undefined) { - // If we have 2 enums with *known* values that differ, they are incompatible. if (!errorReporter) { enumRelation.set(id, RelationComparisonResult.Failed); } @@ -20633,13 +20633,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return false; } - else if (sourceIsString || targetIsString) { - // At this point we know that at least one of the values is 'undefined'. - // This may mean that we have an opaque member from an ambient enum declaration, - // or that we were not able to calculate it (which is basically an error). - // - // Either way, we can assume that it's numeric. - // If the other is a string, we have a mismatch in types. + + // At this point we know that at least one of the values is 'undefined'. + // This may mean that we have an opaque member from an ambient enum declaration, + // or that we were not able to calculate it (which is basically an error). + // + // Either way, we can assume that it's numeric. + // If the other is a string, we have a mismatch in types. + if (sourceIsString || targetIsString) { if (!errorReporter) { enumRelation.set(id, RelationComparisonResult.Failed); } From 2f075c1536bc1819b3507820660c252cddc5960b Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 19 Dec 2023 22:21:28 +0000 Subject: [PATCH 16/17] Add some tests that include a bidirectional enum check. --- tests/cases/compiler/enumAssignmentCompat7.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 tests/cases/compiler/enumAssignmentCompat7.ts diff --git a/tests/cases/compiler/enumAssignmentCompat7.ts b/tests/cases/compiler/enumAssignmentCompat7.ts new file mode 100644 index 0000000000000..179f7d844dbfb --- /dev/null +++ b/tests/cases/compiler/enumAssignmentCompat7.ts @@ -0,0 +1,26 @@ +// @strict: true +// @strictFunctionTypes: false + +namespace first { + export enum E { A = 1 } +} + +namespace second { + export enum E { A = 2 } +} + +class Base { + method(param: first.E) { + + } +} + +class Derived extends Base { + override method(param: second.E) { + } +} + +function overloadingFunction(): first.E +function overloadingFunction(): second.E { + return second.E.B +} \ No newline at end of file From 91e3ac6e6cad772c47028efbcb5c7c0e7c22af10 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 19 Dec 2023 22:21:34 +0000 Subject: [PATCH 17/17] Accept baselines. --- .../enumAssignmentCompat7.errors.txt | 42 ++++++++++ .../reference/enumAssignmentCompat7.js | 77 +++++++++++++++++++ .../reference/enumAssignmentCompat7.symbols | 58 ++++++++++++++ .../reference/enumAssignmentCompat7.types | 58 ++++++++++++++ 4 files changed, 235 insertions(+) create mode 100644 tests/baselines/reference/enumAssignmentCompat7.errors.txt create mode 100644 tests/baselines/reference/enumAssignmentCompat7.js create mode 100644 tests/baselines/reference/enumAssignmentCompat7.symbols create mode 100644 tests/baselines/reference/enumAssignmentCompat7.types diff --git a/tests/baselines/reference/enumAssignmentCompat7.errors.txt b/tests/baselines/reference/enumAssignmentCompat7.errors.txt new file mode 100644 index 0000000000000..b829d9b65dcdd --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat7.errors.txt @@ -0,0 +1,42 @@ +enumAssignmentCompat7.ts(16,14): error TS2416: Property 'method' in type 'Derived' is not assignable to the same property in base type 'Base'. + Type '(param: second.E) => void' is not assignable to type '(param: first.E) => void'. + Types of parameters 'param' and 'param' are incompatible. + Type 'first.E' is not assignable to type 'second.E'. +enumAssignmentCompat7.ts(20,10): error TS2394: This overload signature is not compatible with its implementation signature. +enumAssignmentCompat7.ts(22,21): error TS2339: Property 'B' does not exist on type 'typeof E'. + + +==== enumAssignmentCompat7.ts (3 errors) ==== + namespace first { + export enum E { A = 1 } + } + + namespace second { + export enum E { A = 2 } + } + + class Base { + method(param: first.E) { + + } + } + + class Derived extends Base { + override method(param: second.E) { + ~~~~~~ +!!! error TS2416: Property 'method' in type 'Derived' is not assignable to the same property in base type 'Base'. +!!! error TS2416: Type '(param: second.E) => void' is not assignable to type '(param: first.E) => void'. +!!! error TS2416: Types of parameters 'param' and 'param' are incompatible. +!!! error TS2416: Type 'first.E' is not assignable to type 'second.E'. + } + } + + function overloadingFunction(): first.E + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2394: This overload signature is not compatible with its implementation signature. +!!! related TS2750 enumAssignmentCompat7.ts:21:10: The implementation signature is declared here. + function overloadingFunction(): second.E { + return second.E.B + ~ +!!! error TS2339: Property 'B' does not exist on type 'typeof E'. + } \ No newline at end of file diff --git a/tests/baselines/reference/enumAssignmentCompat7.js b/tests/baselines/reference/enumAssignmentCompat7.js new file mode 100644 index 0000000000000..4521732abed6d --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat7.js @@ -0,0 +1,77 @@ +//// [tests/cases/compiler/enumAssignmentCompat7.ts] //// + +//// [enumAssignmentCompat7.ts] +namespace first { + export enum E { A = 1 } +} + +namespace second { + export enum E { A = 2 } +} + +class Base { + method(param: first.E) { + + } +} + +class Derived extends Base { + override method(param: second.E) { + } +} + +function overloadingFunction(): first.E +function overloadingFunction(): second.E { + return second.E.B +} + +//// [enumAssignmentCompat7.js] +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var first; +(function (first) { + var E; + (function (E) { + E[E["A"] = 1] = "A"; + })(E = first.E || (first.E = {})); +})(first || (first = {})); +var second; +(function (second) { + var E; + (function (E) { + E[E["A"] = 2] = "A"; + })(E = second.E || (second.E = {})); +})(second || (second = {})); +var Base = /** @class */ (function () { + function Base() { + } + Base.prototype.method = function (param) { + }; + return Base; +}()); +var Derived = /** @class */ (function (_super) { + __extends(Derived, _super); + function Derived() { + return _super !== null && _super.apply(this, arguments) || this; + } + Derived.prototype.method = function (param) { + }; + return Derived; +}(Base)); +function overloadingFunction() { + return second.E.B; +} diff --git a/tests/baselines/reference/enumAssignmentCompat7.symbols b/tests/baselines/reference/enumAssignmentCompat7.symbols new file mode 100644 index 0000000000000..8cd0dd808a94a --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat7.symbols @@ -0,0 +1,58 @@ +//// [tests/cases/compiler/enumAssignmentCompat7.ts] //// + +=== enumAssignmentCompat7.ts === +namespace first { +>first : Symbol(first, Decl(enumAssignmentCompat7.ts, 0, 0)) + + export enum E { A = 1 } +>E : Symbol(E, Decl(enumAssignmentCompat7.ts, 0, 17)) +>A : Symbol(E.A, Decl(enumAssignmentCompat7.ts, 1, 19)) +} + +namespace second { +>second : Symbol(second, Decl(enumAssignmentCompat7.ts, 2, 1)) + + export enum E { A = 2 } +>E : Symbol(E, Decl(enumAssignmentCompat7.ts, 4, 18)) +>A : Symbol(E.A, Decl(enumAssignmentCompat7.ts, 5, 19)) +} + +class Base { +>Base : Symbol(Base, Decl(enumAssignmentCompat7.ts, 6, 1)) + + method(param: first.E) { +>method : Symbol(Base.method, Decl(enumAssignmentCompat7.ts, 8, 12)) +>param : Symbol(param, Decl(enumAssignmentCompat7.ts, 9, 11)) +>first : Symbol(first, Decl(enumAssignmentCompat7.ts, 0, 0)) +>E : Symbol(first.E, Decl(enumAssignmentCompat7.ts, 0, 17)) + + } +} + +class Derived extends Base { +>Derived : Symbol(Derived, Decl(enumAssignmentCompat7.ts, 12, 1)) +>Base : Symbol(Base, Decl(enumAssignmentCompat7.ts, 6, 1)) + + override method(param: second.E) { +>method : Symbol(Derived.method, Decl(enumAssignmentCompat7.ts, 14, 28)) +>param : Symbol(param, Decl(enumAssignmentCompat7.ts, 15, 20)) +>second : Symbol(second, Decl(enumAssignmentCompat7.ts, 2, 1)) +>E : Symbol(second.E, Decl(enumAssignmentCompat7.ts, 4, 18)) + } +} + +function overloadingFunction(): first.E +>overloadingFunction : Symbol(overloadingFunction, Decl(enumAssignmentCompat7.ts, 17, 1), Decl(enumAssignmentCompat7.ts, 19, 39)) +>first : Symbol(first, Decl(enumAssignmentCompat7.ts, 0, 0)) +>E : Symbol(first.E, Decl(enumAssignmentCompat7.ts, 0, 17)) + +function overloadingFunction(): second.E { +>overloadingFunction : Symbol(overloadingFunction, Decl(enumAssignmentCompat7.ts, 17, 1), Decl(enumAssignmentCompat7.ts, 19, 39)) +>second : Symbol(second, Decl(enumAssignmentCompat7.ts, 2, 1)) +>E : Symbol(second.E, Decl(enumAssignmentCompat7.ts, 4, 18)) + + return second.E.B +>second.E : Symbol(second.E, Decl(enumAssignmentCompat7.ts, 4, 18)) +>second : Symbol(second, Decl(enumAssignmentCompat7.ts, 2, 1)) +>E : Symbol(second.E, Decl(enumAssignmentCompat7.ts, 4, 18)) +} diff --git a/tests/baselines/reference/enumAssignmentCompat7.types b/tests/baselines/reference/enumAssignmentCompat7.types new file mode 100644 index 0000000000000..0445ae8147ac4 --- /dev/null +++ b/tests/baselines/reference/enumAssignmentCompat7.types @@ -0,0 +1,58 @@ +//// [tests/cases/compiler/enumAssignmentCompat7.ts] //// + +=== enumAssignmentCompat7.ts === +namespace first { +>first : typeof first + + export enum E { A = 1 } +>E : E +>A : E.A +>1 : 1 +} + +namespace second { +>second : typeof second + + export enum E { A = 2 } +>E : E +>A : E.A +>2 : 2 +} + +class Base { +>Base : Base + + method(param: first.E) { +>method : (param: first.E) => void +>param : first.E +>first : any + + } +} + +class Derived extends Base { +>Derived : Derived +>Base : Base + + override method(param: second.E) { +>method : (param: second.E) => void +>param : second.E +>second : any + } +} + +function overloadingFunction(): first.E +>overloadingFunction : () => first.E +>first : any + +function overloadingFunction(): second.E { +>overloadingFunction : () => first.E +>second : any + + return second.E.B +>second.E.B : any +>second.E : typeof second.E +>second : typeof second +>E : typeof second.E +>B : any +}