One reason to define such a function could be satisfying a trait:
enum NoError {}
// necessary to allow unwrap() on Result<T, NoError>
impl fmt::Debug for NoError {
fn fmt(&self, &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {}
}
}
(Usually better to use ! for this, but not in all cases, and your reasoning seems to work just as well for functions taking &!. There’s a proposal to have ! magically impl all the things, but that won’t work for many traits, such as those with static methods.)
Also, it’s pretty easy for free generic functions to end up instantiated with arguments of uninhabited types. For example, in the following, futures::err is if E is uninhabited:
fn dumb_result_to_future<T, E>(r: Result<T, E>) -> futures::BoxFuture<T, E> {
match r {
Ok(t) => futures::ok(t).boxed(),
Err(e) => futures::err(e).boxed(),
}
}
But there’s no reason to forbid either example. The functions can’t actually be called without undefined behavior, but they never will be; they’re just there to satisfy the type system.