Turn top-level comments into module docs in MIR visitor
This commit is contained in:
parent
603ab5bd6e
commit
c82a258ad4
@ -1,70 +1,70 @@
|
||||
//! # 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:
|
||||
//!
|
||||
//! ```rust
|
||||
//! 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.
|
||||
|
||||
use crate::mir::*;
|
||||
use crate::ty::subst::SubstsRef;
|
||||
use crate::ty::{CanonicalUserTypeAnnotation, Ty};
|
||||
use rustc_span::Span;
|
||||
|
||||
// # 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:
|
||||
//
|
||||
// ```rust
|
||||
// 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.
|
||||
|
||||
macro_rules! make_mir_visitor {
|
||||
($visitor_trait_name:ident, $($mutability:ident)?) => {
|
||||
pub trait $visitor_trait_name<'tcx> {
|
||||
|
Loading…
Reference in New Issue
Block a user