I tried to implement std::ops::Index for a custom struct to index it's fields.
Here's the compiler Error:
error: lifetime may not live long enough
--> src/lib.rs:232:13
|
232 | if $index == $index_var {
| ^^ returning this value requires that `'a` must outlive `'static`
...
344 | impl<'a> std::ops::Index<usize> for Parser<'a> {
| -- lifetime `'a` defined here
...
587 | / revparse! {
588 | | [some_option, 's', "help message"];
589 | | [long_name, 'l', "help message", "value"];
590 | | [another_opt, "help message", "value"];
... |
595 | | [pos_help "POSITIONAL ARGUMENT HELP MESSAGE THIS IS TEDIOUS"]
596 | | };
| |_____- in this macro invocation
|
= note: requirement occurs because of the type `RefCell<dyn ResVal<'_>>`, which makes the generic argument `dyn ResVal<'_>` invariant
= note: the struct `RefCell<T>` is invariant over the parameter `T`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
= note: this error originates in the macro `$crate::revparse` which comes from the expansion of the macro `revparse` (in Nightly builds, run with -Z macro-backtrace for more info)
This problem isn’t about the Index trait, but about the dyn return type you have declared not matching what you are returning. You’re mixing up trait lifetime parameters (that you don't need) and trait object lifetime bounds (that you do need).
The trait ResVal has a lifetime parameter it does not use. This parameter should be removed (this is not necessary, but it will reduce confusion).
The type alias A (and perhaps other places, but definitely this one) needs to allow its dyn to have a lifetime bound shorter than 'static, so it should be:
type A<'a> = std::cell::RefCell<dyn ResVal + 'a>;
All together, these changes will make your program compile:
To RefCell<dyn ResVal<'a> + 'static>, which means the highlighted types above need to be able to coerce to dyn ResVal<'a> + 'static. Which requires the highlighted types meet a lifetime bound of : 'static.
But they do not, they only meet a bound of 'a. They can coerce to dyn ResVal<'a> + 'a but not to dyn RevVal<'a> + 'static.