I recently refactored my program to use GATs (supported from rustc >=1.65). Now, I have the problem that my code does not compile with rustc <1.69. I refactored my original problem, in particular this code line, to a minimal example:
$ cargo +1.65 check --quiet
error: `<D as DataT>::V<'_>` does not live long enough
--> src/main.rs:17:8
|
17 | || box_once(y.clone());
| ^^^^^^^^^^^^^^^^^^^
Starting from rustc 1.69, this compiles fine.
Removing either ||, box_once, or .clone() from fails() makes the program compile. But in my actual code, I need all three of these. I thought that maybe I could generalise the signature for box_once a bit, but I wasn't able to.
Do you have any ideas how to adapt my code to compile for rustc 1.65?
[EDIT]
I just found Generic associated types to be stable in Rust 1.65 | Rust Blog, which mentions limitations in initial GAT support with lifetime errors that eerily resemble mine. Could it be that these just cannot be fixed in early Rust versions?
I have experimented a bit with your repo, and yeah, you're basically constantly running into this <1.69.0 bug which amounts to:
if you ever involve an extra trait bound on a GAT (maybe in a higher-ranked context, I don't remember all the specifics of that time right now);
then within the body of such a constrained function, type inference shall be unable to properly infer occurrences of that GAT. So every. F*cken. Generic. Function. Call. needs to be properly turbofished and be provided any GAT (such as your D::V<'a>) or wrapper thereof (such as Exn<D::V<'a>>).
For instance, your box_once() calls, in your real code, needed to be using:
call_once::<Result<D::V<'a>, Exn<D::V<'a>>>>(…)
But you had just so many (normal, natural) layers of functions around to make this ever so remotely practical:
error: `<D as DataT>::V<'_>` does not live long enough ▐
--> jaq-core/src/filter.rs:686:78 ▐
| ▐
686 | box_once::<ResultV<'a, D>>(paths.try_fold(v, |acc, path| path?.update(acc, &f))) ▐
| ^^^^^^^^^^^^^^^^^^^^^
All in all, this is a serious usability-restraining bug we had in those versions, and the workaround (of just Turbofishing Everything™) does indeed not scale, so a toolchain update is indeed the best course of action