I’d say, a huge problem of making this fit into Any
is that Any
already supports types with lifetimes. The lifetimes just need to be 'static
.
I think your rule, i.e. convert &'a T<'b>
into &'a dyn Any
- requiring 'b
to be covariant (and implicitly requiring 'b: 'a
– and to convert &'a dyn Any
back into &'a T<'b1>
requiring 'a: 'b1
is sound. As @SkiFire13 mentioned, it can be simplified to converting &'a dyn Any
back into &'a T<'a>
at the other end.
Anyways, this rule is in contradiction with what happens today: converting &'a T<'static>
into &'a dyn Any
without requirements of covariance, and then downcasting back into &'a T<'static>
. There’s just no way to unify these rules: The requirements going in are orthogonal… one is 'b
must be 'static
, the other is 'b
must be covariant. The type coming out is very different, too: containing lifetime 'a
or lifetime 'static
. I could imagine for the latter point, perhaps, to use different type ids for the different ways of treating a lifetime. But then, if you start out with some x: &'a T<'b>
value, what way would there be to tell the compiler which of these versions you want? Should your “x as &dyn Any
” introduce a requirement of “'b == 'static
” or a requirement of “'b is covariant
”?
You cannot simply make this choice automatically either. The way the borrow checker works, you cannot make compilation choices based on asking a “question” like “is this lifetime 'static
”? The only kind of “question” the borrow checker is designed to answer is the question “does this program compile?” and the only way of relating a lifetime to 'static
is to either require it to be 'static
(which may or may not make the program no longer compile).
And while you can probably easily check for “'b is covariant
”, the natural rule “if 'b
is not covariant, then require 'b
to be 'static
and return a dyn Any
of the respective kind” is useless, too, since that weaker precondition ('b
covariant) only allows us to get a “weaker”/less-useful type out on downcasting, too: &'a T<'a>
instead of &'a T<'static>
.
On that note, for downcasting to &'a T<'b>
, same problem: What constraint should be introduced? 'b == 'a
or 'b == 'static
?
If you need the user to be explicit on how which lifetime is treated, then it doesn’t fit with the existing dyn Any
. E.g. the better_any
approach that’s already mentioned solves the issue by requiring the user to choose the behavior between the two behaviors explained above, for each lifetime, through use of a trait. This means that the “treat which lifetime how” question can only be answered once for every type, but I suppose users can work around this with a newtype-pattern.