Skip to content

Commit 104125d

Browse files
nikomatsakisflodiebold
authored andcommitted
revamp Visitor with a single method for controlling nested visits
1 parent 8575184 commit 104125d

File tree

35 files changed

+197
-174
lines changed

35 files changed

+197
-174
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
317329
pub 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

10631075
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)
10661078
}
10671079

10681080
fn visit_id(&mut self, id: NodeId) {

src/librustc/hir/map/collector.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use super::*;
1212

13-
use hir::intravisit::Visitor;
13+
use hir::intravisit::{Visitor, NestedVisitorMap};
1414
use hir::def_id::DefId;
1515
use middle::cstore::InlinedItem;
1616
use std::iter::repeat;
@@ -91,7 +91,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
9191
/// deep walking so that we walk nested items in the context of
9292
/// their outer items.
9393
94-
fn nested_visit_map(&mut self) -> Option<&map::Map<'ast>> {
94+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
9595
panic!("visit_nested_xxx must be manually implemented in this visitor")
9696
}
9797

src/librustc/hir/map/def_collector.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use hir::map::definitions::*;
1212

1313
use hir;
14-
use hir::intravisit;
14+
use hir::intravisit::{self, Visitor, NestedVisitorMap};
1515
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
1616

1717
use middle::cstore::InlinedItem;
@@ -326,9 +326,10 @@ impl<'a> visit::Visitor for DefCollector<'a> {
326326
}
327327

328328
// We walk the HIR rather than the AST when reading items from metadata.
329-
impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> {
330-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'ast>> {
331-
None
329+
impl<'ast> Visitor<'ast> for DefCollector<'ast> {
330+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
331+
// note however that we override `visit_body` below
332+
NestedVisitorMap::None
332333
}
333334

334335
fn visit_body(&mut self, id: hir::ExprId) {

src/librustc/lint/context.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -791,12 +791,8 @@ impl<'a, 'tcx> hir_visit::Visitor<'tcx> for LateContext<'a, 'tcx> {
791791
/// Because lints are scoped lexically, we want to walk nested
792792
/// items in the context of the outer item, so enable
793793
/// deep-walking.
794-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
795-
Some(&self.tcx.map)
796-
}
797-
798-
fn nested_visit_mode(&mut self) -> hir_visit::NestedVisitMode {
799-
hir_visit::NestedVisitMode::All
794+
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
795+
hir_visit::NestedVisitorMap::All(&self.tcx.map)
800796
}
801797

