Issue with mut/non-mut borrowing and lifetimes

Hi,
I have a situation like this:

fn dispatch(mut pdb: &mut pdbtbx::PDB) -> Result<(), Box<dyn Error>> {
...
    let list: &String = "1,2,3,4".to_string();
    let residue_list: Vec<(isize, Option<&str>)> = parse_residue_list(list, &pdb)?;
    match [something] {
    [some_match] => edit_qm_residues(pdb, 1, residue_list)?,
    }
...
}

fn parse_residue_list<'a>(input: &'a str, pdb: &'a PDB) 
    -> Result<Vec<(isize, Option<&'a str>)>, Box<dyn Error>> {
   [parse stuff]
}

This code won't compile because I'm borrowing mutably and immutably at the same time. parse_residue_list takes an immutable reference whereas edit_qm_residues takes a mutable reference to the PDB struct. The only way I have been able to make it work is via cloning but that's pretty expensive here and I want to avoid that.
As I understand it, this has to do with the fact that the parse_residue_list function has a lifetime annotation because I seem to remember the code to work fine when that wasn't in place (which was before I cleaned up the function to work like it now does).
I've been thinking of using Rc pointers or RefCells but I haven't been able to make it work.
I would be grateful to anyone who can explain to me what might be done here and how it relates to the lifetime annotations because I still haven't understood that very well.

I suggest starting with:

- fn parse_residue_list<'a>(input: &'a str, pdb: &'a PDB) 
+ fn parse_residue_list<'a>(input: &'a str, pdb: &'_ PDB) 
    -> Result<Vec<(isize, Option<&'a str>)>, Box<dyn Error>> {
     [parse stuff]
  }

to express that the returned stuff does not keep borrowing PDB.

  • Should that error, post the error message, and more code context, since you'd be trying to keep borrowing a PDB while also mutating it.
1 Like

That results in an error tellling me "explicit lifetime required in the type of PDB". Looking at the function that makes sense I suppose since it returns a vector that does borrow from both input and pdb. Maybe my recollections are wrong and the function used to not depend on the PDB struct.
In that case, it's just me trying to borrow mutably and immutably at the same time, I suppose but I haven't been able to figure out a way to not do that without cloning.
What more context would be helpful here?

The parse function needs to return owned data to detach its lifetime from the PDB and make future PDB edit operations safe. Consider using either String or Cow<str> inside the vector, or yes Rc<str> is also an option.

I decided using Option<String> would be the most straightforward way to go and it seems to work. Now I've gotta fix my tests but that shouldn't be too hard, hopefully.
Thanks for your input!

Hmm, I think you should be able to create a single producer single consumer channel, and drop the producer side to close out the grpc stream.

I'm afraid, I really don't know what that means. Could you elaborate?

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.