Move value and borrowed value into struct

Hi,

i'm trying to use a library, which has a function like do_something:

struct A;

impl A {
    fn do_something<'a, 'b:'a>(&'b self) -> &'a i32{
        &1
    }
}

struct B<'a> {
    a: A,
    i: &'a i32,
}

impl B<'_> {
    fn new<'a>() -> B<'a> {
        let a = A;
        let i = a.do_something();
        B {a, i}
    }
}

fn main() {
    let b = B::new();
    println!("{:?}", b.i);
}

As you can see I want to store A and the return value of do_something in a struct (B here).
However this does not seem possible:

error[E0515]: cannot return value referencing local variable `a`
  --> src/main.rs:18:9
   |
17 |         let i = a.do_something();
   |                 ---------------- `a` is borrowed here
18 |         B {a, i}
   |         ^^^^^^^^ returns a value referencing data owned by the current function

I am quite confused by this error, as this should be possible as far as I understand. I get that, the borrow of a in line 17 needs to outlive i according to the signature of do_something. However outliving is not enforced strictly (ref), and living equally as long is valid too. And this should be the case since a and i are moved into B.

Why doesn't this work? What am I missing? Can I do something about this?

You are not allowed to hold any references to a value when you move it. If you could, it would result in a dangling reference, which would be UB to access. Therefore, to hold both an A and its borrowed value, either have the caller store the A themself, or (less idiomatically) use a self-referencing crate such as ouroboros or self_cell.

Thank you for your answer :slight_smile:

Your suggestions work well from a practical standpoint and will be what I will do going forward.
Additionally "self-referencing struct" was the missing google term which hindered me to research this topic further.

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.