How did you become proficient with lifetimes?

I strongly suspect a mini-book can be written on just the lifetimes portion of Rust, and all the different ways they manifest. There’s also something to be said about the difference in knowing how lifetimes work and deciphering compiler error messages; a lot of the latter, particularly beyond the “obvious” cases, is just experience - at some point, you know exactly (or close to it) what the compiler is saying. Not because you necessarily find its message crystal clear, but because you’ve seen it before and spent time figuring it out. Then it’s the same pattern(s) repeating in different disguises.

The mental framework I use is to always look at it from the standpoint of “what type of memory unsafety is the compiler trying to prevent here? What could the code I just wrote, that doesn’t compile, do that would be unsafe?”. Then there’s the skill/experience of knowing what you want to express to the compiler but learning the syntax and formulation of how to say it.

Once you’re somewhat out of the water, then come mutable references and they change variance/subtyping - so now you need to learn about what subtyping means and how different borrows and types interplay in that light.

Then you have generic code, with its own lifetime formulations.

Then you have papercuts, such as the ones that NLL fixes. So you learn about those and try to avoid them or work around them.

Then you learn about how lifetimes don’t project with associated types sometimes. Or there’s no variance of lifetimes in types that appear as generic type parameters on traits. Or how last expression of a block extends the borrow to outside the block.

Then you also learn about trait objects and default object bounds.

Then you may come across situations, such as what you had I believe, where you want generic associated types but that feature is missing at the moment.

Then there’s HRTB. And then you want to somehow assemble all of these things in a delicate way and write non-trivial projects. And if you’re creating APIs/abstractions, you almost need to know a lot of this upfront so you can predict whether you’ll design yourself into some corner.

And there’s probably other stuff that I’m missing. The bottom line is it’s completely non trivial and you should expect for it to take a while to sink in. Not so much the high level handwavy parts of what they are, but for how to actually get non trivial work done and make use of them. The best way is to simply log the required mileage with real code and some head banging against the errors. Some will be real, some will be papercuts, and others missing features.

So, continue to use this forum (and other channels) for help without mercy :slight_smile:.

12 Likes