Skip to content

Commit c82a258

Browse files
committed
Turn top-level comments into module docs in MIR visitor
1 parent 603ab5b commit c82a258

File tree

1 file changed

+62
-62
lines changed

1 file changed

+62
-62
lines changed

compiler/rustc_middle/src/mir/visit.rs

+62-62
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,70 @@
1+
//! # The MIR Visitor
2+
//!
3+
//! ## Overview
4+
//!
5+
//! There are two visitors, one for immutable and one for mutable references,
6+
//! but both are generated by the following macro. The code is written according
7+
//! to the following conventions:
8+
//!
9+
//! - introduce a `visit_foo` and a `super_foo` method for every MIR type
10+
//! - `visit_foo`, by default, calls `super_foo`
11+
//! - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
12+
//!
13+
//! This allows you as a user to override `visit_foo` for types are
14+
//! interested in, and invoke (within that method) call
15+
//! `self.super_foo` to get the default behavior. Just as in an OO
16+
//! language, you should never call `super` methods ordinarily except
17+
//! in that circumstance.
18+
//!
19+
//! For the most part, we do not destructure things external to the
20+
//! MIR, e.g., types, spans, etc, but simply visit them and stop. This
21+
//! avoids duplication with other visitors like `TypeFoldable`.
22+
//!
23+
//! ## Updating
24+
//!
25+
//! The code is written in a very deliberate style intended to minimize
26+
//! the chance of things being overlooked. You'll notice that we always
27+
//! use pattern matching to reference fields and we ensure that all
28+
//! matches are exhaustive.
29+
//!
30+
//! For example, the `super_basic_block_data` method begins like this:
31+
//!
32+
//! ```rust
33+
//! fn super_basic_block_data(&mut self,
34+
//! block: BasicBlock,
35+
//! data: & $($mutability)? BasicBlockData<'tcx>) {
36+
//! let BasicBlockData {
37+
//! statements,
38+
//! terminator,
39+
//! is_cleanup: _
40+
//! } = *data;
41+
//!
42+
//! for statement in statements {
43+
//! self.visit_statement(block, statement);
44+
//! }
45+
//!
46+
//! ...
47+
//! }
48+
//! ```
49+
//!
50+
//! Here we used `let BasicBlockData { <fields> } = *data` deliberately,
51+
//! rather than writing `data.statements` in the body. This is because if one
52+
//! adds a new field to `BasicBlockData`, one will be forced to revise this code,
53+
//! and hence one will (hopefully) invoke the correct visit methods (if any).
54+
//!
55+
//! For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
56+
//! That means you never write `..` to skip over fields, nor do you write `_`
57+
//! to skip over variants in a `match`.
58+
//!
59+
//! The only place that `_` is acceptable is to match a field (or
60+
//! variant argument) that does not require visiting, as in
61+
//! `is_cleanup` above.
62+
163
use crate::mir::*;
264
use crate::ty::subst::SubstsRef;
365
use crate::ty::{CanonicalUserTypeAnnotation, Ty};
466
use rustc_span::Span;
567

6-
// # The MIR Visitor
7-
//
8-
// ## Overview
9-
//
10-
// There are two visitors, one for immutable and one for mutable references,
11-
// but both are generated by the following macro. The code is written according
12-
// to the following conventions:
13-
//
14-
// - introduce a `visit_foo` and a `super_foo` method for every MIR type
15-
// - `visit_foo`, by default, calls `super_foo`
16-
// - `super_foo`, by default, destructures the `foo` and calls `visit_foo`
17-
//
18-
// This allows you as a user to override `visit_foo` for types are
19-
// interested in, and invoke (within that method) call
20-
// `self.super_foo` to get the default behavior. Just as in an OO
21-
// language, you should never call `super` methods ordinarily except
22-
// in that circumstance.
23-
//
24-
// For the most part, we do not destructure things external to the
25-
// MIR, e.g., types, spans, etc, but simply visit them and stop. This
26-
// avoids duplication with other visitors like `TypeFoldable`.
27-
//
28-
// ## Updating
29-
//
30-
// The code is written in a very deliberate style intended to minimize
31-
// the chance of things being overlooked. You'll notice that we always
32-
// use pattern matching to reference fields and we ensure that all
33-
// matches are exhaustive.
34-
//
35-
// For example, the `super_basic_block_data` method begins like this:
36-
//
37-
// ```rust
38-
// fn super_basic_block_data(&mut self,
39-
// block: BasicBlock,
40-
// data: & $($mutability)? BasicBlockData<'tcx>) {
41-
// let BasicBlockData {
42-
// statements,
43-
// terminator,
44-
// is_cleanup: _
45-
// } = *data;
46-
//
47-
// for statement in statements {
48-
// self.visit_statement(block, statement);
49-
// }
50-
//
51-
// ...
52-
// }
53-
// ```
54-
//
55-
// Here we used `let BasicBlockData { <fields> } = *data` deliberately,
56-
// rather than writing `data.statements` in the body. This is because if one
57-
// adds a new field to `BasicBlockData`, one will be forced to revise this code,
58-
// and hence one will (hopefully) invoke the correct visit methods (if any).
59-
//
60-
// For this to work, ALL MATCHES MUST BE EXHAUSTIVE IN FIELDS AND VARIANTS.
61-
// That means you never write `..` to skip over fields, nor do you write `_`
62-
// to skip over variants in a `match`.
63-
//
64-
// The only place that `_` is acceptable is to match a field (or
65-
// variant argument) that does not require visiting, as in
66-
// `is_cleanup` above.
67-
6868
macro_rules! make_mir_visitor {
6969
($visitor_trait_name:ident, $($mutability:ident)?) => {
7070
pub trait $visitor_trait_name<'tcx> {

0 commit comments

Comments
 (0)