I am trying to temporarily replace a reference of a structure inside of a block. However, even if I restore the original reference, the borrow checker is complaining about lifetime problems. The code that follows shows the problem:
// ExpensiveData is only a placeholder for a much more complex data structure
struct ExpensiveData(i32);
struct ReferenceToED<'a>(&'a mut ExpensiveData);
impl<'a> ReferenceToED<'a> {
fn new(content: &'a mut ExpensiveData) -> Self {
ReferenceToED(content)
}
fn replace(&mut self, new_content: &'a mut ExpensiveData) -> &'a mut ExpensiveData {
std::mem::replace(&mut self.0, new_content)
}
fn get_ref_ed(&self) -> &ExpensiveData {
self.0
}
// Other methods removed for clarity ...
}
fn check_ref_struct() {
let mut ed = ExpensiveData(2);
let mut ref_ed = ReferenceToED::new(&mut ed);
{
let mut ed = ExpensiveData(5);
// Remember the old reference And exchange it with a new one
let tmp = ref_ed.replace(&mut ed);
assert_eq!(5, ref_ed.get_ref_ed().0);
// Restore the old reference
ref_ed.replace(tmp);
assert_eq!(2, ref_ed.get_ref_ed().0);
}
// Although restored I get an error in this line
assert_eq!(2, ref_ed.get_ref_ed().0);
}
the error message is as follows:
error[E0597]: `ed` does not live long enough
--> src\lib.rs:29:34
|
29 | let tmp = ref_ed.replace(&mut ed);
| ^^^^^^^ borrowed value does not live long enough
...
35 | }
| - `ed` dropped here while still borrowed
...
38 | assert_eq!(3, ref_ed.get_ref_ed().0);
| ------ borrow later used here
Questions:
- How can I convince the borrow checker, that this is safe code? (Of cause besides using unsafe code)
- Is there a typical pattern to follow how to handle these type of problems?