Skip to content

Commit 77739a7

Browse files
committed
auto merge of rust-lang#8527 : pnkfelix/rust/fsk-visitor-vpar-defaults-step1, r=nikomatsakis
Rewriting visit.rs to operate on a borrowed `&mut V` where `<V:Visitor>` r? @nikomatsakis r? @pcwalton This is the first in a planned series of incremental pull requests. (There will probably be five pull requests including this one, though they can be combined or split as necessary.) Part of rust-lang#7081. (But definitely does *not* complete it, not on its own, and not even after all five parts land; there are still a few loose ends to tie up or trim afterwards.) The bulk of this change for this particular PR is 3d83010, which has the changes necessary to visit.rs to support everything else that comes later. The other commits are illustrating the standard mechanical transformation that I am applying. One important point for nearly *all* of these pull requests: I was deliberately *not* trying to be intelligent in the transformation. * My goal was to minimize code churn, and make the transformation as mechanical as possible. * For example, I kept the separation between the Visitor struct (corresponding to the earlier vtable of functions that were potentially closed over local state) and the explicitly passed (and clones) visitor Env. I am certain that this is almost always unnecessary, and a later task will be to go through an meld the Env's into the Visitors as appropriate. (My original goal had been to make such melding part of this task; that's why I turned them into a (Env, vtable) tuple way back when. But I digress.) * Also, my main goal here was to get rid of the record of `@fn`'s as described by the oldvisit.rs API. (This series gets rid of all but one such case; I'm still investigating that.) There is *still* plenty of `@`-boxing left to be removed, I'm sure, and even still some `@fn`'s too; removing all of those is not the goal here; its just to get rid of the encoded protocol of `@fn`'s in the (old)visit API. To see where things will be going in the future (i.e., to get a sneak-preview of future pull-requests in the series), see: * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step1 (that's this one) * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step2 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step3 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step4 * https://github.com/pnkfelix/rust/commits/fsk-visitor-vpar-defaults-step5 * Note that between step 4 and step 5 there is just a single commit, but its a doozy because its the only case where my mechanical transformation did not apply, and thus more serious rewriting was necessary. See commit da902b2
2 parents 790e6bb + ef854c9 commit 77739a7

File tree

8 files changed

+538
-403
lines changed

8 files changed

+538
-403
lines changed

src/librustc/metadata/encoder.rs

Lines changed: 81 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ use syntax::attr;
3939
use syntax::attr::AttrMetaMethods;
4040
use syntax::diagnostic::span_handler;
4141
use syntax::parse::token::special_idents;
42-
use syntax::{ast_util, oldvisit};
42+
use syntax::ast_util;
43+
use syntax::visit;
4344
use syntax::parse::token;
4445
use syntax;
4546
use writer = extra::ebml::writer;
@@ -1184,6 +1185,74 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
11841185
ebml_w.end_tag();
11851186
}
11861187

