I have an operation that I'd like to err out on invalid input, otherwise create one of two structs which implement a trait. I'm sure this isn't a shortcoming of the compiler but rather my poor understanding of the type system and I'm looking for some input. This is a simplified version of my code but the core issue remains.
pub trait Action { ... }
pub struct TaxonomySpotSearch { ... }
impl Action for TaxonomySpotSearch { ... }
pub struct SavedSearch { ... }
impl Action for SavedSearch { ... }
fn do_something() -> Result<i32, ArgError> {
let foo: Box<dyn Action> = match Some(1) {
Some(0) => Ok(Box::new(TaxonomySpotSearch::new())),
Some(1) => Ok(Box::new(SavedSpotSearch::new())),
_ => Err(ArgError::NoSubCommand)
}?;
Ok(...)
}
However, I'm getting the classic E0308 "match arms have incompatible types" error where the compiler is inferring the type of foo
as the return value of the first match arm.
error[E0308]: `match` arms have incompatible types
--> src/main.rs:127:20
|
125 | let foo: Box<dyn Action> = match Some(1) {
| ________________________________-
126 | | Some(0) => Ok(Box::new(TaxonomySpotSearch::new())),
| | --------------------------------------- this is found to be of type `Result<Box<TaxonomySpotSearch>, _>`
127 | | Some(1) => Ok(Box::new(SavedSpotSearch::new())),
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `TaxonomySpotSearch`, found struct `SavedSpotSearch`
128 | | _ => Err(ArgError::NoSubCommand)
129 | | }?;
| |_____- `match` arms have incompatible types
|
= note: expected enum `Result<Box<TaxonomySpotSearch>, _>`
found enum `Result<Box<SavedSpotSearch>, _>`
Am I doing something wrong or is this really a limitation of the type system? I would expect the addition of the explicit type annotation to resolve this, yet here I am.