error[E0597]: `x` does not live long enough
参照先が参照より先に破棄される場合に発生するエラー。
以下では、inside_val
と outside_ref
を比べると、前者が先に破棄される。
そのため、前者の参照は後者に代入できない。
fn main() {
let outside_ref;
{
let inside_val = 0;
outside_ref = &inside_val
}
dbg!(outside_ref);
}
error[E0597]: `inside_val` does not live long enough --> src\main.rs:6:23 | 5 | let inside_val = 0; | ---------- binding `inside_val` declared here 6 | outside_ref = &inside_val | ^^^^^^^^^^^ borrowed value does not live long enough 7 | } | - `inside_val` dropped here while still borrowed 8 | 9 | dbg!(outside_ref); | ----------- borrow later used here
以下では、use_static_ref
の引数は static
ライフタイムの参照型でなければならない。
にも関わらず、ローカルライフタイムの参照 &local
を指定している。
fn main() {
let local = 0;
use_static_ref(&local);
}
fn use_static_ref(_: &'static i32) {
// NOP.
}
error[E0597]: `local` does not live long enough --> src\main.rs:3:20 | 2 | let local = 0; | ----- binding `local` declared here 3 | use_static_ref(&local); | ---------------^^^^^^- | | | | | borrowed value does not live long enough | argument requires that `local` is borrowed for `'static` 4 | } | - `local` dropped here while still borrowed
Drop
トレイトの影響 (兄弟フィールドの参照防止)
詳しくは『Drop トレイトのライフタイムへの影響 - 兄弟フィールドの参照防止』を参照。
(注: Drop
トレイトを直接的に扱っていなくても考慮が必要。)
fn main() {
let mut data = MyData::default();
data.on_drop = Some(OnDrop(&data.id));
}
#[derive(Default)]
struct MyData<'a> {
id: i32,
on_drop: Option<OnDrop<'a>>,
}
struct OnDrop<'a>(&'a i32);
impl<'a> Drop for OnDrop<'a> {
fn drop(&mut self) {
println!("ID [{}] is drpoped.", self.0)
}
}
error[E0597]: `data.id` does not live long enough --> src\main.rs:3:38 | 2 | let mut data = MyData::default(); | -------- binding `data` declared here 3 | data.on_drop = Some(OnDrop(&data.id)); | ^^^^^^^^ borrowed value does not live long enough 4 | } | - | | | `data.id` dropped here while still borrowed | borrow might be used here, when `data` is dropped and runs the destructor for type `MyData<'_>`
Drop
トレイトの影響 (ブロック式の末尾)
詳しくは『Drop トレイトのライフタイムへの影響 - ブロック式の末尾処理』を参照。
(注: Drop
トレイトを直接的に扱っていなくても考慮が必要。)
以下では、OnDrop(&local)
がブロック式の末尾にある。しかし、その破棄による drop
が実行される時点で、local
はすでに破棄され使えなくなっている。
fn main() {
let val = {
let local = 42;
*OnDrop(&local).0
};
println!("{}", val);
}
struct OnDrop<'a>(&'a i32);
impl Drop for OnDrop<'_> {
fn drop(&mut self) {
println!("ID [{}] is drpoped.", self.0)
}
}
error[E0597]: `local` does not live long enough --> src\main.rs:4:11 | 3 | let local = 42; | ----- binding `local` declared here 4 | *OnDrop(&local).0 | -------^^^^^^- | | | | | borrowed value does not live long enough | a temporary with access to the borrow is created here ... 5 | }; | -- ... and the borrow might be used here, when that temporary is dropped and runs the `Drop` code for type `OnDrop` | | | `local` dropped here while still borrowed | = 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 | 4 | let x = *OnDrop(&local).0; x | +++++++ +++
note: due to current limitations in the borrow checker, this implies a `'static` lifetime
このパターンはエラーメッセージに上記の特徴的な注釈が含まれる。
詳しくは『E0597 - HRTB の機能制限』を参照。