1188+
fn my_visit_expr(_e:@expr) { }
1189+
1190+
fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
1191+
ecx_ptr:*int, index: @mut ~[entry<i64>]) {
1192+
match items.get_copy(&i.id) {
1193+
ast_map::node_item(_, pt) => {
1194+
let mut ebml_w = ebml_w.clone();
1195+
// See above
1196+
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1197+
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
1198+
}
1199+
_ => fail!("bad item")
1200+
}
1201+
}
1202+
1203+
fn my_visit_foreign_item(ni:@foreign_item, items: ast_map::map, ebml_w:&writer::Encoder,
1204+
ecx_ptr:*int, index: @mut ~[entry<i64>]) {
1205+
match items.get_copy(&ni.id) {
1206+
ast_map::node_foreign_item(_, abi, _, pt) => {
1207+
debug!("writing foreign item %s::%s",
1208+
ast_map::path_to_str(
1209+
*pt,
1210+
token::get_ident_interner()),
1211+
token::ident_to_str(&ni.ident));
1212+
1213+
let mut ebml_w = ebml_w.clone();
1214+
// See above
1215+
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1216+
encode_info_for_foreign_item(ecx,
1217+
&mut ebml_w,
1218+
ni,
1219+
index,
1220+
pt,
1221+
abi);
1222+
}
1223+
// case for separate item and foreign-item tables
1224+
_ => fail!("bad foreign item")
1225+
}
1226+
}
1227+
1228+
struct EncodeVisitor {
1229+
ebml_w_for_visit_item: writer::Encoder,
1230+
ebml_w_for_visit_foreign_item: writer::Encoder,
1231+
ecx_ptr:*int,
1232+
items: ast_map::map,
1233+
index: @mut ~[entry<i64>],
1234+
}
1235+
1236+
impl visit::Visitor<()> for EncodeVisitor {
1237+
fn visit_expr(&mut self, ex:@expr, _:()) { my_visit_expr(ex); }
1238+
fn visit_item(&mut self, i:@item, _:()) {
1239+
visit::walk_item(self, i, ());
1240+
my_visit_item(i,
1241+
self.items,
1242+
&self.ebml_w_for_visit_item,
1243+
self.ecx_ptr,
1244+
self.index);
1245+
}
1246+
fn visit_foreign_item(&mut self, ni:@foreign_item, _:()) {
1247+
visit::walk_foreign_item(self, ni, ());
1248+
my_visit_foreign_item(ni,
1249+
self.items,
1250+
&self.ebml_w_for_visit_foreign_item,
1251+
self.ecx_ptr,
1252+
self.index);
1253+
}
1254+
}
1255+
11871256
fn encode_info_for_items(ecx: &EncodeContext,
11881257
ebml_w: &mut writer::Encoder,
11891258
crate: &Crate)
@@ -1201,54 +1270,17 @@ fn encode_info_for_items(ecx: &EncodeContext,
12011270
let items = ecx.tcx.items;
12021271

12031272
// See comment in `encode_side_tables_for_ii` in astencode
1204-
let ecx_ptr : *() = unsafe { cast::transmute(ecx) };
1205-
1206-
oldvisit::visit_crate(crate, ((), oldvisit::mk_vt(@oldvisit::Visitor {
1207-
visit_expr: |_e, (_cx, _v)| { },
1208-
visit_item: {
1209-
let ebml_w = (*ebml_w).clone();
1210-
|i, (cx, v)| {
1211-
oldvisit::visit_item(i, (cx, v));
1212-
match items.get_copy(&i.id) {
1213-
ast_map::node_item(_, pt) => {
1214-
let mut ebml_w = ebml_w.clone();
1215-
// See above
1216-
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1217-
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
1218-
}
1219-
_ => fail!("bad item")
1220-
}
1221-
}
1222-
},
1223-
visit_foreign_item: {
1224-
let ebml_w = (*ebml_w).clone();
1225-
|ni, (cx, v)| {
1226-
oldvisit::visit_foreign_item(ni, (cx, v));
1227-
match items.get_copy(&ni.id) {
1228-
ast_map::node_foreign_item(_, abi, _, pt) => {
1229-
debug!("writing foreign item %s::%s",
1230-
ast_map::path_to_str(
1231-
*pt,
1232-
token::get_ident_interner()),
1233-
token::ident_to_str(&ni.ident));
1234-
1235-
let mut ebml_w = ebml_w.clone();
1236-
// See above
1237-
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1238-
encode_info_for_foreign_item(ecx,
1239-
&mut ebml_w,
1240-
ni,
1241-
index,
1242-
pt,
1243-
abi);
1244-
}
1245-
// case for separate item and foreign-item tables
1246-
_ => fail!("bad foreign item")
1247-
}
1248-
}
1249-
},
1250-
..*oldvisit::default_visitor()
1251-
})));
1273+
let ecx_ptr : *int = unsafe { cast::transmute(ecx) };
1274+
let mut visitor = EncodeVisitor {
1275+
index: index,
1276+
items: items,
1277+
ecx_ptr: ecx_ptr,
1278+
ebml_w_for_visit_item: (*ebml_w).clone(),
1279+
ebml_w_for_visit_foreign_item: (*ebml_w).clone(),
1280+
};
1281+
1282+
visit::walk_crate(&mut visitor, crate, ());
1283+
12521284
ebml_w.end_tag();
12531285
return /*bad*/(*index).clone();
12541286
}

src/librustc/middle/borrowck/gather_loans/mod.rs

Lines changed: 65 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ use syntax::ast;
3131
use syntax::ast_util::id_range;
3232
use syntax::codemap::span;
3333
use syntax::print::pprust;
34-
use syntax::oldvisit;
34+
use syntax::visit;
35+
use syntax::visit::Visitor;
36+
use syntax::ast::{expr, fn_kind, fn_decl, Block, NodeId, stmt, pat, Local};
3537

3638
mod lifetime;
3739
mod restrictions;
@@ -72,6 +74,30 @@ struct GatherLoanCtxt {
7274
repeating_ids: ~[ast::NodeId]
7375
}
7476

