Yeah, trait-heavy code is one of Rust's weaker points in practice. I find tower and some of the database crates to be some of the worst offenders: even knowing the language pretty well, I've often gotten lost in a maze of projections and blanket impls when an error occurs. There's no easy way to trace the implementation back to the intended behavior, to compare the expected and actual outcomes.