Solving borrow checker issue with self


#1

Hi

So I have code like

struct Pipeline<'a> {
name : String,
elements : Vec<&'a Element>,
}

impl<'a> Pipeline<'a> {

pub fn new(name: String) -> Self {
    Pipeline{
        name : name,
        elements : Vec::new(),
        data_queue : Vec::new(),
    }
}
pub fn add_element(&mut self, element : &'a Element) -> PipelineResult<&'a Element> {
    let found_element = (&self).find_element(element.get_name());
    
    match found_element {
        Some(found_element) => {
            debug!("Element with that name already exits in pipeline");
            return Err(PipeLineError::ELEMENT_ALREADY_EXISTS)
        }
        None => {
            self.elements.push(element);
            return Ok(element)  
        }
    };
}
pub fn find_element(&self, name : &str) -> Option<&&Element> {
    return self.elements.iter().find(|&&e| e.get_name() == name);
}

}

This gives the error

error[E0502]: cannot borrow self.elements as mutable because self is also borrowed as immutable
–> src/lib.rs:151:17
|
141 | let found_element = (&self).find_element(element.get_name());
| ---- immutable borrow occurs here

151 | self.elements.push(element);
| ^^^^^^^^^^^^^ mutable borrow occurs here

155 | }
| - immutable borrow ends here

Now I can understand the error but I just don’t know how to solve this situation .
What’s the usual way of dealing with this ?

Thanks


#2

Something like this:

pub fn add_element(&mut self, element : &'a Element) -> PipelineResult<&'a Element> {
    
    if let Some(found_element) = self.find_element(element.get_name()) {
            debug!("Element with that name already exits in pipeline");
            return Err(PipeLineError::ELEMENT_ALREADY_EXISTS)
   }; // <-- immutable borrow ends here
   // now you can re-borrow mutably
   self.elements.push(element);
   Ok(element) 
}

#3

Thank you so much. Works Great.
You would not believe how long I spent on that :slight_smile:


#4

No worries - becoming good friends with the borrow checker (and learning of its limitations, like lexical borrow scopes) is a rite of passage :slight_smile:.