Open ijackson opened 3 years ago
@rustbot modify labels to +A-lifetimes +A-traits -T-lang +T-compiler
As far as I can tell, there is no way to write a trait bound for this closure:
let mut k : usize = 0; let mut closure = || &mut k;
You can't write a trait bound for this because it already fails to compile:
error: captured variable cannot escape `FnMut` closure body
--> src/main.rs:4:26
|
3 | let mut k : usize = 0;
| ----- variable defined here
4 | let mut closure = || &mut k;
| - ^^^^^-
| | | |
| | | variable captured here
| | returns a reference to a captured variable which escapes the closure body
| inferred to be a `FnMut` closure
|
= note: `FnMut` closures only have access to their captured variables while they are executing...
= note: ...therefore, they cannot allow references to captured variables to escape
Hi, thanks for looking at this.
You can't write a trait bound for this because it already fails to compile:
= note: `FnMut` closures only have access to their captured variables while they are executing... = note: ...therefore, they cannot allow references to captured variables to escape
Oh! How sad. I don't know how in all my attempts I never managed to see that message, which explains the problem very nicely.
I don't think there is anything incoherent about this program - see my example simulating a closure with a struct. It would also be nice if one could impl FnMut
for that struct.
But yes I was wrong to call this a bug. Thanks for adjusting the labels and sorry for the noise. (I had a look through other issues relating to closures and didn't find anything relevant.)
It seems like this was never a real problem and should be closed?
As far as I can tell, there is no way to write a trait bound for this closure:
The closure's call function takes
&'something mut self
, but there is no way to talk about the lifetimesomething
. But it is necessary to talk about 'something because the return value borrows from it.The following program compiles and works, using
transmute
to promise that the lifetimes are fine. Without the transmute, and removing the spurious'static
, there does not seem to be a way to write the bound onF
.https://gist.github.com/rust-play/dd4471240c781ec26d07139045097b26
I hope I am right in describing this as a bug, although it seems like it's an API/language bug :-/. I tried various approaches, including
for<>
, and various lifetime annotation approaches, without anything resembling success. ISTM that what's really needed is for theFnMut
andFnOnce
traits to have a lifetime parameter for the self reference that the call function gets. I looked in the Reference and the Nomicon and various other places but the documentation in this area was rather thin and informal and didn't seem to come close to addressing this matter.To demonstrate that what I am doing here is not unreasonable, here is a program which achieves the same thing with a "closure" which is actually a struct so has to be called with a method.
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f5add6be7376191011c0367159b8a617
All of these experiments were in the Rust playground, stable channel. 1.48 currently.