Skip to content

Commit f55482e

Browse files
committed
rustc: replace body exprs by their ids
1 parent 069a244 commit f55482e

File tree

22 files changed

+327
-195
lines changed

22 files changed

+327
-195
lines changed

src/librustc/hir/intravisit.rs

Lines changed: 78 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ impl<'a> FnKind<'a> {
6767
}
6868
}
6969

70+
/// Specifies what nested things a visitor wants to visit. Currently there are
71+
/// two modes: `OnlyBodies` descends into item bodies, but not into nested
72+
/// items; `All` descends into item bodies and nested items.
73+
pub enum NestedVisitMode {
74+
OnlyBodies,
75+
All
76+
}
77+
7078
/// Each method of the Visitor trait is a hook to be potentially
7179
/// overridden. Each method's default implementation recursively visits
7280
/// the substructure of the input via the corresponding `walk` method;
@@ -102,7 +110,7 @@ pub trait Visitor<'v> : Sized {
102110
/// `panic!()`. This way, if a new `visit_nested_XXX` variant is
103111
/// added in the future, we will see the panic in your code and
104112
/// fix it appropriately.
105-
fn nested_visit_map(&mut self) -> Option<&Map<'v>> {
113+
fn nested_visit_map(&mut self) -> Option<(&Map<'v>, NestedVisitMode)> {
106114
None
107115
}
108116

@@ -116,7 +124,7 @@ pub trait Visitor<'v> : Sized {
116124
/// but cannot supply a `Map`; see `nested_visit_map` for advice.
117125
#[allow(unused_variables)]
118126
fn visit_nested_item(&mut self, id: ItemId) {
119-
let opt_item = self.nested_visit_map()
127+
let opt_item = map_for_item(self)
120128
.map(|map| map.expect_item(id.id));
121129
if let Some(item) = opt_item {
122130
self.visit_item(item);
@@ -128,13 +136,25 @@ pub trait Visitor<'v> : Sized {
128136
/// method.
129137
#[allow(unused_variables)]
130138
fn visit_nested_impl_item(&mut self, id: ImplItemId) {
131-
let opt_item = self.nested_visit_map()
139+
let opt_item = map_for_item(self)
132140
.map(|map| map.impl_item(id));
133141
if let Some(item) = opt_item {
134142
self.visit_impl_item(item);
135143
}
136144
}
137145

146+
/// Invoked to visit the body of a function, method or closure. Like
147+
/// visit_nested_item, does nothing by default unless you override
148+
/// `nested_visit_map` to return `Some(_)`, in which case it will walk the
149+
/// body.
150+
fn visit_body(&mut self, id: ExprId) {
151+
let opt_expr = map_for_body(self)
152+
.map(|map| map.expr(id));
153+
if let Some(expr) = opt_expr {
154+
self.visit_expr(expr);
155+
}
156+
}
157+
138158
/// Visit the top-level item and (optionally) nested items / impl items. See
139159
/// `visit_nested_item` for details.
140160
fn visit_item(&mut self, i: &'v Item) {
@@ -200,7 +220,7 @@ pub trait Visitor<'v> : Sized {
200220
fn visit_where_predicate(&mut self, predicate: &'v WherePredicate) {
201221
walk_where_predicate(self, predicate)
202222
}
203-
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Expr, s: Span, id: NodeId) {
223+
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: ExprId, s: Span, id: NodeId) {
204224
walk_fn(self, fk, fd, b, s, id)
205225
}
206226
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
@@ -279,6 +299,19 @@ pub trait Visitor<'v> : Sized {
279299
}
280300
}
281301

