Sure, your function wants to return an Option<Error>, but read on a RWLock returns a LockResult<RwLockReadGuard<Error>>, which you then unwrap into a RwLockReadGuard<Error>, which is a different thing. You'll need turn it into an Option<Error>.
I think I see where this is going. You were using * to get out the error and wanted to return that. It won't work, since your errors aren't Copy, and your sync_error takes a reference to self. You might want to try returning an &Option<Error>
You can't leak a value protected by a lock into a plain reference (the point of the lock would be defeated if that were allowed). You need to return either the RwLockReadGuard<Error> or change your API to receive a closure from the caller to which you pass a reference of the Error.
If you want to hide the fact there's a RwLockReadGuard specifically, you can leverage impl Trait:
/// Get sync error
pub fn sync_error<'a>(&'a self) -> impl std::ops::Deref<Target=Option<Error>> + 'a {
self.sync_error.read().unwrap()
}
You can cause a deadlock if you hold the read lock and then try to acquire a write lock; some combination of this may panic instead. But this is just how RwLock is implemented, it’s not specific to sync_error().
In fact, you probably don’t want to hide the fact you’re holding a read lock behind an impl trait type - I thought you had some local operations you wanted to encapsulate, but if you’re holding locks across more code, you’ll want to be pretty explicit about it.