Rust is an interesting language. Much-loved, a systems programming language (no garbage collection, etc) but feels like a higher level language with iterators, fancy type systems, nice tooling, and you can write code that works
without needing to carefully juggle memory.
I've done plenty of systems programming (C, C++) and higher level (Python, C#, etc), so figured Rust should be easy enough to pick up, but I'd hit the same struggles everyone else does, where the borrow checker yells at me, and when do I use a
Eventually I figured out why I was struggling so much though, and now I'll share with you, gentle reader, my revelation.
I was forgetting to think about memory and lifetimes
When coding in C or C++ I'd be constantly aware of every allocation and trying (and sometimes failing) to carefully track the lifetimes of every object I use because if I don't, bad things happen.
In a language like Python I don't because that's all hidden from me. I just code and it's the interpreter's problem.
When writing Rust it felt so easy, so I relaxed and stopped the careful tracking that I would in other systems programming languages. Of course, you can't since it matters in Rust. It has better ergonomics and safety but it's still a systems programming language, that means it assumes you know and care about whether things are heap or stack allocated, or about when exactly something is deallocated.
This then means the solution is sad but easy. I need to go back to thinking about where I want things allocated, how they're getting passed to functions, how long they live for. But at least when I get it wrong I find out from the compiler instead of Project Zero.