Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rust: Borrow with moved ownership with same lifetime [duplicate]

Tags:

rust

ownership

I have some code like this

struct A<'a> {
    b: B,
    c: C<'a>,
}

struct B {}

struct C<'a> {
    b: &'a B
}

impl<'a> A<'a> {
    fn new() -> Self {
        let b = B {};

        Self {
            b,
            c: C { b: &b },
        }
    }
}

where I get the error

error[E0515]: cannot return value referencing local variable `b`
  --> src/dummy.rs:16:9
   |
16 | /         Self {
17 | |             b,
18 | |             c: C { b: &b },
   | |                       -- `b` is borrowed here
19 | |         }
   | |_________^ returns a value referencing data owned by the current function

error[E0382]: borrow of moved value: `b`
  --> src/dummy.rs:18:23
   |
14 |         let b = B {};
   |             - move occurs because `b` has type `B`, which does not implement the `Copy` trait
...
17 |             b,
   |             - value moved here
18 |             c: C { b: &b },
   |                       ^^ value borrowed here after move

Some errors have detailed explanations: E0382, E0515.
For more information about an error, try `rustc --explain E0382`.

I think I understand the error, that of course b has a transferred ownership to that new object of A and therefore it seems like there is no guarantee for the lifetime of the object of C when it borrows from B. However because the object of C has its ownership also transferred to the object of A, the lifetime of the object of C as well as b should be the same, right?

How can I express that in Rust that I can create objects of A where I have an object of B and an object of C that also references to that object of B as B and C will have the same lifetime (the one of A)?

like image 761
h345k34cr Avatar asked Dec 06 '25 07:12

h345k34cr


1 Answers

As pointed out in the comments and the duplicate question, you can't.

If you want to keep your current code structure, you are forced to use reference counters.

use std::{cell::RefCell, rc::Rc};

struct A {
    b: Rc<RefCell<B>>,
    c: C,
}

struct B {}

struct C {
    b: Rc<RefCell<B>>,
}

impl A {
    fn new() -> Self {
        let b = Rc::new(RefCell::new(B {}));

        Self {
            b: b.clone(),
            c: C { b },
        }
    }
}

However, I think it would be more benefitial to refactor your code structure to avoid this problem in the first place. This of course depends on the specific usecase.

like image 193
Finomnis Avatar answered Dec 08 '25 21:12

Finomnis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!