error[E0521]: borrowed data escapes outside of function
error[E0521]: borrowed data escapes outside of method
error[E0521]: borrowed data escapes outside of closure
『E0521 - 参照引数の流出』にサブタイプが関連する派生パターン。
可変参照には被参照型のサブタイプが波及しない。そのため、クロージャのライフタイム制約 (キャプチャ変数のライフタイム) が他のクロージャのそれと包含関係にあっても、それらの可変参照型どうしは互いに互換性がない。
以下では、inc
の型は &'v mut FnMut() + 'v
である。
しかし、関数 callback
には &'v mut FnMuyt + 'static
などが必要になる。
fn main() {
exec(&mut 0);
}
fn exec<'v>(val: &'v mut i32) {
let mut inc = || *val += 1;
callback(&mut inc);
}
fn callback(f: &mut (dyn FnMut() + 'static)) {
f();
}
error[E0521]: borrowed data escapes outside of function --> src\main.rs:7:5 | 5 | fn exec<'v>(val: &'v mut i32) { | -- --- `val` is a reference that is only valid in the function body | | | lifetime `'v` defined here 6 | let mut inc = || *val += 1; 7 | callback(&mut inc); | ^^^^^^^^^^^^^^^^^^ | | | `val` escapes the function body here | argument requires that `'v` must outlive `'static` | = note: requirement occurs because of a mutable reference to `(dyn FnMut() + 'static)` = note: mutable references are invariant over their type parameter = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
'static
ライフタイムの省略
省略された 'static
がエラーに関係するパターンもある。
以下では、type Action = dyn FnMut();
は type Action = dyn FnMut() + 'static;
と等価になるため、前のコードと同様のコンパイルエラーになる。
fn main() {
exec(&mut 0);
}
fn exec<'v>(val: &'v mut i32) {
let mut inc = || *val += 1;
callback(&mut inc);
}
fn callback(f: &mut Action) {
f();
}
type Action = dyn FnMut();
error[E0521]: borrowed data escapes outside of function --> src\main.rs:7:5 | 5 | fn exec<'v>(val: &'v mut i32) { | -- --- `val` is a reference that is only valid in the function body | | | lifetime `'v` defined here 6 | let mut inc = || *val += 1; 7 | callback(&mut inc); | ^^^^^^^^^^^^^^^^^^ | | | `val` escapes the function body here | argument requires that `'v` must outlive `'static` | = note: requirement occurs because of a mutable reference to `(dyn FnMut() + 'static)` = note: mutable references are invariant over their type parameter = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance