0

I am facing a need to create a self-referential structure Foo, and to date I've managed to come up with the following:

use std::pin::Pin;

struct Foo<'a> {
    x: u32,
    xp: Option<&'a u32>,
}

impl From<u32> for Pin<Box<Foo<'_>>> {
    fn from(x: u32) -> Self {
        let mut res = Box::pin(Foo { x, xp: None });
        let x = &res.x;
        let xp = &mut res.xp;
        *xp = Some(x);
        res
    }
}

That looks like a book example of splitting a borrow, but I am probably missing a point here, because the compiler complains with a message that does not make it transparent what exactly is wrong:

error[E0502]: cannot borrow `res` as mutable because it is also borrowed as immutable
  --> src/lib.rs:12:23
   |
9  |     fn from(x: u32) -> Self {
   |                        ---- return type is Pin<Box<Foo<'1>>>
10 |         let mut res = Box::pin(Foo { x, xp: None });
11 |         let x = &res.x;
   |                  --- immutable borrow occurs here
12 |         let xp = &mut res.xp;
   |                       ^^^ mutable borrow occurs here
13 |         *xp = Some(x);
14 |         res
   |         --- returning this value requires that `res` is borrowed for `'1`

I am aware of this question, but why does the compiler thinks that a move of the referred to data occurs here?

Is it possible to express the same idea, probably using unsafe code?

Mike Land
  • 436
  • 4
  • 15
  • @kaya3 I am sure I am using `Pin` the wrong way, but that's what I tried to express: the data behind the `res` pointer should not be moved – Mike Land Dec 29 '22 at 21:29
  • You cannot write your own self-referential types in pure safe Rust, since there's no "self-referential lifetime". The `Pin` type helps dealing with self-referential types by disallowing them to move, but it does not make it possible to express such types in safe Rust, it still requires the types to either use unsafe code or be generated by the compiler. – Frxstrem Dec 29 '22 at 21:50
  • @Frxstrem As stated, I hoped there is a zero-dependency solution using unsafe code – Mike Land Dec 30 '22 at 09:08

0 Answers0