Skip to content

Commit d597f54

Browse files
committed
auto merge of #8539 : pnkfelix/rust/fsk-visitor-vpar-defaults-step2, r=graydon,nikomatsakis
r? @nikomatsakis Follow up to #8527 (which was step 1 of 5). See that for overall description Part of #7081
2 parents 81a7816 + 6c15f21 commit d597f54

File tree

8 files changed

+602
-446
lines changed

8 files changed

+602
-446
lines changed

src/librustc/middle/check_const.rs

+60-36
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,71 @@ use util::ppaux;
1717

1818
use syntax::ast::*;
1919
use syntax::codemap;
20-
use syntax::{oldvisit, ast_util, ast_map};
20+
use syntax::{ast_util, ast_map};
21+
use syntax::visit::Visitor;
22+
use syntax::visit;
23+
24+
struct CheckCrateVisitor {
25+
sess: Session,
26+
ast_map: ast_map::map,
27+
def_map: resolve::DefMap,
28+
method_map: typeck::method_map,
29+
tcx: ty::ctxt,
30+
}
31+
32+
impl Visitor<bool> for CheckCrateVisitor {
33+
fn visit_item(&mut self, i:@item, env:bool) {
34+
check_item(self, self.sess, self.ast_map, self.def_map, i, env);
35+
}
36+
fn visit_pat(&mut self, p:@pat, env:bool) {
37+
check_pat(self, p, env);
38+
}
39+
fn visit_expr(&mut self, ex:@expr, env:bool) {
40+
check_expr(self, self.sess, self.def_map, self.method_map,
41+
self.tcx, ex, env);
42+
}
43+
}
2144

2245
pub fn check_crate(sess: Session,
2346
crate: &Crate,
2447
ast_map: ast_map::map,
2548
def_map: resolve::DefMap,
2649
method_map: typeck::method_map,
2750
tcx: ty::ctxt) {
28-
oldvisit::visit_crate(crate, (false, oldvisit::mk_vt(@oldvisit::Visitor {
29-
visit_item: |a,b| check_item(sess, ast_map, def_map, a, b),
30-
visit_pat: check_pat,
31-
visit_expr: |a,b|
32-
check_expr(sess, def_map, method_map, tcx, a, b),
33-
.. *oldvisit::default_visitor()
34-
})));
51+
let mut v = CheckCrateVisitor {
52+
sess: sess,
53+
ast_map: ast_map,
54+
def_map: def_map,
55+
method_map: method_map,
56+
tcx: tcx,
57+
};
58+
visit::walk_crate(&mut v, crate, false);
3559
sess.abort_if_errors();
3660
}
3761

