Cannot borrow `*buf` as mutable more than once at a time

Hello, I've just started learning Rust and I've been confused on ownership/reusing mutables. I'm used to other languages in which you can reuse objects multiple times without any issues.

Here is my code:

fn my_get_u8<'a>(&mut self, src: &'a mut Cursor<&'a mut Vec<u8>>) -> Result<u8, MyError> {
        if !src.has_remaining() {
            return Err(MyError::Incomplete);
        }
        Ok(src.get_u8())
    }

pub fn my_parse<'a>(
        &'a mut self,
        buf: &'a mut Cursor<&'a mut Vec<u8>>,
    ) -> BoxFuture<'a, Result<Frame, MyError>> {
        Box::pin(async move {
            match self.my_get_u8(buf)? {
                b'+' => {
                    let line = self.my_get_line(buf).await?.to_vec();
                    let string = String::from_utf8(line)?;
                    return Ok(Frame::Simple(string));
                }
                _ => unimplemented!(),
            }
        })
    }

The issue is that I'm using "buf" in the match statement and also when checking for '+', which causes multiple mutable borrows.
I've tried to use buf.clone() in the match statement, but another error message comes up saying:

"The method clone exists for mutable reference &'a mut std::io::Cursor<&'a mut std::vec::Vec<u8>>, but its trait bounds were not satisfied
method cannot be called on &'a mut std::io::Cursor<&'a mut std::vec::Vec<u8>> due to unsatisfied trait bounds"

Thanks for the help

In the signatures of my_get_u8 and my_parse, you're re-using a single lifetime parameter 'a in many places. This often leads to confusing errors, especially when the same lifetime appears multiple types in the same type, for example &'a mut Cursor<&'a mut Vec<u8>>. Signatures like these place unnecessary constraints on the implementation and usage of your functions, which can be removed by using fresh lifetime parameters where appropriate:

// don't need any named lifetimes here
fn my_get_u8(&mut self, src: &mut Cursor<&mut Vec<u8>>) -> Result<u8, MyError>

// here the returned future borrows from both `*self` and from `*buf`,
// so we need to "unify" the lifetimes of those two borrows
fn my_parse<'fut>(&'fut mut self, buf: &'fut mut Cursor<&mut Vec<u8>>) -> BoxFuture<'fut, Result<Frame, MyError>>

I'm also not sure about your use of Cursor<&mut Vec<u8>> here; it doesn't seem to offer any advantage over Cursor<Vec<u8>>, which is more conventional, and it might be causing problems of its own. In any case, you definitely don't want the same lifetime on the borrow of the Cursor and the borrow of the Vec.

Here's a playground where I've fixed up the snippet you posted, stubbing out the types and functions for which you didn't include a definition. (In the future, we can answer your questions faster if you include a play.rust-lang.org link that has all the necessary imports, definitions, etc., so we can skip right to reproducing and debugging the errors you're having trouble with.)

7 Likes

Thank you so much - that worked! I'll make sure to link a playground next ime.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.