diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8e5c03560db3e..7ff5cb1cd5a05 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36603,7 +36603,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else { - Debug.fail("No error for last overload signature"); + // Fallback: Generate a generic error when no specific error can be determined + // This replaces the Debug.fail() to prevent compiler crashes + // See: https://github.com/microsoft/TypeScript/issues/61524 + const fallbackChain = chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.No_overload_matches_this_call, + ); + const errorNode = getErrorNodeForCallNode(node); + const fallbackDiag = createDiagnosticForNodeFromMessageChain( + getSourceFileOfNode(errorNode), + errorNode, + fallbackChain, + /*relatedInformation*/ undefined, + ); + + diagnostics.add(fallbackDiag); } } else { @@ -36624,7 +36639,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { allDiagnostics.push(diags); } else { - Debug.fail("No error for 3 or fewer overload signatures"); + // Fallback: Generate a generic error for this overload candidate + // This prevents crashes when processing multiple overload signatures + const fallbackChain = chainDiagnosticMessages( + /*details*/ undefined, + Diagnostics.Overload_0_of_1_2_gave_the_following_error, + i + 1, + candidates.length, + signatureToString(c), + ); + const errorNode = getErrorNodeForCallNode(node); + const fallbackDiag = createDiagnosticForNodeFromMessageChain( + getSourceFileOfNode(errorNode), + errorNode, + fallbackChain, + /*relatedInformation*/ undefined, + ); + allDiagnostics.push([fallbackDiag]); } i++; } diff --git a/tests/baselines/reference/issue61524DebugFailureCrash.errors.txt b/tests/baselines/reference/issue61524DebugFailureCrash.errors.txt new file mode 100644 index 0000000000000..28fa911c954e2 --- /dev/null +++ b/tests/baselines/reference/issue61524DebugFailureCrash.errors.txt @@ -0,0 +1,28 @@ +issue61524DebugFailureCrash.ts(10,37): error TS2550: Property 'entries' does not exist on type 'ObjectConstructor'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2017' or later. +issue61524DebugFailureCrash.ts(11,9): error TS2769: No overload matches this call. + + +==== issue61524DebugFailureCrash.ts (2 errors) ==== + // Exact reproduction from https://github.com/microsoft/TypeScript/issues/61524 + // This code causes "Debug Failure. No error for last overload signature" + + type Generic = T extends any[] ? T[number] : T[keyof T]; + + export function testFn>( + obj: A, + cb: (b: Generic>) => any + ) { + for (const [key, val] of Object.entries(obj)) { + ~~~~~~~ +!!! error TS2550: Property 'entries' does not exist on type 'ObjectConstructor'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2017' or later. + cb(val as Generic); + ~~ +!!! error TS2769: No overload matches this call. + } + } + + // Usage that triggers the crash + testFn( + { foo: "bar", num: 42 }, + (val) => console.log(val) // Type inference here causes the issue + ); \ No newline at end of file diff --git a/tests/baselines/reference/issue61524DebugFailureCrash.symbols b/tests/baselines/reference/issue61524DebugFailureCrash.symbols new file mode 100644 index 0000000000000..58a0ccdd7ba95 --- /dev/null +++ b/tests/baselines/reference/issue61524DebugFailureCrash.symbols @@ -0,0 +1,61 @@ +//// [tests/cases/compiler/issue61524DebugFailureCrash.ts] //// + +=== issue61524DebugFailureCrash.ts === +// Exact reproduction from https://github.com/microsoft/TypeScript/issues/61524 +// This code causes "Debug Failure. No error for last overload signature" + +type Generic = T extends any[] ? T[number] : T[keyof T]; +>Generic : Symbol(Generic, Decl(issue61524DebugFailureCrash.ts, 0, 0)) +>T : Symbol(T, Decl(issue61524DebugFailureCrash.ts, 3, 13)) +>T : Symbol(T, Decl(issue61524DebugFailureCrash.ts, 3, 13)) +>T : Symbol(T, Decl(issue61524DebugFailureCrash.ts, 3, 13)) +>T : Symbol(T, Decl(issue61524DebugFailureCrash.ts, 3, 13)) +>T : Symbol(T, Decl(issue61524DebugFailureCrash.ts, 3, 13)) + +export function testFn>( +>testFn : Symbol(testFn, Decl(issue61524DebugFailureCrash.ts, 3, 59)) +>A : Symbol(A, Decl(issue61524DebugFailureCrash.ts, 5, 23)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + obj: A, +>obj : Symbol(obj, Decl(issue61524DebugFailureCrash.ts, 5, 54)) +>A : Symbol(A, Decl(issue61524DebugFailureCrash.ts, 5, 23)) + + cb: (b: Generic>) => any +>cb : Symbol(cb, Decl(issue61524DebugFailureCrash.ts, 6, 11)) +>b : Symbol(b, Decl(issue61524DebugFailureCrash.ts, 7, 9)) +>Generic : Symbol(Generic, Decl(issue61524DebugFailureCrash.ts, 0, 0)) +>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --)) +>A : Symbol(A, Decl(issue61524DebugFailureCrash.ts, 5, 23)) + +) { + for (const [key, val] of Object.entries(obj)) { +>key : Symbol(key, Decl(issue61524DebugFailureCrash.ts, 9, 16)) +>val : Symbol(val, Decl(issue61524DebugFailureCrash.ts, 9, 20)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>obj : Symbol(obj, Decl(issue61524DebugFailureCrash.ts, 5, 54)) + + cb(val as Generic); +>cb : Symbol(cb, Decl(issue61524DebugFailureCrash.ts, 6, 11)) +>val : Symbol(val, Decl(issue61524DebugFailureCrash.ts, 9, 20)) +>Generic : Symbol(Generic, Decl(issue61524DebugFailureCrash.ts, 0, 0)) +>A : Symbol(A, Decl(issue61524DebugFailureCrash.ts, 5, 23)) + } +} + +// Usage that triggers the crash +testFn( +>testFn : Symbol(testFn, Decl(issue61524DebugFailureCrash.ts, 3, 59)) + + { foo: "bar", num: 42 }, +>foo : Symbol(foo, Decl(issue61524DebugFailureCrash.ts, 16, 5)) +>num : Symbol(num, Decl(issue61524DebugFailureCrash.ts, 16, 17)) + + (val) => console.log(val) // Type inference here causes the issue +>val : Symbol(val, Decl(issue61524DebugFailureCrash.ts, 17, 5)) +>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>console : Symbol(console, Decl(lib.dom.d.ts, --, --)) +>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --)) +>val : Symbol(val, Decl(issue61524DebugFailureCrash.ts, 17, 5)) + +); diff --git a/tests/baselines/reference/issue61524DebugFailureCrash.types b/tests/baselines/reference/issue61524DebugFailureCrash.types new file mode 100644 index 0000000000000..36312fb89e10f --- /dev/null +++ b/tests/baselines/reference/issue61524DebugFailureCrash.types @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/issue61524DebugFailureCrash.ts] //// + +=== issue61524DebugFailureCrash.ts === +// Exact reproduction from https://github.com/microsoft/TypeScript/issues/61524 +// This code causes "Debug Failure. No error for last overload signature" + +type Generic = T extends any[] ? T[number] : T[keyof T]; +>Generic : Generic +> : ^^^^^^^^^^ + +export function testFn>( +>testFn : >(obj: A, cb: (b: Generic>) => any) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ + + obj: A, +>obj : A +> : ^ + + cb: (b: Generic>) => any +>cb : (b: Generic>) => any +> : ^ ^^ ^^^^^ +>b : Generic> +> : ^^^^^^^^^^^^^^^^^^^ + +) { + for (const [key, val] of Object.entries(obj)) { +>key : any +> : ^^^ +>val : any +> : ^^^ +>Object.entries(obj) : any +> : ^^^ +>Object.entries : any +> : ^^^ +>Object : ObjectConstructor +> : ^^^^^^^^^^^^^^^^^ +>entries : any +> : ^^^ +>obj : A +> : ^ + + cb(val as Generic); +>cb(val as Generic) : any +> : ^^^ +>cb : (b: Generic>) => any +> : ^ ^^ ^^^^^ +>val as Generic : Generic +> : ^^^^^^^^^^ +>val : any +> : ^^^ + } +} + +// Usage that triggers the crash +testFn( +>testFn( { foo: "bar", num: 42 }, (val) => console.log(val) // Type inference here causes the issue) : void +> : ^^^^ +>testFn : >(obj: A, cb: (b: Generic>) => any) => void +> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^ + + { foo: "bar", num: 42 }, +>{ foo: "bar", num: 42 } : { foo: string; num: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>foo : string +> : ^^^^^^ +>"bar" : "bar" +> : ^^^^^ +>num : number +> : ^^^^^^ +>42 : 42 +> : ^^ + + (val) => console.log(val) // Type inference here causes the issue +>(val) => console.log(val) : (val: string | number | undefined) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>val : string | number | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>console.log(val) : void +> : ^^^^ +>console.log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>console : Console +> : ^^^^^^^ +>log : (...data: any[]) => void +> : ^^^^ ^^ ^^^^^ +>val : string | number | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +); diff --git a/tests/cases/compiler/issue61524DebugFailureCrash.ts b/tests/cases/compiler/issue61524DebugFailureCrash.ts new file mode 100644 index 0000000000000..4249ec0fe543d --- /dev/null +++ b/tests/cases/compiler/issue61524DebugFailureCrash.ts @@ -0,0 +1,22 @@ +// @strict: true +// @noEmit: true + +// Exact reproduction from https://github.com/microsoft/TypeScript/issues/61524 +// This code causes "Debug Failure. No error for last overload signature" + +type Generic = T extends any[] ? T[number] : T[keyof T]; + +export function testFn>( + obj: A, + cb: (b: Generic>) => any +) { + for (const [key, val] of Object.entries(obj)) { + cb(val as Generic); + } +} + +// Usage that triggers the crash +testFn( + { foo: "bar", num: 42 }, + (val) => console.log(val) // Type inference here causes the issue +); \ No newline at end of file