@@ -70,9 +70,42 @@ impl<'a> FnKind<'a> {
7070/// Specifies what nested things a visitor wants to visit. Currently there are
7171/// two modes: `OnlyBodies` descends into item bodies, but not into nested
7272/// 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+ }
76109}
77110
78111/// Each method of the Visitor trait is a hook to be potentially
@@ -109,13 +142,7 @@ pub trait Visitor<'v> : Sized {
109142 /// `panic!()`. This way, if a new `visit_nested_XXX` variant is
110143 /// added in the future, we will see the panic in your code and
111144 /// 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 > ;
119146
120147 /// Invoked when a nested item is encountered. By default does
121148 /// nothing unless you override `nested_visit_map` to return
@@ -127,8 +154,7 @@ pub trait Visitor<'v> : Sized {
127154 /// but cannot supply a `Map`; see `nested_visit_map` for advice.
128155 #[ allow( unused_variables) ]
129156 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 ) ) ;
132158 if let Some ( item) = opt_item {
133159 self . visit_item ( item) ;
134160 }
@@ -139,8 +165,7 @@ pub trait Visitor<'v> : Sized {
139165 /// method.
140166 #[ allow( unused_variables) ]
141167 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) ) ;
144169 if let Some ( item) = opt_item {
145170 self . visit_impl_item ( item) ;
146171 }
@@ -151,8 +176,7 @@ pub trait Visitor<'v> : Sized {
151176 /// `nested_visit_map` to return `Some(_)`, in which case it will walk the
152177 /// body.
153178 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) ) ;
156180 if let Some ( expr) = opt_expr {
157181 self . visit_expr ( expr) ;
158182 }
@@ -302,18 +326,6 @@ pub trait Visitor<'v> : Sized {
302326 }
303327}
304328
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-
317329pub fn walk_opt_name < ' v , V : Visitor < ' v > > ( visitor : & mut V , span : Span , opt_name : Option < Name > ) {
318330 if let Some ( name) = opt_name {
319331 visitor. visit_name ( span, name) ;
@@ -1061,8 +1073,8 @@ impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> {
10611073}
10621074
10631075impl < ' 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 )
10661078 }
10671079
10681080 fn visit_id ( & mut self , id : NodeId ) {
0 commit comments