Using unimplemented!() in a function which returns impl trait

The following code does not work:

fn foo() -> impl std::fmt::Display { unimplemented!() }

That's sad, because I used to use unimplemented!() for all functions, which I don't care about in that moment, but is not possible, when I want to return an impl trait.

Is there a workaround? Is that something that could be done with a language change (RFC)?!

Doesn't surprise me. impl Trait still requires the compiler to know what the return type is, and unimplemented!() diverges. Just give the poor compiler a type.

1 Like

As for me, it was interesting to check this case and see the real error:

error[E0277]: `()` doesn't implement `std::fmt::Display`
 --> src/lib.rs:1:13
  |
1 | fn foo() -> impl std::fmt::Display { panic!() }
  |             ^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter

Why is the function returning ! (and, consequently, panic and unimplemented macros) treated as the one returning ()?

1 Like

! isn't a type. It's to types what NaN is to floats... kinda.

A function (or expression) can't evaluate to !, because ! means it doesn't evaluate to anything. But this function is defined to have a return type... so the compiler needs to give it one... and it's been told to infer it... but the body never returns, so... presumably it just gives up and assigns ().

1 Like

Thank you so much! You brought in the right idea :smiley:

never_type is not stabilized (yet)(again), but if you opt-in via #![feature(never_type)] it will work :heart:

So yes, it is possible with a nightly compiler!

2 Likes

The workaround for stable is use a if true else block. Just hope you can construct the type simply or it defeats the purpose (even more) of the unimplemented.

1 Like

No, ! is a type. There're functions in std which returns !, including process::abort, which absolutely makes sense as it never returns. And also, <String as FromStr>::Error will become !, so "foo".parse::<String>() returns Result<String, !>.

No, it's not a type. That's what never_type will change; emphasis on future tense. Currently, it's a thing you can have instead of a return type on functions.