I am trying to figure out why my type is not covariant but I cannot find the reason based on the variance reference.
Are there any special rules for the variance of dyn Fn
compared to fn
?
Here are the types I am interested in:
pub trait MyTrait {}
struct Creator1<'a>(fn() -> Box<dyn MyTrait + 'a>);
struct Creator2<'a>(Box<dyn Fn() -> Box<dyn MyTrait + 'a>>);
I would expect that both types Creator1
and Creator2
are covariant in 'a
but it turns out that only Creator1
is covariant in 'a
, if I do:
fn is_covariant<'long, 'short>(value: Creator2<'long>)
where
'long: 'short,
{
let _: Creator2<'short> = value;
}
I get a compile error while the same with Creator1
works fine.
The error is:
error: lifetime may not live long enough
--> src/lifetimes.rs:10:12
|
6 | fn is_covariant<'long, 'short, T>(value: Creator2<'long>)
| ----- ------ lifetime `'short` defined here
| |
| lifetime `'long` defined here
...
10 | let _: Creator2<'short> = value;
| ^^^^^^^^^^^^^^^^ type annotation requires that `'short` must outlive `'long`
|
= help: consider adding the following bound: `'short: 'long`
= note: requirement occurs because of the type `Creator2<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Creator2<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance