Here's my code:
struct A<'a>(&'a mut u8);
impl<'a> A<'a> {
fn g(&'a mut self) -> &'a mut u8
{
self.0
}
}
fn call_closure<F>(f: F)
where
F: FnOnce(&mut A),
{
let mut x = 5;
let mut a = A(&mut x);
f(&mut a)
}
fn main() {
call_closure(|a| {
a.g();
});
}
Here's the error message that is produced:
$ rustc trash.rs -o trashout
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> trash.rs:21:11
|
21 | a.g();
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the body at 20:18...
--> trash.rs:20:18
|
20 | call_closure(|a| {
| __________________^
21 | | a.g();
22 | | });
| |_____^
note: ...so that reference does not outlive borrowed content
--> trash.rs:21:9
|
21 | a.g();
| ^
note: but, the lifetime must be valid for the anonymous lifetime #3 defined on the body at 20:18...
--> trash.rs:20:18
|
20 | call_closure(|a| {
| __________________^
21 | | a.g();
22 | | });
| |_____^
= note: ...so that the types are compatible:
expected &mut A<'_>
found &mut A<'_>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
I find this pretty opaque. What the heck is autoref? Lifetimes #2 and #3 appear to be identical. The "expected" and "found" types appear to be identical.
I think the message is trying to say it can't infer a lifetime for the reference returned from g
. I understand why that lifetime can't outlive "borrowed content." But what's requiring it to live long enough? I tried a few variations on g
, like this:
impl<'a> A<'a> {
fn g<'b>(&'a mut self) -> &'b mut u8
where
'a: 'b
{
self.0
}
}
with the same result.