@@ -70,9 +70,42 @@ impl<'a> FnKind<'a> {
70
70
/// Specifies what nested things a visitor wants to visit. Currently there are
71
71
/// two modes: `OnlyBodies` descends into item bodies, but not into nested
72
72
/// items; `All` descends into item bodies and nested items.
73
- pub enum NestedVisitMode {
74
- OnlyBodies ,
75
- All
73
+ pub enum NestedVisitorMap < ' this , ' tcx : ' this > {
74
+ /// Do not visit any nested things. When you add a new
75
+ /// "non-nested" thing, you will want to audit such uses to see if
76
+ /// they remain valid.
77
+ None ,
78
+
79
+ /// Do not visit nested item-like things, but visit nested things
80
+ /// that are inside of an item-like.
81
+ ///
82
+ /// **This is the default mode.**
83
+ OnlyBodies ( & ' this Map < ' tcx > ) ,
84
+
85
+ /// Visit all nested things, including item-likes.
86
+ All ( & ' this Map < ' tcx > ) ,
87
+ }
88
+
89
+ impl < ' this , ' tcx > NestedVisitorMap < ' this , ' tcx > {
90
+ /// Returns the map to use for an "intra item-like" thing (if any).
91
+ /// e.g., function body.
92
+ pub fn intra ( self ) -> Option < & ' this Map < ' tcx > > {
93
+ match self {
94
+ NestedVisitorMap :: None => None ,
95
+ NestedVisitorMap :: OnlyBodies ( map) => Some ( map) ,
96
+ NestedVisitorMap :: All ( map) => Some ( map) ,
97
+ }
98
+ }
99
+
100
+ /// Returns the map to use for an "item-like" thing (if any).
101
+ /// e.g., item, impl-item.
102
+ pub fn inter ( self ) -> Option < & ' this Map < ' tcx > > {
103
+ match self {
104
+ NestedVisitorMap :: None => None ,
105
+ NestedVisitorMap :: OnlyBodies ( _) => None ,
106
+ NestedVisitorMap :: All ( map) => Some ( map) ,
107
+ }
108
+ }
76
109
}
77
110
78
111
/// Each method of the Visitor trait is a hook to be potentially
@@ -109,13 +142,7 @@ pub trait Visitor<'v> : Sized {
109
142
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
110
143
/// added in the future, we will see the panic in your code and
111
144
/// fix it appropriately.
112
- fn nested_visit_map ( & mut self ) -> Option < & Map < ' v > > ;
113
-
114
- /// Specifies what things nested things this visitor wants to visit. By
115
- /// default, bodies will be visited, but not nested items.
116
- fn nested_visit_mode ( & mut self ) -> NestedVisitMode {
117
- NestedVisitMode :: OnlyBodies
118
- }
145
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' v > ;
119
146
120
147
/// Invoked when a nested item is encountered. By default does
121
148
/// nothing unless you override `nested_visit_map` to return
@@ -127,8 +154,7 @@ pub trait Visitor<'v> : Sized {
127
154
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
128
155
#[ allow( unused_variables) ]
129
156
fn visit_nested_item ( & mut self , id : ItemId ) {
130
- let opt_item = map_for_item ( self )
131
- . map ( |map| map. expect_item ( id. id ) ) ;
157
+ let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. expect_item ( id. id ) ) ;
132
158
if let Some ( item) = opt_item {
133
159
self . visit_item ( item) ;
134
160
}
@@ -139,8 +165,7 @@ pub trait Visitor<'v> : Sized {
139
165
/// method.
140
166
#[ allow( unused_variables) ]
141
167
fn visit_nested_impl_item ( & mut self , id : ImplItemId ) {
142
- let opt_item = map_for_item ( self )
143
- . map ( |map| map. impl_item ( id) ) ;
168
+ let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. impl_item ( id) ) ;
144
169
if let Some ( item) = opt_item {
145
170
self . visit_impl_item ( item) ;
146
171
}
@@ -151,8 +176,7 @@ pub trait Visitor<'v> : Sized {
151
176
/// `nested_visit_map` to return `Some(_)`, in which case it will walk the
152
177
/// body.
153
178
fn visit_body ( & mut self , id : ExprId ) {
154
- let opt_expr = map_for_body ( self )
155
- . map ( |map| map. expr ( id) ) ;
179
+ let opt_expr = self . nested_visit_map ( ) . intra ( ) . map ( |map| map. expr ( id) ) ;
156
180
if let Some ( expr) = opt_expr {
157
181
self . visit_expr ( expr) ;
158
182
}
@@ -302,18 +326,6 @@ pub trait Visitor<'v> : Sized {
302
326
}
303
327
}
304
328
305
- fn map_for_body < ' v , V : Visitor < ' v > > ( visitor : & mut V ) -> Option < & Map < ' v > > {
306
- visitor. nested_visit_map ( )
307
- }
308
-
309
- fn map_for_item < ' v , V : Visitor < ' v > > ( visitor : & mut V ) -> Option < & Map < ' v > > {
310
- match visitor. nested_visit_mode ( ) {
311
- NestedVisitMode :: OnlyBodies => None ,
312
- NestedVisitMode :: All => Some ( visitor. nested_visit_map ( )
313
- . expect ( "NestedVisitMode::All without nested_visit_map" ) )
314
- }
315
- }
316
-
317
329
pub fn walk_opt_name < ' v , V : Visitor < ' v > > ( visitor : & mut V , span : Span , opt_name : Option < Name > ) {
318
330
if let Some ( name) = opt_name {
319
331
visitor. visit_name ( span, name) ;
@@ -1061,8 +1073,8 @@ impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> {
1061
1073
}
1062
1074
1063
1075
impl < ' a , ' ast > Visitor < ' ast > for IdRangeComputingVisitor < ' a , ' ast > {
1064
- fn nested_visit_map ( & mut self ) -> Option < & Map < ' ast > > {
1065
- Some ( & self . map )
1076
+ fn nested_visit_map < ' this > ( & ' this mut self ) -> NestedVisitorMap < ' this , ' ast > {
1077
+ NestedVisitorMap :: OnlyBodies ( & self . map )
1066
1078
}
1067
1079
1068
1080
fn visit_id ( & mut self , id : NodeId ) {
0 commit comments