The code is taken from learing rust by @quinedot
As it says,
fn foo<'s, 'l: 's>(v: std::cell::Cell<Box<dyn Display + 'l>>) -> std::cell::Cell<Box<dyn Display + 's>> {
v
}
can be compiled, but
fn foo<'s, 'l: 's>(v: std::cell::Cell<Box<Box<dyn Display + 'l>>>) -> std::cell::Cell<Box<Box<dyn Display + 's>>> {
v
}
can't.
It does, but I am thinking is the 2nd one really dangerous?
The Variance is so called unsized coercions
in the book, though is really nothing to do with the sizeness.
I think the reason underhook it because dyn Display + 's
is just an unknown type, you can't assign some reference to the type under dyn Display
, you can only annotate the type's lifetime as whole.
But when it's a member of struct, it is different; because T<dyn Trait + 'long> means T maybe as long as 'long; Cell<Box<dyn Display + 's>>, for example, dyn Display has a life 's, then Box<<dyn Display + 's>> can't exceed the 's
too, then Cell<Box<dyn Display + 's>> is same.
Why
fn foo<'s, 'l: 's>(v: std::cell::Cell<Box<dyn Display + 'l>>) -> std::cell::Cell<Box<dyn Display + 's>> {
v
}
is accepted because the cell is passed by value, after Cell<'l> was considered as Cell<'s>, it can't be move out to outer scope of 's
.
But I think the same applies to Cell<Box<Box<dyn Display + 's>>>
, there is no chance for it to be moved out of 's
, so seems there is no chance for it to result in dangerous things.