Own a value and its inner reference

Is there a way to do something like the following?

struct Foo<'a> {
    bar: Bar<'a>,
    bar_value: &'a u32
}

struct Bar<'b> {
    value: &'b u32
}

impl <'a> Foo<'a> {
    pub fn new(bar: Bar<'a>) -> Self {
        Self {
            bar,
            bar_value: bar.value
        }
    }
}

It compiles if you swap the order:

impl<'a> Foo<'a> {
    pub fn new(bar: Bar<'a>) -> Self {
        Self {
            bar_value: bar.value,
            bar,
        }
    }
}

The other order didn't work because the first line moves bar, but if you swap them, then the reference can be copied first before bar is moved.

3 Likes

hrmf... I tried that in my actual code but it's not working :confused:

code:

pub struct State<'a, D> {
    pub deps: D,
    pub env: Env,
    pub config: Config<'a>,
    _vamm_curve: Cell<Option<VammCurve>>,
}

impl <'a> State<'a, DepsMut<'a>> {
    pub fn new_mut(deps: DepsMut<'a>, env: Env) -> Self {
        Self {
            //deps.storage is &mut dyn Storage
            config: Config::new(deps.storage),
            deps,
            env,
            _vamm_curve: Cell::new(None),
        }
    }
}

error:

38 |   impl <'a> State<'a, DepsMut<'a>> {
   |         -- lifetime `'a` defined here
39 |       pub fn new_mut(deps: DepsMut<'a>, env: Env) -> Self {
40 | /         Self {
41 | |             //deps.storage is &mut dyn Storage
42 | |             config: Config::new(deps.storage),
   | |                                 ------------ borrow of `*deps.storage` occurs here
43 | |             deps,
   | |             ^^^^ move out of `deps` occurs here
44 | |             env,
45 | |             _vamm_curve: Cell::new(None),
46 | |         }
   | |_________- returning this value requires that `*deps.storage` is borrowed for `'a`

For more information about this error, try `rustc --explain E0505`.

You can't if the reference is mutable. Mutable references must be unique.

Sorry- missed a detail there, Config is only taking a &dyn Storage, not &mut dyn Storage

Which is I guess what through me off, since even though I'm getting a regular reference, DepsMut still can't "hand it out" in this case... bummer

Even if it's only mutable in one of the places, you still can't. Mutable references must have exclusive access to their target.

2 Likes