R22BREAKINGfunction

Return Type Never

Flags when a function's return type becomes 'never' (TypeScript) or '!' (Rust), indicating it now always throws or diverges.


Applies to

TypeScriptRust

Why it matters

A function returning never means it never successfully completes. It either always throws an error or enters an infinite loop. Any code after the call becomes unreachable.

Example

Before (returns string)
// handler.ts
export function handleError(err: Error): string {
  return `Error: ${err.message}`;
}
After (never returns)
// handler.ts (BREAKING)
export function handleError(err: Error): never {
  throw new FatalError(err.message);
  // function never returns
}

What you see in the terminal

$ npx dg check

  [BREAKING] handleError (signature_change)
  src/handler.ts:2
  Return type changed to 'never'. Function now always throws — code after this call is unreachable.

How detection works

The classifier checks if the new return type is 'never' (TypeScript) or '!' (Rust) and the old return type was not.

Real-world scenario

A graceful error handler is changed to always throw a FatalError. Callers that expected a returned error message and continued execution will encounter unreachable code.

Edge cases

  • In Rust, this is the '!' (diverging) return type
  • Only TypeScript and Rust have explicit 'never' types