Stupid question: does the back-end have to wait for the front-end to do borrow checking? If so, why?
(I'm not suggesting that it's doing anything wrong. I'm just wondering if borrow checking establishes invariants that the back-end depends on for more than correctness, such that you couldn't do speculative back-end work that you would discard on a borrow checking error.)
Well, there is mrustc[0], a Rust compiler that doesn't include a borrow-checker, so it's possible to compile (at least some versions of) Rust without a borrow checker, though it might not result in the most optimized code.
AFAIK there are some optimization like the infamous `noalias` optimization (which took several tries to get turned on[1]) that uses information established during borrow checking.
I'm also not sure what the relation with NLL (non-lexical lifetimes) is, where I would assume you would need at least a primitive borrow-checker to establish some information that the backend might be interested in. Then again, mrustc compiles Rust versions that have NLL features without a borrow-checker, so it's again probably more on the optimization side than being essential.
The borrow checker determines the set of valid programs.
mrustc gets past not having a borrow checker by compiling invalid programs that would have otherwise had compiler errors. This, at best, results in runtime segfaults etc.
Just like you don't need to validate syntax if you just assume you're only ever fed valid syntax.
Nothing wrong with that, just want to clarify for people.
(I'm not suggesting that it's doing anything wrong. I'm just wondering if borrow checking establishes invariants that the back-end depends on for more than correctness, such that you couldn't do speculative back-end work that you would discard on a borrow checking error.)