302+
fn map_for_body<'v, V: Visitor<'v>>(visitor: &mut V) -> Option<&Map<'v>> {
303+
visitor.nested_visit_map().map(|(map, _mode)| map)
304+
}
305+
306+
fn map_for_item<'v, V: Visitor<'v>>(visitor: &mut V) -> Option<&Map<'v>> {
307+
visitor.nested_visit_map().and_then(|(map, mode)| {
308+
match mode {
309+
NestedVisitMode::OnlyBodies => None,
310+
NestedVisitMode::All => Some(map)
311+
}
312+
})
313+
}
314+
282315
pub fn walk_opt_name<'v, V: Visitor<'v>>(visitor: &mut V, span: Span, opt_name: Option<Name>) {
283316
if let Some(name) = opt_name {
284317
visitor.visit_name(span, name);
@@ -363,7 +396,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
363396
visitor.visit_ty(typ);
364397
visitor.visit_expr(expr);
365398
}
366-
ItemFn(ref declaration, unsafety, constness, abi, ref generics, ref body) => {
399+
ItemFn(ref declaration, unsafety, constness, abi, ref generics, body_id) => {
367400
visitor.visit_fn(FnKind::ItemFn(item.name,
368401
generics,
369402
unsafety,
@@ -372,7 +405,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
372405
&item.vis,
373406
&item.attrs),
374407
declaration,
375-
body,
408+
body_id,
376409
item.span,
377410
item.id)
378411
}
@@ -697,13 +730,25 @@ pub fn walk_fn_kind<'v, V: Visitor<'v>>(visitor: &mut V, function_kind: FnKind<'
697730
pub fn walk_fn<'v, V: Visitor<'v>>(visitor: &mut V,
698731
function_kind: FnKind<'v>,
699732
function_declaration: &'v FnDecl,
700-
function_body: &'v Expr,
733+
body_id: ExprId,
701734
_span: Span,
702735
id: NodeId) {
703736
visitor.visit_id(id);
704737
walk_fn_decl(visitor, function_declaration);
705738
walk_fn_kind(visitor, function_kind);
706-
visitor.visit_expr(function_body)
739+
visitor.visit_body(body_id)
740+
}
741+
742+
pub fn walk_fn_with_body<'v, V: Visitor<'v>>(visitor: &mut V,
743+
function_kind: FnKind<'v>,
744+
function_declaration: &'v FnDecl,
745+
body: &'v Expr,
746+
_span: Span,
747+
id: NodeId) {
748+
visitor.visit_id(id);
749+
walk_fn_decl(visitor, function_declaration);
750+
walk_fn_kind(visitor, function_kind);
751+
visitor.visit_expr(body)
707752
}
708753

709754
pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v TraitItem) {
@@ -720,13 +765,13 @@ pub fn walk_trait_item<'v, V: Visitor<'v>>(visitor: &mut V, trait_item: &'v Trai
720765
visitor.visit_generics(&sig.generics);
721766
walk_fn_decl(visitor, &sig.decl);
722767
}
723-
MethodTraitItem(ref sig, Some(ref body)) => {
768+
MethodTraitItem(ref sig, Some(body_id)) => {
724769
visitor.visit_fn(FnKind::Method(trait_item.name,
725770
sig,
726771
None,
727772
&trait_item.attrs),
728773
&sig.decl,
729-
body,
774+
body_id,
730775
trait_item.span,
731776
trait_item.id);
732777
}
@@ -752,13 +797,13 @@ pub fn walk_impl_item<'v, V: Visitor<'v>>(visitor: &mut V, impl_item: &'v ImplIt
752797
visitor.visit_ty(ty);
753798
visitor.visit_expr(expr);
754799
}
755-
ImplItemKind::Method(ref sig, ref body) => {
800+
ImplItemKind::Method(ref sig, body_id) => {
756801
visitor.visit_fn(FnKind::Method(impl_item.name,
757802
sig,
758803
Some(&impl_item.vis),
759804
&impl_item.attrs),
760805
&sig.decl,
761-
body,
806+
body_id,
762807
impl_item.span,
763808
impl_item.id);
764809
}
@@ -883,7 +928,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
883928
visitor.visit_expr(subexpression);
884929
walk_list!(visitor, visit_arm, arms);
885930
}
886-
ExprClosure(_, ref function_declaration, ref body, _fn_decl_span) => {
931+
ExprClosure(_, ref function_declaration, body, _fn_decl_span) => {
887932
visitor.visit_fn(FnKind::Closure(&expression.attrs),
888933
function_declaration,
889934
body,
@@ -998,34 +1043,40 @@ impl IdRange {
9981043
}
9991044

10001045

1001-
pub struct IdRangeComputingVisitor {
1002-
pub result: IdRange,
1046+
pub struct IdRangeComputingVisitor<'a, 'ast: 'a> {
1047+
result: IdRange,
1048+
map: &'a map::Map<'ast>,
10031049
}
10041050

1005-
impl IdRangeComputingVisitor {
1006-
pub fn new() -> IdRangeComputingVisitor {
1007-
IdRangeComputingVisitor { result: IdRange::max() }
1051+
impl<'a, 'ast> IdRangeComputingVisitor<'a, 'ast> {
1052+
pub fn new(map: &'a map::Map<'ast>) -> IdRangeComputingVisitor<'a, 'ast> {
1053+
IdRangeComputingVisitor { result: IdRange::max(), map: map }
10081054
}
10091055

10101056
pub fn result(&self) -> IdRange {
10111057
self.result
10121058
}
10131059
}
10141060

1015-
impl<'v> Visitor<'v> for IdRangeComputingVisitor {
1061+
impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> {
1062+
fn nested_visit_map(&mut self) -> Option<(&Map<'ast>, NestedVisitMode)> {
1063+
Some((&self.map, NestedVisitMode::OnlyBodies))
1064+
}
1065+
10161066
fn visit_id(&mut self, id: NodeId) {
10171067
self.result.add(id);
10181068
}
10191069
}
10201070

10211071
/// Computes the id range for a single fn body, ignoring nested items.
1022-
pub fn compute_id_range_for_fn_body(fk: FnKind,
1023-
decl: &FnDecl,
1024-
body: &Expr,
1025-
sp: Span,
1026-
id: NodeId)
1027-
-> IdRange {
1028-
let mut visitor = IdRangeComputingVisitor::new();
1029-
visitor.visit_fn(fk, decl, body, sp, id);
1072+
pub fn compute_id_range_for_fn_body<'v>(fk: FnKind<'v>,
1073+
decl: &'v FnDecl,
1074+
body: &'v Expr,
1075+
sp: Span,
1076+
id: NodeId,
1077+
map: &map::Map<'v>)
1078+
-> IdRange {
1079+
let mut visitor = IdRangeComputingVisitor::new(map);
1080+
walk_fn_with_body(&mut visitor, fk, decl, body, sp, id);
10301081
visitor.result()
10311082
}

src/librustc/hir/lowering.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -845,12 +845,14 @@ impl<'a> LoweringContext<'a> {
845845
}
846846
ItemKind::Fn(ref decl, unsafety, constness, abi, ref generics, ref body) => {
847847
let body = self.lower_block(body);
848+
let body = self.expr_block(body, ThinVec::new());
849+
let body_id = self.record_expr(body);
848850
hir::ItemFn(self.lower_fn_decl(decl),
849851
self.lower_unsafety(unsafety),
850852
self.lower_constness(constness),
851853
abi,
852854
self.lower_generics(generics),
853-
P(self.expr_block(body, ThinVec::new())))
855+
body_id)
854856
}
855857
ItemKind::Mod(ref m) => hir::ItemMod(self.lower_mod(m)),
856858
ItemKind::ForeignMod(ref nm) => hir::ItemForeignMod(self.lower_foreign_mod(nm)),
@@ -917,7 +919,8 @@ impl<'a> LoweringContext<'a> {
917919
hir::MethodTraitItem(this.lower_method_sig(sig),
918920
body.as_ref().map(|x| {
919921
let body = this.lower_block(x);
920-
P(this.expr_block(body, ThinVec::new()))
922+
let expr = this.expr_block(body, ThinVec::new());
923+
this.record_expr(expr)
921924
}))
922925
}
923926
TraitItemKind::Type(ref bounds, ref default) => {
@@ -945,8 +948,9 @@ impl<'a> LoweringContext<'a> {
945948
}
946949
ImplItemKind::Method(ref sig, ref body) => {
947950
let body = this.lower_block(body);
948-
hir::ImplItemKind::Method(this.lower_method_sig(sig),
949-
P(this.expr_block(body, ThinVec::new())))
951+
let expr = this.expr_block(body, ThinVec::new());
952+
let expr_id = this.record_expr(expr);
953+
hir::ImplItemKind::Method(this.lower_method_sig(sig), expr_id)
950954
}
951955
ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(this.lower_ty(ty)),
952956
ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"),
@@ -1395,9 +1399,10 @@ impl<'a> LoweringContext<'a> {
13951399
}
13961400
ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
13971401
self.with_parent_def(e.id, |this| {
1402+
let expr = this.lower_expr(body);
13981403
hir::ExprClosure(this.lower_capture_clause(capture_clause),
13991404
this.lower_fn_decl(decl),
1400-
P(this.lower_expr(body)),
1405+
this.record_expr(expr),
14011406
fn_decl_span)
14021407
})
14031408
}

src/librustc/hir/map/blocks.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub trait MaybeFnLike { fn is_fn_like(&self) -> bool; }
4848
/// Components shared by fn-like things (fn items, methods, closures).
4949
pub struct FnParts<'a> {
5050
pub decl: &'a FnDecl,
51-
pub body: &'a Expr,
51+
pub body: ast::ExprId,
5252
pub kind: FnKind<'a>,
5353
pub span: Span,
5454
pub id: NodeId,
@@ -115,7 +115,7 @@ struct ItemFnParts<'a> {
115115
abi: abi::Abi,
116116
vis: &'a ast::Visibility,
117117
generics: &'a ast::Generics,
118-
body: &'a Expr,
118+
body: ast::ExprId,
119119
id: NodeId,
120120
span: Span,
121121
attrs: &'a [Attribute],
@@ -125,14 +125,14 @@ struct ItemFnParts<'a> {
125125
/// for use when implementing FnLikeNode operations.
126126
struct ClosureParts<'a> {
127127
decl: &'a FnDecl,
128-
body: &'a Expr,
128+
body: ast::ExprId,
129129
id: NodeId,
130130
span: Span,
131131
attrs: &'a [Attribute],
132132
}
133133

134134
impl<'a> ClosureParts<'a> {
135-
fn new(d: &'a FnDecl, b: &'a Expr, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
135+
fn new(d: &'a FnDecl, b: ast::ExprId, id: NodeId, s: Span, attrs: &'a [Attribute]) -> Self {
136136
ClosureParts {
137137
decl: d,
138138
body: b,
@@ -172,9 +172,9 @@ impl<'a> FnLikeNode<'a> {
172172
}
173173
}
174174

175-
pub fn body(self) -> &'a Expr {
176-
self.handle(|i: ItemFnParts<'a>| &*i.body,
177-
|_, _, _: &'a ast::MethodSig, _, body: &'a ast::Expr, _, _| body,
175+
pub fn body(self) -> ast::ExprId {
176+
self.handle(|i: ItemFnParts<'a>| i.body,
177+
|_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body,
178178
|c: ClosureParts<'a>| c.body)
179179
}
180180

@@ -215,21 +215,21 @@ impl<'a> FnLikeNode<'a> {
215215
Name,
216216
&'a ast::MethodSig,
217217
Option<&'a ast::Visibility>,
218-
&'a ast::Expr,
218+
ast::ExprId,
219219
Span,
220220
&'a [Attribute])
221221
-> A,
222222
C: FnOnce(ClosureParts<'a>) -> A,
223223
{
224224
match self.node {
225225
map::NodeItem(i) => match i.node {
226-
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, ref block) =>
226+
ast::ItemFn(ref decl, unsafety, constness, abi, ref generics, block) =>
227227
item_fn(ItemFnParts {
228228
id: i.id,
229229
name: i.name,
230230
decl: &decl,
231231
unsafety: unsafety,
232-
body: &block,
232+
body: block,
233233
generics: generics,
234234
abi: abi,
235235
vis: &i.vis,
@@ -240,14 +240,14 @@ impl<'a> FnLikeNode<'a> {
240240
_ => bug!("item FnLikeNode that is not fn-like"),
241241
},
242242
map::NodeTraitItem(ti) => match ti.node {
243-
ast::MethodTraitItem(ref sig, Some(ref body)) => {
243+
ast::MethodTraitItem(ref sig, Some(body)) => {
244244
method(ti.id, ti.name, sig, None, body, ti.span, &ti.attrs)
245245
}
246246
_ => bug!("trait method FnLikeNode that is not fn-like"),
247247
},
248248
map::NodeImplItem(ii) => {
249249
match ii.node {
250-
ast::ImplItemKind::Method(ref sig, ref body) => {
250+
ast::ImplItemKind::Method(ref sig, body) => {
251251
method(ii.id, ii.name, sig, Some(&ii.vis), body, ii.span, &ii.attrs)
252252
}
253253
_ => {
@@ -256,8 +256,8 @@ impl<'a> FnLikeNode<'a> {
256256
}
257257
}
258258
map::NodeExpr(e) => match e.node {
259-
ast::ExprClosure(_, ref decl, ref block, _fn_decl_span) =>
260-
closure(ClosureParts::new(&decl, &block, e.id, e.span, &e.attrs)),
259+
ast::ExprClosure(_, ref decl, block, _fn_decl_span) =>
260+
closure(ClosureParts::new(&decl, block, e.id, e.span, &e.attrs)),
261261
_ => bug!("expr FnLikeNode that is not fn-like"),
262262
},
263263
_ => bug!("other FnLikeNode that is not fn-like"),

0 commit comments

Comments
 (0)