38-
pub fn check_item(sess: Session,
62+
pub fn check_item(v: &mut CheckCrateVisitor,
63+
sess: Session,
3964
ast_map: ast_map::map,
4065
def_map: resolve::DefMap,
4166
it: @item,
42-
(_is_const, v): (bool,
43-
oldvisit::vt<bool>)) {
67+
_is_const: bool) {
4468
match it.node {
4569
item_static(_, _, ex) => {
46-
(v.visit_expr)(ex, (true, v));
70+
v.visit_expr(ex, true);
4771
check_item_recursion(sess, ast_map, def_map, it);
4872
}
4973
item_enum(ref enum_definition, _) => {
5074
for var in (*enum_definition).variants.iter() {
5175
for ex in var.node.disr_expr.iter() {
52-
(v.visit_expr)(*ex, (true, v));
76+
v.visit_expr(*ex, true);
5377
}
5478
}
5579
}
56-
_ => oldvisit::visit_item(it, (false, v))
80+
_ => visit::walk_item(v, it, false)
5781
}
5882
}
5983

60-
pub fn check_pat(p: @pat, (_is_const, v): (bool, oldvisit::vt<bool>)) {
84+
pub fn check_pat(v: &mut CheckCrateVisitor, p: @pat, _is_const: bool) {
6185
fn is_str(e: @expr) -> bool {
6286
match e.node {
6387
expr_vstore(
@@ -72,22 +96,22 @@ pub fn check_pat(p: @pat, (_is_const, v): (bool, oldvisit::vt<bool>)) {
7296
}
7397
match p.node {
7498
// Let through plain ~-string literals here
75-
pat_lit(a) => if !is_str(a) { (v.visit_expr)(a, (true, v)); },
99+
pat_lit(a) => if !is_str(a) { v.visit_expr(a, true); },
76100
pat_range(a, b) => {
77-
if !is_str(a) { (v.visit_expr)(a, (true, v)); }
78-
if !is_str(b) { (v.visit_expr)(b, (true, v)); }
101+
if !is_str(a) { v.visit_expr(a, true); }
102+
if !is_str(b) { v.visit_expr(b, true); }
79103
}
80-
_ => oldvisit::visit_pat(p, (false, v))
104+
_ => visit::walk_pat(v, p, false)
81105
}
82106
}
83107

84-
pub fn check_expr(sess: Session,
108+
pub fn check_expr(v: &mut CheckCrateVisitor,
109+
sess: Session,
85110
def_map: resolve::DefMap,
86111
method_map: typeck::method_map,
87112
tcx: ty::ctxt,
88113
e: @expr,
89-
(is_const, v): (bool,
90-
oldvisit::vt<bool>)) {
114+
is_const: bool) {
91115
if is_const {
92116
match e.node {
93117
expr_unary(_, deref, _) => { }
@@ -152,8 +176,8 @@ pub fn check_expr(sess: Session,
152176
}
153177
}
154178
}
155-
expr_paren(e) => { check_expr(sess, def_map, method_map,
156-
tcx, e, (is_const, v)); }
179+
expr_paren(e) => { check_expr(v, sess, def_map, method_map,
180+
tcx, e, is_const); }
157181
expr_vstore(_, expr_vstore_slice) |
158182
expr_vec(_, m_imm) |
159183
expr_addr_of(m_imm, _) |
@@ -192,7 +216,7 @@ pub fn check_expr(sess: Session,
192216
}
193217
_ => ()
194218
}
195-
oldvisit::visit_expr(e, (is_const, v));
219+
visit::walk_expr(v, e, is_const);
196220
}
197221

198222
#[deriving(Clone)]
@@ -204,6 +228,8 @@ struct env {
204228
idstack: @mut ~[NodeId]
205229
}
206230

231+
struct CheckItemRecursionVisitor;
232+
207233
// Make sure a const item doesn't recursively refer to itself
208234
// FIXME: Should use the dependency graph when it's available (#1356)
209235
pub fn check_item_recursion(sess: Session,
@@ -218,36 +244,34 @@ pub fn check_item_recursion(sess: Session,
218244
idstack: @mut ~[]
219245
};
220246

221-
let visitor = oldvisit::mk_vt(@oldvisit::Visitor {
222-
visit_item: visit_item,
223-
visit_expr: visit_expr,
224-
.. *oldvisit::default_visitor()
225-
});
226-
(visitor.visit_item)(it, (env, visitor));
247+
let mut visitor = CheckItemRecursionVisitor;
248+
visitor.visit_item(it, env);
249+
}
227250

228-
fn visit_item(it: @item, (env, v): (env, oldvisit::vt<env>)) {
251+
impl Visitor<env> for CheckItemRecursionVisitor {
252+
fn visit_item(&mut self, it: @item, env: env) {
229253
if env.idstack.iter().any(|x| x == &(it.id)) {
230254
env.sess.span_fatal(env.root_it.span, "recursive constant");
231255
}
232256
env.idstack.push(it.id);
233-
oldvisit::visit_item(it, (env, v));
257+
visit::walk_item(self, it, env);
234258
env.idstack.pop();
235259
}
236260

237-
fn visit_expr(e: @expr, (env, v): (env, oldvisit::vt<env>)) {
261+
fn visit_expr(&mut self, e: @expr, env: env) {
238262
match e.node {
239263
expr_path(*) => match env.def_map.find(&e.id) {
240264
Some(&def_static(def_id, _)) if ast_util::is_local(def_id) =>
241265
match env.ast_map.get_copy(&def_id.node) {
242266
ast_map::node_item(it, _) => {
243-
(v.visit_item)(it, (env, v));
267+
self.visit_item(it, env);
244268
}
245269
_ => fail!("const not bound to an item")
246270
},
247271
_ => ()
248272
},
249273
_ => ()
250274
}
251-
oldvisit::visit_expr(e, (env, v));
275+
visit::walk_expr(self, e, env);
252276
}
253277
}

src/librustc/middle/check_loop.rs

+30-24
Original file line numberDiff line numberDiff line change
@@ -12,58 +12,64 @@
1212
use middle::ty;
1313

1414
use syntax::ast::*;
15-
use syntax::oldvisit;
15+
use syntax::visit;
16+
use syntax::visit::Visitor;
1617

1718
#[deriving(Clone)]
1819
pub struct Context {
1920
in_loop: bool,
2021
can_ret: bool
2122
}
2223

24+
struct CheckLoopVisitor {
25+
tcx: ty::ctxt,
26+
}
27+
2328
pub fn check_crate(tcx: ty::ctxt, crate: &Crate) {
24-
oldvisit::visit_crate(crate,
25-
(Context { in_loop: false, can_ret: true },
26-
oldvisit::mk_vt(@oldvisit::Visitor {
27-
visit_item: |i, (_cx, v)| {
28-
oldvisit::visit_item(i, (Context {
29+
visit::walk_crate(&mut CheckLoopVisitor { tcx: tcx },
30+
crate,
31+
Context { in_loop: false, can_ret: true });
32+
}
33+
34+
impl Visitor<Context> for CheckLoopVisitor {
35+
fn visit_item(&mut self, i:@item, _cx:Context) {
36+
visit::walk_item(self, i, Context {
2937
in_loop: false,
3038
can_ret: true
31-
}, v));
32-
},
33-
visit_expr: |e: @expr, (cx, v): (Context, oldvisit::vt<Context>)| {
39+
});
40+
}
41+
42+
fn visit_expr(&mut self, e:@expr, cx:Context) {
43+
3444
match e.node {
3545
expr_while(e, ref b) => {
36-
(v.visit_expr)(e, (cx, v));
37-
(v.visit_block)(b, (Context { in_loop: true,.. cx }, v));
46+
self.visit_expr(e, cx);
47+
self.visit_block(b, Context { in_loop: true,.. cx });
3848
}
3949
expr_loop(ref b, _) => {
40-
(v.visit_block)(b, (Context { in_loop: true,.. cx }, v));
50+
self.visit_block(b, Context { in_loop: true,.. cx });
4151
}
4252
expr_fn_block(_, ref b) => {
43-
(v.visit_block)(b, (Context {
44-
in_loop: false,
45-
can_ret: false
46-
}, v));
53+
self.visit_block(b, Context { in_loop: false, can_ret: false });
4754
}
4855
expr_break(_) => {
4956
if !cx.in_loop {
50-
tcx.sess.span_err(e.span, "`break` outside of loop");
57+
self.tcx.sess.span_err(e.span, "`break` outside of loop");
5158
}
5259
}
5360
expr_again(_) => {
5461
if !cx.in_loop {
55-
tcx.sess.span_err(e.span, "`loop` outside of loop");
62+
self.tcx.sess.span_err(e.span, "`loop` outside of loop");
5663
}
5764
}
5865
expr_ret(oe) => {
5966
if !cx.can_ret {
60-
tcx.sess.span_err(e.span, "`return` in block function");
67+
self.tcx.sess.span_err(e.span, "`return` in block function");
6168
}
62-
oldvisit::visit_expr_opt(oe, (cx, v));
69+
visit::walk_expr_opt(self, oe, cx);
6370
}
64-
_ => oldvisit::visit_expr(e, (cx, v))
71+
_ => visit::walk_expr(self, e, cx)
6572
}
66-
},
67-
.. *oldvisit::default_visitor()
68-
})));
73+
74+
}
6975
}

src/librustc/middle/check_match.rs

+35-19
Original file line numberDiff line numberDiff line change
@@ -25,35 +25,50 @@ use extra::sort;
2525
use syntax::ast::*;
2626
use syntax::ast_util::{unguarded_pat, walk_pat};
2727
use syntax::codemap::{span, dummy_sp, spanned};
28-
use syntax::oldvisit;
28+
use syntax::visit;
29+
use syntax::visit::{Visitor,fn_kind};
2930

3031
pub struct MatchCheckCtxt {
3132
tcx: ty::ctxt,
3233
method_map: method_map,
3334
moves_map: moves::MovesMap
3435
}
3536

37+
struct CheckMatchVisitor {
38+
cx: @MatchCheckCtxt
39+
}
40+
41+
impl Visitor<()> for CheckMatchVisitor {
42+
fn visit_expr(&mut self, ex:@expr, e:()) {
43+
check_expr(self, self.cx, ex, e);
44+
}
45+
fn visit_local(&mut self, l:@Local, e:()) {
46+
check_local(self, self.cx, l, e);
47+
}
48+
fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:span, n:NodeId, e:()) {
49+
check_fn(self, self.cx, fk, fd, b, s, n, e);
50+
}
51+
}
52+
3653
pub fn check_crate(tcx: ty::ctxt,
3754
method_map: method_map,
3855
moves_map: moves::MovesMap,
3956
crate: &Crate) {
4057
let cx = @MatchCheckCtxt {tcx: tcx,
4158
method_map: method_map,
4259
moves_map: moves_map};
43-
oldvisit::visit_crate(crate, ((), oldvisit::mk_vt(@oldvisit::Visitor {
44-
visit_expr: |a,b| check_expr(cx, a, b),
45-
visit_local: |a,b| check_local(cx, a, b),
46-
visit_fn: |kind, decl, body, sp, id, (e, v)|
47-
check_fn(cx, kind, decl, body, sp, id, (e, v)),
48-
.. *oldvisit::default_visitor::<()>()
49-
})));
60+
let mut v = CheckMatchVisitor { cx: cx };
61+
62+
visit::walk_crate(&mut v, crate, ());
63+
5064
tcx.sess.abort_if_errors();
5165
}
5266

53-
pub fn check_expr(cx: @MatchCheckCtxt,
67+
pub fn check_expr(v: &mut CheckMatchVisitor,
68+
cx: @MatchCheckCtxt,
5469
ex: @expr,
55-
(s, v): ((), oldvisit::vt<()>)) {
56-
oldvisit::visit_expr(ex, (s, v));
70+
s: ()) {
71+
visit::walk_expr(v, ex, s);
5772
match ex.node {
5873
expr_match(scrut, ref arms) => {
5974
// First, check legality of move bindings.
@@ -787,10 +802,11 @@ pub fn default(cx: &MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> {
787802
else { None }
788803
}
789804

790-
pub fn check_local(cx: &MatchCheckCtxt,
805+
pub fn check_local(v: &mut CheckMatchVisitor,
806+
cx: &MatchCheckCtxt,
791807
loc: @Local,
792-
(s, v): ((), oldvisit::vt<()>)) {
793-
oldvisit::visit_local(loc, (s, v));
808+
s: ()) {
809+
visit::walk_local(v, loc, s);
794810
if is_refutable(cx, loc.pat) {
795811
cx.tcx.sess.span_err(loc.pat.span,
796812
"refutable pattern in local binding");
@@ -800,15 +816,15 @@ pub fn check_local(cx: &MatchCheckCtxt,
800816
check_legality_of_move_bindings(cx, false, [ loc.pat ]);
801817
}
802818

803-
pub fn check_fn(cx: &MatchCheckCtxt,
804-
kind: &oldvisit::fn_kind,
819+
pub fn check_fn(v: &mut CheckMatchVisitor,
820+
cx: &MatchCheckCtxt,
821+
kind: &visit::fn_kind,
805822
decl: &fn_decl,
806823
body: &Block,
807824
sp: span,
808825
id: NodeId,
809-
(s, v): ((),
810-
oldvisit::vt<()>)) {
811-
oldvisit::visit_fn(kind, decl, body, sp, id, (s, v));
826+
s: ()) {
827+
visit::walk_fn(v, kind, decl, body, sp, id, s);
812828
for input in decl.inputs.iter() {
813829
if is_refutable(cx, input.pat) {
814830
cx.tcx.sess.span_err(input.pat.span,

0 commit comments

Comments
 (0)