Why the borrow checker runs on validated, and not optimized, MIR?


Hi! I’m trying to learn how the borrow checker works.

I saw that the borrow checker is run on “validated” MIR, that is different from the final “optimized” MIR.

For example, a move of a mutable reference is _2 = move _1 in optimized MIR, but sometimes it’s a _2 = &mut (*_1) in validated MIR.

My question is: by running the borrow checker on optimized MIR, would it detect all the errors that it would have detected on validated MIR?


I would think that many optimizations will depend on knowing that the input is valid first, even with respect to borrowing, or else that transformation might be invalid itself.


I would think so too, given the comical stuff that comes out of a modern C/++ optimizer when undefined behavior is passed in.


No. For a trivial example, optimized MIR can remove dead code, and you still want checking on that despite it being dead – especially if it’s only dead after inlining, or something. (See a bunch of the bugs that happened with the unsafe checks moving to MIR, where for a while under a particular nightly feature flag you could call unsafe methods in safe code without an unsafe block so long as they were dead, IIRC.)

Optimized MIR doesn’t even necessarily pass typeck – for example, it can copy &muts:


Thanks a lot for the answers! That issue points out exactly what I was looking for