@@ -21464,7 +21464,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2146421464 }
2146521465 const id = getSymbolId(sourceSymbol) + "," + getSymbolId(targetSymbol);
2146621466 const entry = enumRelation.get(id);
21467- if (entry !== undefined && !(!(entry & RelationComparisonResult.Reported) && entry & RelationComparisonResult.Failed && errorReporter)) {
21467+ if (entry !== undefined && !(entry & RelationComparisonResult.Failed && errorReporter)) {
2146821468 return !!(entry & RelationComparisonResult.Succeeded);
2146921469 }
2147021470 const targetEnumType = getTypeOfSymbol(targetSymbol);
@@ -21474,11 +21474,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2147421474 if (!targetProperty || !(targetProperty.flags & SymbolFlags.EnumMember)) {
2147521475 if (errorReporter) {
2147621476 errorReporter(Diagnostics.Property_0_is_missing_in_type_1, symbolName(sourceProperty), typeToString(getDeclaredTypeOfSymbol(targetSymbol), /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType));
21477- enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported);
21478- }
21479- else {
21480- enumRelation.set(id, RelationComparisonResult.Failed);
2148121477 }
21478+ enumRelation.set(id, RelationComparisonResult.Failed);
2148221479 return false;
2148321480 }
2148421481 const sourceValue = getEnumMemberValue(getDeclarationOfKind(sourceProperty, SyntaxKind.EnumMember)!).value;
@@ -21489,15 +21486,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2148921486
2149021487 // If we have 2 enums with *known* values that differ, they are incompatible.
2149121488 if (sourceValue !== undefined && targetValue !== undefined) {
21492- if (!errorReporter) {
21493- enumRelation.set(id, RelationComparisonResult.Failed);
21494- }
21495- else {
21489+ if (errorReporter) {
2149621490 const escapedSource = sourceIsString ? `"${escapeString(sourceValue)}"` : sourceValue;
2149721491 const escapedTarget = targetIsString ? `"${escapeString(targetValue)}"` : targetValue;
2149821492 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);
21499- enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported);
2150021493 }
21494+ enumRelation.set(id, RelationComparisonResult.Failed);
2150121495 return false;
2150221496 }
2150321497
@@ -21508,16 +21502,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2150821502 // Either way, we can assume that it's numeric.
2150921503 // If the other is a string, we have a mismatch in types.
2151021504 if (sourceIsString || targetIsString) {
21511- if (!errorReporter) {
21512- enumRelation.set(id, RelationComparisonResult.Failed);
21513- }
21514- else {
21505+ if (errorReporter) {
2151521506 const knownStringValue = sourceValue ?? targetValue;
2151621507 Debug.assert(typeof knownStringValue === "string");
2151721508 const escapedValue = `"${escapeString(knownStringValue)}"`;
2151821509 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);
21519- enumRelation.set(id, RelationComparisonResult.Failed | RelationComparisonResult.Reported);
2152021510 }
21511+ enumRelation.set(id, RelationComparisonResult.Failed);
2152121512 return false;
2152221513 }
2152321514 }
@@ -21716,7 +21707,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2171621707 if (overflow) {
2171721708 // Record this relation as having failed such that we don't attempt the overflowing operation again.
2171821709 const id = getRelationKey(source, target, /*intersectionState*/ IntersectionState.None, relation, /*ignoreConstraints*/ false);
21719- relation.set(id, RelationComparisonResult.Reported | RelationComparisonResult.Failed );
21710+ relation.set(id, RelationComparisonResult.Failed | (relationCount <= 0 ? RelationComparisonResult.ComplexityOverflow : RelationComparisonResult.StackDepthOverflow) );
2172021711 tracing?.instant(tracing.Phase.CheckTypes, "checkTypeRelatedTo_DepthLimit", { sourceId: source.id, targetId: target.id, depth: sourceDepth, targetDepth });
2172121712 const message = relationCount <= 0 ?
2172221713 Diagnostics.Excessive_complexity_comparing_types_0_and_1 :
@@ -22617,9 +22608,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2261722608 const id = getRelationKey(source, target, intersectionState, relation, /*ignoreConstraints*/ false);
2261822609 const entry = relation.get(id);
2261922610 if (entry !== undefined) {
22620- if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Reported )) {
22621- // We are elaborating errors and the cached result is an unreported failure. The result will be reported
22622- // as a failure, and should be updated as a reported failure by the bottom of this function .
22611+ if (reportErrors && entry & RelationComparisonResult.Failed && !(entry & RelationComparisonResult.Overflow )) {
22612+ // We are elaborating errors and the cached result is a failure not due to a comparison overflow,
22613+ // so we will do the comparison again to generate an error message .
2262322614 }
2262422615 else {
2262522616 if (outofbandVarianceMarkerHandler) {
@@ -22632,6 +22623,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2263222623 instantiateType(source, reportUnreliableMapper);
2263322624 }
2263422625 }
22626+ if (reportErrors && entry & RelationComparisonResult.Overflow) {
22627+ const message = entry & RelationComparisonResult.ComplexityOverflow ?
22628+ Diagnostics.Excessive_complexity_comparing_types_0_and_1 :
22629+ Diagnostics.Excessive_stack_depth_comparing_types_0_and_1;
22630+ reportError(message, typeToString(source), typeToString(target));
22631+ overrideNextErrorInfo++;
22632+ }
2263522633 return entry & RelationComparisonResult.Succeeded ? Ternary.True : Ternary.False;
2263622634 }
2263722635 }
@@ -22735,7 +22733,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2273522733 else {
2273622734 // A false result goes straight into global cache (when something is false under
2273722735 // assumptions it will also be false without assumptions)
22738- relation.set(id, (reportErrors ? RelationComparisonResult.Reported : 0) | RelationComparisonResult.Failed | propagatingVarianceFlags);
22736+ relation.set(id, RelationComparisonResult.Failed | propagatingVarianceFlags);
2273922737 relationCount--;
2274022738 resetMaybeStack(/*markAllAsSucceeded*/ false);
2274122739 }
0 commit comments