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).