Skip to content

Commit 77739a7

Browse files
committed
auto merge of #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 #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 pnkfelix/rust@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 pnkfelix/rust@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)