0

Suppose I have a function which returns a struct that contains a reference like so:

struct Foo<'a> {
    x: &'a i32,
}

fn makeFoo<'a>() -> Foo<'a> {
    let x = 30;
    return Foo{x: &x}
}

The problem with the above code is that x will get dropped at the end of makeFoo which causes the struct reference to outlast it.

Is there a way to transfer the lifetime of x to calling function? In this case, the obvious solution is to redefine the struct and have it take ownership of x directly, but that isn't always possible (in my case the struct is defined in a library I don't control). What is the idiomatic way to solve this problem in rust?

Edit:

While the question is superficially similar to the linked one, it is different. The problem is one of creating variables the refs of which are returned inside of a struct, and then finding a way to tie the lifetime of the refs to the struct itself (without modifying it in this case). This may be impossible, but I would be surprised to learn that this is the case, since I imagine encountering structs which hold references to values is not uncommon in third party libraries.

For example, one would think that the following might be sufficient:

struct Foo<'a> {
    x: &'a i32,
}

fn makeFoo<'a>() -> (Foo<'a>, i32) {
    let x = 30;
    return (Foo{x: &x}, x)
}

if the compiler were clever enough to establish that the value underlying the reference &x is transferred to the caller upon return (though this does not appear to be the case).

curious
  • 133
  • 7
  • _"Is there a way to transfer the lifetime of x to calling function?"_ -- you can't "transfer" a lifetime. The lifetime is the scope of the variable that you are borrowing. – Peter Hall Mar 15 '23 at 02:50
  • If you can't change the library - and if it seems like a well-designed library - perhaps look at why it is designed this way, and how they expect you to use it. – Peter Hall Mar 15 '23 at 02:52
  • Or... replace `let x = 30;` with `let x = &30;`. That will have the static lifetime. – Peter Hall Mar 15 '23 at 02:53
  • `you can't "transfer" a lifetime. The lifetime is the scope of the variable that you are borrowing`: Yes, which is why if I was asking if there was a way to somehow hoist the scope to the calling function. Evidently not. `Or... replace let x = 30; with let x = &30;. That will have the static lifetime.`: This won't work if x can't be represented as a literal, or is a complex type. – curious Mar 15 '23 at 03:23
  • 1
    You can 'hoist' it to the calling function by defining it there and passing in a reference. Your proposed tuple is exactly a self referential struct as from [this question](https://stackoverflow.com/q/32300132/442760) – cafce25 Mar 15 '23 at 08:11

0 Answers0