Compiler error E0515: "cannot move out of `X` because it is borrowed"

Hello.

I'm an absolute beginner in learning Rust.
Please, take a look at the following Rust code:

struct A {
    number: u32
}

impl A {
    pub fn new() -> Self {
        Self {number: 0}
    }

    fn get_number_ref(&self) -> &u32 {
        &self.number
    }
}

struct B<'a> {
    a: A,
    number_ref: & 'a u32
}

impl<'a> B<'a> {
    pub fn new() -> Self {
        let aobj = A::new();
        let number_ref = aobj.get_number_ref();
        
        Self {
            a: aobj,
            number_ref: number_ref
        }
    }
}

Here is the output of compiler:

error[E0515]: cannot return value referencing local variable `aobj`
  --> src/layer.rs:69:9
   |
67 |           let number_ref = aobj.get_number_ref();
   |                            --------------------- `aobj` is borrowed here
68 |           
69 | /         Self {
70 | |             a: aobj,
71 | |             number_ref: number_ref
72 | |         }
   | |_________^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `aobj` because it is borrowed
  --> src/layer.rs:70:16
   |
64 |   impl<'a> B<'a> {
   |        -- lifetime `'a` defined here
65 |       pub fn new() -> Self {
66 |           let aobj = A::new();
   |               ---- binding `aobj` declared here
67 |           let number_ref = aobj.get_number_ref();
   |                            --------------------- borrow of `aobj` occurs here
68 |           
69 | /         Self {
70 | |             a: aobj,
   | |                ^^^^ move out of `aobj` occurs here
71 | |             number_ref: number_ref
72 | |         }
   | |_________- returning this value requires that `aobj` is borrowed for `'a`

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

What I am trying to do, is to create an object A and then get a reference to its number field, and then store both the object A and the number reference into the newly created object B.
Unfortunately, this doesn't work, and the compiler outputs two errors: E0505, E0515.

I don't quite understand why this happens. I move the ownership of aobj into the object B in line:

        Self {
            a: aobj, <<<<
            number_ref: number_ref

And I expect it to work because there are no more borrowed references to aobj anywhere. I even tried to put the get_number_ref call into a separate scope to make sure it doesn't hold reference anymore, but it didn't help.

So could you please explain me where is my mistake?
Thank you!

Then what is number_ref? It's exactly a borrow of that field. (But if you actually read the compiler error, it tells you so much.)

As soon as you move the value (by returning it), the reference is instantly invalidated – so you would always get a dangling reference.

A self-referential type is not (usefully) possible in safe Rust. You'll have to redesign your data structure and separate borrowed data from its owner.

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.