Consider this example
fn ret<'a>(v: &'a A) -> impl Sized /* + Copy #1*/ {
0
}
struct A;
fn main() {
let a = A;
let r = ret(&a);
//drop(r); // #2
a;
//r;
}
In this example, the compiler complains that
error[E0505]: cannot move out of `a` because it is borrowed
--> src/main.rs:9:5
|
6 | let a = A;
| - binding `a` declared here
7 | let r = ret(&a);
| -- borrow of `a` occurs here
8 | //drop(r); // #2
9 | a;
| ^ move out of `a` occurs here
10 | //r;
11 | }
| - borrow might be used here, when `r` is dropped and runs the destructor for type `impl Sized`
|
note: this call may capture more lifetimes than intended, because Rust 2024 has adjusted the `impl Trait` lifetime capture rules
Either uncomment #1
or #2
will eliminate the compiled error. According to lifetime-capture-rules-2024
We want to promise that the opaque type captures some lifetime
'a
, and consequently, that for the opaque type to outlive some other lifetime,'a
must outlive that other lifetime. If we could say in Rust that a lifetime must outlive a type, we would say that the'a
lifetime must outlive the returned opaque type.
In this example, according to the new lifetime-capture rules, the returned opaque type impl Sized
captures the lifetime 'a
, which would require the requirement that 'a: OpaqueType
. So, the requirement means whenever the returned OpaqueType
lives, 'a
must be in the scope.
Q1:
how to understand what capture lifetimes mean here? Does it mean the opaque type would behave as if it had a field of a type with the captured lifetimes?
Q2:
I don't know whether it is the correct way to say that the type without lifetime parameters has a lifetime, for example, the opaque type here is actually i32
, which can have a lifetime.
Q3:
Is the non-lexical lifetime of an opaque type assumed as if it had implemented Drop
, such that the value lives until the scope exits? The extra +Copy
suppresses the assumption and makes it have the non-lexical lifetime?