I think it is also important to recognize that all compilers have this problem and they all stabilize over time. It is an issue orthogonal of safety. These aren't segmentation faults or some kind of memory error but the compiler signaling an internal invariant was violated.
This can happen easily because we are writing a very large program that reads user input, interprets it, and tries to emit a program.
This can happen in multiple situations. One example is the compiler may have a logic bug that violates an internal invariant resulting in an ICE (instead of emitting incorrect code).
Other times it is as simple as the code we have been given is invalid and the error wasn't properly handled, and you end up seeing it in a non-user friendly way (as an ICE).
We are working hard to move the compiler to a more modern, robust design as soon as possible but even with a great design it will be an iterative process that we continue to do over the lifetime of the language, just like everyone else.
Longer answer: The Rust compiler was written in Rust before the Rust language was even what it was today. As one particular example, the AST used to be garbage collected! And when you have a codebase that's 320,000 lines long, you don't update the entire codebase to the latest idiom, because if you did, you'd never actually ship the language.
Basically no other Rust program will ever have to contend with this kind of situation. As such, while I can sympathize with this line of argument, I don't think it's representative.
EDIT: I previously had 750,000 but it's actually 323,326 LOC as of right now. Whoops!
> And presumably Rust will continue to evolve, will it not?
Right, but it will evolve in a backwards-compatible way, rather than in a "the fundamental semantics of the language have changed Yet Again" kind of way.
An evolving language is one thing. Pre-1.0 was more like many stages of violent metamorphasis. Some changes to the language required changing almost every line of code in the tree. Normal technical debt is when you find an old approach doesn't work any more and you need to fix it. Much of rustc's technical debt is from things like features disappearing from underneath it, or things designed before the features that you would use now even existed.
Looking at rustc as a regular large Rust project is unfair. A new project can at least assume that the features you are using today will exist tomorrow and design with that in mind. Your designs may become obsolete due to new features, but you aren't going to have to pick between a hacky workaround and a redesign/rewrite of 1000's of lines of code.
For example, here's about the worst rustc crash I've found: https://github.com/rust-lang/rust/issues/21946. It doesn't even give you an ICE, it terminates with a stack overflow.
So no, Rust cannot magically fix logic errors in large, complicated codebases, but that's not something that a complete beginner needs to worry about thankfully.