Something's definitely wrong here. Even this compiles!
fn parse<T: Default>() -> Option<T> {
Some(T::default())
}
fn main() {
let msg = match parse() {
Some(ok) => ok,
None => return,
};
println!("{:?}", msg);
}
This still compiles with msg: i32
, so I have no idea why it thinks that msg should be inferred as ()
. If I use println!("{}", msg);
then it complains about ()
not implementing Display
.
An even further simplified example also compiles:
fn parse()<T>() -> Option<T> {
println!("type used: {}", std::any::type_name::<T>());
None
}
fn main() {
let _v = match parse() {
Some(v) => v,
None => return,
};
}
If I remove the match
statement, it stops working. This can work with _v
being any type, and we can observe that it chooses ()
.
Maybe this has something to do with how return
expressions have their type inferred?
If you enable #![feature(never_type)]
, then it will infer that type instead (and complain about !
not implementing the traits required, if any):
#![feature(never_type)]
fn parse<T: Default>() -> Option<T> {
Some(T::default())
}
fn main() {
let _v = match parse() {
Some(v) => v,
None => return,
};
}
error[E0277]: the trait bound `!: std::default::Default` is not satisfied
--> src/main.rs:7:20
|
2 | fn parse<T: Default>() -> Option<T> {
| ----- ------- required by this bound in `parse`
...
7 | let _v = match parse() {
| ^^^^^ the trait `std::default::Default` is not implemented for `!`
|
= note: the trait is implemented for `()`. Possibly this error has been caused by changes to Rust's type-inference algorithm (see: https://github.com/rust-lang/rust/issues/48950 for more info). Consider whether you meant to use the type `()` here instead.