MIR visitor
The MIR visitor is a convenient tool for traversing the MIR and either
looking for things or making changes to it. The visitor traits are
defined in the rustc::mir::visit module – there are two of
them, generated via a single macro: Visitor (which operates on a
&Mir and gives back shared references) and MutVisitor (which
operates on a &mut Mir and gives back mutable references).
To implement a visitor, you have to create a type that represents your visitor. Typically, this type wants to "hang on" to whatever state you will need while processing MIR:
struct MyVisitor<...> {
tcx: TyCtxt<'cx, 'tcx, 'tcx>,
...
}
and you then implement the Visitor or MutVisitor trait for that type:
impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
fn visit_foo(&mut self, ...) {
...
self.super_foo(...);
}
}
As shown above, within the impl, you can override any of the
visit_foo methods (e.g., visit_terminator) in order to write some
code that will execute whenever a foo is found. If you want to
recursively walk the contents of the foo, you then invoke the
super_foo method. (NB. You never want to override super_foo.)
A very simple example of a visitor can be found in NoLandingPads.
That visitor doesn't even require any state: it just visits all
terminators and removes their unwind successors.
Traversal
In addition the visitor, the rustc::mir::traversal module
contains useful functions for walking the MIR CFG in
different standard orders (e.g. pre-order, reverse
post-order, and so forth).