'Decoupling ownership from vector

I'm creating factory methods for objects with shared references. The compiler cannot see that the objects from a Vec are not referenced outside the local scope, and that the newly created objects are not linked to the original objects.

How do I get around this issue, what am I missing?

#[derive(Debug)]
pub struct A {}

pub struct B<'b> {
    a: &'b A,
}

impl<'b> B<'b> {
    pub fn new(a: &'b A) -> B {
        B { a: a }
    }

    pub fn combine(&self, _: &B) -> B {
        B::new(self.a)
    }
}

pub fn main() {
    let a: A = A {};

    let mut v1: Vec<B> = vec![];
    v1.push(B::new(&a));
    v1.push(B::new(&a));

    let mut v2: Vec<B> = vec![];
    {
        let b1 = &v1[0]; // << Mutable borrow occurs here - why?
        let b2 = &v1[1];
        let c = b1.combine(&b2);
        v2.push(c)
    }
    v1.clear(); // Error: Cannot borrow due to mutable borrow above
    println!("{:?}", v2[0].a);
}
error[E0502]: cannot borrow `v1` as mutable because it is also borrowed as immutable
  --> src/main.rs:32:5
   |
27 |         let b1 = &v1[0]; // << Mutable borrow occurs here - why?
   |                   -- immutable borrow occurs here
...
32 |     v1.clear(); // Error: Cannot borrow due to mutable borrow above
   |     ^^^^^^^^^^ mutable borrow occurs here
33 |     println!("{:?}", v2[0].a);
   |                      -- immutable borrow later used here

No, sorry, I still do not quite get it.

Here is an even simpler example, without vectors:

    let a:A = A {  };
    
    let mut b1 = B::new(&a);
    let mut b2 = B::new(&a);
    
    let c = &b1.combine(&b2);
    //      ^^^ This creates a mutable reference to b1. How to avoid?
    b1 = B::new(&a);
    b2 = B::new(&a);
    
    println!("{:?}",c.a);

For some reason, the method call on the object will make the compiler assume that I have a reference to the object, despite c having no reference to b1. How do I get around that?

How can I declare the combine()-method to be immutable?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source