I have a if cfg!
ladder, where I want to set some variable to a &str
depending on the target operating system. Since I have not yet tested anything on MacOS I opted to evaluate one member of a tuple struct to unimplemented!()
, which has the type !
which I thought always coerces to any other type. This, however does not compile with the error in the title. Here is the full code:
let (prefix_to_remove, file_ext_change) = if cfg!(target_os = "windows") {
("", (".dll", ".mexw64"))
} else if cfg!(target_os = "linux") {
("lib", (".so", ".mexa64"))
} else if cfg!(target_os = "macos") {
(unimplemented!("MacOS dynamic link library file prefix") , (".dylib", ".mexmeci64"))
} else {
panic!("Unknown target os")
};
The whole error message:
error[E0308]: `if` and `else` have incompatible types
--> xtask/src/test.rs:63:12
|
61 | } else if cfg!(target_os = "linux") {
| _____________-
62 | | ("lib", (".so", ".mexa64"))
| | --------------------------- expected because of this
63 | | } else if cfg!(target_os = "macos") {
| | ____________^
64 | || (unimplemented!("MacOS dynamic link library file prefix") , (".dylib", ".mexmeci64"))
65 | || } else {
66 | || panic!("Unknown target os")
67 | || };
| || ^
| ||_____|
| |_____`if` and `else` have incompatible types
| expected `&str`, found `!`
|
= note: expected tuple `(&str, (&str, &str))`
found tuple `(!, (&str, &str))`
I can circumvent the issue with unimplemented!() as _
, but this is warned against since the cast is unreachable. It is also possible to replace the whole tuple struct expression with an unimplemented!(...)
, which then works fine and apparently coerces as expected.
Is the failure to coerce when the never-type is nested inside another type expected and/or wanted behaviour or could it be made to work? At least for me the current behaviour is surprising.
Maybe this ties together with the never type initiative, I am not sure.