1

My goal is to write a function that will take an Rc<RefCell<&'a mut [u8]>> as an argument and return a struct that contains a reference to the inner slice, but I can't satisfy the borrow checker. My first attempt looked like this:

pub fn mk_buf_holder<'a>(buf: Rc<RefCell<&'a mut [u8]>>) -> BufHolder<'a> {
    BufHolder::<'a> { buf: buf.borrow_mut().deref_mut()}
}

But that doesn't work, of course, because the result of borrow_mut goes out of scope. My next attempt added extra members to the struct, just to keep around values that would otherwise be temporary. I thought that putting them into the struct would give them the same lifetime as buf, but the borrow checker disagrees. Here's the full example:

use std::cell::{Ref, RefCell, RefMut};
use std::ops::DerefMut;
use std::rc::Rc;

pub struct BufHolder<'a> {
    buf: &'a mut [u8],
    bufclone: Rc<RefCell<&'a mut [u8]>>,
    bufref: RefMut<'a, &'a mut[u8]>
}

pub fn mk_buf_holder<'a>(buf: Rc<RefCell<&'a mut [u8]>>) -> BufHolder<'a> {
    let bufclone = buf.clone();
    let bufref = bufclone.borrow_mut();
    BufHolder::<'a> { bufclone: bufclone,
                      buf: bufref.deref_mut(),
                      bufref: bufref }
}

The compiler still tells me that the result of borrow_mut() doesn't live long enough, even though I added it to the output structure. It's as if the compiler is copying into the output, instead of moving it. How can I fix this function?

error: `bufclone` does not live long enough
  --> src/main.rs:13:18
   |
13 |     let bufref = bufclone.borrow_mut();
   |                  ^^^^^^^^ does not live long enough
...
19 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 11:74...
  --> src/main.rs:11:75
   |
11 |   pub fn mk_buf_holder<'a>(buf: Rc<RefCell<&'a mut [u8]>>) -> BufHolder<'a> {
   |  ___________________________________________________________________________^ starting here...
12 | |     let bufclone = buf.clone();
13 | |     let bufref = bufclone.borrow_mut();
14 | |     BufHolder::<'a> {
15 | |         bufclone: bufclone,
16 | |         buf: bufref.deref_mut(),
17 | |         bufref: bufref,
18 | |     }
19 | | }
   | |_^ ...ending here

error: `bufref` does not live long enough
  --> src/main.rs:16:14
   |
16 |         buf: bufref.deref_mut(),
   |              ^^^^^^ does not live long enough
...
19 | }
   | - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the body at 11:74...
  --> src/main.rs:11:75
   |
11 |   pub fn mk_buf_holder<'a>(buf: Rc<RefCell<&'a mut [u8]>>) -> BufHolder<'a> {
   |  ___________________________________________________________________________^ starting here...
12 | |     let bufclone = buf.clone();
13 | |     let bufref = bufclone.borrow_mut();
14 | |     BufHolder::<'a> {
15 | |         bufclone: bufclone,
16 | |         buf: bufref.deref_mut(),
17 | |         bufref: bufref,
18 | |     }
19 | | }
   | |_^ ...ending here
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Alan Somers
  • 86
  • 1
  • 5
  • 1
    Are you sure this has anything to do with `Rc`? Perhaps a duplicate of [Returning the T borrowed from RefCell](http://stackoverflow.com/q/30281664/155423)? – Shepmaster Mar 18 '17 at 03:03
  • You probably also want to read [Why can't I store a value and a reference to that value in the same struct?](http://stackoverflow.com/q/32300132/155423) – Shepmaster Mar 18 '17 at 03:09
  • Thanks @Shepmaster, that second link was useful. I think that my fundamental problem is that I'm trying to store a naked reference in a struct that may be heap-allocated with an indeterminate lifetime. It works for simple test cases, but not for more complicated code where the compiler can't guarantee the lifetimes. I probably need to try to refactor the underlying library to not do that. – Alan Somers Mar 21 '17 at 02:24

0 Answers0