77+
struct GatherLoanVisitor;
78+
79+
impl visit::Visitor<@mut GatherLoanCtxt> for GatherLoanVisitor {
80+
fn visit_expr(&mut self, ex:@expr, e:@mut GatherLoanCtxt) {
81+
gather_loans_in_expr(self, ex, e);
82+
}
83+
fn visit_block(&mut self, b:&Block, e:@mut GatherLoanCtxt) {
84+
gather_loans_in_block(self, b, e);
85+
}
86+
fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block,
87+
s:span, n:NodeId, e:@mut GatherLoanCtxt) {
88+
gather_loans_in_fn(self, fk, fd, b, s, n, e);
89+
}
90+
fn visit_stmt(&mut self, s:@stmt, e:@mut GatherLoanCtxt) {
91+
add_stmt_to_map(self, s, e);
92+
}
93+
fn visit_pat(&mut self, p:@pat, e:@mut GatherLoanCtxt) {
94+
add_pat_to_id_range(self, p, e);
95+
}
96+
fn visit_local(&mut self, l:@Local, e:@mut GatherLoanCtxt) {
97+
gather_loans_in_local(self, l, e);
98+
}
99+
}
100+
75101
pub fn gather_loans(bccx: @BorrowckCtxt,
76102
decl: &ast::fn_decl,
77103
body: &ast::Block)
@@ -85,64 +111,57 @@ pub fn gather_loans(bccx: @BorrowckCtxt,
85111
move_data: @mut MoveData::new()
86112
};
87113
glcx.gather_fn_arg_patterns(decl, body);
88-
let v = oldvisit::mk_vt(@oldvisit::Visitor {
89-
visit_expr: gather_loans_in_expr,
90-
visit_block: gather_loans_in_block,
91-
visit_fn: gather_loans_in_fn,
92-
visit_stmt: add_stmt_to_map,
93-
visit_pat: add_pat_to_id_range,
94-
visit_local: gather_loans_in_local,
95-
.. *oldvisit::default_visitor()
96-
});
97-
(v.visit_block)(body, (glcx, v));
114+
115+
let mut v = GatherLoanVisitor;
116+
v.visit_block(body, glcx);
98117
return (glcx.id_range, glcx.all_loans, glcx.move_data);
99118
}
100119

101-
fn add_pat_to_id_range(p: @ast::pat,
102-
(this, v): (@mut GatherLoanCtxt,
103-
oldvisit::vt<@mut GatherLoanCtxt>)) {
120+
fn add_pat_to_id_range(v: &mut GatherLoanVisitor,
121+
p: @ast::pat,
122+
this: @mut GatherLoanCtxt) {
104123
// NB: This visitor function just adds the pat ids into the id
105124
// range. We gather loans that occur in patterns using the
106125
// `gather_pat()` method below. Eventually these two should be
107126
// brought together.
108127
this.id_range.add(p.id);
109-
oldvisit::visit_pat(p, (this, v));
128+
visit::walk_pat(v, p, this);
110129
}
111130

112-
fn gather_loans_in_fn(fk: &oldvisit::fn_kind,
131+
fn gather_loans_in_fn(v: &mut GatherLoanVisitor,
132+
fk: &fn_kind,
113133
decl: &ast::fn_decl,
114134
body: &ast::Block,
115135
sp: span,
116136
id: ast::NodeId,
117-
(this, v): (@mut GatherLoanCtxt,
118-
oldvisit::vt<@mut GatherLoanCtxt>)) {
137+
this: @mut GatherLoanCtxt) {
119138
match fk {
120139
// Do not visit items here, the outer loop in borrowck/mod
121140
// will visit them for us in turn.
122-
&oldvisit::fk_item_fn(*) | &oldvisit::fk_method(*) => {
141+
&visit::fk_item_fn(*) | &visit::fk_method(*) => {
123142
return;
124143
}
125144

126145
// Visit closures as part of the containing item.
127-
&oldvisit::fk_anon(*) | &oldvisit::fk_fn_block(*) => {
146+
&visit::fk_anon(*) | &visit::fk_fn_block(*) => {
128147
this.push_repeating_id(body.id);
129-
oldvisit::visit_fn(fk, decl, body, sp, id, (this, v));
148+
visit::walk_fn(v, fk, decl, body, sp, id, this);
130149
this.pop_repeating_id(body.id);
131150
this.gather_fn_arg_patterns(decl, body);
132151
}
133152
}
134153
}
135154

136-
fn gather_loans_in_block(blk: &ast::Block,
137-
(this, vt): (@mut GatherLoanCtxt,
138-
oldvisit::vt<@mut GatherLoanCtxt>)) {
155+
fn gather_loans_in_block(v: &mut GatherLoanVisitor,
156+
blk: &ast::Block,
157+
this: @mut GatherLoanCtxt) {
139158
this.id_range.add(blk.id);
140-
oldvisit::visit_block(blk, (this, vt));
159+
visit::walk_block(v, blk, this);
141160
}
142161

143-
fn gather_loans_in_local(local: @ast::Local,
144-
(this, vt): (@mut GatherLoanCtxt,
145-
oldvisit::vt<@mut GatherLoanCtxt>)) {
162+
fn gather_loans_in_local(v: &mut GatherLoanVisitor,
163+
local: @ast::Local,
164+
this: @mut GatherLoanCtxt) {
146165
match local.init {
147166
None => {
148167
// Variable declarations without initializers are considered "moves":
@@ -173,12 +192,13 @@ fn gather_loans_in_local(local: @ast::Local,
173192
}
174193
}
175194

176-
oldvisit::visit_local(local, (this, vt));
195+
visit::walk_local(v, local, this);
177196
}
178197

179-
fn gather_loans_in_expr(ex: @ast::expr,
180-
(this, vt): (@mut GatherLoanCtxt,
181-
oldvisit::vt<@mut GatherLoanCtxt>)) {
198+
199+
fn gather_loans_in_expr(v: &mut GatherLoanVisitor,
200+
ex: @ast::expr,
201+
this: @mut GatherLoanCtxt) {
182202
let bccx = this.bccx;
183203
let tcx = bccx.tcx;
184204

@@ -218,7 +238,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
218238
// for the lifetime `scope_r` of the resulting ptr:
219239
let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex));
220240
this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r);
221-
oldvisit::visit_expr(ex, (this, vt));
241+
visit::walk_expr(v, ex, this);
222242
}
223243

224244
ast::expr_assign(l, _) | ast::expr_assign_op(_, _, l, _) => {
@@ -235,7 +255,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
235255
// with moves etc, just ignore.
236256
}
237257
}
238-
oldvisit::visit_expr(ex, (this, vt));
258+
visit::walk_expr(v, ex, this);
239259
}
240260

241261
ast::expr_match(ex_v, ref arms) => {
@@ -245,7 +265,7 @@ fn gather_loans_in_expr(ex: @ast::expr,
245265
this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id)));
246266
}
247267
}
248-
oldvisit::visit_expr(ex, (this, vt));
268+
visit::walk_expr(v, ex, this);
249269
}
250270

