Skip to content

Commit 56578c5

Browse files
committed
Fix compiler crash on generics overload resolution failure reported by #61524
Replace `Debug.fail()` calls with proper error generation to prevent TypeScript compiler crashes when overload resolution fails for complex generic constraints, for example JSX elements. Problem -- The TypeScript compiler crashes with "Debug Failure. No error for last overload signature" when resolving certain complex generic constraints, e.g., JSX element types. This regression has existed since TypeScript 3.6 and affects many React/JSX projects. Root Cause -- When `getSignatureApplicabilityError()` returns no diagnostics for overload candidates, the compiler calls `Debug.fail()` instead of handling the edge case gracefully, causing an immediate crash. Solution -- - Replace `Debug.fail()` calls with fallback diagnostic generation - Generate appropriate error messages for unhandled overload resolution cases - Ensure compiler continues execution without crashing Related to #61524, #60229, #48636, #33133 Signed-off-by: moznion <[email protected]>
1 parent 2bc8933 commit 56578c5

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

src/compiler/checker.ts

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36603,7 +36603,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3660336603
}
3660436604
}
3660536605
else {
36606-
Debug.fail("No error for last overload signature");
36606+
// Fallback: Generate a generic error when no specific error can be determined
36607+
// This replaces the Debug.fail() to prevent compiler crashes
36608+
// See: https://github.com/microsoft/TypeScript/issues/61524
36609+
const fallbackChain = chainDiagnosticMessages(
36610+
/*details*/ undefined,
36611+
Diagnostics.No_overload_matches_this_call,
36612+
);
36613+
const errorNode = getErrorNodeForCallNode(node);
36614+
const fallbackDiag = createDiagnosticForNodeFromMessageChain(
36615+
getSourceFileOfNode(errorNode),
36616+
errorNode,
36617+
fallbackChain,
36618+
/*relatedInformation*/ undefined,
36619+
);
36620+
36621+
diagnostics.add(fallbackDiag);
3660736622
}
3660836623
}
3660936624
else {
@@ -36624,7 +36639,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3662436639
allDiagnostics.push(diags);
3662536640
}
3662636641
else {
36627-
Debug.fail("No error for 3 or fewer overload signatures");
36642+
// Fallback: Generate a generic error for this overload candidate
36643+
// This prevents crashes when processing multiple overload signatures
36644+
const fallbackChain = chainDiagnosticMessages(
36645+
/*details*/ undefined,
36646+
Diagnostics.Overload_0_of_1_2_gave_the_following_error,
36647+
i + 1,
36648+
candidates.length,
36649+
signatureToString(c),
36650+
);
36651+
const errorNode = getErrorNodeForCallNode(node);
36652+
const fallbackDiag = createDiagnosticForNodeFromMessageChain(
36653+
getSourceFileOfNode(errorNode),
36654+
errorNode,
36655+
fallbackChain,
36656+
/*relatedInformation*/ undefined,
36657+
);
36658+
allDiagnostics.push([fallbackDiag]);
3662836659
}
3662936660
i++;
3663036661
}

0 commit comments

Comments
 (0)