Skip to content

Commit e6e678f

Browse files
committed
auto merge of #8623 : pnkfelix/rust/fsk-visitor-vpar-defaults-step4, r=nmatsakis
Follow up to #8619 (step 3 of 5). (See #8527, which was step 1 of 5, for the full outline.) Part of #7081.
2 parents 4bdceb9 + f93864c commit e6e678f

File tree

8 files changed

+314
-217
lines changed

8 files changed

+314
-217
lines changed

src/librustc/middle/borrowck/check_loans.rs

+49-34
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ use syntax::ast::{m_mutbl, m_imm, m_const};
2727
use syntax::ast;
2828
use syntax::ast_util;
2929
use syntax::codemap::span;
30-
use syntax::oldvisit;
30+
use syntax::visit;
31+
use syntax::visit::Visitor;
3132
use util::ppaux::Repr;
3233

3334
#[deriving(Clone)]
@@ -39,6 +40,27 @@ struct CheckLoanCtxt<'self> {
3940
reported: @mut HashSet<ast::NodeId>,
4041
}
4142

43+
struct CheckLoanVisitor;
44+
45+
impl<'self> Visitor<CheckLoanCtxt<'self>> for CheckLoanVisitor {
46+
fn visit_expr<'a>(&mut self, ex:@ast::expr, e:CheckLoanCtxt<'a>) {
47+
check_loans_in_expr(self, ex, e);
48+
}
49+
fn visit_local(&mut self, l:@ast::Local, e:CheckLoanCtxt) {
50+
check_loans_in_local(self, l, e);
51+
}
52+
fn visit_block(&mut self, b:&ast::Block, e:CheckLoanCtxt) {
53+
check_loans_in_block(self, b, e);
54+
}
55+
fn visit_pat(&mut self, p:@ast::pat, e:CheckLoanCtxt) {
56+
check_loans_in_pat(self, p, e);
57+
}
58+
fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
59+
b:&ast::Block, s:span, n:ast::NodeId, e:CheckLoanCtxt) {
60+
check_loans_in_fn(self, fk, fd, b, s, n, e);
61+
}
62+
}
63+
4264
pub fn check_loans(bccx: @BorrowckCtxt,
4365
dfcx_loans: &LoanDataFlow,
4466
move_data: move_data::FlowedMoveData,
@@ -54,15 +76,8 @@ pub fn check_loans(bccx: @BorrowckCtxt,
5476
reported: @mut HashSet::new(),
5577
};
5678

57-
let vt = oldvisit::mk_vt(@oldvisit::Visitor {
58-
visit_expr: check_loans_in_expr,
59-
visit_local: check_loans_in_local,
60-
visit_block: check_loans_in_block,
61-
visit_pat: check_loans_in_pat,
62-
visit_fn: check_loans_in_fn,
63-
.. *oldvisit::default_visitor()
64-
});
65-
(vt.visit_block)(body, (clcx, vt));
79+
let mut vt = CheckLoanVisitor;
80+
vt.visit_block(body, clcx);
6681
}
6782

6883
enum MoveError {
@@ -626,27 +641,27 @@ impl<'self> CheckLoanCtxt<'self> {
626641
}
627642
}
628643

