Expand description

The MIR Visitor

Overview

There are two visitors, one for immutable and one for mutable references, but both are generated by the following 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 as a user to override visit_foo for types 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

Extra information passed to visit_ty and friends to give context about where the type etc appears.

Traits