I'm using the specs crate which has a Component
trait which extends the std::any::Any
trait (the Any
trait just requires 'static
). I want to include a Box<Fn(T) + 'static>
field (with generic argument T
) in a struct for which Component
is implemented, which means Box<Fn(T) + 'static>
needs to be 'static
. That means I need Fn(T) + 'static
to be 'static
for any T
.
It seems Fn(T) + 'static
is not 'static
for any generic type argument T
. T
could refer to a struct with its own lifetimes, but I expected it not to be a problem because there is no instance of a reference with those lifetimes in the Fn
to make the Fn
itself not 'static
- those lifetimes are only in the arguments passed to the Fn
, but it is as if Fn(T) + 'static
is considered to contain a T
itself.
Example:
struct HandlesT<T> {
handler: Box<Fn(T) + 'static>,
}
impl<T> HandlesT<T> {
pub fn new<F: Fn(T) + 'static>(handler: F) -> HandlesT<T> {
HandlesT {
handler: Box::new(handler),
}
}
}
trait IsStatic: 'static {}
impl<T> IsStatic for HandlesT<T> {}
error[E0310]: the parameter type `T` may not live long enough
--> src/lib.rs:14:9
|
14 | impl<T> IsStatic for HandlesT<T> {}
| - ^^^^^^^^
| |
| help: consider adding an explicit lifetime bound `T: 'static`...
|
note: ...so that the type `HandlesT<T>` will meet its required lifetime bounds
--> src/lib.rs:14:9
|
14 | impl<T> IsStatic for HandlesT<T> {}
| ^^^^^^^^
In the example, since HandlesT<T>
contains no non-static references at all for any given T
(no references at all except those owned by the Fn
, but those must be 'static
), I expected HandlesT<T>
to be static for any T
, but the error indicates that it is not.
The compiler suggestion to "consider adding an explicit lifetime bound T: 'static
" neither supports any generic type argument T, nor provides hints as to why HandlesT<T>
for any generic T
is not 'static
, given that HandlesT<T>
would not contain a T
.
Example of T: 'static
(the compiler's suggestion) not supporting any generic T
, in this case &'a i32
:
struct HandlesT<T: 'static> {
handler: Box<Fn(T) + 'static>,
}
impl<T: 'static> HandlesT<T> {
pub fn new<F: Fn(T) + 'static>(handler: F) -> HandlesT<T> {
HandlesT {
handler: Box::new(handler),
}
}
}
trait IsStatic: 'static {}
impl<T: 'static> IsStatic for HandlesT<T> {}
fn try_nonstatic_t<'a>() {
let handles_t = HandlesT {
handler: Box::new(|i: &'a i32| {}),
};
}
error[E0477]: the type `&'a i32` does not fulfill the required lifetime
--> src\lib.rs:17:21
|
17 | let handles_t = HandlesT {
| ^^^^^^^^
|
= note: type must satisfy the static lifetime
A discussion on discord about this yielded Issue 57325 and the discussion there seems to have left things in a state of:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.