Open
Description
Consider the following code:
struct Foo();
fn bar(foo_ref: &'static mut Foo) {
let mut c = move || {
foo(foo_ref);
};
c();
}
fn foo(foo_ref: &'static mut Foo) {}
fn main() {}
It fails to compile on both nightly and stable:
error: lifetime may not live long enough
--> src/main.rs:5:9
|
4 | let mut c = move || {
| ------- lifetime `'1` represents this closure's body
5 | foo(foo_ref);
| ^^^^^^^^^^^^ argument requires that `'1` must outlive `'static`
|
= note: closure implements `FnMut`, so references to captured variables can't escape the closure
If I'm reading the error correctly, this is because Rust tries to implement FnMut
for the closure. However, since the closure consumes the &'static mut Foo
, it can only implement FnOnce
. Indeed, I can "manually" create such a closure on nightly:
#![feature(unboxed_closures)]
#![feature(fn_traits)]
struct Foo();
fn bar(foo_ref: &'static mut Foo) {
let c = ManualClosure { foo_ref };
c();
}
fn foo(foo_ref: &'static mut Foo) {}
struct ManualClosure {
foo_ref: &'static mut Foo,
}
impl FnOnce<()> for ManualClosure {
type Output = ();
extern "rust-call" fn call_once(self, args: ()) -> Self::Output {
foo(self.foo_ref);
}
}
I would expect the original code to work pretty much the same, with c
being FnOnce
but not FnMut
. Is this a bug?