802798
fn visit_item(&mut self, it: &'tcx hir::Item) {
@@ -1113,8 +1109,8 @@ struct IdVisitor<'a, 'b: 'a, 'tcx: 'a+'b> {
11131109

11141110
// Output any lints that were previously added to the session.
11151111
impl<'a, 'b, 'tcx> hir_visit::Visitor<'tcx> for IdVisitor<'a, 'b, 'tcx> {
1116-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
1117-
Some(&self.cx.tcx.map)
1112+
fn nested_visit_map<'this>(&'this mut self) -> hir_visit::NestedVisitorMap<'this, 'tcx> {
1113+
hir_visit::NestedVisitorMap::OnlyBodies(&self.cx.tcx.map)
11181114
}
11191115

11201116
fn visit_id(&mut self, id: ast::NodeId) {

src/librustc/middle/dataflow.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ fn build_nodeid_to_index(decl: Option<&hir::FnDecl>,
193193
let mut formals = Formals { entry: entry, index: index };
194194
intravisit::walk_fn_decl(&mut formals, decl);
195195
impl<'a, 'v> intravisit::Visitor<'v> for Formals<'a> {
196-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'v>> { None }
196+
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'v> {
197+
panic!("should not encounter fn bodies or items")
198+
}
197199

198200
fn visit_pat(&mut self, p: &hir::Pat) {
199201
self.index.entry(p.id).or_insert(vec![]).push(self.entry);

src/librustc/middle/dead.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use dep_graph::DepNode;
1616
use hir::map as ast_map;
1717
use hir::{self, PatKind};
18-
use hir::intravisit::{self, Visitor, NestedVisitMode};
18+
use hir::intravisit::{self, Visitor, NestedVisitorMap};
1919
use hir::itemlikevisit::ItemLikeVisitor;
2020

2121
use middle::privacy;
@@ -221,8 +221,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
221221
}
222222

223223
impl<'a, 'tcx> Visitor<'tcx> for MarkSymbolVisitor<'a, 'tcx> {
224-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
225-
Some(&self.tcx.map)
224+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
225+
NestedVisitorMap::OnlyBodies(&self.tcx.map)
226226
}
227227

228228
fn visit_variant_data(&mut self, def: &'tcx hir::VariantData, _: ast::Name,
@@ -510,12 +510,10 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> {
510510
/// on inner functions when the outer function is already getting
511511
/// an error. We could do this also by checking the parents, but
512512
/// this is how the code is setup and it seems harmless enough.
513-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
514-
Some(&self.tcx.map)
513+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
514+
NestedVisitorMap::All(&self.tcx.map)
515515
}
516516

517-
fn nested_visit_mode(&mut self) -> NestedVisitMode { NestedVisitMode::All }
518-
519517
fn visit_item(&mut self, item: &'tcx hir::Item) {
520518
if self.should_warn_about_item(item) {
521519
self.warn_dead_code(

src/librustc/middle/effect.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use syntax::ast;
2121
use syntax_pos::Span;
2222
use hir::{self, PatKind};
2323
use hir::def::Def;
24-
use hir::intravisit::{self, FnKind, Visitor};
24+
use hir::intravisit::{self, FnKind, Visitor, NestedVisitorMap};
2525

2626
#[derive(Copy, Clone)]
2727
struct UnsafeContext {
@@ -93,8 +93,8 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
9393
}
9494

9595
impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> {
96-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
97-
Some(&self.tcx.map)
96+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
97+
NestedVisitorMap::OnlyBodies(&self.tcx.map)
9898
}
9999

100100
fn visit_fn(&mut self, fn_kind: FnKind<'tcx>, fn_decl: &'tcx hir::FnDecl,

src/librustc/middle/intrinsicck.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use ty::layout::{LayoutError, Pointer, SizeSkeleton};
1919
use syntax::abi::Abi::RustIntrinsic;
2020
use syntax::ast;
2121
use syntax_pos::Span;
22-
use hir::intravisit::{self, Visitor, FnKind};
22+
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
2323
use hir;
2424

2525
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
@@ -117,8 +117,8 @@ impl<'a, 'gcx, 'tcx> ExprVisitor<'a, 'gcx, 'tcx> {
117117
}
118118

119119
impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
120-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
121-
Some(&self.tcx.map)
120+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
121+
NestedVisitorMap::OnlyBodies(&self.tcx.map)
122122
}
123123

124124
// const, static and N in [T; N].
@@ -163,8 +163,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ItemVisitor<'a, 'tcx> {
163163
}
164164

165165
impl<'a, 'gcx, 'tcx> Visitor<'gcx> for ExprVisitor<'a, 'gcx, 'tcx> {
166-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'gcx>> {
167-
Some(&self.infcx.tcx.map)
166+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'gcx> {
167+
NestedVisitorMap::OnlyBodies(&self.infcx.tcx.map)
168168
}
169169

170170
fn visit_expr(&mut self, expr: &'gcx hir::Expr) {

src/librustc/middle/liveness.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ use syntax_pos::Span;
128128
use hir::Expr;
129129
use hir;
130130
use hir::print::{expr_to_string, block_to_string};
131-
use hir::intravisit::{self, Visitor, FnKind};
131+
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
132132

133133
/// For use with `propagate_through_loop`.
134134
enum LoopKind<'a> {
@@ -183,9 +183,10 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt) -> String {
183183
}
184184

185185
impl<'a, 'tcx> Visitor<'tcx> for IrMaps<'a, 'tcx> {
186-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
187-
Some(&self.tcx.map)
186+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
187+
NestedVisitorMap::OnlyBodies(&self.tcx.map)
188188
}
189+
189190
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl,
190191
b: hir::ExprId, s: Span, id: NodeId) {
191192
visit_fn(self, fk, fd, b, s, id);
@@ -352,9 +353,10 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
352353
}
353354

354355
impl<'a, 'tcx> Visitor<'tcx> for Liveness<'a, 'tcx> {
355-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
356-
Some(&self.ir.tcx.map)
356+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
357+
NestedVisitorMap::OnlyBodies(&self.ir.tcx.map)
357358
}
359+
358360
fn visit_fn(&mut self, _: FnKind<'tcx>, _: &'tcx hir::FnDecl,
359361
_: hir::ExprId, _: Span, _: NodeId) {
360362
// do not check contents of nested fns

src/librustc/middle/reachable.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use syntax::abi::Abi;
2828
use syntax::ast;
2929
use syntax::attr;
3030
use hir;
31-
use hir::intravisit::{Visitor};
31+
use hir::intravisit::{Visitor, NestedVisitorMap};
3232
use hir::itemlikevisit::ItemLikeVisitor;
3333
use hir::intravisit;
3434

@@ -89,8 +89,8 @@ struct ReachableContext<'a, 'tcx: 'a> {
8989
}
9090

9191
impl<'a, 'tcx> Visitor<'tcx> for ReachableContext<'a, 'tcx> {
92-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'tcx>> {
93-
Some(&self.tcx.map)
92+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
93+
NestedVisitorMap::OnlyBodies(&self.tcx.map)
9494
}
9595

9696
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {

src/librustc/middle/region.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use syntax::ast::{self, NodeId};
3131
use syntax_pos::Span;
3232

3333
use hir;
34-
use hir::intravisit::{self, Visitor, FnKind};
34+
use hir::intravisit::{self, Visitor, FnKind, NestedVisitorMap};
3535
use hir::{Block, Item, FnDecl, Arm, Pat, PatKind, Stmt, Expr, Local};
3636

3737
#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash, RustcEncodable,
@@ -1170,8 +1170,8 @@ impl<'ast, 'a> RegionResolutionVisitor<'ast, 'a> {
11701170
}
11711171

11721172
impl<'ast, 'a> Visitor<'ast> for RegionResolutionVisitor<'ast, 'a> {
1173-
fn nested_visit_map(&mut self) -> Option<&hir::map::Map<'ast>> {
1174-
Some(&self.map)
1173+
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'ast> {
1174+
NestedVisitorMap::OnlyBodies(&self.map)
11751175
}
11761176

11771177
fn visit_block(&mut self, b: &'ast Block) {

0 commit comments

Comments
 (0)