Reputation: 55
(English is not my native language; please excuse typing errors.)
In my project thers is an error type:
pub type RvzResult<T> = Result<T, RvzError>;
#[derive(Error, Debug)]
pub enum RvzError {
// some error types...
,
OtherErr(Box<dyn Error>)
}
One day I had a Mutex
object and used it like this:
pub fn some_func() -> RvzResult<()> {
// ...
let lock = the_mutex.lock()?;
// ...
}
But rustc wasn't so happy:error[E0277]: '?' couldn't convert the error to 'RvzError'
I tried to impl From
trait like this:
impl <T> From<PoisonError<T>> for RvzError {
fn from(err: PoisonError<T>) -> Self {
Self::OtherErr(Box::new(err))
}
}
It failed:error[E0310]: the parameter type 'T' may not live long enough
Upvotes: 4
Views: 1161
Reputation: 43982
A PoisonError
is not just an error code, but has a special function: it allows you to bypass the lock-poisoning check and access the data anyway. The <T>
parameter of PoisonError is the lock guard object that it can be asked to return, so the PoisonError
in your function is a borrow of the_mutex
.
Therefore, it cannot be made into a Box<dyn Error>
(which is implicitly + 'static
) and should not be returned from some_func()
anyway. Instead, create a new error which doesn't try to contain the original PoisonError
value — either a variant of RvzError
:
impl<T> From<PoisonError<T>> for RvzError {
fn from(err: PoisonError<T>) -> Self {
Self::Poison
}
}
Or a boxed string error (using this impl):
impl<T> From<PoisonError<T>> for RvzError {
fn from(_: PoisonError<T>) -> Self {
Self::OtherErr(Box::<dyn Error>::from("PoisonError"))
}
}
Upvotes: 6