sorry I coudn't think of a more concise title to better describe the problem, probably because I don't really understand the problem.
I was writing wrapper types for some third party library, which has a Resource type and a guard type to actually call the methods on. I want to wrap both of them to provide some extra check or transformation for certain operations.
the code looks like:
// these are from extern crate
struct Resource {}
struct Token<'a> {
resource: &'a mut Resource,
}
impl Resource {
fn try_grant<'a>(&'a mut self) -> Option<Token<'a>> {
// check availability
Some(Token {
resource: self
})
}
}
// these are my wrappers
struct ResourceWrapper {
inner: Resource,
}
struct TokenWrapper<'a> {
inner: Token<'a>,
}
impl ResourceWrapper {
fn grant<'a>(&'a mut self) -> TokenWrapper<'a> {
if let Some(token) = self.inner.try_grant() {
return TokenWrapper {
inner: token,
}
}
self.wait_ready();
if let Some(token) = self.inner.try_grant() {
TokenWrapper {
inner: token,
}
} else {
unreachable!()
}
}
fn wait_ready(&mut self) {
// locking and synchronization stuff
}
}
this code gives: error[E0499]: cannot borrow `*self` as mutable more than once at a time --- specifically, the line return TokenWrapper{...} under the if let branch prevents self from being used again. I really don't understand why it is the case, and how to express this (prefer safe code, but unsafe is acceptable if I have to). any suggestions are appreciated.
here is the same code snippet on rust playground if you want to see the actual compiler message or play with it
It's a known limitation to borrow checker. It happens when you return a mutable reference in one branch and use it in another. The easy way out is just using unsafe.