@@ -160,87 +160,44 @@ impl<'hir> Map<'hir> for ! {
160
160
}
161
161
}
162
162
163
- /// An erased version of `Map<'hir>`, using dynamic dispatch.
164
- /// NOTE: This type is effectively only usable with `NestedVisitorMap::None`.
165
- pub struct ErasedMap < ' hir > ( & ' hir dyn Map < ' hir > ) ;
163
+ pub mod nested_filter {
164
+ use super :: Map ;
166
165
167
- impl < ' hir > Map < ' hir > for ErasedMap < ' hir > {
168
- fn find ( & self , _: HirId ) -> Option < Node < ' hir > > {
169
- None
170
- }
171
- fn body ( & self , id : BodyId ) -> & ' hir Body < ' hir > {
172
- self . 0 . body ( id)
173
- }
174
- fn item ( & self , id : ItemId ) -> & ' hir Item < ' hir > {
175
- self . 0 . item ( id)
176
- }
177
- fn trait_item ( & self , id : TraitItemId ) -> & ' hir TraitItem < ' hir > {
178
- self . 0 . trait_item ( id)
179
- }
180
- fn impl_item ( & self , id : ImplItemId ) -> & ' hir ImplItem < ' hir > {
181
- self . 0 . impl_item ( id)
182
- }
183
- fn foreign_item ( & self , id : ForeignItemId ) -> & ' hir ForeignItem < ' hir > {
184
- self . 0 . foreign_item ( id)
166
+ /// Specifies what nested things a visitor wants to visit. The most
167
+ /// common choice is `OnlyBodies`, which will cause the visitor to
168
+ /// visit fn bodies for fns that it encounters, but skip over nested
169
+ /// item-like things.
170
+ ///
171
+ /// See the comments on `ItemLikeVisitor` for more details on the overall
172
+ /// visit strategy.
173
+ pub trait NestedFilter < ' hir > {
174
+ type Map : Map < ' hir > ;
175
+
176
+ /// Whether the visitor visits nested "item-like" things.
177
+ /// E.g., item, impl-item.
178
+ const INTER : bool ;
179
+ /// Whether the visitor visits "intra item-like" things.
180
+ /// E.g., function body, closure, `AnonConst`
181
+ const INTRA : bool ;
185
182
}
186
- }
187
183
188
- /// Specifies what nested things a visitor wants to visit. The most
189
- /// common choice is `OnlyBodies`, which will cause the visitor to
190
- /// visit fn bodies for fns that it encounters, but skip over nested
191
- /// item-like things.
192
- ///
193
- /// See the comments on `ItemLikeVisitor` for more details on the overall
194
- /// visit strategy.
195
- pub enum NestedVisitorMap < M > {
196
184
/// Do not visit any nested things. When you add a new
197
185
/// "non-nested" thing, you will want to audit such uses to see if
198
186
/// they remain valid.
199
187
///
200
188
/// Use this if you are only walking some particular kind of tree
201
189
/// (i.e., a type, or fn signature) and you don't want to thread a
202
190
/// HIR map around.
203
- None ,
204
-
205
- /// Do not visit nested item-like things, but visit nested things
206
- /// that are inside of an item-like.
207
- ///
208
- /// **This is the most common choice.** A very common pattern is
209
- /// to use `visit_all_item_likes()` as an outer loop,
210
- /// and to have the visitor that visits the contents of each item
211
- /// using this setting.
212
- OnlyBodies ( M ) ,
213
-
214
- /// Visits all nested things, including item-likes.
215
- ///
216
- /// **This is an unusual choice.** It is used when you want to
217
- /// process everything within their lexical context. Typically you
218
- /// kick off the visit by doing `walk_krate()`.
219
- All ( M ) ,
220
- }
221
-
222
- impl < M > NestedVisitorMap < M > {
223
- /// Returns the map to use for an "intra item-like" thing (if any).
224
- /// E.g., function body.
225
- fn intra ( self ) -> Option < M > {
226
- match self {
227
- NestedVisitorMap :: None => None ,
228
- NestedVisitorMap :: OnlyBodies ( map) => Some ( map) ,
229
- NestedVisitorMap :: All ( map) => Some ( map) ,
230
- }
231
- }
232
-
233
- /// Returns the map to use for an "item-like" thing (if any).
234
- /// E.g., item, impl-item.
235
- fn inter ( self ) -> Option < M > {
236
- match self {
237
- NestedVisitorMap :: None => None ,
238
- NestedVisitorMap :: OnlyBodies ( _) => None ,
239
- NestedVisitorMap :: All ( map) => Some ( map) ,
240
- }
191
+ pub struct None ( ( ) ) ;
192
+ impl NestedFilter < ' _ > for None {
193
+ type Map = !;
194
+ const INTER : bool = false ;
195
+ const INTRA : bool = false ;
241
196
}
242
197
}
243
198
199
+ use nested_filter:: NestedFilter ;
200
+
244
201
/// Each method of the Visitor trait is a hook to be potentially
245
202
/// overridden. Each method's default implementation recursively visits
246
203
/// the substructure of the input via the corresponding `walk` method;
@@ -258,7 +215,9 @@ impl<M> NestedVisitorMap<M> {
258
215
/// to monitor future changes to `Visitor` in case a new method with a
259
216
/// new default implementation gets introduced.)
260
217
pub trait Visitor < ' v > : Sized {
261
- type Map : Map < ' v > ;
218
+ // this type should not be overridden, it exists for convenient usage as `Self::Map`
219
+ type Map : Map < ' v > = <Self :: NestedFilter as NestedFilter < ' v > >:: Map ;
220
+ type NestedFilter : NestedFilter < ' v > = nested_filter:: None ;
262
221
263
222
///////////////////////////////////////////////////////////////////////////
264
223
// Nested items.
@@ -279,7 +238,12 @@ pub trait Visitor<'v>: Sized {
279
238
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
280
239
/// added in the future, we will see the panic in your code and
281
240
/// fix it appropriately.
282
- fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > ;
241
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
242
+ panic ! (
243
+ "nested_visit_map must be implemented or consider using \
244
+ `type NestedFilter = nested_filter::None` (the default)"
245
+ ) ;
246
+ }
283
247
284
248
/// Invoked when a nested item is encountered. By default does
285
249
/// nothing unless you override `nested_visit_map` to return other than
@@ -290,41 +254,51 @@ pub trait Visitor<'v>: Sized {
290
254
/// reason to override this method is if you want a nested pattern
291
255
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
292
256
fn visit_nested_item ( & mut self , id : ItemId ) {
293
- let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. item ( id) ) ;
294
- walk_list ! ( self , visit_item, opt_item) ;
257
+ if Self :: NestedFilter :: INTER {
258
+ let item = self . nested_visit_map ( ) . item ( id) ;
259
+ self . visit_item ( item) ;
260
+ }
295
261
}
296
262
297
263
/// Like `visit_nested_item()`, but for trait items. See
298
264
/// `visit_nested_item()` for advice on when to override this
299
265
/// method.
300
266
fn visit_nested_trait_item ( & mut self , id : TraitItemId ) {
301
- let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. trait_item ( id) ) ;
302
- walk_list ! ( self , visit_trait_item, opt_item) ;
267
+ if Self :: NestedFilter :: INTER {
268
+ let item = self . nested_visit_map ( ) . trait_item ( id) ;
269
+ self . visit_trait_item ( item) ;
270
+ }
303
271
}
304
272
305
273
/// Like `visit_nested_item()`, but for impl items. See
306
274
/// `visit_nested_item()` for advice on when to override this
307
275
/// method.
308
276
fn visit_nested_impl_item ( & mut self , id : ImplItemId ) {
309
- let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. impl_item ( id) ) ;
310
- walk_list ! ( self , visit_impl_item, opt_item) ;
277
+ if Self :: NestedFilter :: INTER {
278
+ let item = self . nested_visit_map ( ) . impl_item ( id) ;
279
+ self . visit_impl_item ( item) ;
280
+ }
311
281
}
312
282
313
283
/// Like `visit_nested_item()`, but for foreign items. See
314
284
/// `visit_nested_item()` for advice on when to override this
315
285
/// method.
316
286
fn visit_nested_foreign_item ( & mut self , id : ForeignItemId ) {
317
- let opt_item = self . nested_visit_map ( ) . inter ( ) . map ( |map| map. foreign_item ( id) ) ;
318
- walk_list ! ( self , visit_foreign_item, opt_item) ;
287
+ if Self :: NestedFilter :: INTER {
288
+ let item = self . nested_visit_map ( ) . foreign_item ( id) ;
289
+ self . visit_foreign_item ( item) ;
290
+ }
319
291
}
320
292
321
293
/// Invoked to visit the body of a function, method or closure. Like
322
294
/// visit_nested_item, does nothing by default unless you override
323
295
/// `nested_visit_map` to return other than `None`, in which case it will walk
324
296
/// the body.
325
297
fn visit_nested_body ( & mut self , id : BodyId ) {
326
- let opt_body = self . nested_visit_map ( ) . intra ( ) . map ( |map| map. body ( id) ) ;
327
- walk_list ! ( self , visit_body, opt_body) ;
298
+ if Self :: NestedFilter :: INTRA {
299
+ let body = self . nested_visit_map ( ) . body ( id) ;
300
+ self . visit_body ( body) ;
301
+ }
328
302
}
329
303
330
304
fn visit_param ( & mut self , param : & ' v Param < ' v > ) {
0 commit comments