rustc_middle::mir

Module visit

Source
Expand description

§The MIR Visitor

§Overview

There are two visitors, one for immutable and one for mutable references, but both are generated by the make_mir_visitor macro. The code is written according to the following conventions:

  • introduce a visit_foo and a super_foo method for every MIR type
  • visit_foo, by default, calls super_foo
  • super_foo, by default, destructures the foo and calls visit_foo

This allows you to override visit_foo for types you are interested in, and invoke (within that method call) self.super_foo to get the default behavior. Just as in an OO language, you should never call super methods ordinarily except in that circumstance.

For the most part, we do not destructure things external to the MIR, e.g., types, spans, etc, but simply visit them and stop. This avoids duplication with other visitors like TypeFoldable.

§Updating

The code is written in a very deliberate style intended to minimize the chance of things being overlooked. You’ll notice that we always use pattern matching to reference fields and we ensure that all matches are exhaustive.

For example, the super_basic_block_data method begins like this:

fn super_basic_block_data(
    &mut self,
    block: BasicBlock,
    data: & $($mutability)? BasicBlockData<'tcx>
) {
    let BasicBlockData {
        statements,
        terminator,
        is_cleanup: _
    } = *data;

    for statement in statements {
        self.visit_statement(block, statement);
    }

    ...
}

Here we used let BasicBlockData { <fields> } = *data deliberately, rather than writing data.statements in the body. This is because if one adds a new field to BasicBlockData, one will be forced to revise this code, and hence one will (hopefully) invoke the correct visit methods (if any).

For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS. That means you never write .. to skip over fields, nor do you write _ to skip over variants in a match.

The only place that _ is acceptable is to match a field (or variant argument) that does not require visiting, as in is_cleanup above.

Macros§

Enums§

Traits§