Skip to content

Commit

Permalink
Remove unnecessary error state capture
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Feb 7, 2022
1 parent 16b986b commit 1c69acb
Showing 1 changed file with 29 additions and 34 deletions.
63 changes: 29 additions & 34 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18342,47 +18342,43 @@ namespace ts {

traceUnionsOrIntersectionsTooLarge(source, target);

let result = Ternary.False;
const saveErrorInfo = captureErrorCalculationState();

if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) {
const skipCaching = source.flags & TypeFlags.Union && (source as UnionType).types.length < 4 && !(target.flags & TypeFlags.Union) ||
target.flags & TypeFlags.Union && (target as UnionType).types.length < 4 && !(source.flags & TypeFlags.StructuredOrInstantiable);
if (skipCaching) {
result = unionOrIntersectionRelatedTo(source, target, reportErrors, intersectionState);
let result = skipCaching ?
unionOrIntersectionRelatedTo(source, target, reportErrors, intersectionState) :
recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags);
// For certain combinations involving intersections and optional, excess, or mismatched properties we need
// an extra property check where the intersection is viewed as a single object. The following are motivating
// examples that all should be errors, but aren't without this extra property check:
//
// let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
//
// declare let wrong: { a: { y: string } };
// let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
//
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
// x = y; // Mismatched property in source intersection
// }
//
// We suppress recursive intersection property checks because they can generate lots of work when relating
// recursive intersections that are structurally similar but not exactly identical. See #37854.
if (result && !inPropertyCheck && (
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
inPropertyCheck = true;
result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags);
inPropertyCheck = false;
}
else if (result = recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags)) {
resetErrorInfo(saveErrorInfo);
if (result) {
return result;
}
}

// For certain combinations involving intersections and optional, excess, or mismatched properties we need
// an extra property check where the intersection is viewed as a single object. The following are motivating
// examples that all should be errors, but aren't without this extra property check:
//
// let obj: { a: { x: string } } & { c: number } = { a: { x: 'hello', y: 2 }, c: 5 }; // Nested excess property
//
// declare let wrong: { a: { y: string } };
// let weak: { a?: { x?: number } } & { c?: string } = wrong; // Nested weak object type
//
// function foo<T extends object>(x: { a?: string }, y: T & { a: boolean }) {
// x = y; // Mismatched property in source intersection
// }
//
// We suppress recursive intersection property checks because they can generate lots of work when relating
// recursive intersections that are structurally similar but not exactly identical. See #37854.
if (result && !inPropertyCheck && (
target.flags & TypeFlags.Intersection && (isPerformingExcessPropertyChecks || isPerformingCommonPropertyChecks) ||
isNonGenericObjectType(target) && !isArrayType(target) && !isTupleType(target) && source.flags & TypeFlags.Intersection && getApparentType(source).flags & TypeFlags.StructuredType && !some((source as IntersectionType).types, t => !!(getObjectFlags(t) & ObjectFlags.NonInferrableType)))) {
inPropertyCheck = true;
result &= recursiveTypeRelatedTo(source, target, reportErrors, IntersectionState.PropertyCheck, recursionFlags);
inPropertyCheck = false;
}

if (!result && reportErrors) {
if (reportErrors) {
reportErrorResults(originalSource, originalTarget, source, target, headMessage);
}
return result;
return Ternary.False;
}

function reportErrorResults(originalSource: Type, originalTarget: Type, source: Type, target: Type, headMessage: DiagnosticMessage | undefined) {
Expand Down Expand Up @@ -19946,7 +19942,6 @@ namespace ts {
}

let result = Ternary.True;
const saveErrorInfo = captureErrorCalculationState();
const incompatibleReporter = kind === SignatureKind.Construct ? reportIncompatibleConstructSignatureReturn : reportIncompatibleCallSignatureReturn;
const sourceObjectFlags = getObjectFlags(source);
const targetObjectFlags = getObjectFlags(target);
Expand Down Expand Up @@ -19985,6 +19980,7 @@ namespace ts {
}
else {
outer: for (const t of targetSignatures) {
const saveErrorInfo = captureErrorCalculationState();
// Only elaborate errors from the first failure
let shouldElaborateErrors = reportErrors;
for (const s of sourceSignatures) {
Expand All @@ -19996,7 +19992,6 @@ namespace ts {
}
shouldElaborateErrors = false;
}

if (shouldElaborateErrors) {
reportError(Diagnostics.Type_0_provides_no_match_for_the_signature_1,
typeToString(source),
Expand Down

0 comments on commit 1c69acb

Please sign in to comment.