Compiling playground v0.0.1 (/playground)
error[E0597]: `x` does not live long enough
--> src/lib.rs:11:5
|
11 | x.borrow().val
| ^---------
| |
| borrowed value does not live long enough
| a temporary with access to the borrow is created here ...
12 | }
| -
| |
| `x` dropped here while still borrowed
| ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Ref<'_, Foo>`
|
= note: the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
|
11 | let x = x.borrow().val; x
| ^^^^^^^ ^^^
Besides, can anyone help me understand what does this mean from above error message?
the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
It is a "feature" of rust 1.0. End of block expressions don't follow the intuitive order you would expect items to get dropped in. (A language change would break existing code.)
struct Dr(i32);
impl Dr { fn val(&self) -> i32 { self.0 } }
impl Drop for Dr {
fn drop(&mut self) { println!("drop {}", self.0); }
}
pub fn foo() -> i32 {
let _x = Dr(1);
let _y = Dr(2);
let _z = Dr(3);
Dr(4).val()
}
You borrow the wrapped (in RefCell) value val. But as the compiler suggests you try to use borrowed (from x) value after x get dropped. That's why the compiler says x does not live long enough.
The message
the temporary is part of an expression at the end of a block;
consider forcing this temporary to be dropped sooner...
is a suggestion what you could do if you want to return the wrapped value. Since i32 implements Copy you could save (copy) the val in another var and return it at the end of the function body. For example,
pub fn demo() -> i32 {
let x = RefCell::new(Foo { val: 10 });
let y = x.borrow().val;
y
}
or without y
pub fn demo() -> i32 {
let x = RefCell::new(Foo { val: 10 });
let x = x.borrow().val;
x
}