Yes, that’s what I meant.
However, we’d have to explain to developers what this magic macro does, and, IMO, it would look very much like a band-aid.
Hey, here’s another idea: Can we restructure try! and FromError such that the return type no longer has to be specifically a Result, and impl FromError for ()?
Something like this:
macro_rules! try {
($expr:expr) => (match $expr {
$crate::result::Result::Ok(val) => val,
$crate::result::Result::Err(err) => {
//was: return $crate::result::Result::Err(
// $crate::error::FromError::from_error(err))
return $crate::error::FromError::from_error(err)
}
})
}
// back-compat with existing code
impl<T,E,F> FromError<F> for Result<T,E> where E:FromError<F> {
fn from_error(err:F) -> Self {
std::result::Result::Err(FromError::from_error(err))
}
}
impl<E> FromError<E> for () where E:Error {
fn from_error(err: E) -> () {
panic!(err.description().to_string());
}
}
Unfortunately, right now ‘impl<T,E,F> FromError<F> for Result<T,E>…’ above conflicts with ‘impl<E> FromError<E> for E’ from std.
I wonder if negative trait impls would help here? I.e. could we re-define the latter as ‘impl<E> FromError<E> for E where E:!FromError<E>’ ?