0

I've simplified the code and made a self-contained version of it as follows:

struct TakesRef<'a> {
    string_ref: &'a str,
}

impl<'a> TakesRef<'a> {
    fn new(string_ref: &'a str) -> TakesRef<'a> {
        TakesRef { string_ref }
    }
}

struct Wrapper<'a> {
    string: String,
    obj: TakesRef<'a>,
}

impl<'a> Wrapper<'a> {
    fn new(string: String) -> Wrapper<'a> {
        let obj = TakesRef::new(&string);
        Wrapper { obj, string }
    }
}

The error I get is:

error[E0515]: cannot return value referencing function parameter `string`
  --> src/lib.rs:19:9
   |
18 |         let obj = TakesRef::new(&string);
   |                                 ------- `string` is borrowed here
19 |         Wrapper { obj, string }
   |         ^^^^^^^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function

error[E0505]: cannot move out of `string` because it is borrowed
  --> src/lib.rs:19:24
   |
16 | impl<'a> Wrapper<'a> {
   |      -- lifetime `'a` defined here
17 |     fn new(string: String) -> Wrapper<'a> {
18 |         let obj = TakesRef::new(&string);
   |                                 ------- borrow of `string` occurs here
19 |         Wrapper { obj, string }
   |         ---------------^^^^^^--
   |         |              |
   |         |              move out of `string` occurs here
   |         returning this value requires that `string` is borrowed for `'a`

I can't change the definition of TakesRef since it is a library class. How can I design Wrapper to be able to store a TakesRef inside? I tried using the owned-ref and rental crates... as well as RefCell but I still can't figure out how to compile this code.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
therealtypon
  • 455
  • 2
  • 5
  • 12
  • I read the responses to that question - they don't help me. In my particular case, `TakesRef` is not code owned by me - its library code. I need a solution that doesn't require me to change the parameters of the problem, but solve it at the Wrapper level – therealtypon Mar 28 '19 at 02:47
  • 2
    The way I see it, the solution is not to have `string` and `obj` together (hence, abolish `Wrapper` and rethink the API), which is one of the first recommendations in the proposed duplicate target. – E_net4 Mar 28 '19 at 11:28
  • 1
    I've updated the duplicate with a selection of pre-existing Q&A that I found by searching Stack Overflow for "rental". The selected ones solve real problems, so they should be a good starting point, especially [this one](https://stackoverflow.com/a/50413062/155423), which mirrors your situation exactly. – Shepmaster Mar 28 '19 at 11:50

1 Answers1

-1

such self-referential structures is the exact reason of why std::pin has been introduced. You might want to check this RFC and this example from documentation.

Laney
  • 1,571
  • 9
  • 7
  • 1
    As described in the duplicate, pinning does not help you create a strict with a **reference** to itself. It only helps correctly use a raw pointer. – Shepmaster Mar 28 '19 at 11:37