251271
ast::expr_index(_, _, arg) |
@@ -259,36 +279,36 @@ fn gather_loans_in_expr(ex: @ast::expr,
259279
let scope_r = ty::re_scope(ex.id);
260280
let arg_cmt = this.bccx.cat_expr(arg);
261281
this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r);
262-
oldvisit::visit_expr(ex, (this, vt));
282+
visit::walk_expr(v, ex, this);
263283
}
264284

265285
// see explanation attached to the `root_ub` field:
266286
ast::expr_while(cond, ref body) => {
267287
// during the condition, can only root for the condition
268288
this.push_repeating_id(cond.id);
269-
(vt.visit_expr)(cond, (this, vt));
289+
v.visit_expr(cond, this);
270290
this.pop_repeating_id(cond.id);
271291

272292
// during body, can only root for the body
273293
this.push_repeating_id(body.id);
274-
(vt.visit_block)(body, (this, vt));
294+
v.visit_block(body, this);
275295
this.pop_repeating_id(body.id);
276296
}
277297

278298
// see explanation attached to the `root_ub` field:
279299
ast::expr_loop(ref body, _) => {
280300
this.push_repeating_id(body.id);
281-
oldvisit::visit_expr(ex, (this, vt));
301+
visit::walk_expr(v, ex, this);
282302
this.pop_repeating_id(body.id);
283303
}
284304

285305
ast::expr_fn_block(*) => {
286306
gather_moves::gather_captures(this.bccx, this.move_data, ex);
287-
oldvisit::visit_expr(ex, (this, vt));
307+
visit::walk_expr(v, ex, this);
288308
}
289309

290310
_ => {
291-
oldvisit::visit_expr(ex, (this, vt));
311+
visit::walk_expr(v, ex, this);
292312
}
293313
}
294314
}
@@ -770,14 +790,14 @@ impl GatherLoanCtxt {
770790

771791
// Setting up info that preserve needs.
772792
// This is just the most convenient place to do it.
773-
fn add_stmt_to_map(stmt: @ast::stmt,
774-
(this, vt): (@mut GatherLoanCtxt,
775-
oldvisit::vt<@mut GatherLoanCtxt>)) {
793+
fn add_stmt_to_map(v: &mut GatherLoanVisitor,
794+
stmt: @ast::stmt,
795+
this: @mut GatherLoanCtxt) {
776796
match stmt.node {
777797
ast::stmt_expr(_, id) | ast::stmt_semi(_, id) => {
778798
this.bccx.stmt_map.insert(id);
779799
}
780800
_ => ()
781801
}
782-
oldvisit::visit_stmt(stmt, (this, vt));
802+
visit::walk_stmt(v, stmt, this);
783803
}

0 commit comments

Comments
 (0)