629-
fn check_loans_in_fn<'a>(fk: &oldvisit::fn_kind,
644+
fn check_loans_in_fn<'a>(visitor: &mut CheckLoanVisitor,
645+
fk: &visit::fn_kind,
630646
decl: &ast::fn_decl,
631647
body: &ast::Block,
632648
sp: span,
633649
id: ast::NodeId,
634-
(this, visitor): (CheckLoanCtxt<'a>,
635-
oldvisit::vt<CheckLoanCtxt<'a>>)) {
650+
this: CheckLoanCtxt<'a>) {
636651
match *fk {
637-
oldvisit::fk_item_fn(*) |
638-
oldvisit::fk_method(*) => {
652+
visit::fk_item_fn(*) |
653+
visit::fk_method(*) => {
639654
// Don't process nested items.
640655
return;
641656
}
642657

643-
oldvisit::fk_anon(*) |
644-
oldvisit::fk_fn_block(*) => {
658+
visit::fk_anon(*) |
659+
visit::fk_fn_block(*) => {
645660
check_captured_variables(this, id, sp);
646661
}
647662
}
648663

649-
oldvisit::visit_fn(fk, decl, body, sp, id, (this, visitor));
664+
visit::walk_fn(visitor, fk, decl, body, sp, id, this);
650665

651666
fn check_captured_variables(this: CheckLoanCtxt,
652667
closure_id: ast::NodeId,
@@ -689,16 +704,16 @@ fn check_loans_in_fn<'a>(fk: &oldvisit::fn_kind,
689704
}
690705
}
691706

692-
fn check_loans_in_local<'a>(local: @ast::Local,
693-
(this, vt): (CheckLoanCtxt<'a>,
694-
oldvisit::vt<CheckLoanCtxt<'a>>)) {
695-
oldvisit::visit_local(local, (this, vt));
707+
fn check_loans_in_local<'a>(vt: &mut CheckLoanVisitor,
708+
local: @ast::Local,
709+
this: CheckLoanCtxt<'a>) {
710+
visit::walk_local(vt, local, this);
696711
}
697712

698-
fn check_loans_in_expr<'a>(expr: @ast::expr,
699-
(this, vt): (CheckLoanCtxt<'a>,
700-
oldvisit::vt<CheckLoanCtxt<'a>>)) {
701-
oldvisit::visit_expr(expr, (this, vt));
713+
fn check_loans_in_expr<'a>(vt: &mut CheckLoanVisitor,
714+
expr: @ast::expr,
715+
this: CheckLoanCtxt<'a>) {
716+
visit::walk_expr(vt, expr, this);
702717

703718
debug!("check_loans_in_expr(expr=%s)",
704719
expr.repr(this.tcx()));
@@ -749,19 +764,19 @@ fn check_loans_in_expr<'a>(expr: @ast::expr,
749764
}
750765
}
751766

752-
fn check_loans_in_pat<'a>(pat: @ast::pat,
753-
(this, vt): (CheckLoanCtxt<'a>,
754-
oldvisit::vt<CheckLoanCtxt<'a>>))
767+
fn check_loans_in_pat<'a>(vt: &mut CheckLoanVisitor,
768+
pat: @ast::pat,
769+
this: CheckLoanCtxt<'a>)
755770
{
756771
this.check_for_conflicting_loans(pat.id);
757772
this.check_move_out_from_id(pat.id, pat.span);
758-
oldvisit::visit_pat(pat, (this, vt));
773+
visit::walk_pat(vt, pat, this);
759774
}
760775

761-
fn check_loans_in_block<'a>(blk: &ast::Block,
762-
(this, vt): (CheckLoanCtxt<'a>,
763-
oldvisit::vt<CheckLoanCtxt<'a>>))
776+
fn check_loans_in_block<'a>(vt: &mut CheckLoanVisitor,
777+
blk: &ast::Block,
778+
this: CheckLoanCtxt<'a>)
764779
{
765-
oldvisit::visit_block(blk, (this, vt));
780+
visit::walk_block(vt, blk, this);
766781
this.check_for_conflicting_loans(blk.id);
767782
}

src/librustc/middle/entry.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ use syntax::ast::{Crate, NodeId, item, item_fn};
1515
use syntax::ast_map;
1616
use syntax::attr;
1717
use syntax::codemap::span;
18-
use syntax::oldvisit::{default_visitor, mk_vt, vt, Visitor, visit_crate};
19-
use syntax::oldvisit::{visit_item};
2018
use syntax::parse::token::special_idents;
19+
use syntax::visit;
20+
use syntax::visit::Visitor;
2121
use std::util;
2222

2323
struct EntryContext {
@@ -39,7 +39,13 @@ struct EntryContext {
3939
non_main_fns: ~[(NodeId, span)],
4040
}
4141

42-
type EntryVisitor = vt<@mut EntryContext>;
42+
struct EntryVisitor;
43+
44+
impl Visitor<@mut EntryContext> for EntryVisitor {
45+
fn visit_item(&mut self, item:@item, ctxt:@mut EntryContext) {
46+
find_item(item, ctxt, self);
47+
}
48+
}
4349

4450
pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map) {
4551

@@ -65,15 +71,14 @@ pub fn find_entry_point(session: Session, crate: &Crate, ast_map: ast_map::map)
6571
non_main_fns: ~[],
6672
};
6773

68-
visit_crate(crate, (ctxt, mk_vt(@Visitor {
69-
visit_item: |item, (ctxt, visitor)| find_item(item, ctxt, visitor),
70-
.. *default_visitor()
71-
})));
74+
let mut v = EntryVisitor;
75+
76+
visit::walk_crate(&mut v, crate, ctxt);
7277

7378
configure_main(ctxt);
7479
}
7580

76-
fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) {
81+
fn find_item(item: @item, ctxt: @mut EntryContext, visitor: &mut EntryVisitor) {
7782
match item.node {
7883
item_fn(*) => {
7984
if item.ident == special_idents::main {
@@ -120,7 +125,7 @@ fn find_item(item: @item, ctxt: @mut EntryContext, visitor: EntryVisitor) {
120125
_ => ()
121126
}
122127

123-
visit_item(item, (ctxt, visitor));
128+
visit::walk_item(visitor, item, ctxt);
124129
}
125130

126131
fn configure_main(ctxt: @mut EntryContext) {

src/librustc/middle/freevars.rs

+61-37
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ use middle::ty;
1717

1818
use std::hashmap::HashMap;
1919
use syntax::codemap::span;
20-
use syntax::{ast, ast_util, oldvisit};
20+
use syntax::{ast, ast_util};
21+
use syntax::visit;
22+
use syntax::visit::Visitor;
23+
use syntax::ast::{item};
2124

2225
// A vector of defs representing the free variables referred to in a function.
2326
// (The def_upvar will already have been stripped).
@@ -29,27 +32,27 @@ pub struct freevar_entry {
2932
pub type freevar_info = @~[@freevar_entry];
3033
pub type freevar_map = @mut HashMap<ast::NodeId, freevar_info>;
3134

32-
// Searches through part of the AST for all references to locals or
33-
// upvars in this frame and returns the list of definition IDs thus found.
34-
// Since we want to be able to collect upvars in some arbitrary piece
35-
// of the AST, we take a walker function that we invoke with a visitor
36-
// in order to start the search.
37-
fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block)
38-
-> freevar_info {
39-
let seen = @mut HashMap::new();
40-
let refs = @mut ~[];
35+
struct CollectFreevarsVisitor {
36+
seen: @mut HashMap<ast::NodeId, ()>,
37+
refs: @mut ~[@freevar_entry],
38+
def_map: resolve::DefMap,
39+
}
40+
41+
impl Visitor<int> for CollectFreevarsVisitor {
4142

42-
fn ignore_item(_i: @ast::item, (_depth, _v): (int, oldvisit::vt<int>)) { }
43+
fn visit_item(&mut self, _:@item, _:int) {
44+
// ignore_item
45+
}
46+
47+
fn visit_expr(&mut self, expr:@ast::expr, depth:int) {
4348

44-
let walk_expr: @fn(expr: @ast::expr, (int, oldvisit::vt<int>)) =
45-
|expr, (depth, v)| {
4649
match expr.node {
4750
ast::expr_fn_block(*) => {
48-
oldvisit::visit_expr(expr, (depth + 1, v))
51+
visit::walk_expr(self, expr, depth + 1)
4952
}
5053
ast::expr_path(*) | ast::expr_self => {
5154
let mut i = 0;
52-
match def_map.find(&expr.id) {
55+
match self.def_map.find(&expr.id) {
5356
None => fail!("path not found"),
5457
Some(&df) => {
5558
let mut def = df;
@@ -62,28 +65,58 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block)
6265
}
6366
if i == depth { // Made it to end of loop
6467
let dnum = ast_util::def_id_of_def(def).node;
65-
if !seen.contains_key(&dnum) {
66-
refs.push(@freevar_entry {
68+
if !self.seen.contains_key(&dnum) {
69+
self.refs.push(@freevar_entry {
6770
def: def,
6871
span: expr.span,
6972
});
70-
seen.insert(dnum, ());
73+
self.seen.insert(dnum, ());
7174
}
7275
}
7376
}
7477
}
7578
}
76-
_ => oldvisit::visit_expr(expr, (depth, v))
79+
_ => visit::walk_expr(self, expr, depth)
7780
}
78-
};
81+
}
7982

80-
let v = oldvisit::mk_vt(@oldvisit::Visitor {visit_item: ignore_item,
81-
visit_expr: walk_expr,
82-
.. *oldvisit::default_visitor()});
83-
(v.visit_block)(blk, (1, v));
83+
84+
}
85+
86+
// Searches through part of the AST for all references to locals or
87+
// upvars in this frame and returns the list of definition IDs thus found.
88+
// Since we want to be able to collect upvars in some arbitrary piece
89+
// of the AST, we take a walker function that we invoke with a visitor
90+
// in order to start the search.
91+
fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block)
92+
-> freevar_info {
93+
let seen = @mut HashMap::new();
94+
let refs = @mut ~[];
95+
96+
let mut v = CollectFreevarsVisitor {
97+
seen: seen,
98+
refs: refs,
99+
def_map: def_map,
100+
};
101+
102+
v.visit_block(blk, 1);
84103
return @(*refs).clone();
85104
}
86105

106+
struct AnnotateFreevarsVisitor {
107+
def_map: resolve::DefMap,
108+
freevars: freevar_map,
109+
}
110+
111+
impl Visitor<()> for AnnotateFreevarsVisitor {
112+
fn visit_fn(&mut self, fk:&visit::fn_kind, fd:&ast::fn_decl,
113+
blk:&ast::Block, s:span, nid:ast::NodeId, _:()) {
114+
let vars = collect_freevars(self.def_map, blk);
115+
self.freevars.insert(nid, vars);
116+
visit::walk_fn(self, fk, fd, blk, s, nid, ());
117+
}
118+
}
119+
87120
// Build a map from every function and for-each body to a set of the
88121
// freevars contained in it. The implementation is not particularly
89122
// efficient as it fully recomputes the free variables at every
@@ -93,20 +126,11 @@ pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::Crate) ->
93126
freevar_map {
94127
let freevars = @mut HashMap::new();
95128

96-
let walk_fn: @fn(&oldvisit::fn_kind,
97-
&ast::fn_decl,
98-
&ast::Block,
99-
span,
100-
ast::NodeId) = |_, _, blk, _, nid| {
101-
let vars = collect_freevars(def_map, blk);
102-
freevars.insert(nid, vars);
129+
let mut visitor = AnnotateFreevarsVisitor {
130+
def_map: def_map,
131+
freevars: freevars,
103132
};
104-
105-
let visitor =
106-
oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor {
107-
visit_fn: walk_fn,
108-
.. *oldvisit::default_simple_visitor()});
109-
oldvisit::visit_crate(crate, ((), visitor));
133+
visit::walk_crate(&mut visitor, crate, ());
110134

111135
return freevars;
112136
}

0 commit comments

Comments
 (0)