However not all of them are. Back in the pre-async/await days you'd end up with some really gnarly implicit types in some really big functions with lots of returns. Then sometimes you'd make a mistake on one of the returns and the compiler would assume that your mistaken type was the right one & point out all the places where the actually correct type was returned. Then you'd have to go hunt for where you needed to add a `as Box<Future<Item = _, Error = _>>` to get it to compile again.
I haven't hit any issues like that since I started converting the gnarly stuff to infinitely simplier async/await code, but I have to imagine those kinds of issues are still lurking in other areas where you can't get away from complicated code.
Even with that I whole-heartedly recommend anyone that's thinking about it just go try it out and/or read some of the book. It's a delightful language to work with. I have way more fun working with Rust than I have with any other language. It takes care of so much of the BS that I don't want to have to think about, so I can just think about the interesting stuff.
And will do, if I encounter them.
Years past we spent a lot of time honing general common errors to a pretty neat level, then we moved on to detecting specific cases. I would say that the quality of the output is a bimodal distribution with a cluster of really high quality for common errors, and a big but shrinking cluster of confusing errors for more advanced features.
To give an example, async await relies on three things: syntactic sugar (which means there's generated code that's not in the user written code), associated types (that had badly confusing type errors) and impl Trait (that had confusing type errors). The later two features didn't receive much love for a while because they were advanced features that a newcomer would be unlikely to hit, with exceptions for crates doing interesting but confusing things with them to provide a nicer API. But when the dust started to settle aroune async/await it was clear to me that people would be seeing the stabilization announcement, consider trying rust and jump straight to very arcane errors that would now be very easy to hit. This made me and a few others actually spend the time to drastically (if not entirely) improve those errors ahead of async/await stabilization, with the nice side effect that those features are also up to the level of quality that we want for newcomers. The syntactic sugar part also plays a part on how you explain succinctly and clearly that the type or inference error you're seeing comes from a return type materialized out if the aether, but I think we've gotten good at that.
If you will be picking up Rust to try it out, I encourage people to use nightly, not because of features but rather because we have diagnostics improvements daily and they can be the difference between having to read the book to understand how to fix your issue and just following the compiler's lead. As an example, you can see this recently landed PR: https://github.com/rust-lang/rust/pull/68267
I've recently been using Flutter and it's a delight to get an error message like "you did X, but Y was uninitialized, so you need to put a call to Y.Z in your code first". When my problem is some conceptual mistake, a traditional error message, like "null pointer error in Y" just confuses me, because I don't even know what Y relates to what I'm doing.
I love that you and others are taking the time to see what really went wrong. Partly because it solves my immediate problem, but also because I know that's exerting backpressure on confusing language and library features, which I hope will drive more platform improvements down the road.
It's still possible to hit some edge cases where error messages aren't as helpful as they could be. But these are considered bugs and so will hopefully be fixed.
Some errors are admittedly worse, and people like estebank are actively working on improving them.