2
struct Context<'a> {
    ctx: &'a str
}

impl <'a> Context<'a> {
    pub fn new(s : &'a str) -> Self {
        Context { ctx : s}
    }
}

struct Runner<'a> {
    context: Context<'a>,
    content: Box<String>
}

impl<'a> Runner<'a> {
    fn new(f : Box<String>) -> Self {
        Runner {context: Context::new(&*f), content: f }
    }
}

Context holds the reference to some string slice, which is provided by the Runner. Runner holds the entire string and the context. The compiler complains (Link)

error[E0515]: cannot return value referencing local data `*f`
  --> src/main.rs:18:9
   |
18 |         Runner {context: Context::new(&*f), content: f }
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^
   |         |                             |
   |         |                             `*f` is borrowed here
   |         returns a value referencing data owned by the current function

error[E0505]: cannot move out of `f` because it is borrowed
  --> src/main.rs:18:54
   |
16 | impl<'a> Runner<'a> {
   |      -- lifetime `'a` defined here
17 |     fn new(f : Box<String>) -> Self {
18 |         Runner {context: Context::new(&*f), content: f }
   |         ---------------------------------------------^--
   |         |                             |              |
   |         |                             |              move out of `f` occurs here
   |         |                             borrow of `*f` occurs here
   |         returning this value requires that `*f` is borrowed for `'a`

error: aborting due to 2 previous errors

The problem is that even if Box<String> provides the address stability of the underlying string, Context wouldn't accept the reference to the String since it thinks the underlying String will be moved after content : f.

Is there a way to tell Rust compiler that the underlying reference of the Boxed value is safe even after moving the data?

Jaebum
  • 1,397
  • 1
  • 13
  • 33
  • 2
    Does this answer your question? [Why can't I store a value and a reference to that value in the same struct?](https://stackoverflow.com/questions/32300132/why-cant-i-store-a-value-and-a-reference-to-that-value-in-the-same-struct) – Jmb May 31 '21 at 07:39
  • 1
    No it does not. Even when Runner gets moved, the address of string that Box hold should not change. So I think it is different – Jaebum May 31 '21 at 07:47
  • 1
    One problem is that the compiler doesn't know that - as far borrow checking is concerned, `Box` is a container like any other. Allowing self-referential structs in some form is in the works (google polonius borrow checker), but it's not there yet. Currently the workaround is to either restructure your data so the references are decoupled from the values they borrow from (so that the values can clearly outlive the references), or to store indexes in `Context` and create the actual `&str` on demand, given a context/runner pair. – user4815162342 May 31 '21 at 09:10

0 Answers0