1

I know this has been asked in different ways before, but I'm not finding anything that is clearing the fog for me. I have distilled my issue down to the code below, but I cannot figure out what I am doing wrong.

struct Container<'a, T> {
    input:  Vec<T>,
    work:   Vec<&'a T>
}

impl<'a,T> Container<'a, T> {

    fn new() -> Self {
        Container {
            input: Vec::new(),
            work: Vec::new()
        }
    }

    fn set( &'a mut self, _value : T ) {
        // elided for the moment
    }
}


fn main() {

    let mut c = Container::<i64>::new();

    // first one is ok
    c.set(3);
    // second one fails
    c.set(4);
}

The error is "error[E0499]: cannot borrow c as mutable more than once at a time". The first function call is fine, but the second fails.

Let me also point out two things that got me to this situation:

  1. This is the third implementation (lots of code elided of course). The first used raw pointers and works like a champ but seems not very Rust-like. The second used Rc<RefCell<>>'s and also worked like a champ but was significantly slower than the raw pointer version. Thus, the attempt to use references as a middle ground.

  2. Everything was peaches until I added the vector of references called 'work' into the container structure. That triggered the need for the lifetime annotations and ultimately the borrow checker complaining about the second call with the mutable structure.

So my question is how do I write this correctly? Surely the raw pointers were not the preferred solution.

cafce25
  • 15,907
  • 4
  • 25
  • 31

1 Answers1

4

You reuse the same lifetime telling the compiler you keep the mutable borrow on self for as long as self is around here:

impl<'a,T> Container<'a, T> {
    fn set( &'a mut self, _value : T ) {
    }
}

Just remove that extraneous lifetime on the self parameter:

impl<'a,T> Container<'a, T> {
    fn set(&mut self, _value : T ) {
    }
}

If you try to hold on to references of objects in input inside of work then that's not possible you should either stick to your solution with something reference counted (Rc/Arc) or store indices into input in work.

cafce25
  • 15,907
  • 4
  • 25
  • 31