An intermediate language allows you to describe the high-level semantics in a more primitive form, so it is easier to both manipulate and reason about while preserving the high-level semantics. In this case (as far as I understand it,) MIR needs to be as primitive as possible while still modeling Rust's scoping, safety, and type rules. This is an optimization design pattern that occurs quite frequently in practice.