Module rustc_mir_transform::simplify

source ·
Expand description

A number of passes which remove various redundancies in the CFG.

The SimplifyCfg pass gets rid of unnecessary blocks in the CFG, whereas the SimplifyLocals gets rid of all the unnecessary local variable declarations.

The SimplifyLocals pass is kinda expensive and therefore not very suitable to be run often. Most of the passes should not care or be impacted in meaningful ways due to extra locals either, so running the pass once, right before codegen, should suffice.

On the other side of the spectrum, the SimplifyCfg pass is considerably cheap to run, thus one should run it after every pass which may modify CFG in significant ways. This pass must also be run before any analysis passes because it removes dead blocks, and some of these can be ill-typed.

The cause of this typing issue is typeck allowing most blocks whose end is not reachable have an arbitrary return type, rather than having the usual () return type (as a note, typeck’s notion of reachability is in fact slightly weaker than MIR CFG reachability - see #31617). A standard example of the situation is:

  fn example() {
      let _a: char = { return; };

Here the block ({ return; }) has the return type char, rather than (), but the MIR we naively generate still contains the _a = () write in the unreachable block “after” the return.