Question about never type and closures

I was wondering why one of the following function compiles and one doesn't:

fn exit() -> ! {

pub fn okay() {
    let _: u8 = Some(42).unwrap_or_else(|| exit());

// Error: type mismatch resolving `<fn() -> ! {exit} as std::ops::FnOnce<()>>::Output == {integer}`
pub fn not_okay() {
    let _: u8 = Some(42).unwrap_or_else(exit);

Shouldn't the second one be okay since the types of both closures is FnOnce() -> !?

Thanks in advance!

In the okay case, the type of closure is in fact impl FnOnce() -> {integer}, since this is dictated by the unwrap_or_else signature. But inside it, exit's return type of never can coerce to the required type of {integer}. When you're using exit directly, there's no "bare" never type, so there's nothing to coerce, hence the mismatch.


If you want to perform that eta reduction, you can write exit as follows (coercing within the body of the exit function itself, rather than coercing when calling it):

fn exit<T> () -> T


//              exit::<_>
//              exit::<u8>

will work.


This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.