diff options
42 files changed, 2639 insertions, 1382 deletions
diff --git a/doc/tutorial.md b/doc/tutorial.md index c9f1dfcd5a3..89c3fa0bcae 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -1455,7 +1455,7 @@ compiler needs assistance, though, the arguments and return types may be annotated. ~~~~ -let square = |x: int| -> uint { x * x as uint }; +let square = |x: int| -> uint { (x * x) as uint }; ~~~~ There are several forms of closure, each with its own role. The most diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 1ce6f664c27..644f4a78349 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -17,14 +17,14 @@ use metadata::filesearch::FileSearch; use metadata::loader; use std::hashmap::HashMap; +use syntax::ast; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::{span, dummy_sp}; use syntax::diagnostic::span_handler; use syntax::parse::token; use syntax::parse::token::ident_interner; -use syntax::visit; -use syntax::ast; +use syntax::oldvisit; // Traverses an AST, reading all the information about use'd crates and extern // libraries necessary for later resolving, typechecking, linking, etc. @@ -46,12 +46,12 @@ pub fn read_crates(diag: @span_handler, intr: intr }; let v = - visit::mk_simple_visitor(@visit::SimpleVisitor { + oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_view_item: |a| visit_view_item(e, a), visit_item: |a| visit_item(e, a), - .. *visit::default_simple_visitor()}); + .. *oldvisit::default_simple_visitor()}); visit_crate(e, crate); - visit::visit_crate(crate, ((), v)); + oldvisit::visit_crate(crate, ((), v)); dump_crates(*e.crate_cache); warn_if_multiple_versions(e, diag, *e.crate_cache); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index bebfc889a7d..3915ae9f421 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -39,7 +39,7 @@ use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::diagnostic::span_handler; use syntax::parse::token::special_idents; -use syntax::{ast_util, visit}; +use syntax::{ast_util, oldvisit}; use syntax::parse::token; use syntax; use writer = extra::ebml::writer; @@ -1199,12 +1199,12 @@ fn encode_info_for_items(ecx: &EncodeContext, // See comment in `encode_side_tables_for_ii` in astencode let ecx_ptr : *() = unsafe { cast::transmute(ecx) }; - visit::visit_crate(crate, ((), visit::mk_vt(@visit::Visitor { + oldvisit::visit_crate(crate, ((), oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: |_e, (_cx, _v)| { }, visit_item: { let ebml_w = (*ebml_w).clone(); |i, (cx, v)| { - visit::visit_item(i, (cx, v)); + oldvisit::visit_item(i, (cx, v)); match items.get_copy(&i.id) { ast_map::node_item(_, pt) => { let mut ebml_w = ebml_w.clone(); @@ -1219,7 +1219,7 @@ fn encode_info_for_items(ecx: &EncodeContext, visit_foreign_item: { let ebml_w = (*ebml_w).clone(); |ni, (cx, v)| { - visit::visit_foreign_item(ni, (cx, v)); + oldvisit::visit_foreign_item(ni, (cx, v)); match items.get_copy(&ni.id) { ast_map::node_foreign_item(_, abi, _, pt) => { debug!("writing foreign item %s::%s", @@ -1243,7 +1243,7 @@ fn encode_info_for_items(ecx: &EncodeContext, } } }, - ..*visit::default_visitor() + ..*oldvisit::default_visitor() }))); ebml_w.end_tag(); return /*bad*/(*index).clone(); diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 4291ae2e7de..5ed2335192a 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -27,7 +27,7 @@ use syntax::ast::{m_mutbl, m_imm, m_const}; use syntax::ast; use syntax::ast_util; use syntax::codemap::span; -use syntax::visit; +use syntax::oldvisit; use util::ppaux::Repr; #[deriving(Clone)] @@ -54,12 +54,14 @@ pub fn check_loans(bccx: @BorrowckCtxt, reported: @mut HashSet::new(), }; - let vt = visit::mk_vt(@visit::Visitor {visit_expr: check_loans_in_expr, - visit_local: check_loans_in_local, - visit_block: check_loans_in_block, - visit_pat: check_loans_in_pat, - visit_fn: check_loans_in_fn, - .. *visit::default_visitor()}); + let vt = oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: check_loans_in_expr, + visit_local: check_loans_in_local, + visit_block: check_loans_in_block, + visit_pat: check_loans_in_pat, + visit_fn: check_loans_in_fn, + .. *oldvisit::default_visitor() + }); (vt.visit_block)(body, (clcx, vt)); } @@ -612,27 +614,27 @@ impl<'self> CheckLoanCtxt<'self> { } } -fn check_loans_in_fn<'a>(fk: &visit::fn_kind, +fn check_loans_in_fn<'a>(fk: &oldvisit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, sp: span, id: ast::NodeId, (this, visitor): (CheckLoanCtxt<'a>, - visit::vt<CheckLoanCtxt<'a>>)) { + oldvisit::vt<CheckLoanCtxt<'a>>)) { match *fk { - visit::fk_item_fn(*) | - visit::fk_method(*) => { + oldvisit::fk_item_fn(*) | + oldvisit::fk_method(*) => { // Don't process nested items. return; } - visit::fk_anon(*) | - visit::fk_fn_block(*) => { + oldvisit::fk_anon(*) | + oldvisit::fk_fn_block(*) => { check_captured_variables(this, id, sp); } } - visit::visit_fn(fk, decl, body, sp, id, (this, visitor)); + oldvisit::visit_fn(fk, decl, body, sp, id, (this, visitor)); fn check_captured_variables(this: CheckLoanCtxt, closure_id: ast::NodeId, @@ -677,14 +679,14 @@ fn check_loans_in_fn<'a>(fk: &visit::fn_kind, fn check_loans_in_local<'a>(local: @ast::Local, (this, vt): (CheckLoanCtxt<'a>, - visit::vt<CheckLoanCtxt<'a>>)) { - visit::visit_local(local, (this, vt)); + oldvisit::vt<CheckLoanCtxt<'a>>)) { + oldvisit::visit_local(local, (this, vt)); } fn check_loans_in_expr<'a>(expr: @ast::expr, (this, vt): (CheckLoanCtxt<'a>, - visit::vt<CheckLoanCtxt<'a>>)) { - visit::visit_expr(expr, (this, vt)); + oldvisit::vt<CheckLoanCtxt<'a>>)) { + oldvisit::visit_expr(expr, (this, vt)); debug!("check_loans_in_expr(expr=%s)", expr.repr(this.tcx())); @@ -737,17 +739,17 @@ fn check_loans_in_expr<'a>(expr: @ast::expr, fn check_loans_in_pat<'a>(pat: @ast::pat, (this, vt): (CheckLoanCtxt<'a>, - visit::vt<CheckLoanCtxt<'a>>)) + oldvisit::vt<CheckLoanCtxt<'a>>)) { this.check_for_conflicting_loans(pat.id); this.check_move_out_from_id(pat.id, pat.span); - visit::visit_pat(pat, (this, vt)); + oldvisit::visit_pat(pat, (this, vt)); } fn check_loans_in_block<'a>(blk: &ast::Block, (this, vt): (CheckLoanCtxt<'a>, - visit::vt<CheckLoanCtxt<'a>>)) + oldvisit::vt<CheckLoanCtxt<'a>>)) { - visit::visit_block(blk, (this, vt)); + oldvisit::visit_block(blk, (this, vt)); this.check_for_conflicting_loans(blk.id); } diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 4c4a5648c8b..a4d177becdd 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -31,7 +31,7 @@ use syntax::ast; use syntax::ast_util::id_range; use syntax::codemap::span; use syntax::print::pprust; -use syntax::visit; +use syntax::oldvisit; mod lifetime; mod restrictions; @@ -85,46 +85,48 @@ pub fn gather_loans(bccx: @BorrowckCtxt, move_data: @mut MoveData::new() }; glcx.gather_fn_arg_patterns(decl, body); - let v = visit::mk_vt(@visit::Visitor {visit_expr: gather_loans_in_expr, - visit_block: gather_loans_in_block, - visit_fn: gather_loans_in_fn, - visit_stmt: add_stmt_to_map, - visit_pat: add_pat_to_id_range, - visit_local: gather_loans_in_local, - .. *visit::default_visitor()}); + let v = oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: gather_loans_in_expr, + visit_block: gather_loans_in_block, + visit_fn: gather_loans_in_fn, + visit_stmt: add_stmt_to_map, + visit_pat: add_pat_to_id_range, + visit_local: gather_loans_in_local, + .. *oldvisit::default_visitor() + }); (v.visit_block)(body, (glcx, v)); return (glcx.id_range, glcx.all_loans, glcx.move_data); } fn add_pat_to_id_range(p: @ast::pat, (this, v): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { // NB: This visitor function just adds the pat ids into the id // range. We gather loans that occur in patterns using the // `gather_pat()` method below. Eventually these two should be // brought together. this.id_range.add(p.id); - visit::visit_pat(p, (this, v)); + oldvisit::visit_pat(p, (this, v)); } -fn gather_loans_in_fn(fk: &visit::fn_kind, +fn gather_loans_in_fn(fk: &oldvisit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, sp: span, id: ast::NodeId, (this, v): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { match fk { // Do not visit items here, the outer loop in borrowck/mod // will visit them for us in turn. - &visit::fk_item_fn(*) | &visit::fk_method(*) => { + &oldvisit::fk_item_fn(*) | &oldvisit::fk_method(*) => { return; } // Visit closures as part of the containing item. - &visit::fk_anon(*) | &visit::fk_fn_block(*) => { + &oldvisit::fk_anon(*) | &oldvisit::fk_fn_block(*) => { this.push_repeating_id(body.id); - visit::visit_fn(fk, decl, body, sp, id, (this, v)); + oldvisit::visit_fn(fk, decl, body, sp, id, (this, v)); this.pop_repeating_id(body.id); this.gather_fn_arg_patterns(decl, body); } @@ -133,14 +135,14 @@ fn gather_loans_in_fn(fk: &visit::fn_kind, fn gather_loans_in_block(blk: &ast::Block, (this, vt): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { this.id_range.add(blk.id); - visit::visit_block(blk, (this, vt)); + oldvisit::visit_block(blk, (this, vt)); } fn gather_loans_in_local(local: @ast::Local, (this, vt): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { match local.init { None => { // Variable declarations without initializers are considered "moves": @@ -171,12 +173,12 @@ fn gather_loans_in_local(local: @ast::Local, } } - visit::visit_local(local, (this, vt)); + oldvisit::visit_local(local, (this, vt)); } fn gather_loans_in_expr(ex: @ast::expr, (this, vt): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { let bccx = this.bccx; let tcx = bccx.tcx; @@ -216,7 +218,7 @@ fn gather_loans_in_expr(ex: @ast::expr, // for the lifetime `scope_r` of the resulting ptr: let scope_r = ty_region(tcx, ex.span, ty::expr_ty(tcx, ex)); this.guarantee_valid(ex.id, ex.span, base_cmt, mutbl, scope_r); - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } ast::expr_assign(l, _) | ast::expr_assign_op(_, _, l, _) => { @@ -233,7 +235,7 @@ fn gather_loans_in_expr(ex: @ast::expr, // with moves etc, just ignore. } } - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } ast::expr_match(ex_v, ref arms) => { @@ -243,7 +245,7 @@ fn gather_loans_in_expr(ex: @ast::expr, this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id))); } } - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } ast::expr_index(_, _, arg) | @@ -257,7 +259,7 @@ fn gather_loans_in_expr(ex: @ast::expr, let scope_r = ty::re_scope(ex.id); let arg_cmt = this.bccx.cat_expr(arg); this.guarantee_valid(arg.id, arg.span, arg_cmt, m_imm, scope_r); - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } // see explanation attached to the `root_ub` field: @@ -276,17 +278,17 @@ fn gather_loans_in_expr(ex: @ast::expr, // see explanation attached to the `root_ub` field: ast::expr_loop(ref body, _) => { this.push_repeating_id(body.id); - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); this.pop_repeating_id(body.id); } ast::expr_fn_block(*) => { gather_moves::gather_captures(this.bccx, this.move_data, ex); - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } _ => { - visit::visit_expr(ex, (this, vt)); + oldvisit::visit_expr(ex, (this, vt)); } } } @@ -762,12 +764,12 @@ impl GatherLoanCtxt { // This is just the most convenient place to do it. fn add_stmt_to_map(stmt: @ast::stmt, (this, vt): (@mut GatherLoanCtxt, - visit::vt<@mut GatherLoanCtxt>)) { + oldvisit::vt<@mut GatherLoanCtxt>)) { match stmt.node { ast::stmt_expr(_, id) | ast::stmt_semi(_, id) => { this.bccx.stmt_map.insert(id); } _ => () } - visit::visit_stmt(stmt, (this, vt)); + oldvisit::visit_stmt(stmt, (this, vt)); } diff --git a/src/librustc/middle/borrowck/mod.rs b/src/librustc/middle/borrowck/mod.rs index 8ddf1a6c1d8..afebae207bd 100644 --- a/src/librustc/middle/borrowck/mod.rs +++ b/src/librustc/middle/borrowck/mod.rs @@ -26,7 +26,7 @@ use std::ops::{BitOr, BitAnd}; use std::result::{Result}; use syntax::ast; use syntax::ast_map; -use syntax::visit; +use syntax::oldvisit; use syntax::codemap::span; use syntax::parse::token; @@ -86,9 +86,9 @@ pub fn check_crate( } }; - let v = visit::mk_vt(@visit::Visitor {visit_fn: borrowck_fn, - ..*visit::default_visitor()}); - visit::visit_crate(crate, (bccx, v)); + let v = oldvisit::mk_vt(@oldvisit::Visitor {visit_fn: borrowck_fn, + ..*oldvisit::default_visitor()}); + oldvisit::visit_crate(crate, (bccx, v)); if tcx.sess.borrowck_stats() { io::println("--- borrowck stats ---"); @@ -113,21 +113,21 @@ pub fn check_crate( } } -fn borrowck_fn(fk: &visit::fn_kind, +fn borrowck_fn(fk: &oldvisit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, sp: span, id: ast::NodeId, (this, v): (@BorrowckCtxt, - visit::vt<@BorrowckCtxt>)) { + oldvisit::vt<@BorrowckCtxt>)) { match fk { - &visit::fk_anon(*) | - &visit::fk_fn_block(*) => { + &oldvisit::fk_anon(*) | + &oldvisit::fk_fn_block(*) => { // Closures are checked as part of their containing fn item. } - &visit::fk_item_fn(*) | - &visit::fk_method(*) => { + &oldvisit::fk_item_fn(*) | + &oldvisit::fk_method(*) => { debug!("borrowck_fn(id=%?)", id); // Check the body of fn items. @@ -156,7 +156,7 @@ fn borrowck_fn(fk: &visit::fn_kind, } } - visit::visit_fn(fk, decl, body, sp, id, (this, v)); + oldvisit::visit_fn(fk, decl, body, sp, id, (this, v)); } // ---------------------------------------------------------------------- diff --git a/src/librustc/middle/check_const.rs b/src/librustc/middle/check_const.rs index 11d2268725d..9416eb365b3 100644 --- a/src/librustc/middle/check_const.rs +++ b/src/librustc/middle/check_const.rs @@ -17,7 +17,7 @@ use util::ppaux; use syntax::ast::*; use syntax::codemap; -use syntax::{visit, ast_util, ast_map}; +use syntax::{oldvisit, ast_util, ast_map}; pub fn check_crate(sess: Session, crate: &Crate, @@ -25,12 +25,12 @@ pub fn check_crate(sess: Session, def_map: resolve::DefMap, method_map: typeck::method_map, tcx: ty::ctxt) { - visit::visit_crate(crate, (false, visit::mk_vt(@visit::Visitor { + oldvisit::visit_crate(crate, (false, oldvisit::mk_vt(@oldvisit::Visitor { visit_item: |a,b| check_item(sess, ast_map, def_map, a, b), visit_pat: check_pat, visit_expr: |a,b| check_expr(sess, def_map, method_map, tcx, a, b), - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }))); sess.abort_if_errors(); } @@ -40,7 +40,7 @@ pub fn check_item(sess: Session, def_map: resolve::DefMap, it: @item, (_is_const, v): (bool, - visit::vt<bool>)) { + oldvisit::vt<bool>)) { match it.node { item_static(_, _, ex) => { (v.visit_expr)(ex, (true, v)); @@ -53,11 +53,11 @@ pub fn check_item(sess: Session, } } } - _ => visit::visit_item(it, (false, v)) + _ => oldvisit::visit_item(it, (false, v)) } } -pub fn check_pat(p: @pat, (_is_const, v): (bool, visit::vt<bool>)) { +pub fn check_pat(p: @pat, (_is_const, v): (bool, oldvisit::vt<bool>)) { fn is_str(e: @expr) -> bool { match e.node { expr_vstore( @@ -77,7 +77,7 @@ pub fn check_pat(p: @pat, (_is_const, v): (bool, visit::vt<bool>)) { if !is_str(a) { (v.visit_expr)(a, (true, v)); } if !is_str(b) { (v.visit_expr)(b, (true, v)); } } - _ => visit::visit_pat(p, (false, v)) + _ => oldvisit::visit_pat(p, (false, v)) } } @@ -87,7 +87,7 @@ pub fn check_expr(sess: Session, tcx: ty::ctxt, e: @expr, (is_const, v): (bool, - visit::vt<bool>)) { + oldvisit::vt<bool>)) { if is_const { match e.node { expr_unary(_, deref, _) => { } @@ -191,7 +191,7 @@ pub fn check_expr(sess: Session, } _ => () } - visit::visit_expr(e, (is_const, v)); + oldvisit::visit_expr(e, (is_const, v)); } #[deriving(Clone)] @@ -217,23 +217,23 @@ pub fn check_item_recursion(sess: Session, idstack: @mut ~[] }; - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_item: visit_item, visit_expr: visit_expr, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); (visitor.visit_item)(it, (env, visitor)); - fn visit_item(it: @item, (env, v): (env, visit::vt<env>)) { + fn visit_item(it: @item, (env, v): (env, oldvisit::vt<env>)) { if env.idstack.iter().any(|x| x == &(it.id)) { env.sess.span_fatal(env.root_it.span, "recursive constant"); } env.idstack.push(it.id); - visit::visit_item(it, (env, v)); + oldvisit::visit_item(it, (env, v)); env.idstack.pop(); } - fn visit_expr(e: @expr, (env, v): (env, visit::vt<env>)) { + fn visit_expr(e: @expr, (env, v): (env, oldvisit::vt<env>)) { match e.node { expr_path(*) => match env.def_map.find(&e.id) { Some(&def_static(def_id, _)) if ast_util::is_local(def_id) => @@ -247,6 +247,6 @@ pub fn check_item_recursion(sess: Session, }, _ => () } - visit::visit_expr(e, (env, v)); + oldvisit::visit_expr(e, (env, v)); } } diff --git a/src/librustc/middle/check_loop.rs b/src/librustc/middle/check_loop.rs index ae9a96dee1a..0dabb304fbc 100644 --- a/src/librustc/middle/check_loop.rs +++ b/src/librustc/middle/check_loop.rs @@ -12,7 +12,7 @@ use middle::ty; use syntax::ast::*; -use syntax::visit; +use syntax::oldvisit; #[deriving(Clone)] pub struct Context { @@ -21,16 +21,16 @@ pub struct Context { } pub fn check_crate(tcx: ty::ctxt, crate: &Crate) { - visit::visit_crate(crate, - (Context { in_loop: false, can_ret: true }, - visit::mk_vt(@visit::Visitor { + oldvisit::visit_crate(crate, + (Context { in_loop: false, can_ret: true }, + oldvisit::mk_vt(@oldvisit::Visitor { visit_item: |i, (_cx, v)| { - visit::visit_item(i, (Context { + oldvisit::visit_item(i, (Context { in_loop: false, can_ret: true }, v)); }, - visit_expr: |e: @expr, (cx, v): (Context, visit::vt<Context>)| { + visit_expr: |e: @expr, (cx, v): (Context, oldvisit::vt<Context>)| { match e.node { expr_while(e, ref b) => { (v.visit_expr)(e, (cx, v)); @@ -67,11 +67,11 @@ pub fn check_crate(tcx: ty::ctxt, crate: &Crate) { if !cx.can_ret { tcx.sess.span_err(e.span, "`return` in block function"); } - visit::visit_expr_opt(oe, (cx, v)); + oldvisit::visit_expr_opt(oe, (cx, v)); } - _ => visit::visit_expr(e, (cx, v)) + _ => oldvisit::visit_expr(e, (cx, v)) } }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }))); } diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index df59461bda5..05f42509cd4 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -25,7 +25,7 @@ use extra::sort; use syntax::ast::*; use syntax::ast_util::{unguarded_pat, walk_pat}; use syntax::codemap::{span, dummy_sp, spanned}; -use syntax::visit; +use syntax::oldvisit; pub struct MatchCheckCtxt { tcx: ty::ctxt, @@ -40,18 +40,20 @@ pub fn check_crate(tcx: ty::ctxt, let cx = @MatchCheckCtxt {tcx: tcx, method_map: method_map, moves_map: moves_map}; - visit::visit_crate(crate, ((), visit::mk_vt(@visit::Visitor { + oldvisit::visit_crate(crate, ((), oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: |a,b| check_expr(cx, a, b), visit_local: |a,b| check_local(cx, a, b), visit_fn: |kind, decl, body, sp, id, (e, v)| check_fn(cx, kind, decl, body, sp, id, (e, v)), - .. *visit::default_visitor::<()>() + .. *oldvisit::default_visitor::<()>() }))); tcx.sess.abort_if_errors(); } -pub fn check_expr(cx: @MatchCheckCtxt, ex: @expr, (s, v): ((), visit::vt<()>)) { - visit::visit_expr(ex, (s, v)); +pub fn check_expr(cx: @MatchCheckCtxt, + ex: @expr, + (s, v): ((), oldvisit::vt<()>)) { + oldvisit::visit_expr(ex, (s, v)); match ex.node { expr_match(scrut, ref arms) => { // First, check legality of move bindings. @@ -760,9 +762,8 @@ pub fn default(cx: &MatchCheckCtxt, r: &[@pat]) -> Option<~[@pat]> { pub fn check_local(cx: &MatchCheckCtxt, loc: @Local, - (s, v): ((), - visit::vt<()>)) { - visit::visit_local(loc, (s, v)); + (s, v): ((), oldvisit::vt<()>)) { + oldvisit::visit_local(loc, (s, v)); if is_refutable(cx, loc.pat) { cx.tcx.sess.span_err(loc.pat.span, "refutable pattern in local binding"); @@ -773,14 +774,14 @@ pub fn check_local(cx: &MatchCheckCtxt, } pub fn check_fn(cx: &MatchCheckCtxt, - kind: &visit::fn_kind, + kind: &oldvisit::fn_kind, decl: &fn_decl, body: &Block, sp: span, id: NodeId, (s, v): ((), - visit::vt<()>)) { - visit::visit_fn(kind, decl, body, sp, id, (s, v)); + oldvisit::vt<()>)) { + oldvisit::visit_fn(kind, decl, body, sp, id, (s, v)); foreach input in decl.inputs.iter() { if is_refutable(cx, input.pat) { cx.tcx.sess.span_err(input.pat.span, diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 957a59cdaa0..3e8cce061f1 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -14,7 +14,7 @@ use middle::astencode; use middle::ty; use middle; -use syntax::{ast, ast_map, ast_util, visit}; +use syntax::{ast, ast_map, ast_util, oldvisit}; use syntax::ast::*; use std::float; @@ -267,11 +267,11 @@ pub fn lookup_constness(tcx: ty::ctxt, e: &expr) -> constness { pub fn process_crate(crate: &ast::Crate, tcx: ty::ctxt) { - let v = visit::mk_simple_visitor(@visit::SimpleVisitor { + let v = oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_expr_post: |e| { classify(e, tcx); }, - .. *visit::default_simple_visitor() + .. *oldvisit::default_simple_visitor() }); - visit::visit_crate(crate, ((), v)); + oldvisit::visit_crate(crate, ((), v)); tcx.sess.abort_if_errors(); } diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 711598ed155..651ce292d28 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -20,8 +20,8 @@ use syntax::ast::{deref, expr_call, expr_inline_asm, expr_method_call}; use syntax::ast::{expr_unary, unsafe_fn, expr_path}; use syntax::ast; use syntax::codemap::span; -use syntax::visit::{fk_item_fn, fk_method}; -use syntax::visit; +use syntax::oldvisit::{fk_item_fn, fk_method}; +use syntax::oldvisit; #[deriving(Eq)] enum UnsafeContext { @@ -71,7 +71,7 @@ pub fn check_crate(tcx: ty::ctxt, } }; - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_fn: |fn_kind, fn_decl, block, span, node_id, (_, visitor)| { let (is_item_fn, is_unsafe_fn) = match *fn_kind { fk_item_fn(_, _, purity, _) => (true, purity == unsafe_fn), @@ -86,7 +86,7 @@ pub fn check_crate(tcx: ty::ctxt, context.unsafe_context = SafeContext } - visit::visit_fn(fn_kind, + oldvisit::visit_fn(fn_kind, fn_decl, block, span, @@ -104,7 +104,7 @@ pub fn check_crate(tcx: ty::ctxt, context.unsafe_context = UnsafeBlock(block.id) } - visit::visit_block(block, ((), visitor)); + oldvisit::visit_block(block, ((), visitor)); context.unsafe_context = old_unsafe_context }, @@ -154,11 +154,11 @@ pub fn check_crate(tcx: ty::ctxt, _ => {} } - visit::visit_expr(expr, ((), visitor)) + oldvisit::visit_expr(expr, ((), visitor)) }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, ((), visitor)) + oldvisit::visit_crate(crate, ((), visitor)) } diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 73ead06bf07..469c1c2f93e 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -11,12 +11,13 @@ use driver::session; use driver::session::Session; -use syntax::parse::token::special_idents; use syntax::ast::{Crate, NodeId, item, item_fn}; +use syntax::ast_map; use syntax::attr; use syntax::codemap::span; -use syntax::visit::{default_visitor, mk_vt, vt, Visitor, visit_crate, visit_item}; -use syntax::ast_map; +use syntax::oldvisit::{default_visitor, mk_vt, vt, Visitor, visit_crate}; +use syntax::oldvisit::{visit_item}; +use syntax::parse::token::special_idents; use std::util; struct EntryContext { diff --git a/src/librustc/middle/freevars.rs b/src/librustc/middle/freevars.rs index 65903442964..5f7ef8d31f7 100644 --- a/src/librustc/middle/freevars.rs +++ b/src/librustc/middle/freevars.rs @@ -17,7 +17,7 @@ use middle::ty; use std::hashmap::HashMap; use syntax::codemap::span; -use syntax::{ast, ast_util, visit}; +use syntax::{ast, ast_util, oldvisit}; // A vector of defs representing the free variables referred to in a function. // (The def_upvar will already have been stripped). @@ -39,12 +39,14 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) let seen = @mut HashMap::new(); let refs = @mut ~[]; - fn ignore_item(_i: @ast::item, (_depth, _v): (int, visit::vt<int>)) { } + fn ignore_item(_i: @ast::item, (_depth, _v): (int, oldvisit::vt<int>)) { } - let walk_expr: @fn(expr: @ast::expr, (int, visit::vt<int>)) = + let walk_expr: @fn(expr: @ast::expr, (int, oldvisit::vt<int>)) = |expr, (depth, v)| { match expr.node { - ast::expr_fn_block(*) => visit::visit_expr(expr, (depth + 1, v)), + ast::expr_fn_block(*) => { + oldvisit::visit_expr(expr, (depth + 1, v)) + } ast::expr_path(*) | ast::expr_self => { let mut i = 0; match def_map.find(&expr.id) { @@ -71,13 +73,13 @@ fn collect_freevars(def_map: resolve::DefMap, blk: &ast::Block) } } } - _ => visit::visit_expr(expr, (depth, v)) + _ => oldvisit::visit_expr(expr, (depth, v)) } }; - let v = visit::mk_vt(@visit::Visitor {visit_item: ignore_item, + let v = oldvisit::mk_vt(@oldvisit::Visitor {visit_item: ignore_item, visit_expr: walk_expr, - .. *visit::default_visitor()}); + .. *oldvisit::default_visitor()}); (v.visit_block)(blk, (1, v)); return @(*refs).clone(); } @@ -91,7 +93,7 @@ pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::Crate) -> freevar_map { let freevars = @mut HashMap::new(); - let walk_fn: @fn(&visit::fn_kind, + let walk_fn: @fn(&oldvisit::fn_kind, &ast::fn_decl, &ast::Block, span, @@ -101,10 +103,10 @@ pub fn annotate_freevars(def_map: resolve::DefMap, crate: &ast::Crate) -> }; let visitor = - visit::mk_simple_visitor(@visit::SimpleVisitor { + oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_fn: walk_fn, - .. *visit::default_simple_visitor()}); - visit::visit_crate(crate, ((), visitor)); + .. *oldvisit::default_simple_visitor()}); + oldvisit::visit_crate(crate, ((), visitor)); return freevars; } diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a992e9fb0f0..c389ae6eba2 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -21,7 +21,7 @@ use syntax::attr; use syntax::codemap::span; use syntax::opt_vec; use syntax::print::pprust::expr_to_str; -use syntax::{visit, ast_util}; +use syntax::{oldvisit, ast_util}; // Kind analysis pass. // @@ -66,15 +66,15 @@ pub fn check_crate(tcx: ty::ctxt, method_map: method_map, current_item: -1 }; - let visit = visit::mk_vt(@visit::Visitor { + let visit = oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: check_expr, visit_fn: check_fn, visit_ty: check_ty, visit_item: check_item, visit_block: check_block, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, (ctx, visit)); + oldvisit::visit_crate(crate, (ctx, visit)); tcx.sess.abort_if_errors(); } @@ -108,11 +108,12 @@ fn check_struct_safe_for_destructor(cx: Context, } } -fn check_block(block: &Block, (cx, visitor): (Context, visit::vt<Context>)) { - visit::visit_block(block, (cx, visitor)); +fn check_block(block: &Block, + (cx, visitor): (Context, oldvisit::vt<Context>)) { + oldvisit::visit_block(block, (cx, visitor)); } -fn check_item(item: @item, (cx, visitor): (Context, visit::vt<Context>)) { +fn check_item(item: @item, (cx, visitor): (Context, oldvisit::vt<Context>)) { // If this is a destructor, check kinds. if !attr::contains_name(item.attrs, "unsafe_destructor") { match item.node { @@ -152,7 +153,7 @@ fn check_item(item: @item, (cx, visitor): (Context, visit::vt<Context>)) { } let cx = Context { current_item: item.id, ..cx }; - visit::visit_item(item, (cx, visitor)); + oldvisit::visit_item(item, (cx, visitor)); } // Yields the appropriate function to check the kind of closed over @@ -226,13 +227,13 @@ fn with_appropriate_checker(cx: Context, id: NodeId, // Check that the free variables used in a shared/sendable closure conform // to the copy/move kind bounds. Then recursively check the function body. fn check_fn( - fk: &visit::fn_kind, + fk: &oldvisit::fn_kind, decl: &fn_decl, body: &Block, sp: span, fn_id: NodeId, (cx, v): (Context, - visit::vt<Context>)) { + oldvisit::vt<Context>)) { // Check kinds on free variables: do with_appropriate_checker(cx, fn_id) |chk| { @@ -242,10 +243,10 @@ fn check_fn( } } - visit::visit_fn(fk, decl, body, sp, fn_id, (cx, v)); + oldvisit::visit_fn(fk, decl, body, sp, fn_id, (cx, v)); } -pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt<Context>)) { +pub fn check_expr(e: @expr, (cx, v): (Context, oldvisit::vt<Context>)) { debug!("kind::check_expr(%s)", expr_to_str(e, cx.tcx.sess.intr())); // Handle any kind bounds on type parameters @@ -310,10 +311,10 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt<Context>)) { } _ => {} } - visit::visit_expr(e, (cx, v)); + oldvisit::visit_expr(e, (cx, v)); } -fn check_ty(aty: &Ty, (cx, v): (Context, visit::vt<Context>)) { +fn check_ty(aty: &Ty, (cx, v): (Context, oldvisit::vt<Context>)) { match aty.node { ty_path(_, _, id) => { let r = cx.tcx.node_type_substs.find(&id); @@ -328,7 +329,7 @@ fn check_ty(aty: &Ty, (cx, v): (Context, visit::vt<Context>)) { } _ => {} } - visit::visit_ty(aty, (cx, v)); + oldvisit::visit_ty(aty, (cx, v)); } // Calls "any_missing" if any bounds were missing. diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 0c54da66d73..c115a64039a 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -26,8 +26,8 @@ use metadata::cstore::iter_crate_data; use syntax::ast::{Crate, def_id, MetaItem}; use syntax::ast_util::local_def; use syntax::attr::AttrMetaMethods; -use syntax::visit::{default_simple_visitor, mk_simple_visitor, SimpleVisitor}; -use syntax::visit::visit_crate; +use syntax::oldvisit::{default_simple_visitor, mk_simple_visitor}; +use syntax::oldvisit::{SimpleVisitor, visit_crate}; use std::hashmap::HashMap; diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index f972406ae11..4348823eb0f 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -25,11 +25,13 @@ use std::u32; use std::u64; use std::u8; use extra::smallintmap::SmallIntMap; +use syntax::ast_map; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::codemap::span; use syntax::codemap; -use syntax::{ast, visit, ast_util}; +use syntax::parse::token; +use syntax::{ast, oldvisit, ast_util, visit}; /** * A 'lint' check is a kind of miscellaneous constraint that a user _might_ @@ -53,13 +55,13 @@ use syntax::{ast, visit, ast_util}; * lint attributes. * * At each node of the ast which can modify lint attributes, all known lint - * passes are also applied. Each lint pass is a visit::vt<()> structure. These - * visitors are constructed via the lint_*() functions below. There are also - * some lint checks which operate directly on ast nodes (such as @ast::item), - * and those are organized as check_item_*(). Each visitor added to the lint - * context is modified to stop once it reaches a node which could alter the lint - * levels. This means that everything is looked at once and only once by every - * lint pass. + * passes are also applied. Each lint pass is an oldvisit::vt<()> structure. + * The visitors are constructed via the lint_*() functions below. There are + * also some lint checks which operate directly on ast nodes (such as + * @ast::item), and those are organized as check_item_*(). Each visitor added + * to the lint context is modified to stop once it reaches a node which could + * alter the lint levels. This means that everything is looked at once and + * only once by every lint pass. * * With this all in place, to add a new lint warning, all you need to do is to * either invoke `add_lint` on the session at the appropriate time, or write a @@ -298,6 +300,18 @@ pub fn get_lint_dict() -> LintDict { return map; } +enum AnyVisitor { + // This is a pair so every visitor can visit every node. When a lint pass + // is registered, another visitor is created which stops at all items + // which can alter the attributes of the ast. This "item stopping visitor" + // is the second element of the pair, while the original visitor is the + // first element. This means that when visiting a node, the original + // recursive call can use the original visitor's method, although the + // recursing visitor supplied to the method is the item stopping visitor. + OldVisitor(oldvisit::vt<@mut Context>, oldvisit::vt<@mut Context>), + NewVisitor(@visit::Visitor<()>), +} + struct Context { // All known lint modes (string versions) dict: @LintDict, @@ -321,15 +335,7 @@ struct Context { // Others operate directly on @ast::item structures (or similar). Finally, // others still are added to the Session object via `add_lint`, and these // are all passed with the lint_session visitor. - // - // This is a pair so every visitor can visit every node. When a lint pass is - // registered, another visitor is created which stops at all items which can - // alter the attributes of the ast. This "item stopping visitor" is the - // second element of the pair, while the original visitor is the first - // element. This means that when visiting a node, the original recursive - // call can used the original visitor's method, although the recursing - // visitor supplied to the method is the item stopping visitor. - visitors: ~[(visit::vt<@mut Context>, visit::vt<@mut Context>)], + visitors: ~[AnyVisitor], } impl Context { @@ -465,8 +471,12 @@ impl Context { } } - fn add_lint(&mut self, v: visit::vt<@mut Context>) { - self.visitors.push((v, item_stopping_visitor(v))); + fn add_oldvisit_lint(&mut self, v: oldvisit::vt<@mut Context>) { + self.visitors.push(OldVisitor(v, item_stopping_visitor(v))); + } + + fn add_lint(&mut self, v: @visit::Visitor<()>) { + self.visitors.push(NewVisitor(v)); } fn process(@mut self, n: AttributedNode) { @@ -474,23 +484,58 @@ impl Context { // pair instead of just one visitor. match n { Item(it) => { - foreach &(orig, stopping) in self.visitors.iter() { - (orig.visit_item)(it, (self, stopping)); + foreach visitor in self.visitors.iter() { + match *visitor { + OldVisitor(orig, stopping) => { + (orig.visit_item)(it, (self, stopping)); + } + NewVisitor(new_visitor) => { + new_visitor.visit_item(it, ()); + } + } } } Crate(c) => { - foreach &(_, stopping) in self.visitors.iter() { - visit::visit_crate(c, (self, stopping)); + for self.visitors.iter().advance |visitor| { + match *visitor { + OldVisitor(_, stopping) => { + oldvisit::visit_crate(c, (self, stopping)) + } + NewVisitor(new_visitor) => { + visit::visit_crate(new_visitor, c, ()) + } + } } } - // Can't use visit::visit_method_helper because the + // Can't use oldvisit::visit_method_helper because the // item_stopping_visitor has overridden visit_fn(&fk_method(... )) // to be a no-op, so manually invoke visit_fn. Method(m) => { - let fk = visit::fk_method(m.ident, &m.generics, m); - foreach &(orig, stopping) in self.visitors.iter() { - (orig.visit_fn)(&fk, &m.decl, &m.body, m.span, m.id, - (self, stopping)); + foreach visitor in self.visitors.iter() { + match *visitor { + OldVisitor(orig, stopping) => { + let fk = oldvisit::fk_method(m.ident, + &m.generics, + m); + (orig.visit_fn)(&fk, + &m.decl, + &m.body, + m.span, + m.id, + (self, stopping)); + } + NewVisitor(new_visitor) => { + let fk = visit::fk_method(m.ident, + &m.generics, + m); + new_visitor.visit_fn(&fk, + &m.decl, + &m.body, + m.span, + m.id, + ()) + } + } } } } @@ -533,21 +578,22 @@ pub fn each_lint(sess: session::Session, // This is used to make the simple visitors used for the lint passes // not traverse into subitems, since that is handled by the outer // lint visitor. -fn item_stopping_visitor<E>(outer: visit::vt<E>) -> visit::vt<E> { - visit::mk_vt(@visit::Visitor { +fn item_stopping_visitor<E>(outer: oldvisit::vt<E>) -> oldvisit::vt<E> { + oldvisit::mk_vt(@oldvisit::Visitor { visit_item: |_i, (_e, _v)| { }, visit_fn: |fk, fd, b, s, id, (e, v)| { match *fk { - visit::fk_method(*) => {} + oldvisit::fk_method(*) => {} _ => (outer.visit_fn)(fk, fd, b, s, id, (e, v)) } }, .. **outer}) } -fn lint_while_true() -> visit::vt<@mut Context> { - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { +fn lint_while_true() -> oldvisit::vt<@mut Context> { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { match e.node { ast::expr_while(cond, _) => { match cond.node { @@ -563,15 +609,15 @@ fn lint_while_true() -> visit::vt<@mut Context> { } _ => () } - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_deprecated_for_loop() -> visit::vt<@mut Context> { - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { +fn lint_deprecated_for_loop() -> oldvisit::vt<@mut Context> { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { match e.node { ast::expr_call(_, _, ast::ForSugar) | ast::expr_method_call(_, _, _, _, _, ast::ForSugar) => { @@ -581,13 +627,13 @@ fn lint_deprecated_for_loop() -> visit::vt<@mut Context> { } _ => {} } - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_type_limits() -> visit::vt<@mut Context> { +fn lint_type_limits() -> oldvisit::vt<@mut Context> { fn is_valid<T:cmp::Ord>(binop: ast::binop, v: T, min: T, max: T) -> bool { match binop { @@ -689,8 +735,9 @@ fn lint_type_limits() -> visit::vt<@mut Context> { } } - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { match e.node { ast::expr_binary(_, ref binop, l, r) => { if is_comparison(*binop) @@ -701,10 +748,10 @@ fn lint_type_limits() -> visit::vt<@mut Context> { } _ => () } - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } @@ -811,20 +858,22 @@ fn check_item_heap(cx: &Context, it: &ast::item) { } } -fn lint_heap() -> visit::vt<@mut Context> { - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { +fn lint_heap() -> oldvisit::vt<@mut Context> { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { let ty = ty::expr_ty(cx.tcx, e); check_type(cx, e.span, ty); - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_path_statement() -> visit::vt<@mut Context> { - visit::mk_vt(@visit::Visitor { - visit_stmt: |s, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { +fn lint_path_statement() -> oldvisit::vt<@mut Context> { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_stmt: |s, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { match s.node { ast::stmt_semi( @ast::expr { node: ast::expr_path(_), _ }, @@ -835,9 +884,9 @@ fn lint_path_statement() -> visit::vt<@mut Context> { } _ => () } - visit::visit_stmt(s, (cx, vt)); + oldvisit::visit_stmt(s, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } @@ -896,9 +945,10 @@ fn check_item_non_uppercase_statics(cx: &Context, it: &ast::item) { } } -fn lint_unused_unsafe() -> visit::vt<@mut Context> { - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { +fn lint_unused_unsafe() -> oldvisit::vt<@mut Context> { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { match e.node { ast::expr_block(ref blk) if blk.rules == ast::UnsafeBlock => { if !cx.tcx.used_unsafe.contains(&blk.id) { @@ -908,13 +958,13 @@ fn lint_unused_unsafe() -> visit::vt<@mut Context> { } _ => () } - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_unused_mut() -> visit::vt<@mut Context> { +fn lint_unused_mut() -> oldvisit::vt<@mut Context> { fn check_pat(cx: &Context, p: @ast::pat) { let mut used = false; let mut bindings = 0; @@ -940,34 +990,35 @@ fn lint_unused_mut() -> visit::vt<@mut Context> { } } - visit::mk_vt(@visit::Visitor { - visit_local: |l, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_local: |l, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { if l.is_mutbl { check_pat(cx, l.pat); } - visit::visit_local(l, (cx, vt)); + oldvisit::visit_local(l, (cx, vt)); }, visit_fn: |a, fd, b, c, d, (cx, vt)| { visit_fn_decl(cx, fd); - visit::visit_fn(a, fd, b, c, d, (cx, vt)); + oldvisit::visit_fn(a, fd, b, c, d, (cx, vt)); }, visit_ty_method: |tm, (cx, vt)| { visit_fn_decl(cx, &tm.decl); - visit::visit_ty_method(tm, (cx, vt)); + oldvisit::visit_ty_method(tm, (cx, vt)); }, visit_trait_method: |tm, (cx, vt)| { match *tm { ast::required(ref tm) => visit_fn_decl(cx, &tm.decl), ast::provided(m) => visit_fn_decl(cx, &m.decl) } - visit::visit_trait_method(tm, (cx, vt)); + oldvisit::visit_trait_method(tm, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_session() -> visit::vt<@mut Context> { - ast_util::id_visitor(|id, cx: @mut Context| { +fn lint_session(cx: @mut Context) -> @visit::Visitor<()> { + ast_util::id_visitor(|id| { match cx.tcx.sess.lints.pop(&id) { None => {}, Some(l) => { @@ -976,10 +1027,10 @@ fn lint_session() -> visit::vt<@mut Context> { } } } - }) + }, false) } -fn lint_unnecessary_allocations() -> visit::vt<@mut Context> { +fn lint_unnecessary_allocations() -> oldvisit::vt<@mut Context> { // Warn if string and vector literals with sigils are immediately borrowed. // Those can have the sigil removed. fn check(cx: &Context, e: &ast::expr) { @@ -1009,18 +1060,21 @@ fn lint_unnecessary_allocations() -> visit::vt<@mut Context> { } } - visit::mk_vt(@visit::Visitor { - visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { + oldvisit::mk_vt(@oldvisit::Visitor { + visit_expr: |e, + (cx, vt): (@mut Context, oldvisit::vt<@mut Context>)| { check(cx, e); - visit::visit_expr(e, (cx, vt)); + oldvisit::visit_expr(e, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } -fn lint_missing_doc() -> visit::vt<@mut Context> { - fn check_attrs(cx: @mut Context, attrs: &[ast::Attribute], - sp: span, msg: &str) { +fn lint_missing_doc() -> oldvisit::vt<@mut Context> { + fn check_attrs(cx: @mut Context, + attrs: &[ast::Attribute], + sp: span, + msg: &str) { // If we're building a test harness, then warning about documentation is // probably not really relevant right now if cx.tcx.sess.opts.test { return } @@ -1033,20 +1087,20 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { cx.span_lint(missing_doc, sp, msg); } - visit::mk_vt(@visit::Visitor { + oldvisit::mk_vt(@oldvisit::Visitor { visit_ty_method: |m, (cx, vt)| { // All ty_method objects are linted about because they're part of a // trait (no visibility) check_attrs(cx, m.attrs, m.span, "missing documentation for a method"); - visit::visit_ty_method(m, (cx, vt)); + oldvisit::visit_ty_method(m, (cx, vt)); }, visit_fn: |fk, d, b, sp, id, (cx, vt)| { // Only warn about explicitly public methods. Soon implicit // public-ness will hopefully be going away. match *fk { - visit::fk_method(_, _, m) if m.vis == ast::public => { + oldvisit::fk_method(_, _, m) if m.vis == ast::public => { // If we're in a trait implementation, no need to duplicate // documentation if !cx.in_trait_impl { @@ -1057,7 +1111,7 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { _ => {} } - visit::visit_fn(fk, d, b, sp, id, (cx, vt)); + oldvisit::visit_fn(fk, d, b, sp, id, (cx, vt)); }, visit_item: |it, (cx, vt)| { @@ -1092,10 +1146,10 @@ fn lint_missing_doc() -> visit::vt<@mut Context> { _ => {} }; - visit::visit_item(it, (cx, vt)); + oldvisit::visit_item(it, (cx, vt)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }) } @@ -1121,23 +1175,25 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) { } // Register each of the lint passes with the context - cx.add_lint(lint_while_true()); - cx.add_lint(lint_deprecated_for_loop()); - cx.add_lint(lint_path_statement()); - cx.add_lint(lint_heap()); - cx.add_lint(lint_type_limits()); - cx.add_lint(lint_unused_unsafe()); - cx.add_lint(lint_unused_mut()); - cx.add_lint(lint_session()); - cx.add_lint(lint_unnecessary_allocations()); - cx.add_lint(lint_missing_doc()); + cx.add_oldvisit_lint(lint_while_true()); + cx.add_oldvisit_lint(lint_deprecated_for_loop()); + cx.add_oldvisit_lint(lint_path_statement()); + cx.add_oldvisit_lint(lint_heap()); + cx.add_oldvisit_lint(lint_type_limits()); + cx.add_oldvisit_lint(lint_unused_unsafe()); + cx.add_oldvisit_lint(lint_unused_mut()); + cx.add_oldvisit_lint(lint_unnecessary_allocations()); + cx.add_oldvisit_lint(lint_missing_doc()); + cx.add_lint(lint_session(cx)); // Actually perform the lint checks (iterating the ast) do cx.with_lint_attrs(crate.attrs) { cx.process(Crate(crate)); - visit::visit_crate(crate, (cx, visit::mk_vt(@visit::Visitor { - visit_item: |it, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { + oldvisit::visit_crate(crate, (cx, oldvisit::mk_vt(@oldvisit::Visitor { + visit_item: |it, + (cx, vt): + (@mut Context, oldvisit::vt<@mut Context>)| { do cx.with_lint_attrs(it.attrs) { match it.node { ast::item_impl(_, Some(*), _, _) => { @@ -1151,35 +1207,51 @@ pub fn check_crate(tcx: ty::ctxt, crate: @ast::Crate) { check_item_heap(cx, it); cx.process(Item(it)); - visit::visit_item(it, (cx, vt)); + oldvisit::visit_item(it, (cx, vt)); cx.in_trait_impl = false; } }, visit_fn: |fk, decl, body, span, id, (cx, vt)| { match *fk { - visit::fk_method(_, _, m) => { + oldvisit::fk_method(_, _, m) => { do cx.with_lint_attrs(m.attrs) { cx.process(Method(m)); - visit::visit_fn(fk, decl, body, span, id, (cx, vt)); + oldvisit::visit_fn(fk, + decl, + body, + span, + id, + (cx, vt)); } } _ => { - visit::visit_fn(fk, decl, body, span, id, (cx, vt)); + oldvisit::visit_fn(fk, + decl, + body, + span, + id, + (cx, vt)); } } }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }))); } // If we missed any lints added to the session, then there's a bug somewhere // in the iteration code. - foreach (_, v) in tcx.sess.lints.iter() { + foreach (id, v) in tcx.sess.lints.iter() { foreach t in v.iter() { match *t { (lint, span, ref msg) => - tcx.sess.span_bug(span, fmt!("unprocessed lint %?: %s", - lint, *msg)) + tcx.sess.span_bug(span, fmt!("unprocessed lint %? at %s: \ + %s", + lint, + ast_map::node_id_to_str( + tcx.items, + *id, + token::get_ident_interner()), + *msg)) } } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 3e1d4b3ba8c..7794a37d7e2 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -119,9 +119,9 @@ use syntax::ast::*; use syntax::codemap::span; use syntax::parse::token::special_idents; use syntax::print::pprust::{expr_to_str, block_to_str}; -use syntax::visit::{fk_anon, fk_fn_block, fk_item_fn, fk_method}; -use syntax::visit::{vt}; -use syntax::{visit, ast_util}; +use syntax::oldvisit::{fk_anon, fk_fn_block, fk_item_fn, fk_method}; +use syntax::oldvisit::{vt}; +use syntax::{oldvisit, ast_util}; #[deriving(Eq)] struct Variable(uint); @@ -156,18 +156,18 @@ pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, capture_map: moves::CaptureMap, crate: &Crate) { - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_fn: visit_fn, visit_local: visit_local, visit_expr: visit_expr, visit_arm: visit_arm, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); let initial_maps = @mut IrMaps(tcx, method_map, capture_map); - visit::visit_crate(crate, (initial_maps, visitor)); + oldvisit::visit_crate(crate, (initial_maps, visitor)); tcx.sess.abort_if_errors(); } @@ -341,7 +341,7 @@ impl IrMaps { } } -fn visit_fn(fk: &visit::fn_kind, +fn visit_fn(fk: &oldvisit::fn_kind, decl: &fn_decl, body: &Block, sp: span, @@ -385,7 +385,7 @@ fn visit_fn(fk: &visit::fn_kind, // gather up the various local variables, significant expressions, // and so forth: - visit::visit_fn(fk, decl, body, sp, id, (fn_maps, v)); + oldvisit::visit_fn(fk, decl, body, sp, id, (fn_maps, v)); // Special nodes and variables: // - exit_ln represents the end of the fn, either by return or fail @@ -402,12 +402,12 @@ fn visit_fn(fk: &visit::fn_kind, let entry_ln = (*lsets).compute(decl, body); // check for various error conditions - let check_vt = visit::mk_vt(@visit::Visitor { + let check_vt = oldvisit::mk_vt(@oldvisit::Visitor { visit_fn: check_fn, visit_local: check_local, visit_expr: check_expr, visit_arm: check_arm, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); (check_vt.visit_block)(body, (lsets, check_vt)); lsets.check_ret(id, sp, fk, entry_ln); @@ -431,7 +431,7 @@ fn visit_local(local: @Local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { kind: kind })); } - visit::visit_local(local, (this, vt)); + oldvisit::visit_local(local, (this, vt)); } fn visit_arm(arm: &arm, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { @@ -450,7 +450,7 @@ fn visit_arm(arm: &arm, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { })); } } - visit::visit_arm(arm, (this, vt)); + oldvisit::visit_arm(arm, (this, vt)); } fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { @@ -462,7 +462,7 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { if moves::moved_variable_node_id_from_def(def).is_some() { this.add_live_node_for_node(expr.id, ExprNode(expr.span)); } - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } expr_fn_block(*) => { // Interesting control flow (for loops can contain labeled @@ -495,18 +495,18 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { } this.set_captures(expr.id, call_caps); - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } // live nodes required for interesting control flow: expr_if(*) | expr_match(*) | expr_while(*) | expr_loop(*) => { this.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } expr_for_loop(*) => fail!("non-desugared expr_for_loop"), expr_binary(_, op, _, _) if ast_util::lazy_binop(op) => { this.add_live_node_for_node(expr.id, ExprNode(expr.span)); - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } // otherwise, live nodes are not required: @@ -518,7 +518,7 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) { expr_assign(*) | expr_assign_op(*) | expr_mac(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) | expr_inline_asm(*) => { - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } } } @@ -1435,14 +1435,14 @@ fn check_local(local: @Local, (this, vt): (@Liveness, vt<@Liveness>)) { } } - visit::visit_local(local, (this, vt)); + oldvisit::visit_local(local, (this, vt)); } fn check_arm(arm: &arm, (this, vt): (@Liveness, vt<@Liveness>)) { do this.arm_pats_bindings(arm.pats) |ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); } - visit::visit_arm(arm, (this, vt)); + oldvisit::visit_arm(arm, (this, vt)); } fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) { @@ -1451,13 +1451,13 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) { this.check_lvalue(l, vt); (vt.visit_expr)(r, (this, vt)); - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } expr_assign_op(_, _, l, _) => { this.check_lvalue(l, vt); - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } expr_inline_asm(ref ia) => { @@ -1476,7 +1476,7 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) { (vt.visit_expr)(out, (this, vt)); } - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } // no correctness conditions related to liveness @@ -1488,14 +1488,17 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) { expr_again(*) | expr_lit(_) | expr_block(*) | expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) | expr_paren(*) | expr_fn_block(*) | expr_path(*) | expr_self(*) => { - visit::visit_expr(expr, (this, vt)); + oldvisit::visit_expr(expr, (this, vt)); } expr_for_loop(*) => fail!("non-desugared expr_for_loop") } } -fn check_fn(_fk: &visit::fn_kind, _decl: &fn_decl, - _body: &Block, _sp: span, _id: NodeId, +fn check_fn(_fk: &oldvisit::fn_kind, + _decl: &fn_decl, + _body: &Block, + _sp: span, + _id: NodeId, (_self, _v): (@Liveness, vt<@Liveness>)) { // do not check contents of nested fns } @@ -1511,7 +1514,7 @@ impl Liveness { pub fn check_ret(&self, id: NodeId, sp: span, - _fk: &visit::fn_kind, + _fk: &oldvisit::fn_kind, entry_ln: LiveNode) { if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() { // if no_ret_var is live, then we fall off the end of the @@ -1560,7 +1563,7 @@ impl Liveness { _ => { // For other kinds of lvalues, no checks are required, // and any embedded expressions are actually rvalues - visit::visit_expr(expr, (self, vt)); + oldvisit::visit_expr(expr, (self, vt)); } } } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index a31003d8a16..5b02a826d1c 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -139,8 +139,8 @@ use std::at_vec; use std::hashmap::{HashSet, HashMap}; use syntax::ast::*; use syntax::ast_util; -use syntax::visit; -use syntax::visit::vt; +use syntax::oldvisit; +use syntax::oldvisit::vt; use syntax::codemap::span; #[deriving(Encodable, Decodable)] @@ -194,11 +194,11 @@ pub fn compute_moves(tcx: ty::ctxt, method_map: method_map, crate: &Crate) -> MoveMaps { - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_fn: compute_modes_for_fn, visit_expr: compute_modes_for_expr, visit_local: compute_modes_for_local, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); let visit_cx = VisitContext { tcx: tcx, @@ -209,7 +209,7 @@ pub fn compute_moves(tcx: ty::ctxt, moved_variables_set: @mut HashSet::new() } }; - visit::visit_crate(crate, (visit_cx, visitor)); + oldvisit::visit_crate(crate, (visit_cx, visitor)); return visit_cx.move_maps; } @@ -236,7 +236,7 @@ fn compute_modes_for_local<'a>(local: @Local, } } -fn compute_modes_for_fn(fk: &visit::fn_kind, +fn compute_modes_for_fn(fk: &oldvisit::fn_kind, decl: &fn_decl, body: &Block, span: span, @@ -246,7 +246,7 @@ fn compute_modes_for_fn(fk: &visit::fn_kind, foreach a in decl.inputs.iter() { cx.use_pat(a.pat); } - visit::visit_fn(fk, decl, body, span, id, (cx, v)); + oldvisit::visit_fn(fk, decl, body, span, id, (cx, v)); } fn compute_modes_for_expr(expr: @expr, diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 8b2171b59ac..e858ec26304 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -34,7 +34,7 @@ use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy}; use syntax::attr; use syntax::codemap::span; use syntax::parse::token; -use syntax::visit; +use syntax::oldvisit; pub fn check_crate<'mm>(tcx: ty::ctxt, method_map: &'mm method_map, @@ -334,11 +334,14 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } }; - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_mod: |the_module, span, node_id, (method_map, visitor)| { let n_added = add_privileged_items(the_module.items); - visit::visit_mod(the_module, span, node_id, (method_map, visitor)); + oldvisit::visit_mod(the_module, + span, + node_id, + (method_map, visitor)); do n_added.times { ignore(privileged_items.pop()); @@ -348,7 +351,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, // Do not check privacy inside items with the resolve_unexported // attribute. This is used for the test runner. if !attr::contains_name(item.attrs, "!resolve_unexported") { - visit::visit_item(item, (method_map, visitor)); + oldvisit::visit_item(item, (method_map, visitor)); } }, visit_block: |block, (method_map, visitor)| { @@ -368,13 +371,15 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, } } - visit::visit_block(block, (method_map, visitor)); + oldvisit::visit_block(block, (method_map, visitor)); do n_added.times { ignore(privileged_items.pop()); } }, - visit_expr: |expr, (method_map, visitor): (&'mm method_map, visit::vt<&'mm method_map>)| { + visit_expr: |expr, + (method_map, visitor): + (&'mm method_map, oldvisit::vt<&'mm method_map>)| { match expr.node { expr_field(base, ident, _) => { // Method calls are now a special syntactic form, @@ -480,7 +485,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, _ => {} } - visit::visit_expr(expr, (method_map, visitor)); + oldvisit::visit_expr(expr, (method_map, visitor)); }, visit_pat: |pattern, (method_map, visitor)| { match pattern.node { @@ -528,9 +533,9 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, _ => {} } - visit::visit_pat(pattern, (method_map, visitor)); + oldvisit::visit_pat(pattern, (method_map, visitor)); }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, (method_map, visitor)); + oldvisit::visit_crate(crate, (method_map, visitor)); } diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index 681fc0316ca..e012d9a2ff9 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -26,8 +26,8 @@ use syntax::ast_map; use syntax::ast_util::def_id_of_def; use syntax::attr; use syntax::parse::token; -use syntax::visit::Visitor; -use syntax::visit; +use syntax::oldvisit::Visitor; +use syntax::oldvisit; // Returns true if the given set of attributes contains the `#[inline]` // attribute. @@ -113,9 +113,9 @@ impl ReachableContext { fn mark_public_symbols(&self, crate: @Crate) { let reachable_symbols = self.reachable_symbols; let worklist = self.worklist; - let visitor = visit::mk_vt(@Visitor { + let visitor = oldvisit::mk_vt(@Visitor { visit_item: |item, (privacy_context, visitor): - (PrivacyContext, visit::vt<PrivacyContext>)| { + (PrivacyContext, oldvisit::vt<PrivacyContext>)| { match item.node { item_fn(*) => { if privacy_context == PublicContext { @@ -201,15 +201,15 @@ impl ReachableContext { } if item.vis == public && privacy_context == PublicContext { - visit::visit_item(item, (PublicContext, visitor)) + oldvisit::visit_item(item, (PublicContext, visitor)) } else { - visit::visit_item(item, (PrivateContext, visitor)) + oldvisit::visit_item(item, (PrivateContext, visitor)) } }, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, (PublicContext, visitor)) + oldvisit::visit_crate(crate, (PublicContext, visitor)) } // Returns true if the given def ID represents a local item that is @@ -271,10 +271,10 @@ impl ReachableContext { } // Helper function to set up a visitor for `propagate()` below. - fn init_visitor(&self) -> visit::vt<()> { + fn init_visitor(&self) -> oldvisit::vt<()> { let (worklist, method_map) = (self.worklist, self.method_map); let (tcx, reachable_symbols) = (self.tcx, self.reachable_symbols); - visit::mk_vt(@visit::Visitor { + oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: |expr, (_, visitor)| { match expr.node { expr_path(_) => { @@ -319,9 +319,9 @@ impl ReachableContext { _ => {} } - visit::visit_expr(expr, ((), visitor)) + oldvisit::visit_expr(expr, ((), visitor)) }, - ..*visit::default_visitor() + ..*oldvisit::default_visitor() }) } @@ -344,7 +344,7 @@ impl ReachableContext { Some(&ast_map::node_item(item, _)) => { match item.node { item_fn(_, _, _, _, ref search_block) => { - visit::visit_block(search_block, ((), visitor)) + oldvisit::visit_block(search_block, ((), visitor)) } _ => { self.tcx.sess.span_bug(item.span, @@ -361,12 +361,12 @@ impl ReachableContext { worklist?!") } provided(ref method) => { - visit::visit_block(&method.body, ((), visitor)) + oldvisit::visit_block(&method.body, ((), visitor)) } } } Some(&ast_map::node_method(ref method, _, _)) => { - visit::visit_block(&method.body, ((), visitor)) + oldvisit::visit_block(&method.body, ((), visitor)) } Some(_) => { let ident_interner = token::get_ident_interner(); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index 0a50a88a6ed..3aa2f3278b9 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -34,7 +34,7 @@ use syntax::codemap::span; use syntax::print::pprust; use syntax::parse::token; use syntax::parse::token::special_idents; -use syntax::{ast, visit}; +use syntax::{ast, oldvisit}; /** The region maps encode information about region relationships. @@ -323,7 +323,8 @@ fn parent_to_expr(cx: Context, child_id: ast::NodeId, sp: span) { } } -fn resolve_block(blk: &ast::Block, (cx, visitor): (Context, visit::vt<Context>)) { +fn resolve_block(blk: &ast::Block, + (cx, visitor): (Context, oldvisit::vt<Context>)) { // Record the parent of this block. parent_to_expr(cx, blk.id, blk.span); @@ -331,35 +332,39 @@ fn resolve_block(blk: &ast::Block, (cx, visitor): (Context, visit::vt<Context>)) let new_cx = Context {var_parent: Some(blk.id), parent: Some(blk.id), ..cx}; - visit::visit_block(blk, (new_cx, visitor)); + oldvisit::visit_block(blk, (new_cx, visitor)); } -fn resolve_arm(arm: &ast::arm, (cx, visitor): (Context, visit::vt<Context>)) { - visit::visit_arm(arm, (cx, visitor)); +fn resolve_arm(arm: &ast::arm, + (cx, visitor): (Context, oldvisit::vt<Context>)) { + oldvisit::visit_arm(arm, (cx, visitor)); } -fn resolve_pat(pat: @ast::pat, (cx, visitor): (Context, visit::vt<Context>)) { +fn resolve_pat(pat: @ast::pat, + (cx, visitor): (Context, oldvisit::vt<Context>)) { assert_eq!(cx.var_parent, cx.parent); parent_to_expr(cx, pat.id, pat.span); - visit::visit_pat(pat, (cx, visitor)); + oldvisit::visit_pat(pat, (cx, visitor)); } -fn resolve_stmt(stmt: @ast::stmt, (cx, visitor): (Context, visit::vt<Context>)) { +fn resolve_stmt(stmt: @ast::stmt, + (cx, visitor): (Context, oldvisit::vt<Context>)) { match stmt.node { ast::stmt_decl(*) => { - visit::visit_stmt(stmt, (cx, visitor)); + oldvisit::visit_stmt(stmt, (cx, visitor)); } ast::stmt_expr(_, stmt_id) | ast::stmt_semi(_, stmt_id) => { parent_to_expr(cx, stmt_id, stmt.span); let expr_cx = Context {parent: Some(stmt_id), ..cx}; - visit::visit_stmt(stmt, (expr_cx, visitor)); + oldvisit::visit_stmt(stmt, (expr_cx, visitor)); } ast::stmt_mac(*) => cx.sess.bug("unexpanded macro") } } -fn resolve_expr(expr: @ast::expr, (cx, visitor): (Context, visit::vt<Context>)) { +fn resolve_expr(expr: @ast::expr, + (cx, visitor): (Context, oldvisit::vt<Context>)) { parent_to_expr(cx, expr.id, expr.span); let mut new_cx = cx; @@ -395,30 +400,30 @@ fn resolve_expr(expr: @ast::expr, (cx, visitor): (Context, visit::vt<Context>)) }; - visit::visit_expr(expr, (new_cx, visitor)); + oldvisit::visit_expr(expr, (new_cx, visitor)); } fn resolve_local(local: @ast::Local, - (cx, visitor) : (Context, - visit::vt<Context>)) { + (cx, visitor): (Context, oldvisit::vt<Context>)) { assert_eq!(cx.var_parent, cx.parent); parent_to_expr(cx, local.id, local.span); - visit::visit_local(local, (cx, visitor)); + oldvisit::visit_local(local, (cx, visitor)); } -fn resolve_item(item: @ast::item, (cx, visitor): (Context, visit::vt<Context>)) { +fn resolve_item(item: @ast::item, + (cx, visitor): (Context, oldvisit::vt<Context>)) { // Items create a new outer block scope as far as we're concerned. let new_cx = Context {var_parent: None, parent: None, ..cx}; - visit::visit_item(item, (new_cx, visitor)); + oldvisit::visit_item(item, (new_cx, visitor)); } -fn resolve_fn(fk: &visit::fn_kind, +fn resolve_fn(fk: &oldvisit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, sp: span, id: ast::NodeId, (cx, visitor): (Context, - visit::vt<Context>)) { + oldvisit::vt<Context>)) { debug!("region::resolve_fn(id=%?, \ span=%?, \ body.id=%?, \ @@ -433,22 +438,22 @@ fn resolve_fn(fk: &visit::fn_kind, var_parent: Some(body.id), ..cx}; match *fk { - visit::fk_method(_, _, method) => { + oldvisit::fk_method(_, _, method) => { cx.region_maps.record_parent(method.self_id, body.id); } _ => {} } - visit::visit_fn_decl(decl, (decl_cx, visitor)); + oldvisit::visit_fn_decl(decl, (decl_cx, visitor)); // The body of the fn itself is either a root scope (top-level fn) // or it continues with the inherited scope (closures). let body_cx = match *fk { - visit::fk_item_fn(*) | - visit::fk_method(*) => { + oldvisit::fk_item_fn(*) | + oldvisit::fk_method(*) => { Context {parent: None, var_parent: None, ..cx} } - visit::fk_anon(*) | - visit::fk_fn_block(*) => { + oldvisit::fk_anon(*) | + oldvisit::fk_fn_block(*) => { cx } }; @@ -469,7 +474,7 @@ pub fn resolve_crate(sess: Session, region_maps: region_maps, parent: None, var_parent: None}; - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_block: resolve_block, visit_item: resolve_item, visit_fn: resolve_fn, @@ -478,9 +483,9 @@ pub fn resolve_crate(sess: Session, visit_stmt: resolve_stmt, visit_expr: resolve_expr, visit_local: resolve_local, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, (cx, visitor)); + oldvisit::visit_crate(crate, (cx, visitor)); return region_maps; } @@ -698,19 +703,19 @@ impl DetermineRpCtxt { fn determine_rp_in_item(item: @ast::item, (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { + oldvisit::vt<@mut DetermineRpCtxt>)) { do cx.with(item.id, true) { - visit::visit_item(item, (cx, visitor)); + oldvisit::visit_item(item, (cx, visitor)); } } -fn determine_rp_in_fn(fk: &visit::fn_kind, +fn determine_rp_in_fn(fk: &oldvisit::fn_kind, decl: &ast::fn_decl, body: &ast::Block, _: span, _: ast::NodeId, (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { + oldvisit::vt<@mut DetermineRpCtxt>)) { do cx.with(cx.item_id, false) { do cx.with_ambient_variance(rv_contravariant) { foreach a in decl.inputs.iter() { @@ -718,23 +723,24 @@ fn determine_rp_in_fn(fk: &visit::fn_kind, } } (visitor.visit_ty)(&decl.output, (cx, visitor)); - let generics = visit::generics_of_fn(fk); + let generics = oldvisit::generics_of_fn(fk); (visitor.visit_generics)(&generics, (cx, visitor)); (visitor.visit_block)(body, (cx, visitor)); } } fn determine_rp_in_ty_method(ty_m: &ast::TypeMethod, - (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { + (cx, visitor): + (@mut DetermineRpCtxt, + oldvisit::vt<@mut DetermineRpCtxt>)) { do cx.with(cx.item_id, false) { - visit::visit_ty_method(ty_m, (cx, visitor)); + oldvisit::visit_ty_method(ty_m, (cx, visitor)); } } fn determine_rp_in_ty(ty: &ast::Ty, (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { + oldvisit::vt<@mut DetermineRpCtxt>)) { // we are only interested in types that will require an item to // be region-parameterized. if cx.item_id is zero, then this type // is not a member of a type defn nor is it a constitutent of an @@ -846,13 +852,13 @@ fn determine_rp_in_ty(ty: &ast::Ty, } _ => { - visit::visit_ty(ty, (cx, visitor)); + oldvisit::visit_ty(ty, (cx, visitor)); } } fn visit_mt(mt: &ast::mt, (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { + oldvisit::vt<@mut DetermineRpCtxt>)) { // mutability is invariant if mt.mutbl == ast::m_mutbl { do cx.with_ambient_variance(rv_invariant) { @@ -867,8 +873,8 @@ fn determine_rp_in_ty(ty: &ast::Ty, fn determine_rp_in_struct_field( cm: @ast::struct_field, (cx, visitor): (@mut DetermineRpCtxt, - visit::vt<@mut DetermineRpCtxt>)) { - visit::visit_struct_field(cm, (cx, visitor)); + oldvisit::vt<@mut DetermineRpCtxt>)) { + oldvisit::visit_struct_field(cm, (cx, visitor)); } pub fn determine_rp_in_crate(sess: Session, @@ -889,15 +895,15 @@ pub fn determine_rp_in_crate(sess: Session, }; // Gather up the base set, worklist and dep_map - let visitor = visit::mk_vt(@visit::Visitor { + let visitor = oldvisit::mk_vt(@oldvisit::Visitor { visit_fn: determine_rp_in_fn, visit_item: determine_rp_in_item, visit_ty: determine_rp_in_ty, visit_ty_method: determine_rp_in_ty_method, visit_struct_field: determine_rp_in_struct_field, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }); - visit::visit_crate(crate, (cx, visitor)); + oldvisit::visit_crate(crate, (cx, visitor)); // Propagate indirect dependencies // diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index b92960a49fa..bdce2595e78 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -27,16 +27,16 @@ use syntax::ast_util::{path_to_ident, walk_pat, trait_method_to_ty_method}; use syntax::ast_util::{Privacy, Public, Private}; use syntax::ast_util::{variant_visibility_to_privacy, visibility_to_privacy}; use syntax::attr; +use syntax::oldvisit::{mk_simple_visitor, default_simple_visitor}; +use syntax::oldvisit::{default_visitor, mk_vt, Visitor, visit_block}; +use syntax::oldvisit::{visit_crate, visit_expr, visit_expr_opt}; +use syntax::oldvisit::{visit_foreign_item, visit_item}; +use syntax::oldvisit::{visit_mod, visit_ty, vt, SimpleVisitor}; use syntax::parse::token; use syntax::parse::token::ident_interner; use syntax::parse::token::special_idents; use syntax::print::pprust::path_to_str; use syntax::codemap::{span, dummy_sp, BytePos}; -use syntax::visit::{mk_simple_visitor, default_simple_visitor, SimpleVisitor}; -use syntax::visit::{default_visitor, mk_vt, Visitor, visit_block}; -use syntax::visit::{visit_crate, visit_expr, visit_expr_opt}; -use syntax::visit::{visit_foreign_item, visit_item}; -use syntax::visit::{visit_mod, visit_ty, vt}; use syntax::opt_vec::OptVec; use std::str; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 7f3922af014..a9d31b15121 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -83,7 +83,7 @@ use syntax::codemap::span; use syntax::parse::token; use syntax::parse::token::{special_idents}; use syntax::print::pprust::stmt_to_str; -use syntax::visit; +use syntax::oldvisit; use syntax::{ast, ast_util, codemap, ast_map}; use syntax::abi::{X86, X86_64, Arm, Mips}; @@ -2653,11 +2653,11 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) { } pub fn trans_constants(ccx: @mut CrateContext, crate: &ast::Crate) { - visit::visit_crate( + oldvisit::visit_crate( crate, ((), - visit::mk_simple_visitor(@visit::SimpleVisitor { + oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_item: |a| trans_constant(ccx, a), - ..*visit::default_simple_visitor() + ..*oldvisit::default_simple_visitor() }))); } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 4ad4400e982..d8c68c70604 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -107,9 +107,9 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option<Attribute>) { let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - Type::array(&Type::i32(), (size + 3) / 4 as u64) + Type::array(&Type::i32(), ((size + 3) / 4) as u64) } else { - Type::array(&Type::i64(), (size + 7) / 8 as u64) + Type::array(&Type::i64(), ((size + 7) / 8) as u64) }; (LLVMType { cast: true, ty: llty }, None) } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 6492c8a1cf2..8b8b020d8b6 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -48,7 +48,7 @@ use middle::trans::type_::Type; use syntax::ast; use syntax::ast_map; -use syntax::visit; +use syntax::oldvisit; // Represents a (possibly monomorphized) top-level fn item or method // item. Note that this is just the fn-ptr and is not a Rust closure @@ -529,17 +529,18 @@ pub fn trans_lang_call_with_type_params(bcx: @mut Block, pub fn body_contains_ret(body: &ast::Block) -> bool { let cx = @mut false; - visit::visit_block(body, (cx, visit::mk_vt(@visit::Visitor { + oldvisit::visit_block(body, (cx, oldvisit::mk_vt(@oldvisit::Visitor { visit_item: |_i, (_cx, _v)| { }, - visit_expr: |e: @ast::expr, (cx, v): (@mut bool, visit::vt<@mut bool>)| { + visit_expr: |e: @ast::expr, + (cx, v): (@mut bool, oldvisit::vt<@mut bool>)| { if !*cx { match e.node { ast::expr_ret(_) => *cx = true, - _ => visit::visit_expr(e, (cx, v)), + _ => oldvisit::visit_expr(e, (cx, v)), } } }, - ..*visit::default_visitor() + ..*oldvisit::default_visitor() }))); *cx } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 799cf7ece80..b895ec729f8 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -42,7 +42,7 @@ use syntax::ast::*; use syntax::ast_map; use syntax::ast_util; use syntax::parse::token; -use syntax::visit; +use syntax::oldvisit; pub type type_uses = uint; // Bitmask pub static use_repr: uint = 1; /* Dependency on size/alignment/mode and @@ -407,27 +407,27 @@ pub fn mark_for_expr(cx: &Context, e: &expr) { } pub fn handle_body(cx: &Context, body: &Block) { - let v = visit::mk_vt(@visit::Visitor { + let v = oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: |e, (cx, v)| { - visit::visit_expr(e, (cx, v)); + oldvisit::visit_expr(e, (cx, v)); mark_for_expr(cx, e); }, visit_local: |l, (cx, v)| { - visit::visit_local(l, (cx, v)); + oldvisit::visit_local(l, (cx, v)); node_type_needs(cx, use_repr, l.id); }, visit_pat: |p, (cx, v)| { - visit::visit_pat(p, (cx, v)); + oldvisit::visit_pat(p, (cx, v)); node_type_needs(cx, use_repr, p.id); }, visit_block: |b, (cx, v)| { - visit::visit_block(b, (cx, v)); + oldvisit::visit_block(b, (cx, v)); foreach e in b.expr.iter() { node_type_needs(cx, use_repr, e.id); } }, visit_item: |_i, (_cx, _v)| { }, - ..*visit::default_visitor() + ..*oldvisit::default_visitor() }); (v.visit_block)(body, (cx, v)); } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index a8d1a1d49d7..0a72e907ae8 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -129,7 +129,7 @@ use syntax::opt_vec; use syntax::parse::token; use syntax::parse::token::special_idents; use syntax::print::pprust; -use syntax::visit; +use syntax::oldvisit; use syntax; pub mod _match; @@ -304,11 +304,11 @@ impl ExprTyProvider for FnCtxt { } pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) { - let visit = visit::mk_simple_visitor(@visit::SimpleVisitor { + let visit = oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_item: |a| check_item(ccx, a), - .. *visit::default_simple_visitor() + .. *oldvisit::default_simple_visitor() }); - visit::visit_crate(crate, ((), visit)); + oldvisit::visit_crate(crate, ((), visit)); } pub fn check_bare_fn(ccx: @mut CrateCtxt, @@ -484,7 +484,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, } // Add explicitly-declared locals. - let visit_local: @fn(@ast::Local, ((), visit::vt<()>)) = + let visit_local: @fn(@ast::Local, ((), oldvisit::vt<()>)) = |local, (e, v)| { let o_ty = match local.ty.node { ast::ty_infer => None, @@ -495,11 +495,11 @@ pub fn check_fn(ccx: @mut CrateCtxt, fcx.pat_to_str(local.pat), fcx.infcx().ty_to_str( fcx.inh.locals.get_copy(&local.id))); - visit::visit_local(local, (e, v)); + oldvisit::visit_local(local, (e, v)); }; // Add pattern bindings. - let visit_pat: @fn(@ast::pat, ((), visit::vt<()>)) = |p, (e, v)| { + let visit_pat: @fn(@ast::pat, ((), oldvisit::vt<()>)) = |p, (e, v)| { match p.node { ast::pat_ident(_, ref path, _) if pat_util::pat_is_binding(fcx.ccx.tcx.def_map, p) => { @@ -511,32 +511,36 @@ pub fn check_fn(ccx: @mut CrateCtxt, } _ => {} } - visit::visit_pat(p, (e, v)); + oldvisit::visit_pat(p, (e, v)); }; - let visit_block: @fn(&ast::Block, ((), visit::vt<()>)) = |b, (e, v)| { + let visit_block: + @fn(&ast::Block, ((), oldvisit::vt<()>)) = |b, (e, v)| { // non-obvious: the `blk` variable maps to region lb, so // we have to keep this up-to-date. This // is... unfortunate. It'd be nice to not need this. do fcx.with_region_lb(b.id) { - visit::visit_block(b, (e, v)); + oldvisit::visit_block(b, (e, v)); } }; // Don't descend into fns and items - fn visit_fn(_fk: &visit::fn_kind, _decl: &ast::fn_decl, - _body: &ast::Block, _sp: span, - _id: ast::NodeId, (_t,_v): ((), visit::vt<()>)) { + fn visit_fn(_fk: &oldvisit::fn_kind, + _decl: &ast::fn_decl, + _body: &ast::Block, + _sp: span, + _id: ast::NodeId, + (_t,_v): ((), oldvisit::vt<()>)) { } - fn visit_item(_i: @ast::item, (_e,_v): ((), visit::vt<()>)) { } + fn visit_item(_i: @ast::item, (_e,_v): ((), oldvisit::vt<()>)) { } - let visit = visit::mk_vt( - @visit::Visitor {visit_local: visit_local, + let visit = oldvisit::mk_vt( + @oldvisit::Visitor {visit_local: visit_local, visit_pat: visit_pat, visit_fn: visit_fn, visit_item: visit_item, visit_block: visit_block, - ..*visit::default_visitor()}); + ..*oldvisit::default_visitor()}); (visit.visit_block)(body, ((), visit)); } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 8730e22447c..fdb2925d30b 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -43,7 +43,7 @@ use syntax::ast::{ManagedSigil, OwnedSigil, BorrowedSigil}; use syntax::ast::{def_arg, def_binding, def_local, def_self, def_upvar}; use syntax::ast; use syntax::codemap::span; -use syntax::visit; +use syntax::oldvisit; pub struct Rcx { fcx: @mut FnCtxt, @@ -53,7 +53,7 @@ pub struct Rcx { repeating_scope: ast::NodeId, } -pub type rvt = visit::vt<@mut Rcx>; +pub type rvt = oldvisit::vt<@mut Rcx>; fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::def) -> ty::Region { let tcx = fcx.tcx(); @@ -171,15 +171,17 @@ fn regionck_visitor() -> rvt { // addressed by deferring the construction of the region // hierarchy, and in particular the relationships between free // regions, until regionck, as described in #3238. - visit::mk_vt(@visit::Visitor {visit_item: visit_item, - visit_expr: visit_expr, + oldvisit::mk_vt(@oldvisit::Visitor { + visit_item: visit_item, + visit_expr: visit_expr, - //visit_pat: visit_pat, // (*) see above - visit_arm: visit_arm, - visit_local: visit_local, + //visit_pat: visit_pat, // (*) see above + visit_arm: visit_arm, + visit_local: visit_local, - visit_block: visit_block, - .. *visit::default_visitor()}) + visit_block: visit_block, + .. *oldvisit::default_visitor() + }) } fn visit_item(_item: @ast::item, (_rcx, _v): (@mut Rcx, rvt)) { @@ -188,7 +190,7 @@ fn visit_item(_item: @ast::item, (_rcx, _v): (@mut Rcx, rvt)) { fn visit_block(b: &ast::Block, (rcx, v): (@mut Rcx, rvt)) { rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id); - visit::visit_block(b, (rcx, v)); + oldvisit::visit_block(b, (rcx, v)); } fn visit_arm(arm: &ast::arm, (rcx, v): (@mut Rcx, rvt)) { @@ -197,13 +199,13 @@ fn visit_arm(arm: &ast::arm, (rcx, v): (@mut Rcx, rvt)) { constrain_bindings_in_pat(p, rcx); } - visit::visit_arm(arm, (rcx, v)); + oldvisit::visit_arm(arm, (rcx, v)); } fn visit_local(l: @ast::Local, (rcx, v): (@mut Rcx, rvt)) { // see above constrain_bindings_in_pat(l.pat, rcx); - visit::visit_local(l, (rcx, v)); + oldvisit::visit_local(l, (rcx, v)); } fn constrain_bindings_in_pat(pat: @ast::pat, rcx: @mut Rcx) { @@ -328,13 +330,13 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { constrain_callee(rcx, callee.id, expr, callee); constrain_call(rcx, callee.id, expr, None, *args, false); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_method_call(callee_id, arg0, _, _, ref args, _) => { constrain_call(rcx, callee_id, expr, Some(arg0), *args, false); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_index(callee_id, lhs, rhs) | @@ -346,14 +348,14 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { // should be converted to an adjustment! constrain_call(rcx, callee_id, expr, Some(lhs), [rhs], true); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_unary(callee_id, _, lhs) if has_method_map => { // As above. constrain_call(rcx, callee_id, expr, Some(lhs), [], true); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_unary(_, ast::deref, base) => { @@ -361,7 +363,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { let base_ty = rcx.resolve_node_type(base.id); constrain_derefs(rcx, expr, 1, base_ty); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_index(_, vec_expr, _) => { @@ -369,7 +371,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { let vec_type = rcx.resolve_expr_type_adjusted(vec_expr); constrain_index(rcx, expr, vec_type); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_cast(source, _) => { @@ -399,7 +401,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { _ => () } - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_addr_of(_, base) => { @@ -415,13 +417,13 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { let ty0 = rcx.resolve_node_type(expr.id); constrain_regions_in_type(rcx, ty::re_scope(expr.id), infer::AddrOf(expr.span), ty0); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_match(discr, ref arms) => { guarantor::for_match(rcx, discr, *arms); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } ast::expr_loop_body(subexpr) => { @@ -434,7 +436,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { ast::expr_loop(ref body, _) => { let repeating_scope = rcx.set_repeating_scope(body.id); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); rcx.set_repeating_scope(repeating_scope); } @@ -449,7 +451,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { } _ => { - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); } } } @@ -486,7 +488,7 @@ fn check_expr_fn_block(rcx: @mut Rcx, } let repeating_scope = rcx.set_repeating_scope(body.id); - visit::visit_expr(expr, (rcx, v)); + oldvisit::visit_expr(expr, (rcx, v)); rcx.set_repeating_scope(repeating_scope); } diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index ec86945887e..ec2e3674a43 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -29,7 +29,7 @@ use syntax::ast; use syntax::ast_util; use syntax::codemap::span; use syntax::print::pprust::expr_to_str; -use syntax::visit; +use syntax::oldvisit; // vtable resolution looks for places where trait bounds are // substituted in and figures out which vtable is used. There is some @@ -721,9 +721,9 @@ pub fn early_resolve_expr(ex: @ast::expr, fn resolve_expr(ex: @ast::expr, (fcx, v): (@mut FnCtxt, - visit::vt<@mut FnCtxt>)) { + oldvisit::vt<@mut FnCtxt>)) { early_resolve_expr(ex, fcx, false); - visit::visit_expr(ex, (fcx, v)); + oldvisit::visit_expr(ex, (fcx, v)); } pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) { @@ -773,9 +773,9 @@ pub fn resolve_impl(ccx: @mut CrateCtxt, impl_item: @ast::item) { // Detect points where a trait-bounded type parameter is // instantiated, resolve the impls for the parameters. pub fn resolve_in_block(fcx: @mut FnCtxt, bl: &ast::Block) { - visit::visit_block(bl, (fcx, visit::mk_vt(@visit::Visitor { + oldvisit::visit_block(bl, (fcx, oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: resolve_expr, visit_item: |_,_| {}, - .. *visit::default_visitor() + .. *oldvisit::default_visitor() }))); } diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index b46df585b73..b0d0bb3f082 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -29,7 +29,7 @@ use util::ppaux; use syntax::ast; use syntax::codemap::span; use syntax::print::pprust::pat_to_str; -use syntax::visit; +use syntax::oldvisit; fn resolve_type_vars_in_type(fcx: @mut FnCtxt, sp: span, typ: ty::t) -> Option<ty::t> { @@ -212,12 +212,12 @@ struct WbCtxt { success: bool, } -type wb_vt = visit::vt<@mut WbCtxt>; +type wb_vt = oldvisit::vt<@mut WbCtxt>; fn visit_stmt(s: @ast::stmt, (wbcx, v): (@mut WbCtxt, wb_vt)) { if !wbcx.success { return; } resolve_type_vars_for_node(wbcx, s.span, ty::stmt_node_id(s)); - visit::visit_stmt(s, (wbcx, v)); + oldvisit::visit_stmt(s, (wbcx, v)); } fn visit_expr(e: @ast::expr, (wbcx, v): (@mut WbCtxt, wb_vt)) { @@ -265,7 +265,7 @@ fn visit_expr(e: @ast::expr, (wbcx, v): (@mut WbCtxt, wb_vt)) { _ => () } - visit::visit_expr(e, (wbcx, v)); + oldvisit::visit_expr(e, (wbcx, v)); } fn visit_block(b: &ast::Block, (wbcx, v): (@mut WbCtxt, wb_vt)) { @@ -274,7 +274,7 @@ fn visit_block(b: &ast::Block, (wbcx, v): (@mut WbCtxt, wb_vt)) { } resolve_type_vars_for_node(wbcx, b.span, b.id); - visit::visit_block(b, (wbcx, v)); + oldvisit::visit_block(b, (wbcx, v)); } fn visit_pat(p: @ast::pat, (wbcx, v): (@mut WbCtxt, wb_vt)) { @@ -288,7 +288,7 @@ fn visit_pat(p: @ast::pat, (wbcx, v): (@mut WbCtxt, wb_vt)) { wbcx.fcx.infcx().ty_to_str( ty::node_id_to_type(wbcx.fcx.ccx.tcx, p.id))); - visit::visit_pat(p, (wbcx, v)); + oldvisit::visit_pat(p, (wbcx, v)); } fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, wb_vt)) { @@ -311,20 +311,20 @@ fn visit_local(l: @ast::Local, (wbcx, v): (@mut WbCtxt, wb_vt)) { wbcx.success = false; } } - visit::visit_local(l, (wbcx, v)); + oldvisit::visit_local(l, (wbcx, v)); } fn visit_item(_item: @ast::item, (_wbcx, _v): (@mut WbCtxt, wb_vt)) { // Ignore items } -fn mk_visitor() -> visit::vt<@mut WbCtxt> { - visit::mk_vt(@visit::Visitor {visit_item: visit_item, +fn mk_visitor() -> oldvisit::vt<@mut WbCtxt> { + oldvisit::mk_vt(@oldvisit::Visitor {visit_item: visit_item, visit_stmt: visit_stmt, visit_expr: visit_expr, visit_block: visit_block, visit_pat: visit_pat, visit_local: visit_local, - .. *visit::default_visitor()}) + .. *oldvisit::default_visitor()}) } pub fn resolve_type_vars_in_expr(fcx: @mut FnCtxt, e: @ast::expr) -> bool { diff --git a/src/librustc/middle/typeck/coherence.rs b/src/librustc/middle/typeck/coherence.rs index f79d7dd3587..0fc5a3f2006 100644 --- a/src/librustc/middle/typeck/coherence.rs +++ b/src/librustc/middle/typeck/coherence.rs @@ -44,12 +44,12 @@ use syntax::ast_map::node_item; use syntax::ast_map; use syntax::ast_util::{def_id_of_def, local_def}; use syntax::codemap::{span, dummy_sp}; -use syntax::parse; use syntax::opt_vec; -use syntax::visit::{default_simple_visitor, default_visitor}; -use syntax::visit::{mk_simple_visitor, mk_vt, visit_crate, visit_item}; -use syntax::visit::{Visitor, SimpleVisitor}; -use syntax::visit::{visit_mod}; +use syntax::oldvisit::{default_simple_visitor, default_visitor}; +use syntax::oldvisit::{mk_simple_visitor, mk_vt, visit_crate, visit_item}; +use syntax::oldvisit::{Visitor, SimpleVisitor}; +use syntax::oldvisit::{visit_mod}; +use syntax::parse; use util::ppaux::ty_to_str; use std::hashmap::{HashMap, HashSet}; diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index 63c14dd8288..584a59c35ae 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -56,7 +56,7 @@ use syntax::ast_util::{local_def, split_trait_methods}; use syntax::codemap::span; use syntax::codemap; use syntax::print::pprust::{path_to_str, explicit_self_to_str}; -use syntax::visit; +use syntax::oldvisit; use syntax::opt_vec::OptVec; use syntax::opt_vec; use syntax::parse::token::special_idents; @@ -76,12 +76,12 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) { Some(id) => { collect_intrinsic_type(ccx, id); } None => {} } - visit::visit_crate( + oldvisit::visit_crate( crate, ((), - visit::mk_simple_visitor(@visit::SimpleVisitor { + oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor { visit_item: |a| convert(ccx, a), visit_foreign_item: |a|convert_foreign(ccx, a), - .. *visit::default_simple_visitor() + .. *oldvisit::default_simple_visitor() }))); } diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 2e698227120..7ed2d00e7c4 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -11,7 +11,7 @@ use syntax::ast; use syntax::codemap::{span}; -use syntax::visit; +use syntax::oldvisit; use std::hashmap::HashSet; use extra; @@ -65,20 +65,20 @@ pub fn loop_query(b: &ast::Block, p: @fn(&ast::expr_) -> bool) -> bool { let rs = @mut false; let visit_expr: @fn(@ast::expr, (@mut bool, - visit::vt<@mut bool>)) = |e, (flag, v)| { + oldvisit::vt<@mut bool>)) = |e, (flag, v)| { *flag |= p(&e.node); match e.node { // Skip inner loops, since a break in the inner loop isn't a // break inside the outer loop ast::expr_loop(*) | ast::expr_while(*) | ast::expr_loop_body(*) => {} - _ => visit::visit_expr(e, (flag, v)) + _ => oldvisit::visit_expr(e, (flag, v)) } }; - let v = visit::mk_vt(@visit::Visitor { + let v = oldvisit::mk_vt(@oldvisit::Visitor { visit_expr: visit_expr, - .. *visit::default_visitor()}); - visit::visit_block(b, (rs, v)); + .. *oldvisit::default_visitor()}); + oldvisit::visit_block(b, (rs, v)); return *rs; } @@ -88,14 +88,14 @@ pub fn block_query(b: &ast::Block, p: @fn(@ast::expr) -> bool) -> bool { let rs = @mut false; let visit_expr: @fn(@ast::expr, (@mut bool, - visit::vt<@mut bool>)) = |e, (flag, v)| { + oldvisit::vt<@mut bool>)) = |e, (flag, v)| { *flag |= p(e); - visit::visit_expr(e, (flag, v)) + oldvisit::visit_expr(e, (flag, v)) }; - let v = visit::mk_vt(@visit::Visitor{ + let v = oldvisit::mk_vt(@oldvisit::Visitor{ visit_expr: visit_expr, - .. *visit::default_visitor()}); - visit::visit_block(b, (rs, v)); + .. *oldvisit::default_visitor()}); + oldvisit::visit_block(b, (rs, v)); return *rs; } diff --git a/src/librusti/utils.rs b/src/librusti/utils.rs index eca20483266..94c0e4fe01e 100644 --- a/src/librusti/utils.rs +++ b/src/librusti/utils.rs @@ -15,10 +15,10 @@ use syntax::print::pprust; use syntax::parse::token; pub fn each_binding(l: @ast::Local, f: @fn(&ast::Path, ast::NodeId)) { - use syntax::visit; + use syntax::oldvisit; - let vt = visit::mk_simple_visitor( - @visit::SimpleVisitor { + let vt = oldvisit::mk_simple_visitor( + @oldvisit::SimpleVisitor { visit_pat: |pat| { match pat.node { ast::pat_ident(_, ref path, _) => { @@ -27,7 +27,7 @@ pub fn each_binding(l: @ast::Local, f: @fn(&ast::Path, ast::NodeId)) { _ => {} } }, - .. *visit::default_simple_visitor() + .. *oldvisit::default_simple_visitor() } ); (vt.visit_pat)(l.pat, ((), vt)); diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index bee0f113aa7..9c0f2d34a6c 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -13,12 +13,14 @@ use ast::*; use ast; use ast_util::{inlined_item_utils, stmt_id}; use ast_util; +use codemap::span; use codemap; use diagnostic::span_handler; use parse::token::ident_interner; +use parse::token::special_idents; use print::pprust; +use visit::{Visitor, fn_kind}; use visit; -use syntax::parse::token::special_idents; use std::hashmap::HashMap; use std::vec; @@ -86,22 +88,282 @@ pub struct Ctx { diag: @span_handler, } -pub type vt = visit::vt<@mut Ctx>; +impl Ctx { + fn extend(@mut self, elt: ident) -> @path { + @vec::append(self.path.clone(), [path_name(elt)]) + } + + fn map_method(@mut self, + impl_did: def_id, + impl_path: @path, + m: @method, + is_provided: bool) { + let entry = if is_provided { + node_trait_method(@provided(m), impl_did, impl_path) + } else { + node_method(m, impl_did, impl_path) + }; + self.map.insert(m.id, entry); + self.map.insert(m.self_id, node_local(special_idents::self_)); + } + + fn map_struct_def(@mut self, + struct_def: @ast::struct_def, + parent_node: ast_node, + ident: ast::ident) { + let p = self.extend(ident); + + // If this is a tuple-like struct, register the constructor. + match struct_def.ctor_id { + None => {} + Some(ctor_id) => { + match parent_node { + node_item(item, _) => { + self.map.insert(ctor_id, + node_struct_ctor(struct_def, + item, + p)); + } + _ => fail!("struct def parent wasn't an item") + } + } + } + } + + fn map_expr(@mut self, ex: @expr) { + self.map.insert(ex.id, node_expr(ex)); + + // Expressions which are or might be calls: + { + let r = ex.get_callee_id(); + foreach callee_id in r.iter() { + self.map.insert(*callee_id, node_callee_scope(ex)); + } + } + + visit::visit_expr(self as @Visitor<()>, ex, ()); + } -pub fn extend(cx: @mut Ctx, elt: ident) -> @path { - @(vec::append(cx.path.clone(), [path_name(elt)])) + fn map_fn(@mut self, + fk: &visit::fn_kind, + decl: &fn_decl, + body: &Block, + sp: codemap::span, + id: NodeId) { + foreach a in decl.inputs.iter() { + self.map.insert(a.id, node_arg); + } + visit::visit_fn(self as @Visitor<()>, fk, decl, body, sp, id, ()); + } + + fn map_stmt(@mut self, stmt: @stmt) { + self.map.insert(stmt_id(stmt), node_stmt(stmt)); + visit::visit_stmt(self as @Visitor<()>, stmt, ()); + } + + fn map_block(@mut self, b: &Block) { + // clone is FIXME #2543 + self.map.insert(b.id, node_block((*b).clone())); + visit::visit_block(self as @Visitor<()>, b, ()); + } + + fn map_pat(@mut self, pat: @pat) { + match pat.node { + pat_ident(_, ref path, _) => { + // Note: this is at least *potentially* a pattern... + self.map.insert(pat.id, + node_local(ast_util::path_to_ident(path))); + } + _ => () + } + + visit::visit_pat(self as @Visitor<()>, pat, ()); + } } -pub fn mk_ast_map_visitor() -> vt { - return visit::mk_vt(@visit::Visitor { - visit_item: map_item, - visit_expr: map_expr, - visit_stmt: map_stmt, - visit_fn: map_fn, - visit_block: map_block, - visit_pat: map_pat, - .. *visit::default_visitor() - }); +impl Visitor<()> for Ctx { + fn visit_item(@mut self, i: @item, _: ()) { + // clone is FIXME #2543 + let item_path = @self.path.clone(); + self.map.insert(i.id, node_item(i, item_path)); + match i.node { + item_impl(_, _, _, ref ms) => { + let impl_did = ast_util::local_def(i.id); + foreach m in ms.iter() { + self.map_method(impl_did, self.extend(i.ident), *m, false) + } + } + item_enum(ref enum_definition, _) => { + foreach v in (*enum_definition).variants.iter() { + // FIXME #2543: bad clone + self.map.insert(v.node.id, + node_variant((*v).clone(), + i, + self.extend(i.ident))); + } + } + item_foreign_mod(ref nm) => { + foreach nitem in nm.items.iter() { + // Compute the visibility for this native item. + let visibility = match nitem.vis { + public => public, + private => private, + inherited => i.vis + }; + + self.map.insert(nitem.id, + node_foreign_item(*nitem, + nm.abis, + visibility, + // FIXME (#2543) + if nm.sort == + ast::named { + self.extend(i.ident) + } else { + // Anonymous extern + // mods go in the + // parent scope. + @self.path.clone() + })); + } + } + item_struct(struct_def, _) => { + self.map_struct_def(struct_def, + node_item(i, item_path), + i.ident) + } + item_trait(_, ref traits, ref methods) => { + foreach p in traits.iter() { + self.map.insert(p.ref_id, node_item(i, item_path)); + } + foreach tm in methods.iter() { + let id = ast_util::trait_method_to_ty_method(tm).id; + let d_id = ast_util::local_def(i.id); + self.map.insert(id, + node_trait_method(@(*tm).clone(), + d_id, + item_path)); + } + } + _ => {} + } + + match i.node { + item_mod(_) | item_foreign_mod(_) => { + self.path.push(path_mod(i.ident)); + } + _ => self.path.push(path_name(i.ident)) + } + visit::visit_item(self as @Visitor<()>, i, ()); + self.path.pop(); + } + + fn visit_pat(@mut self, pat: @pat, _: ()) { + self.map_pat(pat); + visit::visit_pat(self as @Visitor<()>, pat, ()) + } + + fn visit_expr(@mut self, expr: @expr, _: ()) { + self.map_expr(expr) + } + + fn visit_stmt(@mut self, stmt: @stmt, _: ()) { + self.map_stmt(stmt) + } + + fn visit_fn(@mut self, + function_kind: &fn_kind, + function_declaration: &fn_decl, + block: &Block, + span: span, + node_id: NodeId, + _: ()) { + self.map_fn(function_kind, function_declaration, block, span, node_id) + } + + fn visit_block(@mut self, block: &Block, _: ()) { + self.map_block(block) + } + + // XXX: Methods below can become default methods. + + fn visit_mod(@mut self, module: &_mod, _: span, _: NodeId, _: ()) { + visit::visit_mod(self as @Visitor<()>, module, ()) + } + + fn visit_view_item(@mut self, view_item: &view_item, _: ()) { + visit::visit_view_item(self as @Visitor<()>, view_item, ()) + } + + fn visit_foreign_item(@mut self, foreign_item: @foreign_item, _: ()) { + visit::visit_foreign_item(self as @Visitor<()>, foreign_item, ()) + } + + fn visit_local(@mut self, local: @Local, _: ()) { + visit::visit_local(self as @Visitor<()>, local, ()) + } + + fn visit_arm(@mut self, arm: &arm, _: ()) { + visit::visit_arm(self as @Visitor<()>, arm, ()) + } + + fn visit_decl(@mut self, decl: @decl, _: ()) { + visit::visit_decl(self as @Visitor<()>, decl, ()) + } + + fn visit_expr_post(@mut self, _: @expr, _: ()) { + // Empty! + } + + fn visit_ty(@mut self, typ: &Ty, _: ()) { + visit::visit_ty(self as @Visitor<()>, typ, ()) + } + + fn visit_generics(@mut self, generics: &Generics, _: ()) { + visit::visit_generics(self as @Visitor<()>, generics, ()) + } + + fn visit_fn(@mut self, + function_kind: &fn_kind, + function_declaration: &fn_decl, + block: &Block, + span: span, + node_id: NodeId, + _: ()) { + visit::visit_fn(self as @Visitor<()>, + function_kind, + function_declaration, + block, + span, + node_id, + ()) + } + + fn visit_ty_method(@mut self, ty_method: &TypeMethod, _: ()) { + visit::visit_ty_method(self as @Visitor<()>, ty_method, ()) + } + + fn visit_trait_method(@mut self, trait_method: &trait_method, _: ()) { + visit::visit_trait_method(self as @Visitor<()>, trait_method, ()) + } + + fn visit_struct_def(@mut self, + struct_def: @struct_def, + ident: ident, + generics: &Generics, + node_id: NodeId, + _: ()) { + visit::visit_struct_def(self as @Visitor<()>, + struct_def, + ident, + generics, + node_id, + ()) + } + + fn visit_struct_field(@mut self, struct_field: @struct_field, _: ()) { + visit::visit_struct_field(self as @Visitor<()>, struct_field, ()) + } } pub fn map_crate(diag: @span_handler, c: &Crate) -> map { @@ -110,7 +372,7 @@ pub fn map_crate(diag: @span_handler, c: &Crate) -> map { path: ~[], diag: diag, }; - visit::visit_crate(c, (cx, mk_ast_map_visitor())); + visit::visit_crate(cx as @Visitor<()>, c, ()); cx.map } @@ -123,194 +385,31 @@ pub fn map_decoded_item(diag: @span_handler, ii: &inlined_item) { // I believe it is ok for the local IDs of inlined items from other crates // to overlap with the local ids from this crate, so just generate the ids - // starting from 0. (In particular, I think these ids are only used in - // alias analysis, which we will not be running on the inlined items, and - // even if we did I think it only needs an ordering between local - // variables that are simultaneously in scope). + // starting from 0. let cx = @mut Ctx { map: map, path: path.clone(), diag: diag, }; - let v = mk_ast_map_visitor(); // methods get added to the AST map when their impl is visited. Since we // don't decode and instantiate the impl, but just the method, we have to // add it to the table now: match *ii { - ii_item(*) => { /* fallthrough */ } - ii_foreign(i) => { - cx.map.insert(i.id, node_foreign_item(i, - AbiSet::Intrinsic(), - i.vis, // Wrong but OK - @path)); - } - ii_method(impl_did, is_provided, m) => { - map_method(impl_did, @path, m, is_provided, cx); - } - } - - // visit the item / method contents and add those to the map: - ii.accept(cx, v); -} - -pub fn map_fn( - fk: &visit::fn_kind, - decl: &fn_decl, - body: &Block, - sp: codemap::span, - id: NodeId, - (cx,v): (@mut Ctx, - visit::vt<@mut Ctx>) -) { - foreach a in decl.inputs.iter() { - cx.map.insert(a.id, node_arg); - } - visit::visit_fn(fk, decl, body, sp, id, (cx, v)); -} - -pub fn map_block(b: &Block, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { - cx.map.insert(b.id, node_block(/* FIXME (#2543) */ (*b).clone())); - visit::visit_block(b, (cx, v)); -} - -pub fn map_pat(pat: @pat, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { - match pat.node { - pat_ident(_, ref path, _) => { - // Note: this is at least *potentially* a pattern... - cx.map.insert(pat.id, node_local(ast_util::path_to_ident(path))); + ii_item(*) => {} // fallthrough + ii_foreign(i) => { + cx.map.insert(i.id, node_foreign_item(i, + AbiSet::Intrinsic(), + i.vis, // Wrong but OK + @path)); } - _ => () - } - - visit::visit_pat(pat, (cx, v)); -} - -pub fn map_method(impl_did: def_id, impl_path: @path, - m: @method, is_provided: bool, cx: @mut Ctx) { - let entry = if is_provided { - node_trait_method(@provided(m), impl_did, impl_path) - } else { node_method(m, impl_did, impl_path) }; - cx.map.insert(m.id, entry); - cx.map.insert(m.self_id, node_local(special_idents::self_)); -} - -pub fn map_item(i: @item, (cx, v): (@mut Ctx, visit::vt<@mut Ctx>)) { - let item_path = @/* FIXME (#2543) */ cx.path.clone(); - cx.map.insert(i.id, node_item(i, item_path)); - match i.node { - item_impl(_, _, _, ref ms) => { - let impl_did = ast_util::local_def(i.id); - foreach m in ms.iter() { - map_method(impl_did, extend(cx, i.ident), *m, false, cx); - } - } - item_enum(ref enum_definition, _) => { - foreach v in (*enum_definition).variants.iter() { - cx.map.insert(v.node.id, node_variant( - /* FIXME (#2543) */ (*v).clone(), - i, - extend(cx, i.ident))); - } - } - item_foreign_mod(ref nm) => { - foreach nitem in nm.items.iter() { - // Compute the visibility for this native item. - let visibility = match nitem.vis { - public => public, - private => private, - inherited => i.vis - }; - - cx.map.insert(nitem.id, - node_foreign_item( - *nitem, - nm.abis, - visibility, - // FIXME (#2543) - if nm.sort == ast::named { - extend(cx, i.ident) - } else { - // Anonymous extern mods go in the parent scope - @cx.path.clone() - } - ) - ); - } - } - item_struct(struct_def, _) => { - map_struct_def( - struct_def, - node_item(i, item_path), - i.ident, - (cx, - v) - ); - } - item_trait(_, ref traits, ref methods) => { - foreach p in traits.iter() { - cx.map.insert(p.ref_id, node_item(i, item_path)); - } - foreach tm in methods.iter() { - let id = ast_util::trait_method_to_ty_method(tm).id; - let d_id = ast_util::local_def(i.id); - cx.map.insert( - id, - node_trait_method(@(*tm).clone(), d_id, item_path) - ); - } + ii_method(impl_did, is_provided, m) => { + cx.map_method(impl_did, @path, m, is_provided); } - _ => () } - match i.node { - item_mod(_) | item_foreign_mod(_) => { - cx.path.push(path_mod(i.ident)); - } - _ => cx.path.push(path_name(i.ident)) - } - visit::visit_item(i, (cx, v)); - cx.path.pop(); -} - -pub fn map_struct_def( - struct_def: @ast::struct_def, - parent_node: ast_node, - ident: ast::ident, - (cx, _v): (@mut Ctx, - visit::vt<@mut Ctx>) -) { - let p = extend(cx, ident); - // If this is a tuple-like struct, register the constructor. - match struct_def.ctor_id { - None => {} - Some(ctor_id) => { - match parent_node { - node_item(item, _) => { - cx.map.insert(ctor_id, - node_struct_ctor(struct_def, item, p)); - } - _ => fail!("struct def parent wasn't an item") - } - } - } -} - -pub fn map_expr(ex: @expr, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { - cx.map.insert(ex.id, node_expr(ex)); - // Expressions which are or might be calls: - { - let r = ex.get_callee_id(); - foreach callee_id in r.iter() { - cx.map.insert(*callee_id, node_callee_scope(ex)); - } - } - visit::visit_expr(ex, (cx, v)); -} - -pub fn map_stmt(stmt: @stmt, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { - cx.map.insert(stmt_id(stmt), node_stmt(stmt)); - visit::visit_stmt(stmt, (cx, v)); + // visit the item / method contents and add those to the map: + ii.accept((), cx as @Visitor<()>); } pub fn node_id_to_str(map: map, id: NodeId, itr: @ident_interner) -> ~str { diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index b8a2ea1b57d..45238c30d73 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -14,6 +14,7 @@ use ast_util; use codemap::{span, dummy_sp}; use opt_vec; use parse::token; +use visit::{SimpleVisitor, SimpleVisitorVisitor, Visitor}; use visit; use std::hashmap::HashMap; @@ -297,7 +298,7 @@ pub fn struct_field_visibility(field: ast::struct_field) -> visibility { pub trait inlined_item_utils { fn ident(&self) -> ident; fn id(&self) -> ast::NodeId; - fn accept<E: Clone>(&self, e: E, v: visit::vt<E>); + fn accept<E: Clone>(&self, e: E, v: @Visitor<E>); } impl inlined_item_utils for inlined_item { @@ -317,11 +318,11 @@ impl inlined_item_utils for inlined_item { } } - fn accept<E: Clone>(&self, e: E, v: visit::vt<E>) { + fn accept<E: Clone>(&self, e: E, v: @Visitor<E>) { match *self { - ii_item(i) => (v.visit_item)(i, (e, v)), - ii_foreign(i) => (v.visit_foreign_item)(i, (e, v)), - ii_method(_, _, m) => visit::visit_method_helper(m, (e, v)), + ii_item(i) => v.visit_item(i, e), + ii_foreign(i) => v.visit_foreign_item(i, e), + ii_method(_, _, m) => visit::visit_method_helper(v, m, e), } } } @@ -339,8 +340,8 @@ pub fn is_self(d: ast::def) -> bool { /// Maps a binary operator to its precedence pub fn operator_prec(op: ast::binop) -> uint { match op { - mul | div | rem => 12u, - // 'as' sits between here with 11 + // 'as' sits here with 12 + mul | div | rem => 11u, add | subtract => 10u, shl | shr => 9u, bitand => 8u, @@ -355,7 +356,7 @@ pub fn operator_prec(op: ast::binop) -> uint { /// Precedence of the `as` operator, which is a binary operator /// not appearing in the prior table. -pub static as_prec: uint = 11u; +pub static as_prec: uint = 12u; pub fn empty_generics() -> Generics { Generics {lifetimes: opt_vec::Empty, @@ -389,134 +390,238 @@ impl id_range { } } -pub fn id_visitor<T: Clone>(vfn: @fn(NodeId, T)) -> visit::vt<T> { - let visit_generics: @fn(&Generics, T) = |generics, t| { - foreach p in generics.ty_params.iter() { - vfn(p.id, t.clone()); +struct IdVisitor { + visit_callback: @fn(NodeId), + pass_through_items: bool, + visited_outermost: bool, +} + +impl IdVisitor { + fn visit_generics_helper(@mut self, generics: &Generics) { + foreach type_parameter in generics.ty_params.iter() { + (self.visit_callback)(type_parameter.id) } - foreach p in generics.lifetimes.iter() { - vfn(p.id, t.clone()); + foreach lifetime in generics.lifetimes.iter() { + (self.visit_callback)(lifetime.id) } - }; - visit::mk_vt(@visit::Visitor { - visit_mod: |m, sp, id, (t, vt): (T, visit::vt<T>)| { - vfn(id, t.clone()); - visit::visit_mod(m, sp, id, (t, vt)); - }, + } +} - visit_view_item: |vi, (t, vt)| { - match vi.node { - view_item_extern_mod(_, _, id) => vfn(id, t.clone()), - view_item_use(ref vps) => { - foreach vp in vps.iter() { - match vp.node { - view_path_simple(_, _, id) => vfn(id, t.clone()), - view_path_glob(_, id) => vfn(id, t.clone()), - view_path_list(_, ref paths, id) => { - vfn(id, t.clone()); - foreach p in paths.iter() { - vfn(p.node.id, t.clone()); - } - } - } - } - } +impl Visitor<()> for IdVisitor { + fn visit_mod(@mut self, + module: &_mod, + span: span, + node_id: NodeId, + env: ()) { + (self.visit_callback)(node_id); + visit::visit_mod(self as @Visitor<()>, module, env) + } + + fn visit_view_item(@mut self, view_item: &view_item, env: ()) { + match view_item.node { + view_item_extern_mod(_, _, node_id) => { + (self.visit_callback)(node_id) } - visit::visit_view_item(vi, (t, vt)); - }, + view_item_use(ref view_paths) => { + foreach view_path in view_paths.iter() { + match view_path.node { + view_path_simple(_, _, node_id) | + view_path_glob(_, node_id) => { + (self.visit_callback)(node_id) + } + view_path_list(_, ref paths, node_id) => { + (self.visit_callback)(node_id); + foreach path in paths.iter() { + (self.visit_callback)(path.node.id) + } + } + } + } + } + } + visit::visit_view_item(self as @Visitor<()>, view_item, env) + } - visit_foreign_item: |ni, (t, vt)| { - vfn(ni.id, t.clone()); - visit::visit_foreign_item(ni, (t, vt)); - }, + fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) { + (self.visit_callback)(foreign_item.id); + visit::visit_foreign_item(self as @Visitor<()>, foreign_item, env) + } - visit_item: |i, (t, vt)| { - vfn(i.id, t.clone()); - match i.node { - item_enum(ref enum_definition, _) => - foreach v in (*enum_definition).variants.iter() { - vfn(v.node.id, t.clone()); - }, - _ => () + fn visit_item(@mut self, item: @item, env: ()) { + if !self.pass_through_items { + if self.visited_outermost { + return + } else { + self.visited_outermost = true } - visit::visit_item(i, (t, vt)); - }, - - visit_local: |l, (t, vt)| { - vfn(l.id, t.clone()); - visit::visit_local(l, (t, vt)); - }, - visit_block: |b, (t, vt)| { - vfn(b.id, t.clone()); - visit::visit_block(b, (t, vt)); - }, - visit_stmt: |s, (t, vt)| { - vfn(ast_util::stmt_id(s), t.clone()); - visit::visit_stmt(s, (t, vt)); - }, - visit_pat: |p, (t, vt)| { - vfn(p.id, t.clone()); - visit::visit_pat(p, (t, vt)); - }, + } - visit_expr: |e, (t, vt)| { - { - let r = e.get_callee_id(); - foreach callee_id in r.iter() { - vfn(*callee_id, t.clone()); + (self.visit_callback)(item.id); + match item.node { + item_enum(ref enum_definition, _) => { + foreach variant in enum_definition.variants.iter() { + (self.visit_callback)(variant.node.id) } } - vfn(e.id, t.clone()); - visit::visit_expr(e, (t, vt)); - }, + _ => {} + } + + visit::visit_item(self as @Visitor<()>, item, env); + + self.visited_outermost = false + } + + fn visit_local(@mut self, local: @Local, env: ()) { + (self.visit_callback)(local.id); + visit::visit_local(self as @Visitor<()>, local, env) + } + + fn visit_block(@mut self, block: &Block, env: ()) { + (self.visit_callback)(block.id); + visit::visit_block(self as @Visitor<()>, block, env) + } + + fn visit_stmt(@mut self, statement: @stmt, env: ()) { + (self.visit_callback)(ast_util::stmt_id(statement)); + visit::visit_stmt(self as @Visitor<()>, statement, env) + } + + // XXX: Default + fn visit_arm(@mut self, arm: &arm, env: ()) { + visit::visit_arm(self as @Visitor<()>, arm, env) + } - visit_ty: |ty, (t, vt)| { - vfn(ty.id, t.clone()); - match ty.node { - ty_path(_, _, id) => vfn(id, t.clone()), - _ => { /* fall through */ } + fn visit_pat(@mut self, pattern: @pat, env: ()) { + (self.visit_callback)(pattern.id); + visit::visit_pat(self as @Visitor<()>, pattern, env) + } + + // XXX: Default + fn visit_decl(@mut self, declaration: @decl, env: ()) { + visit::visit_decl(self as @Visitor<()>, declaration, env) + } + + fn visit_expr(@mut self, expression: @expr, env: ()) { + { + let optional_callee_id = expression.get_callee_id(); + foreach callee_id in optional_callee_id.iter() { + (self.visit_callback)(*callee_id) } - visit::visit_ty(ty, (t, vt)); - }, + } + (self.visit_callback)(expression.id); + visit::visit_expr(self as @Visitor<()>, expression, env) + } - visit_generics: |generics, (t, vt)| { - visit_generics(generics, t.clone()); - visit::visit_generics(generics, (t, vt)); - }, + // XXX: Default + fn visit_expr_post(@mut self, _: @expr, _: ()) { + // Empty! + } - visit_fn: |fk, d, a, b, id, (t, vt)| { - vfn(id, t.clone()); + fn visit_ty(@mut self, typ: &Ty, env: ()) { + (self.visit_callback)(typ.id); + match typ.node { + ty_path(_, _, id) => (self.visit_callback)(id), + _ => {} + } + visit::visit_ty(self as @Visitor<()>, typ, env) + } - match *fk { - visit::fk_item_fn(_, generics, _, _) => { - visit_generics(generics, t.clone()); - } - visit::fk_method(_, generics, m) => { - vfn(m.self_id, t.clone()); - visit_generics(generics, t.clone()); - } - visit::fk_anon(_) | - visit::fk_fn_block => { - } + fn visit_generics(@mut self, generics: &Generics, env: ()) { + self.visit_generics_helper(generics); + visit::visit_generics(self as @Visitor<()>, generics, env) + } + + fn visit_fn(@mut self, + function_kind: &visit::fn_kind, + function_declaration: &fn_decl, + block: &Block, + span: span, + node_id: NodeId, + env: ()) { + if !self.pass_through_items { + match *function_kind { + visit::fk_method(*) if self.visited_outermost => return, + visit::fk_method(*) => self.visited_outermost = true, + _ => {} } + } + + (self.visit_callback)(node_id); - foreach arg in d.inputs.iter() { - vfn(arg.id, t.clone()) + match *function_kind { + visit::fk_item_fn(_, generics, _, _) => { + self.visit_generics_helper(generics) } - visit::visit_fn(fk, d, a, b, id, (t.clone(), vt)); - }, + visit::fk_method(_, generics, method) => { + (self.visit_callback)(method.self_id); + self.visit_generics_helper(generics) + } + visit::fk_anon(_) | visit::fk_fn_block => {} + } - visit_struct_field: |f, (t, vt)| { - vfn(f.node.id, t.clone()); - visit::visit_struct_field(f, (t, vt)); - }, + foreach argument in function_declaration.inputs.iter() { + (self.visit_callback)(argument.id) + } - .. *visit::default_visitor() - }) + visit::visit_fn(self as @Visitor<()>, + function_kind, + function_declaration, + block, + span, + node_id, + env); + + if !self.pass_through_items { + match *function_kind { + visit::fk_method(*) => self.visited_outermost = false, + _ => {} + } + } + } + + // XXX: Default + fn visit_ty_method(@mut self, type_method: &TypeMethod, env: ()) { + visit::visit_ty_method(self as @Visitor<()>, type_method, env) + } + + // XXX: Default + fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) { + visit::visit_trait_method(self as @Visitor<()>, trait_method, env) + } + + // XXX: Default + fn visit_struct_def(@mut self, + struct_definition: @struct_def, + identifier: ident, + generics: &Generics, + node_id: NodeId, + env: ()) { + visit::visit_struct_def(self as @Visitor<()>, + struct_definition, + identifier, + generics, + node_id, + env) + } + + fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) { + (self.visit_callback)(struct_field.node.id); + visit::visit_struct_field(self as @Visitor<()>, struct_field, env) + } +} + +pub fn id_visitor(vfn: @fn(NodeId), pass_through_items: bool) + -> @Visitor<()> { + let visitor = @IdVisitor { + visit_callback: vfn, + pass_through_items: pass_through_items, + visited_outermost: false, + }; + visitor as @Visitor<()> } pub fn visit_ids_for_inlined_item(item: &inlined_item, vfn: @fn(NodeId)) { - item.accept((), id_visitor(|id, ()| vfn(id))); + item.accept((), id_visitor(|id| vfn(id), true)); } pub fn compute_id_range(visit_ids_fn: &fn(@fn(NodeId))) -> id_range { @@ -570,13 +675,91 @@ pub trait EachViewItem { pub fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool; } +struct EachViewItemData { + callback: @fn(&ast::view_item) -> bool, +} + +impl SimpleVisitor for EachViewItemData { + fn visit_mod(@mut self, _: &_mod, _: span, _: NodeId) { + // XXX: Default method. + } + fn visit_view_item(@mut self, view_item: &view_item) { + let _ = (self.callback)(view_item); + } + fn visit_foreign_item(@mut self, _: @foreign_item) { + // XXX: Default method. + } + fn visit_item(@mut self, _: @item) { + // XXX: Default method. + } + fn visit_local(@mut self, _: @Local) { + // XXX: Default method. + } + fn visit_block(@mut self, _: &Block) { + // XXX: Default method. + } + fn visit_stmt(@mut self, _: @stmt) { + // XXX: Default method. + } + fn visit_arm(@mut self, _: &arm) { + // XXX: Default method. + } + fn visit_pat(@mut self, _: @pat) { + // XXX: Default method. + } + fn visit_decl(@mut self, _: @decl) { + // XXX: Default method. + } + fn visit_expr(@mut self, _: @expr) { + // XXX: Default method. + } + fn visit_expr_post(@mut self, _: @expr) { + // XXX: Default method. + } + fn visit_ty(@mut self, _: &Ty) { + // XXX: Default method. + } + fn visit_generics(@mut self, _: &Generics) { + // XXX: Default method. + } + fn visit_fn(@mut self, + _: &visit::fn_kind, + _: &fn_decl, + _: &Block, + _: span, + _: NodeId) { + // XXX: Default method. + } + fn visit_ty_method(@mut self, _: &TypeMethod) { + // XXX: Default method. + } + fn visit_trait_method(@mut self, _: &trait_method) { + // XXX: Default method. + } + fn visit_struct_def(@mut self, + _: @struct_def, + _: ident, + _: &Generics, + _: NodeId) { + // XXX: Default method. + } + fn visit_struct_field(@mut self, _: @struct_field) { + // XXX: Default method. + } + fn visit_struct_method(@mut self, _: @method) { + // XXX: Default method. + } +} + impl EachViewItem for ast::Crate { fn each_view_item(&self, f: @fn(&ast::view_item) -> bool) -> bool { - let broke = @mut false; - let vtor: visit::vt<()> = visit::mk_simple_visitor(@visit::SimpleVisitor { - visit_view_item: |vi| { *broke = f(vi); }, ..*visit::default_simple_visitor() - }); - visit::visit_crate(self, ((), vtor)); + let data = @mut EachViewItemData { + callback: f, + }; + let visitor = @mut SimpleVisitorVisitor { + simple_visitor: data as @SimpleVisitor, + }; + visit::visit_crate(visitor as @Visitor<()>, self, ()); true } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index dc096a145cc..0ec367653c0 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{Block, Crate, expr_, expr_mac, mac_invoc_tt}; +use ast::{Block, Crate, NodeId, expr_, expr_mac, ident, mac_invoc_tt}; use ast::{item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use ast::{illegal_ctxt}; use ast; @@ -516,35 +516,153 @@ pub fn expand_stmt(extsbox: @mut SyntaxEnv, } -// return a visitor that extracts the pat_ident paths -// from a given pattern and puts them in a mutable -// array (passed in to the traversal) -pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> { - let default_visitor = visit::default_visitor(); - @Visitor{ - visit_pat : |p:@ast::pat, - (ident_accum, v): (@mut ~[ast::ident], visit::vt<@mut ~[ast::ident]>)| { - match *p { - // we found a pat_ident! - ast::pat{id:_, node: ast::pat_ident(_,ref path,ref inner), span:_} => { - match path { - // a path of length one: - &ast::Path{global: false,idents: [id], span:_,rp:_,types:_} => - ident_accum.push(id), - // I believe these must be enums... - _ => () - } - // visit optional subpattern of pat_ident: - foreach subpat in inner.iter() { - (v.visit_pat)(*subpat, (ident_accum, v)) - } +#[deriving(Clone)] +struct NewNameFinderContext { + ident_accumulator: @mut ~[ast::ident], +} + +impl Visitor<()> for NewNameFinderContext { + fn visit_pat(@mut self, pattern: @ast::pat, _: ()) { + match *pattern { + // we found a pat_ident! + ast::pat { + id: _, + node: ast::pat_ident(_, ref path, ref inner), + span: _ + } => { + match path { + // a path of length one: + &ast::Path { + global: false, + idents: [id], + span: _, + rp: _, + types: _ + } => self.ident_accumulator.push(id), + // I believe these must be enums... + _ => () + } + // visit optional subpattern of pat_ident: + foreach subpat in inner.iter() { + self.visit_pat(*subpat, ()) } - // use the default traversal for non-pat_idents - _ => visit::visit_pat(p,(ident_accum,v)) } - }, - .. *default_visitor + // use the default traversal for non-pat_idents + _ => visit::visit_pat(self as @Visitor<()>, pattern, ()) + } + } + + // XXX: Methods below can become default methods. + + fn visit_mod(@mut self, module: &ast::_mod, _: span, _: NodeId, _: ()) { + visit::visit_mod(self as @Visitor<()>, module, ()) + } + + fn visit_view_item(@mut self, view_item: &ast::view_item, _: ()) { + visit::visit_view_item(self as @Visitor<()>, view_item, ()) + } + + fn visit_item(@mut self, item: @ast::item, _: ()) { + visit::visit_item(self as @Visitor<()>, item, ()) + } + + fn visit_foreign_item(@mut self, + foreign_item: @ast::foreign_item, + _: ()) { + visit::visit_foreign_item(self as @Visitor<()>, foreign_item, ()) + } + + fn visit_local(@mut self, local: @ast::Local, _: ()) { + visit::visit_local(self as @Visitor<()>, local, ()) + } + + fn visit_block(@mut self, block: &ast::Block, _: ()) { + visit::visit_block(self as @Visitor<()>, block, ()) + } + + fn visit_stmt(@mut self, stmt: @ast::stmt, _: ()) { + visit::visit_stmt(self as @Visitor<()>, stmt, ()) + } + + fn visit_arm(@mut self, arm: &ast::arm, _: ()) { + visit::visit_arm(self as @Visitor<()>, arm, ()) } + + fn visit_decl(@mut self, decl: @ast::decl, _: ()) { + visit::visit_decl(self as @Visitor<()>, decl, ()) + } + + fn visit_expr(@mut self, expr: @ast::expr, _: ()) { + visit::visit_expr(self as @Visitor<()>, expr, ()) + } + + fn visit_expr_post(@mut self, _: @ast::expr, _: ()) { + // Empty! + } + + fn visit_ty(@mut self, typ: &ast::Ty, _: ()) { + visit::visit_ty(self as @Visitor<()>, typ, ()) + } + + fn visit_generics(@mut self, generics: &ast::Generics, _: ()) { + visit::visit_generics(self as @Visitor<()>, generics, ()) + } + + fn visit_fn(@mut self, + function_kind: &visit::fn_kind, + function_declaration: &ast::fn_decl, + block: &ast::Block, + span: span, + node_id: NodeId, + _: ()) { + visit::visit_fn(self as @Visitor<()>, + function_kind, + function_declaration, + block, + span, + node_id, + ()) + } + + fn visit_ty_method(@mut self, ty_method: &ast::TypeMethod, _: ()) { + visit::visit_ty_method(self as @Visitor<()>, ty_method, ()) + } + + fn visit_trait_method(@mut self, + trait_method: &ast::trait_method, + _: ()) { + visit::visit_trait_method(self as @Visitor<()>, trait_method, ()) + } + + fn visit_struct_def(@mut self, + struct_def: @ast::struct_def, + ident: ident, + generics: &ast::Generics, + node_id: NodeId, + _: ()) { + visit::visit_struct_def(self as @Visitor<()>, + struct_def, + ident, + generics, + node_id, + ()) + } + + fn visit_struct_field(@mut self, + struct_field: @ast::struct_field, + _: ()) { + visit::visit_struct_field(self as @Visitor<()>, struct_field, ()) + } +} + +// return a visitor that extracts the pat_ident paths +// from a given pattern and puts them in a mutable +// array (passed in to the traversal) +pub fn new_name_finder(idents: @mut ~[ast::ident]) -> @Visitor<()> { + let context = @mut NewNameFinderContext { + ident_accumulator: idents, + }; + context as @Visitor<()> } pub fn expand_block(extsbox: @mut SyntaxEnv, @@ -955,7 +1073,7 @@ mod test { use parse::token::{intern, get_ident_interner}; use print::pprust; use util::parser_testing::{string_to_item, string_to_pat, strs_to_idents}; - use visit::{mk_vt}; + use oldvisit::{mk_vt}; // make sure that fail! is present #[test] fn fail_exists_test () { @@ -1079,9 +1197,9 @@ mod test { #[test] fn pat_idents(){ let pat = string_to_pat(@"(a,Foo{x:c @ (b,9),y:Bar(4,d)})"); - let pat_idents = new_name_finder(); let idents = @mut ~[]; - ((*pat_idents).visit_pat)(pat, (idents, mk_vt(pat_idents))); - assert_eq!(idents,@mut strs_to_idents(~["a","c","b","d"])); + let pat_idents = new_name_finder(idents); + pat_idents.visit_pat(pat, ()); + assert_eq!(idents, @mut strs_to_idents(~["a","c","b","d"])); } } diff --git a/src/libsyntax/oldvisit.rs b/src/libsyntax/oldvisit.rs new file mode 100644 index 00000000000..c421ded6d75 --- /dev/null +++ b/src/libsyntax/oldvisit.rs @@ -0,0 +1,775 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use abi::AbiSet; +use ast::*; +use ast; +use codemap::span; +use parse; +use opt_vec; +use opt_vec::OptVec; + +// Context-passing AST walker. Each overridden visit method has full control +// over what happens with its node, it can do its own traversal of the node's +// children (potentially passing in different contexts to each), call +// visit::visit_* to apply the default traversal algorithm (again, it can +// override the context), or prevent deeper traversal by doing nothing. +// +// Note: it is an important invariant that the default visitor walks the body +// of a function in "execution order" (more concretely, reverse post-order +// with respect to the CFG implied by the AST), meaning that if AST node A may +// execute before AST node B, then A is visited first. The borrow checker in +// particular relies on this property. + +// Our typesystem doesn't do circular types, so the visitor record can not +// hold functions that take visitors. A vt enum is used to break the cycle. +pub enum vt<E> { mk_vt(visitor<E>), } + +pub enum fn_kind<'self> { + // fn foo() or extern "Abi" fn foo() + fk_item_fn(ident, &'self Generics, purity, AbiSet), + + // fn foo(&self) + fk_method(ident, &'self Generics, &'self method), + + // @fn(x, y) { ... } + fk_anon(ast::Sigil), + + // |x, y| ... + fk_fn_block, +} + +pub fn name_of_fn(fk: &fn_kind) -> ident { + match *fk { + fk_item_fn(name, _, _, _) | fk_method(name, _, _) => { + name + } + fk_anon(*) | fk_fn_block(*) => parse::token::special_idents::anon, + } +} + +pub fn generics_of_fn(fk: &fn_kind) -> Generics { + match *fk { + fk_item_fn(_, generics, _, _) | + fk_method(_, generics, _) => { + (*generics).clone() + } + fk_anon(*) | fk_fn_block(*) => { + Generics { + lifetimes: opt_vec::Empty, + ty_params: opt_vec::Empty, + } + } + } +} + +pub struct Visitor<E> { + visit_mod: @fn(&_mod, span, NodeId, (E, vt<E>)), + visit_view_item: @fn(&view_item, (E, vt<E>)), + visit_foreign_item: @fn(@foreign_item, (E, vt<E>)), + visit_item: @fn(@item, (E, vt<E>)), + visit_local: @fn(@Local, (E, vt<E>)), + visit_block: @fn(&Block, (E, vt<E>)), + visit_stmt: @fn(@stmt, (E, vt<E>)), + visit_arm: @fn(&arm, (E, vt<E>)), + visit_pat: @fn(@pat, (E, vt<E>)), + visit_decl: @fn(@decl, (E, vt<E>)), + visit_expr: @fn(@expr, (E, vt<E>)), + visit_expr_post: @fn(@expr, (E, vt<E>)), + visit_ty: @fn(&Ty, (E, vt<E>)), + visit_generics: @fn(&Generics, (E, vt<E>)), + visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, NodeId, (E, vt<E>)), + visit_ty_method: @fn(&TypeMethod, (E, vt<E>)), + visit_trait_method: @fn(&trait_method, (E, vt<E>)), + visit_struct_def: @fn(@struct_def, ident, &Generics, NodeId, (E, vt<E>)), + visit_struct_field: @fn(@struct_field, (E, vt<E>)), +} + +pub type visitor<E> = @Visitor<E>; + +pub fn default_visitor<E:Clone>() -> visitor<E> { + return @Visitor { + visit_mod: |a,b,c,d|visit_mod::<E>(a, b, c, d), + visit_view_item: |a,b|visit_view_item::<E>(a, b), + visit_foreign_item: |a,b|visit_foreign_item::<E>(a, b), + visit_item: |a,b|visit_item::<E>(a, b), + visit_local: |a,b|visit_local::<E>(a, b), + visit_block: |a,b|visit_block::<E>(a, b), + visit_stmt: |a,b|visit_stmt::<E>(a, b), + visit_arm: |a,b|visit_arm::<E>(a, b), + visit_pat: |a,b|visit_pat::<E>(a, b), + visit_decl: |a,b|visit_decl::<E>(a, b), + visit_expr: |a,b|visit_expr::<E>(a, b), + visit_expr_post: |_a,_b| (), + visit_ty: |a,b|skip_ty::<E>(a, b), + visit_generics: |a,b|visit_generics::<E>(a, b), + visit_fn: |a,b,c,d,e,f|visit_fn::<E>(a, b, c, d, e, f), + visit_ty_method: |a,b|visit_ty_method::<E>(a, b), + visit_trait_method: |a,b|visit_trait_method::<E>(a, b), + visit_struct_def: |a,b,c,d,e|visit_struct_def::<E>(a, b, c, d, e), + visit_struct_field: |a,b|visit_struct_field::<E>(a, b), + }; +} + +pub fn visit_crate<E:Clone>(c: &Crate, (e, v): (E, vt<E>)) { + (v.visit_mod)(&c.module, c.span, CRATE_NODE_ID, (e, v)); +} + +pub fn visit_mod<E:Clone>(m: &_mod, + _sp: span, + _id: NodeId, + (e, v): (E, vt<E>)) { + for m.view_items.iter().advance |vi| { + (v.visit_view_item)(vi, (e.clone(), v)); + } + for m.items.iter().advance |i| { + (v.visit_item)(*i, (e.clone(), v)); + } +} + +pub fn visit_view_item<E>(_vi: &view_item, (_e, _v): (E, vt<E>)) { } + +pub fn visit_local<E:Clone>(loc: &Local, (e, v): (E, vt<E>)) { + (v.visit_pat)(loc.pat, (e.clone(), v)); + (v.visit_ty)(&loc.ty, (e.clone(), v)); + match loc.init { + None => (), + Some(ex) => (v.visit_expr)(ex, (e, v)) + } +} + +fn visit_trait_ref<E:Clone>(tref: &ast::trait_ref, (e, v): (E, vt<E>)) { + visit_path(&tref.path, (e, v)); +} + +pub fn visit_item<E:Clone>(i: &item, (e, v): (E, vt<E>)) { + match i.node { + item_static(ref t, _, ex) => { + (v.visit_ty)(t, (e.clone(), v)); + (v.visit_expr)(ex, (e.clone(), v)); + } + item_fn(ref decl, purity, abi, ref generics, ref body) => { + (v.visit_fn)( + &fk_item_fn( + i.ident, + generics, + purity, + abi + ), + decl, + body, + i.span, + i.id, + (e, + v) + ); + } + item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)), + item_foreign_mod(ref nm) => { + for nm.view_items.iter().advance |vi| { + (v.visit_view_item)(vi, (e.clone(), v)); + } + for nm.items.iter().advance |ni| { + (v.visit_foreign_item)(*ni, (e.clone(), v)); + } + } + item_ty(ref t, ref tps) => { + (v.visit_ty)(t, (e.clone(), v)); + (v.visit_generics)(tps, (e, v)); + } + item_enum(ref enum_definition, ref tps) => { + (v.visit_generics)(tps, (e.clone(), v)); + visit_enum_def( + enum_definition, + tps, + (e, v) + ); + } + item_impl(ref tps, ref traits, ref ty, ref methods) => { + (v.visit_generics)(tps, (e.clone(), v)); + for traits.iter().advance |p| { + visit_trait_ref(p, (e.clone(), v)); + } + (v.visit_ty)(ty, (e.clone(), v)); + for methods.iter().advance |m| { + visit_method_helper(*m, (e.clone(), v)) + } + } + item_struct(struct_def, ref generics) => { + (v.visit_generics)(generics, (e.clone(), v)); + (v.visit_struct_def)(struct_def, i.ident, generics, i.id, (e, v)); + } + item_trait(ref generics, ref traits, ref methods) => { + (v.visit_generics)(generics, (e.clone(), v)); + for traits.iter().advance |p| { + visit_path(&p.path, (e.clone(), v)); + } + for methods.iter().advance |m| { + (v.visit_trait_method)(m, (e.clone(), v)); + } + } + item_mac(ref m) => visit_mac(m, (e, v)) + } +} + +pub fn visit_enum_def<E:Clone>(enum_definition: &ast::enum_def, + tps: &Generics, + (e, v): (E, vt<E>)) { + for enum_definition.variants.iter().advance |vr| { + match vr.node.kind { + tuple_variant_kind(ref variant_args) => { + for variant_args.iter().advance |va| { + (v.visit_ty)(&va.ty, (e.clone(), v)); + } + } + struct_variant_kind(struct_def) => { + (v.visit_struct_def)(struct_def, vr.node.name, tps, + vr.node.id, (e.clone(), v)); + } + } + // Visit the disr expr if it exists + for vr.node.disr_expr.iter().advance |ex| { + (v.visit_expr)(*ex, (e.clone(), v)) + } + } +} + +pub fn skip_ty<E>(_t: &Ty, (_e,_v): (E, vt<E>)) {} + +pub fn visit_ty<E:Clone>(t: &Ty, (e, v): (E, vt<E>)) { + match t.node { + ty_box(ref mt) | ty_uniq(ref mt) | + ty_vec(ref mt) | ty_ptr(ref mt) | ty_rptr(_, ref mt) => { + (v.visit_ty)(mt.ty, (e, v)); + }, + ty_tup(ref ts) => { + for ts.iter().advance |tt| { + (v.visit_ty)(tt, (e.clone(), v)); + } + }, + ty_closure(ref f) => { + for f.decl.inputs.iter().advance |a| { + (v.visit_ty)(&a.ty, (e.clone(), v)); + } + (v.visit_ty)(&f.decl.output, (e.clone(), v)); + do f.bounds.map |bounds| { + visit_ty_param_bounds(bounds, (e.clone(), v)); + }; + }, + ty_bare_fn(ref f) => { + for f.decl.inputs.iter().advance |a| { + (v.visit_ty)(&a.ty, (e.clone(), v)); + } + (v.visit_ty)(&f.decl.output, (e, v)); + }, + ty_path(ref p, ref bounds, _) => { + visit_path(p, (e.clone(), v)); + do bounds.map |bounds| { + visit_ty_param_bounds(bounds, (e.clone(), v)); + }; + }, + ty_fixed_length_vec(ref mt, ex) => { + (v.visit_ty)(mt.ty, (e.clone(), v)); + (v.visit_expr)(ex, (e.clone(), v)); + }, + ty_nil | ty_bot | ty_mac(_) | ty_infer => () + } +} + +pub fn visit_path<E:Clone>(p: &Path, (e, v): (E, vt<E>)) { + for p.types.iter().advance |tp| { (v.visit_ty)(tp, (e.clone(), v)); } +} + +pub fn visit_pat<E:Clone>(p: &pat, (e, v): (E, vt<E>)) { + match p.node { + pat_enum(ref path, ref children) => { + visit_path(path, (e.clone(), v)); + for children.iter().advance |children| { + for children.iter().advance |child| { + (v.visit_pat)(*child, (e.clone(), v)); + } + } + } + pat_struct(ref path, ref fields, _) => { + visit_path(path, (e.clone(), v)); + for fields.iter().advance |f| { + (v.visit_pat)(f.pat, (e.clone(), v)); + } + } + pat_tup(ref elts) => { + for elts.iter().advance |elt| { + (v.visit_pat)(*elt, (e.clone(), v)) + } + }, + pat_box(inner) | pat_uniq(inner) | pat_region(inner) => { + (v.visit_pat)(inner, (e, v)) + }, + pat_ident(_, ref path, ref inner) => { + visit_path(path, (e.clone(), v)); + for inner.iter().advance |subpat| { + (v.visit_pat)(*subpat, (e.clone(), v)) + } + } + pat_lit(ex) => (v.visit_expr)(ex, (e, v)), + pat_range(e1, e2) => { + (v.visit_expr)(e1, (e.clone(), v)); + (v.visit_expr)(e2, (e, v)); + } + pat_wild => (), + pat_vec(ref before, ref slice, ref after) => { + for before.iter().advance |elt| { + (v.visit_pat)(*elt, (e.clone(), v)); + } + for slice.iter().advance |elt| { + (v.visit_pat)(*elt, (e.clone(), v)); + } + for after.iter().advance |tail| { + (v.visit_pat)(*tail, (e.clone(), v)); + } + } + } +} + +pub fn visit_foreign_item<E:Clone>(ni: &foreign_item, (e, v): (E, vt<E>)) { + match ni.node { + foreign_item_fn(ref fd, _, ref generics) => { + visit_fn_decl(fd, (e.clone(), v)); + (v.visit_generics)(generics, (e, v)); + } + foreign_item_static(ref t, _) => { + (v.visit_ty)(t, (e, v)); + } + } +} + +pub fn visit_ty_param_bounds<E:Clone>(bounds: &OptVec<TyParamBound>, + (e, v): (E, vt<E>)) { + for bounds.iter().advance |bound| { + match *bound { + TraitTyParamBound(ref ty) => visit_trait_ref(ty, (e.clone(), v)), + RegionTyParamBound => {} + } + } +} + +pub fn visit_generics<E:Clone>(generics: &Generics, (e, v): (E, vt<E>)) { + for generics.ty_params.iter().advance |tp| { + visit_ty_param_bounds(&tp.bounds, (e.clone(), v)); + } +} + +pub fn visit_fn_decl<E:Clone>(fd: &fn_decl, (e, v): (E, vt<E>)) { + for fd.inputs.iter().advance |a| { + (v.visit_pat)(a.pat, (e.clone(), v)); + (v.visit_ty)(&a.ty, (e.clone(), v)); + } + (v.visit_ty)(&fd.output, (e, v)); +} + +// Note: there is no visit_method() method in the visitor, instead override +// visit_fn() and check for fk_method(). I named this visit_method_helper() +// because it is not a default impl of any method, though I doubt that really +// clarifies anything. - Niko +pub fn visit_method_helper<E:Clone>(m: &method, (e, v): (E, vt<E>)) { + (v.visit_fn)(&fk_method(m.ident, &m.generics, m), + &m.decl, + &m.body, + m.span, + m.id, + (e, v)); +} + +pub fn visit_fn<E:Clone>(fk: &fn_kind, + decl: &fn_decl, + body: &Block, + _sp: span, + _id: NodeId, + (e, v): (E, vt<E>)) { + visit_fn_decl(decl, (e.clone(), v)); + let generics = generics_of_fn(fk); + (v.visit_generics)(&generics, (e.clone(), v)); + (v.visit_block)(body, (e, v)); +} + +pub fn visit_ty_method<E:Clone>(m: &TypeMethod, (e, v): (E, vt<E>)) { + for m.decl.inputs.iter().advance |a| { + (v.visit_ty)(&a.ty, (e.clone(), v)); + } + (v.visit_generics)(&m.generics, (e.clone(), v)); + (v.visit_ty)(&m.decl.output, (e, v)); +} + +pub fn visit_trait_method<E:Clone>(m: &trait_method, (e, v): (E, vt<E>)) { + match *m { + required(ref ty_m) => (v.visit_ty_method)(ty_m, (e, v)), + provided(m) => visit_method_helper(m, (e, v)) + } +} + +pub fn visit_struct_def<E:Clone>( + sd: @struct_def, + _nm: ast::ident, + _generics: &Generics, + _id: NodeId, + (e, v): (E, vt<E>) +) { + for sd.fields.iter().advance |f| { + (v.visit_struct_field)(*f, (e.clone(), v)); + } +} + +pub fn visit_struct_field<E:Clone>(sf: &struct_field, (e, v): (E, vt<E>)) { + (v.visit_ty)(&sf.node.ty, (e, v)); +} + +pub fn visit_block<E:Clone>(b: &Block, (e, v): (E, vt<E>)) { + for b.view_items.iter().advance |vi| { + (v.visit_view_item)(vi, (e.clone(), v)); + } + for b.stmts.iter().advance |s| { + (v.visit_stmt)(*s, (e.clone(), v)); + } + visit_expr_opt(b.expr, (e, v)); +} + +pub fn visit_stmt<E>(s: &stmt, (e, v): (E, vt<E>)) { + match s.node { + stmt_decl(d, _) => (v.visit_decl)(d, (e, v)), + stmt_expr(ex, _) => (v.visit_expr)(ex, (e, v)), + stmt_semi(ex, _) => (v.visit_expr)(ex, (e, v)), + stmt_mac(ref mac, _) => visit_mac(mac, (e, v)) + } +} + +pub fn visit_decl<E:Clone>(d: &decl, (e, v): (E, vt<E>)) { + match d.node { + decl_local(ref loc) => (v.visit_local)(*loc, (e, v)), + decl_item(it) => (v.visit_item)(it, (e, v)) + } +} + +pub fn visit_expr_opt<E>(eo: Option<@expr>, (e, v): (E, vt<E>)) { + match eo { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) } +} + +pub fn visit_exprs<E:Clone>(exprs: &[@expr], (e, v): (E, vt<E>)) { + for exprs.iter().advance |ex| { (v.visit_expr)(*ex, (e.clone(), v)); } +} + +pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) { + /* no user-serviceable parts inside */ +} + +pub fn visit_expr<E:Clone>(ex: @expr, (e, v): (E, vt<E>)) { + match ex.node { + expr_vstore(x, _) => (v.visit_expr)(x, (e.clone(), v)), + expr_vec(ref es, _) => visit_exprs(*es, (e.clone(), v)), + expr_repeat(element, count, _) => { + (v.visit_expr)(element, (e.clone(), v)); + (v.visit_expr)(count, (e.clone(), v)); + } + expr_struct(ref p, ref flds, base) => { + visit_path(p, (e.clone(), v)); + for flds.iter().advance |f| { + (v.visit_expr)(f.expr, (e.clone(), v)); + } + visit_expr_opt(base, (e.clone(), v)); + } + expr_tup(ref elts) => { + for elts.iter().advance |el| { (v.visit_expr)(*el, (e.clone(), v)) } + } + expr_call(callee, ref args, _) => { + visit_exprs(*args, (e.clone(), v)); + (v.visit_expr)(callee, (e.clone(), v)); + } + expr_method_call(_, callee, _, ref tys, ref args, _) => { + visit_exprs(*args, (e.clone(), v)); + for tys.iter().advance |tp| { + (v.visit_ty)(tp, (e.clone(), v)); + } + (v.visit_expr)(callee, (e.clone(), v)); + } + expr_binary(_, _, a, b) => { + (v.visit_expr)(a, (e.clone(), v)); + (v.visit_expr)(b, (e.clone(), v)); + } + expr_addr_of(_, x) | expr_unary(_, _, x) | + expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e.clone(), v)), + expr_lit(_) => (), + expr_cast(x, ref t) => { + (v.visit_expr)(x, (e.clone(), v)); + (v.visit_ty)(t, (e.clone(), v)); + } + expr_if(x, ref b, eo) => { + (v.visit_expr)(x, (e.clone(), v)); + (v.visit_block)(b, (e.clone(), v)); + visit_expr_opt(eo, (e.clone(), v)); + } + expr_while(x, ref b) => { + (v.visit_expr)(x, (e.clone(), v)); + (v.visit_block)(b, (e.clone(), v)); + } + expr_for_loop(pattern, subexpression, ref block) => { + (v.visit_pat)(pattern, (e.clone(), v)); + (v.visit_expr)(subexpression, (e.clone(), v)); + (v.visit_block)(block, (e.clone(), v)) + } + expr_loop(ref b, _) => (v.visit_block)(b, (e.clone(), v)), + expr_match(x, ref arms) => { + (v.visit_expr)(x, (e.clone(), v)); + for arms.iter().advance |a| { (v.visit_arm)(a, (e.clone(), v)); } + } + expr_fn_block(ref decl, ref body) => { + (v.visit_fn)( + &fk_fn_block, + decl, + body, + ex.span, + ex.id, + (e.clone(), v) + ); + } + expr_block(ref b) => (v.visit_block)(b, (e.clone(), v)), + expr_assign(a, b) => { + (v.visit_expr)(b, (e.clone(), v)); + (v.visit_expr)(a, (e.clone(), v)); + } + expr_assign_op(_, _, a, b) => { + (v.visit_expr)(b, (e.clone(), v)); + (v.visit_expr)(a, (e.clone(), v)); + } + expr_field(x, _, ref tys) => { + (v.visit_expr)(x, (e.clone(), v)); + for tys.iter().advance |tp| { + (v.visit_ty)(tp, (e.clone(), v)); + } + } + expr_index(_, a, b) => { + (v.visit_expr)(a, (e.clone(), v)); + (v.visit_expr)(b, (e.clone(), v)); + } + expr_path(ref p) => visit_path(p, (e.clone(), v)), + expr_self => (), + expr_break(_) => (), + expr_again(_) => (), + expr_ret(eo) => visit_expr_opt(eo, (e.clone(), v)), + expr_log(lv, x) => { + (v.visit_expr)(lv, (e.clone(), v)); + (v.visit_expr)(x, (e.clone(), v)); + } + expr_mac(ref mac) => visit_mac(mac, (e.clone(), v)), + expr_paren(x) => (v.visit_expr)(x, (e.clone(), v)), + expr_inline_asm(ref a) => { + for a.inputs.iter().advance |&(_, input)| { + (v.visit_expr)(input, (e.clone(), v)); + } + for a.outputs.iter().advance |&(_, out)| { + (v.visit_expr)(out, (e.clone(), v)); + } + } + } + (v.visit_expr_post)(ex, (e, v)); +} + +pub fn visit_arm<E:Clone>(a: &arm, (e, v): (E, vt<E>)) { + for a.pats.iter().advance |p| { (v.visit_pat)(*p, (e.clone(), v)); } + visit_expr_opt(a.guard, (e.clone(), v)); + (v.visit_block)(&a.body, (e.clone(), v)); +} + +// Simpler, non-context passing interface. Always walks the whole tree, simply +// calls the given functions on the nodes. + +pub struct SimpleVisitor { + visit_mod: @fn(&_mod, span, NodeId), + visit_view_item: @fn(&view_item), + visit_foreign_item: @fn(@foreign_item), + visit_item: @fn(@item), + visit_local: @fn(@Local), + visit_block: @fn(&Block), + visit_stmt: @fn(@stmt), + visit_arm: @fn(&arm), + visit_pat: @fn(@pat), + visit_decl: @fn(@decl), + visit_expr: @fn(@expr), + visit_expr_post: @fn(@expr), + visit_ty: @fn(&Ty), + visit_generics: @fn(&Generics), + visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, NodeId), + visit_ty_method: @fn(&TypeMethod), + visit_trait_method: @fn(&trait_method), + visit_struct_def: @fn(@struct_def, ident, &Generics, NodeId), + visit_struct_field: @fn(@struct_field), + visit_struct_method: @fn(@method) +} + +pub type simple_visitor = @SimpleVisitor; + +pub fn simple_ignore_ty(_t: &Ty) {} + +pub fn default_simple_visitor() -> @SimpleVisitor { + @SimpleVisitor { + visit_mod: |_m, _sp, _id| { }, + visit_view_item: |_vi| { }, + visit_foreign_item: |_ni| { }, + visit_item: |_i| { }, + visit_local: |_l| { }, + visit_block: |_b| { }, + visit_stmt: |_s| { }, + visit_arm: |_a| { }, + visit_pat: |_p| { }, + visit_decl: |_d| { }, + visit_expr: |_e| { }, + visit_expr_post: |_e| { }, + visit_ty: simple_ignore_ty, + visit_generics: |_| {}, + visit_fn: |_, _, _, _, _| {}, + visit_ty_method: |_| {}, + visit_trait_method: |_| {}, + visit_struct_def: |_, _, _, _| {}, + visit_struct_field: |_| {}, + visit_struct_method: |_| {}, + } +} + +pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { + fn v_mod( + f: @fn(&_mod, span, NodeId), + m: &_mod, + sp: span, + id: NodeId, + (e, v): ((), vt<()>) + ) { + f(m, sp, id); + visit_mod(m, sp, id, (e, v)); + } + fn v_view_item(f: @fn(&view_item), vi: &view_item, (e, v): ((), vt<()>)) { + f(vi); + visit_view_item(vi, (e, v)); + } + fn v_foreign_item(f: @fn(@foreign_item), ni: @foreign_item, (e, v): ((), vt<()>)) { + f(ni); + visit_foreign_item(ni, (e, v)); + } + fn v_item(f: @fn(@item), i: @item, (e, v): ((), vt<()>)) { + f(i); + visit_item(i, (e, v)); + } + fn v_local(f: @fn(@Local), l: @Local, (e, v): ((), vt<()>)) { + f(l); + visit_local(l, (e, v)); + } + fn v_block(f: @fn(&ast::Block), bl: &ast::Block, (e, v): ((), vt<()>)) { + f(bl); + visit_block(bl, (e, v)); + } + fn v_stmt(f: @fn(@stmt), st: @stmt, (e, v): ((), vt<()>)) { + f(st); + visit_stmt(st, (e, v)); + } + fn v_arm(f: @fn(&arm), a: &arm, (e, v): ((), vt<()>)) { + f(a); + visit_arm(a, (e, v)); + } + fn v_pat(f: @fn(@pat), p: @pat, (e, v): ((), vt<()>)) { + f(p); + visit_pat(p, (e, v)); + } + fn v_decl(f: @fn(@decl), d: @decl, (e, v): ((), vt<()>)) { + f(d); + visit_decl(d, (e, v)); + } + fn v_expr(f: @fn(@expr), ex: @expr, (e, v): ((), vt<()>)) { + f(ex); + visit_expr(ex, (e, v)); + } + fn v_expr_post(f: @fn(@expr), ex: @expr, (_e, _v): ((), vt<()>)) { + f(ex); + } + fn v_ty(f: @fn(&Ty), ty: &Ty, (e, v): ((), vt<()>)) { + f(ty); + visit_ty(ty, (e, v)); + } + fn v_ty_method(f: @fn(&TypeMethod), ty: &TypeMethod, (e, v): ((), vt<()>)) { + f(ty); + visit_ty_method(ty, (e, v)); + } + fn v_trait_method(f: @fn(&trait_method), + m: &trait_method, + (e, v): ((), vt<()>)) { + f(m); + visit_trait_method(m, (e, v)); + } + fn v_struct_def( + f: @fn(@struct_def, ident, &Generics, NodeId), + sd: @struct_def, + nm: ident, + generics: &Generics, + id: NodeId, + (e, v): ((), vt<()>) + ) { + f(sd, nm, generics, id); + visit_struct_def(sd, nm, generics, id, (e, v)); + } + fn v_generics( + f: @fn(&Generics), + ps: &Generics, + (e, v): ((), vt<()>) + ) { + f(ps); + visit_generics(ps, (e, v)); + } + fn v_fn( + f: @fn(&fn_kind, &fn_decl, &Block, span, NodeId), + fk: &fn_kind, + decl: &fn_decl, + body: &Block, + sp: span, + id: NodeId, + (e, v): ((), vt<()>) + ) { + f(fk, decl, body, sp, id); + visit_fn(fk, decl, body, sp, id, (e, v)); + } + let visit_ty: @fn(&Ty, ((), vt<()>)) = + |a,b| v_ty(v.visit_ty, a, b); + fn v_struct_field(f: @fn(@struct_field), sf: @struct_field, (e, v): ((), vt<()>)) { + f(sf); + visit_struct_field(sf, (e, v)); + } + return mk_vt(@Visitor { + visit_mod: |a,b,c,d|v_mod(v.visit_mod, a, b, c, d), + visit_view_item: |a,b| v_view_item(v.visit_view_item, a, b), + visit_foreign_item: + |a,b|v_foreign_item(v.visit_foreign_item, a, b), + visit_item: |a,b|v_item(v.visit_item, a, b), + visit_local: |a,b|v_local(v.visit_local, a, b), + visit_block: |a,b|v_block(v.visit_block, a, b), + visit_stmt: |a,b|v_stmt(v.visit_stmt, a, b), + visit_arm: |a,b|v_arm(v.visit_arm, a, b), + visit_pat: |a,b|v_pat(v.visit_pat, a, b), + visit_decl: |a,b|v_decl(v.visit_decl, a, b), + visit_expr: |a,b|v_expr(v.visit_expr, a, b), + visit_expr_post: |a,b| v_expr_post(v.visit_expr_post, a, b), + visit_ty: visit_ty, + visit_generics: |a,b| + v_generics(v.visit_generics, a, b), + visit_fn: |a,b,c,d,e,f| + v_fn(v.visit_fn, a, b, c, d, e, f), + visit_ty_method: |a,b| + v_ty_method(v.visit_ty_method, a, b), + visit_trait_method: |a,b| + v_trait_method(v.visit_trait_method, a, b), + visit_struct_def: |a,b,c,d,e| + v_struct_def(v.visit_struct_def, a, b, c, d, e), + visit_struct_field: |a,b| + v_struct_field(v.visit_struct_field, a, b), + }); +} diff --git a/src/libsyntax/syntax.rs b/src/libsyntax/syntax.rs index 4d604faa6e1..e0f5aa848a2 100644 --- a/src/libsyntax/syntax.rs +++ b/src/libsyntax/syntax.rs @@ -43,6 +43,7 @@ pub mod ast_util; pub mod ast_map; pub mod visit; pub mod fold; +pub mod oldvisit; pub mod parse; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index d988f96d3d4..7278bdeb376 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -28,10 +28,6 @@ use opt_vec::OptVec; // execute before AST node B, then A is visited first. The borrow checker in // particular relies on this property. -// Our typesystem doesn't do circular types, so the visitor record can not -// hold functions that take visitors. A vt enum is used to break the cycle. -pub enum vt<E> { mk_vt(visitor<E>), } - pub enum fn_kind<'self> { // fn foo() or extern "Abi" fn foo() fk_item_fn(ident, &'self Generics, purity, AbiSet), @@ -70,702 +66,682 @@ pub fn generics_of_fn(fk: &fn_kind) -> Generics { } } -pub struct Visitor<E> { - visit_mod: @fn(&_mod, span, NodeId, (E, vt<E>)), - visit_view_item: @fn(&view_item, (E, vt<E>)), - visit_foreign_item: @fn(@foreign_item, (E, vt<E>)), - visit_item: @fn(@item, (E, vt<E>)), - visit_local: @fn(@Local, (E, vt<E>)), - visit_block: @fn(&Block, (E, vt<E>)), - visit_stmt: @fn(@stmt, (E, vt<E>)), - visit_arm: @fn(&arm, (E, vt<E>)), - visit_pat: @fn(@pat, (E, vt<E>)), - visit_decl: @fn(@decl, (E, vt<E>)), - visit_expr: @fn(@expr, (E, vt<E>)), - visit_expr_post: @fn(@expr, (E, vt<E>)), - visit_ty: @fn(&Ty, (E, vt<E>)), - visit_generics: @fn(&Generics, (E, vt<E>)), - visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, NodeId, (E, vt<E>)), - visit_ty_method: @fn(&TypeMethod, (E, vt<E>)), - visit_trait_method: @fn(&trait_method, (E, vt<E>)), - visit_struct_def: @fn(@struct_def, ident, &Generics, NodeId, (E, vt<E>)), - visit_struct_field: @fn(@struct_field, (E, vt<E>)), -} - -pub type visitor<E> = @Visitor<E>; - -pub fn default_visitor<E:Clone>() -> visitor<E> { - return @Visitor { - visit_mod: |a,b,c,d|visit_mod::<E>(a, b, c, d), - visit_view_item: |a,b|visit_view_item::<E>(a, b), - visit_foreign_item: |a,b|visit_foreign_item::<E>(a, b), - visit_item: |a,b|visit_item::<E>(a, b), - visit_local: |a,b|visit_local::<E>(a, b), - visit_block: |a,b|visit_block::<E>(a, b), - visit_stmt: |a,b|visit_stmt::<E>(a, b), - visit_arm: |a,b|visit_arm::<E>(a, b), - visit_pat: |a,b|visit_pat::<E>(a, b), - visit_decl: |a,b|visit_decl::<E>(a, b), - visit_expr: |a,b|visit_expr::<E>(a, b), - visit_expr_post: |_a,_b| (), - visit_ty: |a,b|skip_ty::<E>(a, b), - visit_generics: |a,b|visit_generics::<E>(a, b), - visit_fn: |a,b,c,d,e,f|visit_fn::<E>(a, b, c, d, e, f), - visit_ty_method: |a,b|visit_ty_method::<E>(a, b), - visit_trait_method: |a,b|visit_trait_method::<E>(a, b), - visit_struct_def: |a,b,c,d,e|visit_struct_def::<E>(a, b, c, d, e), - visit_struct_field: |a,b|visit_struct_field::<E>(a, b), - }; -} - -pub fn visit_crate<E:Clone>(c: &Crate, (e, v): (E, vt<E>)) { - (v.visit_mod)(&c.module, c.span, CRATE_NODE_ID, (e, v)); -} - -pub fn visit_mod<E:Clone>(m: &_mod, - _sp: span, - _id: NodeId, - (e, v): (E, vt<E>)) { - foreach vi in m.view_items.iter() { - (v.visit_view_item)(vi, (e.clone(), v)); - } - foreach i in m.items.iter() { - (v.visit_item)(*i, (e.clone(), v)); - } -} - -pub fn visit_view_item<E>(_vi: &view_item, (_e, _v): (E, vt<E>)) { } - -pub fn visit_local<E:Clone>(loc: &Local, (e, v): (E, vt<E>)) { - (v.visit_pat)(loc.pat, (e.clone(), v)); - (v.visit_ty)(&loc.ty, (e.clone(), v)); - match loc.init { - None => (), - Some(ex) => (v.visit_expr)(ex, (e, v)) - } -} - -fn visit_trait_ref<E:Clone>(tref: &ast::trait_ref, (e, v): (E, vt<E>)) { - visit_path(&tref.path, (e, v)); -} - -pub fn visit_item<E:Clone>(i: &item, (e, v): (E, vt<E>)) { - match i.node { - item_static(ref t, _, ex) => { - (v.visit_ty)(t, (e.clone(), v)); - (v.visit_expr)(ex, (e.clone(), v)); - } - item_fn(ref decl, purity, abi, ref generics, ref body) => { - (v.visit_fn)( - &fk_item_fn( - i.ident, - generics, - purity, - abi - ), - decl, - body, - i.span, - i.id, - (e, - v) - ); - } - item_mod(ref m) => (v.visit_mod)(m, i.span, i.id, (e, v)), - item_foreign_mod(ref nm) => { - foreach vi in nm.view_items.iter() { - (v.visit_view_item)(vi, (e.clone(), v)); +pub trait Visitor<E> { + fn visit_mod(@mut self, &_mod, span, NodeId, E); + fn visit_view_item(@mut self, &view_item, E); + fn visit_foreign_item(@mut self, @foreign_item, E); + fn visit_item(@mut self, @item, E); + fn visit_local(@mut self, @Local, E); + fn visit_block(@mut self, &Block, E); + fn visit_stmt(@mut self, @stmt, E); + fn visit_arm(@mut self, &arm, E); + fn visit_pat(@mut self, @pat, E); + fn visit_decl(@mut self, @decl, E); + fn visit_expr(@mut self, @expr, E); + fn visit_expr_post(@mut self, @expr, E); + fn visit_ty(@mut self, &Ty, E); + fn visit_generics(@mut self, &Generics, E); + fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId, E); + fn visit_ty_method(@mut self, &TypeMethod, E); + fn visit_trait_method(@mut self, &trait_method, E); + fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId, E); + fn visit_struct_field(@mut self, @struct_field, E); +} + +pub fn visit_crate<E:Clone>(visitor: @Visitor<E>, crate: &Crate, env: E) { + visitor.visit_mod(&crate.module, crate.span, CRATE_NODE_ID, env) +} + +pub fn visit_mod<E:Clone>(visitor: @Visitor<E>, module: &_mod, env: E) { + foreach view_item in module.view_items.iter() { + visitor.visit_view_item(view_item, env.clone()) + } + foreach item in module.items.iter() { + visitor.visit_item(*item, env.clone()) + } +} + +pub fn visit_view_item<E:Clone>(_: @Visitor<E>, _: &view_item, _: E) { + // Empty! +} + +pub fn visit_local<E:Clone>(visitor: @Visitor<E>, local: &Local, env: E) { + visitor.visit_pat(local.pat, env.clone()); + visitor.visit_ty(&local.ty, env.clone()); + match local.init { + None => {} + Some(initializer) => visitor.visit_expr(initializer, env), + } +} + +fn visit_trait_ref<E:Clone>(visitor: @Visitor<E>, + trait_ref: &ast::trait_ref, + env: E) { + visit_path(visitor, &trait_ref.path, env) +} + +pub fn visit_item<E:Clone>(visitor: @Visitor<E>, item: &item, env: E) { + match item.node { + item_static(ref typ, _, expr) => { + visitor.visit_ty(typ, env.clone()); + visitor.visit_expr(expr, env); + } + item_fn(ref declaration, purity, abi, ref generics, ref body) => { + visitor.visit_fn(&fk_item_fn(item.ident, generics, purity, abi), + declaration, + body, + item.span, + item.id, + env) + } + item_mod(ref module) => { + visitor.visit_mod(module, item.span, item.id, env) + } + item_foreign_mod(ref foreign_module) => { + foreach view_item in foreign_module.view_items.iter() { + visitor.visit_view_item(view_item, env.clone()) } - foreach ni in nm.items.iter() { - (v.visit_foreign_item)(*ni, (e.clone(), v)); + foreach foreign_item in foreign_module.items.iter() { + visitor.visit_foreign_item(*foreign_item, env.clone()) } } - item_ty(ref t, ref tps) => { - (v.visit_ty)(t, (e.clone(), v)); - (v.visit_generics)(tps, (e, v)); - } - item_enum(ref enum_definition, ref tps) => { - (v.visit_generics)(tps, (e.clone(), v)); - visit_enum_def( - enum_definition, - tps, - (e, v) - ); - } - item_impl(ref tps, ref traits, ref ty, ref methods) => { - (v.visit_generics)(tps, (e.clone(), v)); - foreach p in traits.iter() { - visit_trait_ref(p, (e.clone(), v)); + item_ty(ref typ, ref type_parameters) => { + visitor.visit_ty(typ, env.clone()); + visitor.visit_generics(type_parameters, env) + } + item_enum(ref enum_definition, ref type_parameters) => { + visitor.visit_generics(type_parameters, env.clone()); + visit_enum_def(visitor, enum_definition, type_parameters, env) + } + item_impl(ref type_parameters, + ref trait_references, + ref typ, + ref methods) => { + visitor.visit_generics(type_parameters, env.clone()); + foreach trait_reference in trait_references.iter() { + visit_trait_ref(visitor, trait_reference, env.clone()) } - (v.visit_ty)(ty, (e.clone(), v)); - foreach m in methods.iter() { - visit_method_helper(*m, (e.clone(), v)) + visitor.visit_ty(typ, env.clone()); + foreach method in methods.iter() { + visit_method_helper(visitor, *method, env.clone()) } } - item_struct(struct_def, ref generics) => { - (v.visit_generics)(generics, (e.clone(), v)); - (v.visit_struct_def)(struct_def, i.ident, generics, i.id, (e, v)); - } - item_trait(ref generics, ref traits, ref methods) => { - (v.visit_generics)(generics, (e.clone(), v)); - foreach p in traits.iter() { - visit_path(&p.path, (e.clone(), v)); + item_struct(struct_definition, ref generics) => { + visitor.visit_generics(generics, env.clone()); + visitor.visit_struct_def(struct_definition, + item.ident, + generics, + item.id, + env) + } + item_trait(ref generics, ref trait_paths, ref methods) => { + visitor.visit_generics(generics, env.clone()); + foreach trait_path in trait_paths.iter() { + visit_path(visitor, &trait_path.path, env.clone()) } - foreach m in methods.iter() { - (v.visit_trait_method)(m, (e.clone(), v)); + foreach method in methods.iter() { + visitor.visit_trait_method(method, env.clone()) } } - item_mac(ref m) => visit_mac(m, (e, v)) + item_mac(ref macro) => visit_mac(visitor, macro, env), } } -pub fn visit_enum_def<E:Clone>(enum_definition: &ast::enum_def, - tps: &Generics, - (e, v): (E, vt<E>)) { - foreach vr in enum_definition.variants.iter() { - match vr.node.kind { - tuple_variant_kind(ref variant_args) => { - foreach va in variant_args.iter() { - (v.visit_ty)(&va.ty, (e.clone(), v)); +pub fn visit_enum_def<E:Clone>(visitor: @Visitor<E>, + enum_definition: &ast::enum_def, + generics: &Generics, + env: E) { + foreach variant in enum_definition.variants.iter() { + match variant.node.kind { + tuple_variant_kind(ref variant_arguments) => { + foreach variant_argument in variant_arguments.iter() { + visitor.visit_ty(&variant_argument.ty, env.clone()) } } - struct_variant_kind(struct_def) => { - (v.visit_struct_def)(struct_def, vr.node.name, tps, - vr.node.id, (e.clone(), v)); + struct_variant_kind(struct_definition) => { + visitor.visit_struct_def(struct_definition, + variant.node.name, + generics, + variant.node.id, + env.clone()) } } - // Visit the disr expr if it exists - foreach ex in vr.node.disr_expr.iter() { - (v.visit_expr)(*ex, (e.clone(), v)) - } } } -pub fn skip_ty<E>(_t: &Ty, (_e,_v): (E, vt<E>)) {} +pub fn skip_ty<E>(_: @Visitor<E>, _: &Ty, _: E) { + // Empty! +} -pub fn visit_ty<E:Clone>(t: &Ty, (e, v): (E, vt<E>)) { - match t.node { - ty_box(ref mt) | ty_uniq(ref mt) | - ty_vec(ref mt) | ty_ptr(ref mt) | ty_rptr(_, ref mt) => { - (v.visit_ty)(mt.ty, (e, v)); - }, - ty_tup(ref ts) => { - foreach tt in ts.iter() { - (v.visit_ty)(tt, (e.clone(), v)); +pub fn visit_ty<E:Clone>(visitor: @Visitor<E>, typ: &Ty, env: E) { + match typ.node { + ty_box(ref mutable_type) | ty_uniq(ref mutable_type) | + ty_vec(ref mutable_type) | ty_ptr(ref mutable_type) | + ty_rptr(_, ref mutable_type) => { + visitor.visit_ty(mutable_type.ty, env) + } + ty_tup(ref tuple_element_types) => { + foreach tuple_element_type in tuple_element_types.iter() { + visitor.visit_ty(tuple_element_type, env.clone()) } - }, - ty_closure(ref f) => { - foreach a in f.decl.inputs.iter() { - (v.visit_ty)(&a.ty, (e.clone(), v)); + } + ty_closure(ref function_declaration) => { + foreach argument in function_declaration.decl.inputs.iter() { + visitor.visit_ty(&argument.ty, env.clone()) + } + visitor.visit_ty(&function_declaration.decl.output, env.clone()); + foreach bounds in function_declaration.bounds.iter() { + visit_ty_param_bounds(visitor, bounds, env.clone()) + } + } + ty_bare_fn(ref function_declaration) => { + foreach argument in function_declaration.decl.inputs.iter() { + visitor.visit_ty(&argument.ty, env.clone()) } - (v.visit_ty)(&f.decl.output, (e.clone(), v)); - do f.bounds.map |bounds| { - visit_ty_param_bounds(bounds, (e.clone(), v)); - }; - }, - ty_bare_fn(ref f) => { - foreach a in f.decl.inputs.iter() { - (v.visit_ty)(&a.ty, (e.clone(), v)); + visitor.visit_ty(&function_declaration.decl.output, env.clone()) + } + ty_path(ref path, ref bounds, _) => { + visit_path(visitor, path, env.clone()); + foreach bounds in bounds.iter() { + visit_ty_param_bounds(visitor, bounds, env.clone()) } - (v.visit_ty)(&f.decl.output, (e, v)); - }, - ty_path(ref p, ref bounds, _) => { - visit_path(p, (e.clone(), v)); - do bounds.map |bounds| { - visit_ty_param_bounds(bounds, (e.clone(), v)); - }; - }, - ty_fixed_length_vec(ref mt, ex) => { - (v.visit_ty)(mt.ty, (e.clone(), v)); - (v.visit_expr)(ex, (e.clone(), v)); - }, + } + ty_fixed_length_vec(ref mutable_type, expression) => { + visitor.visit_ty(mutable_type.ty, env.clone()); + visitor.visit_expr(expression, env) + } ty_nil | ty_bot | ty_mac(_) | ty_infer => () } } -pub fn visit_path<E:Clone>(p: &Path, (e, v): (E, vt<E>)) { - foreach tp in p.types.iter() { (v.visit_ty)(tp, (e.clone(), v)); } +pub fn visit_path<E:Clone>(visitor: @Visitor<E>, path: &Path, env: E) { + foreach typ in path.types.iter() { + visitor.visit_ty(typ, env.clone()) + } } -pub fn visit_pat<E:Clone>(p: &pat, (e, v): (E, vt<E>)) { - match p.node { +pub fn visit_pat<E:Clone>(visitor: @Visitor<E>, pattern: &pat, env: E) { + match pattern.node { pat_enum(ref path, ref children) => { - visit_path(path, (e.clone(), v)); + visit_path(visitor, path, env.clone()); foreach children in children.iter() { foreach child in children.iter() { - (v.visit_pat)(*child, (e.clone(), v)); + visitor.visit_pat(*child, env.clone()) } } } pat_struct(ref path, ref fields, _) => { - visit_path(path, (e.clone(), v)); - foreach f in fields.iter() { - (v.visit_pat)(f.pat, (e.clone(), v)); + visit_path(visitor, path, env.clone()); + foreach field in fields.iter() { + visitor.visit_pat(field.pat, env.clone()) } } - pat_tup(ref elts) => { - foreach elt in elts.iter() { - (v.visit_pat)(*elt, (e.clone(), v)) + pat_tup(ref tuple_elements) => { + foreach tuple_element in tuple_elements.iter() { + visitor.visit_pat(*tuple_element, env.clone()) } - }, - pat_box(inner) | pat_uniq(inner) | pat_region(inner) => { - (v.visit_pat)(inner, (e, v)) - }, - pat_ident(_, ref path, ref inner) => { - visit_path(path, (e.clone(), v)); - foreach subpat in inner.iter() { - (v.visit_pat)(*subpat, (e.clone(), v)) + } + pat_box(subpattern) | + pat_uniq(subpattern) | + pat_region(subpattern) => { + visitor.visit_pat(subpattern, env) + } + pat_ident(_, ref path, ref optional_subpattern) => { + visit_path(visitor, path, env.clone()); + match *optional_subpattern { + None => {} + Some(subpattern) => visitor.visit_pat(subpattern, env), } } - pat_lit(ex) => (v.visit_expr)(ex, (e, v)), - pat_range(e1, e2) => { - (v.visit_expr)(e1, (e.clone(), v)); - (v.visit_expr)(e2, (e, v)); + pat_lit(expression) => visitor.visit_expr(expression, env), + pat_range(lower_bound, upper_bound) => { + visitor.visit_expr(lower_bound, env.clone()); + visitor.visit_expr(upper_bound, env) } pat_wild => (), - pat_vec(ref before, ref slice, ref after) => { - foreach elt in before.iter() { - (v.visit_pat)(*elt, (e.clone(), v)); + pat_vec(ref prepattern, ref slice_pattern, ref postpatterns) => { + foreach prepattern in prepattern.iter() { + visitor.visit_pat(*prepattern, env.clone()) } - foreach elt in slice.iter() { - (v.visit_pat)(*elt, (e.clone(), v)); + foreach slice_pattern in slice_pattern.iter() { + visitor.visit_pat(*slice_pattern, env.clone()) } - foreach tail in after.iter() { - (v.visit_pat)(*tail, (e.clone(), v)); + foreach postpattern in postpatterns.iter() { + visitor.visit_pat(*postpattern, env.clone()) } } } } -pub fn visit_foreign_item<E:Clone>(ni: &foreign_item, (e, v): (E, vt<E>)) { - match ni.node { - foreign_item_fn(ref fd, _, ref generics) => { - visit_fn_decl(fd, (e.clone(), v)); - (v.visit_generics)(generics, (e, v)); - } - foreign_item_static(ref t, _) => { - (v.visit_ty)(t, (e, v)); +pub fn visit_foreign_item<E:Clone>(visitor: @Visitor<E>, + foreign_item: &foreign_item, + env: E) { + match foreign_item.node { + foreign_item_fn(ref function_declaration, _, ref generics) => { + visit_fn_decl(visitor, function_declaration, env.clone()); + visitor.visit_generics(generics, env) } + foreign_item_static(ref typ, _) => visitor.visit_ty(typ, env), } } -pub fn visit_ty_param_bounds<E:Clone>(bounds: &OptVec<TyParamBound>, - (e, v): (E, vt<E>)) { +pub fn visit_ty_param_bounds<E:Clone>(visitor: @Visitor<E>, + bounds: &OptVec<TyParamBound>, + env: E) { foreach bound in bounds.iter() { match *bound { - TraitTyParamBound(ref ty) => visit_trait_ref(ty, (e.clone(), v)), + TraitTyParamBound(ref typ) => { + visit_trait_ref(visitor, typ, env.clone()) + } RegionTyParamBound => {} } } } -pub fn visit_generics<E:Clone>(generics: &Generics, (e, v): (E, vt<E>)) { - foreach tp in generics.ty_params.iter() { - visit_ty_param_bounds(&tp.bounds, (e.clone(), v)); +pub fn visit_generics<E:Clone>(visitor: @Visitor<E>, + generics: &Generics, + env: E) { + foreach type_parameter in generics.ty_params.iter() { + visit_ty_param_bounds(visitor, &type_parameter.bounds, env.clone()) } } -pub fn visit_fn_decl<E:Clone>(fd: &fn_decl, (e, v): (E, vt<E>)) { - foreach a in fd.inputs.iter() { - (v.visit_pat)(a.pat, (e.clone(), v)); - (v.visit_ty)(&a.ty, (e.clone(), v)); +pub fn visit_fn_decl<E:Clone>(visitor: @Visitor<E>, + function_declaration: &fn_decl, + env: E) { + foreach argument in function_declaration.inputs.iter() { + visitor.visit_pat(argument.pat, env.clone()); + visitor.visit_ty(&argument.ty, env.clone()) } - (v.visit_ty)(&fd.output, (e, v)); + visitor.visit_ty(&function_declaration.output, env) } // Note: there is no visit_method() method in the visitor, instead override // visit_fn() and check for fk_method(). I named this visit_method_helper() // because it is not a default impl of any method, though I doubt that really // clarifies anything. - Niko -pub fn visit_method_helper<E:Clone>(m: &method, (e, v): (E, vt<E>)) { - (v.visit_fn)(&fk_method(m.ident, &m.generics, m), - &m.decl, - &m.body, - m.span, - m.id, - (e, v)); +pub fn visit_method_helper<E:Clone>(visitor: @Visitor<E>, + method: &method, + env: E) { + visitor.visit_fn(&fk_method(method.ident, &method.generics, method), + &method.decl, + &method.body, + method.span, + method.id, + env) } -pub fn visit_fn<E:Clone>(fk: &fn_kind, decl: &fn_decl, body: &Block, _sp: span, - _id: NodeId, (e, v): (E, vt<E>)) { - visit_fn_decl(decl, (e.clone(), v)); - let generics = generics_of_fn(fk); - (v.visit_generics)(&generics, (e.clone(), v)); - (v.visit_block)(body, (e, v)); +pub fn visit_fn<E:Clone>(visitor: @Visitor<E>, + function_kind: &fn_kind, + function_declaration: &fn_decl, + function_body: &Block, + _: span, + _: NodeId, + env: E) { + visit_fn_decl(visitor, function_declaration, env.clone()); + let generics = generics_of_fn(function_kind); + visitor.visit_generics(&generics, env.clone()); + visitor.visit_block(function_body, env) } -pub fn visit_ty_method<E:Clone>(m: &TypeMethod, (e, v): (E, vt<E>)) { - foreach a in m.decl.inputs.iter() { - (v.visit_ty)(&a.ty, (e.clone(), v)); +pub fn visit_ty_method<E:Clone>(visitor: @Visitor<E>, + method_type: &TypeMethod, + env: E) { + foreach argument_type in method_type.decl.inputs.iter() { + visitor.visit_ty(&argument_type.ty, env.clone()) } - (v.visit_generics)(&m.generics, (e.clone(), v)); - (v.visit_ty)(&m.decl.output, (e, v)); + visitor.visit_generics(&method_type.generics, env.clone()); + visitor.visit_ty(&method_type.decl.output, env.clone()) } -pub fn visit_trait_method<E:Clone>(m: &trait_method, (e, v): (E, vt<E>)) { - match *m { - required(ref ty_m) => (v.visit_ty_method)(ty_m, (e, v)), - provided(m) => visit_method_helper(m, (e, v)) +pub fn visit_trait_method<E:Clone>(visitor: @Visitor<E>, + trait_method: &trait_method, + env: E) { + match *trait_method { + required(ref method_type) => { + visitor.visit_ty_method(method_type, env) + } + provided(method) => visit_method_helper(visitor, method, env), } } -pub fn visit_struct_def<E:Clone>( - sd: @struct_def, - _nm: ast::ident, - _generics: &Generics, - _id: NodeId, - (e, v): (E, vt<E>) -) { - foreach f in sd.fields.iter() { - (v.visit_struct_field)(*f, (e.clone(), v)); +pub fn visit_struct_def<E:Clone>(visitor: @Visitor<E>, + struct_definition: @struct_def, + _: ast::ident, + _: &Generics, + _: NodeId, + env: E) { + foreach field in struct_definition.fields.iter() { + visitor.visit_struct_field(*field, env.clone()) } } -pub fn visit_struct_field<E:Clone>(sf: &struct_field, (e, v): (E, vt<E>)) { - (v.visit_ty)(&sf.node.ty, (e, v)); +pub fn visit_struct_field<E:Clone>(visitor: @Visitor<E>, + struct_field: &struct_field, + env: E) { + visitor.visit_ty(&struct_field.node.ty, env) } -pub fn visit_block<E:Clone>(b: &Block, (e, v): (E, vt<E>)) { - foreach vi in b.view_items.iter() { - (v.visit_view_item)(vi, (e.clone(), v)); +pub fn visit_block<E:Clone>(visitor: @Visitor<E>, block: &Block, env: E) { + foreach view_item in block.view_items.iter() { + visitor.visit_view_item(view_item, env.clone()) } - foreach s in b.stmts.iter() { - (v.visit_stmt)(*s, (e.clone(), v)); + foreach statement in block.stmts.iter() { + visitor.visit_stmt(*statement, env.clone()) } - visit_expr_opt(b.expr, (e, v)); + visit_expr_opt(visitor, block.expr, env) } -pub fn visit_stmt<E>(s: &stmt, (e, v): (E, vt<E>)) { - match s.node { - stmt_decl(d, _) => (v.visit_decl)(d, (e, v)), - stmt_expr(ex, _) => (v.visit_expr)(ex, (e, v)), - stmt_semi(ex, _) => (v.visit_expr)(ex, (e, v)), - stmt_mac(ref mac, _) => visit_mac(mac, (e, v)) +pub fn visit_stmt<E>(visitor: @Visitor<E>, statement: &stmt, env: E) { + match statement.node { + stmt_decl(declaration, _) => visitor.visit_decl(declaration, env), + stmt_expr(expression, _) | stmt_semi(expression, _) => { + visitor.visit_expr(expression, env) + } + stmt_mac(ref macro, _) => visit_mac(visitor, macro, env), } } -pub fn visit_decl<E:Clone>(d: &decl, (e, v): (E, vt<E>)) { - match d.node { - decl_local(ref loc) => (v.visit_local)(*loc, (e, v)), - decl_item(it) => (v.visit_item)(it, (e, v)) +pub fn visit_decl<E:Clone>(visitor: @Visitor<E>, declaration: &decl, env: E) { + match declaration.node { + decl_local(ref local) => visitor.visit_local(*local, env), + decl_item(item) => visitor.visit_item(item, env), } } -pub fn visit_expr_opt<E>(eo: Option<@expr>, (e, v): (E, vt<E>)) { - match eo { None => (), Some(ex) => (v.visit_expr)(ex, (e, v)) } +pub fn visit_expr_opt<E>(visitor: @Visitor<E>, + optional_expression: Option<@expr>, + env: E) { + match optional_expression { + None => {} + Some(expression) => visitor.visit_expr(expression, env), + } } -pub fn visit_exprs<E:Clone>(exprs: &[@expr], (e, v): (E, vt<E>)) { - foreach ex in exprs.iter() { (v.visit_expr)(*ex, (e.clone(), v)); } +pub fn visit_exprs<E:Clone>(visitor: @Visitor<E>, + expressions: &[@expr], + env: E) { + foreach expression in expressions.iter() { + visitor.visit_expr(*expression, env.clone()) + } } -pub fn visit_mac<E>(_m: &mac, (_e, _v): (E, vt<E>)) { - /* no user-serviceable parts inside */ +pub fn visit_mac<E>(_: @Visitor<E>, _: &mac, _: E) { + // Empty! } -pub fn visit_expr<E:Clone>(ex: @expr, (e, v): (E, vt<E>)) { - match ex.node { - expr_vstore(x, _) => (v.visit_expr)(x, (e.clone(), v)), - expr_vec(ref es, _) => visit_exprs(*es, (e.clone(), v)), +pub fn visit_expr<E:Clone>(visitor: @Visitor<E>, expression: @expr, env: E) { + match expression.node { + expr_vstore(subexpression, _) => { + visitor.visit_expr(subexpression, env.clone()) + } + expr_vec(ref subexpressions, _) => { + visit_exprs(visitor, *subexpressions, env.clone()) + } expr_repeat(element, count, _) => { - (v.visit_expr)(element, (e.clone(), v)); - (v.visit_expr)(count, (e.clone(), v)); + visitor.visit_expr(element, env.clone()); + visitor.visit_expr(count, env.clone()) } - expr_struct(ref p, ref flds, base) => { - visit_path(p, (e.clone(), v)); - foreach f in flds.iter() { - (v.visit_expr)(f.expr, (e.clone(), v)); + expr_struct(ref path, ref fields, optional_base) => { + visit_path(visitor, path, env.clone()); + foreach field in fields.iter() { + visitor.visit_expr(field.expr, env.clone()) } - visit_expr_opt(base, (e.clone(), v)); + visit_expr_opt(visitor, optional_base, env.clone()) } - expr_tup(ref elts) => { - foreach el in elts.iter() { (v.visit_expr)(*el, (e.clone(), v)) } + expr_tup(ref subexpressions) => { + foreach subexpression in subexpressions.iter() { + visitor.visit_expr(*subexpression, env.clone()) + } } - expr_call(callee, ref args, _) => { - visit_exprs(*args, (e.clone(), v)); - (v.visit_expr)(callee, (e.clone(), v)); + expr_call(callee_expression, ref arguments, _) => { + foreach argument in arguments.iter() { + visitor.visit_expr(*argument, env.clone()) + } + visitor.visit_expr(callee_expression, env.clone()) } - expr_method_call(_, callee, _, ref tys, ref args, _) => { - visit_exprs(*args, (e.clone(), v)); - foreach tp in tys.iter() { - (v.visit_ty)(tp, (e.clone(), v)); + expr_method_call(_, callee, _, ref types, ref arguments, _) => { + visit_exprs(visitor, *arguments, env.clone()); + foreach typ in types.iter() { + visitor.visit_ty(typ, env.clone()) + } + visitor.visit_expr(callee, env.clone()) + } + expr_binary(_, _, left_expression, right_expression) => { + visitor.visit_expr(left_expression, env.clone()); + visitor.visit_expr(right_expression, env.clone()) + } + expr_addr_of(_, subexpression) | + expr_unary(_, _, subexpression) | + expr_loop_body(subexpression) | + expr_do_body(subexpression) => { + visitor.visit_expr(subexpression, env.clone()) + } + expr_lit(_) => {} + expr_cast(subexpression, ref typ) => { + visitor.visit_expr(subexpression, env.clone()); + visitor.visit_ty(typ, env.clone()) + } + expr_if(head_expression, ref if_block, optional_else) => { + visitor.visit_expr(head_expression, env.clone()); + visitor.visit_block(if_block, env.clone()); + visit_expr_opt(visitor, optional_else, env.clone()) + } + expr_while(subexpression, ref block) => { + visitor.visit_expr(subexpression, env.clone()); + visitor.visit_block(block, env.clone()) + } + expr_for_loop(pattern, subexpression, ref block) => { + visitor.visit_pat(pattern, env.clone()); + visitor.visit_expr(subexpression, env.clone()); + visitor.visit_block(block, env.clone()) + } + expr_loop(ref block, _) => visitor.visit_block(block, env.clone()), + expr_match(subexpression, ref arms) => { + visitor.visit_expr(subexpression, env.clone()); + foreach arm in arms.iter() { + visitor.visit_arm(arm, env.clone()) } - (v.visit_expr)(callee, (e.clone(), v)); - } - expr_binary(_, _, a, b) => { - (v.visit_expr)(a, (e.clone(), v)); - (v.visit_expr)(b, (e.clone(), v)); - } - expr_addr_of(_, x) | expr_unary(_, _, x) | - expr_loop_body(x) | expr_do_body(x) => (v.visit_expr)(x, (e.clone(), v)), - expr_lit(_) => (), - expr_cast(x, ref t) => { - (v.visit_expr)(x, (e.clone(), v)); - (v.visit_ty)(t, (e.clone(), v)); - } - expr_if(x, ref b, eo) => { - (v.visit_expr)(x, (e.clone(), v)); - (v.visit_block)(b, (e.clone(), v)); - visit_expr_opt(eo, (e.clone(), v)); - } - expr_while(x, ref b) => { - (v.visit_expr)(x, (e.clone(), v)); - (v.visit_block)(b, (e.clone(), v)); - } - expr_for_loop(pat, iter, ref b) => { - (v.visit_pat)(pat, (e.clone(), v)); - (v.visit_expr)(iter, (e.clone(), v)); - (v.visit_block)(b, (e.clone(), v)); - } - expr_loop(ref b, _) => (v.visit_block)(b, (e.clone(), v)), - expr_match(x, ref arms) => { - (v.visit_expr)(x, (e.clone(), v)); - foreach a in arms.iter() { (v.visit_arm)(a, (e.clone(), v)); } - } - expr_fn_block(ref decl, ref body) => { - (v.visit_fn)( - &fk_fn_block, - decl, - body, - ex.span, - ex.id, - (e.clone(), v) - ); - } - expr_block(ref b) => (v.visit_block)(b, (e.clone(), v)), - expr_assign(a, b) => { - (v.visit_expr)(b, (e.clone(), v)); - (v.visit_expr)(a, (e.clone(), v)); - } - expr_assign_op(_, _, a, b) => { - (v.visit_expr)(b, (e.clone(), v)); - (v.visit_expr)(a, (e.clone(), v)); - } - expr_field(x, _, ref tys) => { - (v.visit_expr)(x, (e.clone(), v)); - foreach tp in tys.iter() { - (v.visit_ty)(tp, (e.clone(), v)); + } + expr_fn_block(ref function_declaration, ref body) => { + visitor.visit_fn(&fk_fn_block, + function_declaration, + body, + expression.span, + expression.id, + env.clone()) + } + expr_block(ref block) => visitor.visit_block(block, env.clone()), + expr_assign(left_hand_expression, right_hand_expression) => { + visitor.visit_expr(right_hand_expression, env.clone()); + visitor.visit_expr(left_hand_expression, env.clone()) + } + expr_assign_op(_, _, left_expression, right_expression) => { + visitor.visit_expr(right_expression, env.clone()); + visitor.visit_expr(left_expression, env.clone()) + } + expr_field(subexpression, _, ref types) => { + visitor.visit_expr(subexpression, env.clone()); + foreach typ in types.iter() { + visitor.visit_ty(typ, env.clone()) } } - expr_index(_, a, b) => { - (v.visit_expr)(a, (e.clone(), v)); - (v.visit_expr)(b, (e.clone(), v)); - } - expr_path(ref p) => visit_path(p, (e.clone(), v)), - expr_self => (), - expr_break(_) => (), - expr_again(_) => (), - expr_ret(eo) => visit_expr_opt(eo, (e.clone(), v)), - expr_log(lv, x) => { - (v.visit_expr)(lv, (e.clone(), v)); - (v.visit_expr)(x, (e.clone(), v)); - } - expr_mac(ref mac) => visit_mac(mac, (e.clone(), v)), - expr_paren(x) => (v.visit_expr)(x, (e.clone(), v)), - expr_inline_asm(ref a) => { - foreach &(_, input) in a.inputs.iter() { - (v.visit_expr)(input, (e.clone(), v)); + expr_index(_, main_expression, index_expression) => { + visitor.visit_expr(main_expression, env.clone()); + visitor.visit_expr(index_expression, env.clone()) + } + expr_path(ref path) => visit_path(visitor, path, env.clone()), + expr_self | expr_break(_) | expr_again(_) => {} + expr_ret(optional_expression) => { + visit_expr_opt(visitor, optional_expression, env.clone()) + } + expr_log(level, subexpression) => { + visitor.visit_expr(level, env.clone()); + visitor.visit_expr(subexpression, env.clone()); + } + expr_mac(ref macro) => visit_mac(visitor, macro, env.clone()), + expr_paren(subexpression) => { + visitor.visit_expr(subexpression, env.clone()) + } + expr_inline_asm(ref assembler) => { + foreach &(_, input) in assembler.inputs.iter() { + visitor.visit_expr(input, env.clone()) } - foreach &(_, out) in a.outputs.iter() { - (v.visit_expr)(out, (e.clone(), v)); + foreach &(_, output) in assembler.outputs.iter() { + visitor.visit_expr(output, env.clone()) } } } - (v.visit_expr_post)(ex, (e, v)); + + visitor.visit_expr_post(expression, env.clone()) } -pub fn visit_arm<E:Clone>(a: &arm, (e, v): (E, vt<E>)) { - foreach p in a.pats.iter() { (v.visit_pat)(*p, (e.clone(), v)); } - visit_expr_opt(a.guard, (e.clone(), v)); - (v.visit_block)(&a.body, (e.clone(), v)); +pub fn visit_arm<E:Clone>(visitor: @Visitor<E>, arm: &arm, env: E) { + foreach pattern in arm.pats.iter() { + visitor.visit_pat(*pattern, env.clone()) + } + visit_expr_opt(visitor, arm.guard, env.clone()); + visitor.visit_block(&arm.body, env) } // Simpler, non-context passing interface. Always walks the whole tree, simply // calls the given functions on the nodes. -pub struct SimpleVisitor { - visit_mod: @fn(&_mod, span, NodeId), - visit_view_item: @fn(&view_item), - visit_foreign_item: @fn(@foreign_item), - visit_item: @fn(@item), - visit_local: @fn(@Local), - visit_block: @fn(&Block), - visit_stmt: @fn(@stmt), - visit_arm: @fn(&arm), - visit_pat: @fn(@pat), - visit_decl: @fn(@decl), - visit_expr: @fn(@expr), - visit_expr_post: @fn(@expr), - visit_ty: @fn(&Ty), - visit_generics: @fn(&Generics), - visit_fn: @fn(&fn_kind, &fn_decl, &Block, span, NodeId), - visit_ty_method: @fn(&TypeMethod), - visit_trait_method: @fn(&trait_method), - visit_struct_def: @fn(@struct_def, ident, &Generics, NodeId), - visit_struct_field: @fn(@struct_field), - visit_struct_method: @fn(@method) -} - -pub type simple_visitor = @SimpleVisitor; - -pub fn simple_ignore_ty(_t: &Ty) {} - -pub fn default_simple_visitor() -> @SimpleVisitor { - @SimpleVisitor { - visit_mod: |_m, _sp, _id| { }, - visit_view_item: |_vi| { }, - visit_foreign_item: |_ni| { }, - visit_item: |_i| { }, - visit_local: |_l| { }, - visit_block: |_b| { }, - visit_stmt: |_s| { }, - visit_arm: |_a| { }, - visit_pat: |_p| { }, - visit_decl: |_d| { }, - visit_expr: |_e| { }, - visit_expr_post: |_e| { }, - visit_ty: simple_ignore_ty, - visit_generics: |_| {}, - visit_fn: |_, _, _, _, _| {}, - visit_ty_method: |_| {}, - visit_trait_method: |_| {}, - visit_struct_def: |_, _, _, _| {}, - visit_struct_field: |_| {}, - visit_struct_method: |_| {}, - } -} - -pub fn mk_simple_visitor(v: simple_visitor) -> vt<()> { - fn v_mod( - f: @fn(&_mod, span, NodeId), - m: &_mod, - sp: span, - id: NodeId, - (e, v): ((), vt<()>) - ) { - f(m, sp, id); - visit_mod(m, sp, id, (e, v)); - } - fn v_view_item(f: @fn(&view_item), vi: &view_item, (e, v): ((), vt<()>)) { - f(vi); - visit_view_item(vi, (e, v)); - } - fn v_foreign_item(f: @fn(@foreign_item), ni: @foreign_item, (e, v): ((), vt<()>)) { - f(ni); - visit_foreign_item(ni, (e, v)); - } - fn v_item(f: @fn(@item), i: @item, (e, v): ((), vt<()>)) { - f(i); - visit_item(i, (e, v)); - } - fn v_local(f: @fn(@Local), l: @Local, (e, v): ((), vt<()>)) { - f(l); - visit_local(l, (e, v)); - } - fn v_block(f: @fn(&ast::Block), bl: &ast::Block, (e, v): ((), vt<()>)) { - f(bl); - visit_block(bl, (e, v)); - } - fn v_stmt(f: @fn(@stmt), st: @stmt, (e, v): ((), vt<()>)) { - f(st); - visit_stmt(st, (e, v)); - } - fn v_arm(f: @fn(&arm), a: &arm, (e, v): ((), vt<()>)) { - f(a); - visit_arm(a, (e, v)); - } - fn v_pat(f: @fn(@pat), p: @pat, (e, v): ((), vt<()>)) { - f(p); - visit_pat(p, (e, v)); - } - fn v_decl(f: @fn(@decl), d: @decl, (e, v): ((), vt<()>)) { - f(d); - visit_decl(d, (e, v)); - } - fn v_expr(f: @fn(@expr), ex: @expr, (e, v): ((), vt<()>)) { - f(ex); - visit_expr(ex, (e, v)); - } - fn v_expr_post(f: @fn(@expr), ex: @expr, (_e, _v): ((), vt<()>)) { - f(ex); - } - fn v_ty(f: @fn(&Ty), ty: &Ty, (e, v): ((), vt<()>)) { - f(ty); - visit_ty(ty, (e, v)); - } - fn v_ty_method(f: @fn(&TypeMethod), ty: &TypeMethod, (e, v): ((), vt<()>)) { - f(ty); - visit_ty_method(ty, (e, v)); - } - fn v_trait_method(f: @fn(&trait_method), - m: &trait_method, - (e, v): ((), vt<()>)) { - f(m); - visit_trait_method(m, (e, v)); - } - fn v_struct_def( - f: @fn(@struct_def, ident, &Generics, NodeId), - sd: @struct_def, - nm: ident, - generics: &Generics, - id: NodeId, - (e, v): ((), vt<()>) - ) { - f(sd, nm, generics, id); - visit_struct_def(sd, nm, generics, id, (e, v)); - } - fn v_generics( - f: @fn(&Generics), - ps: &Generics, - (e, v): ((), vt<()>) - ) { - f(ps); - visit_generics(ps, (e, v)); - } - fn v_fn( - f: @fn(&fn_kind, &fn_decl, &Block, span, NodeId), - fk: &fn_kind, - decl: &fn_decl, - body: &Block, - sp: span, - id: NodeId, - (e, v): ((), vt<()>) - ) { - f(fk, decl, body, sp, id); - visit_fn(fk, decl, body, sp, id, (e, v)); - } - let visit_ty: @fn(&Ty, ((), vt<()>)) = - |a,b| v_ty(v.visit_ty, a, b); - fn v_struct_field(f: @fn(@struct_field), sf: @struct_field, (e, v): ((), vt<()>)) { - f(sf); - visit_struct_field(sf, (e, v)); - } - return mk_vt(@Visitor { - visit_mod: |a,b,c,d|v_mod(v.visit_mod, a, b, c, d), - visit_view_item: |a,b| v_view_item(v.visit_view_item, a, b), - visit_foreign_item: - |a,b|v_foreign_item(v.visit_foreign_item, a, b), - visit_item: |a,b|v_item(v.visit_item, a, b), - visit_local: |a,b|v_local(v.visit_local, a, b), - visit_block: |a,b|v_block(v.visit_block, a, b), - visit_stmt: |a,b|v_stmt(v.visit_stmt, a, b), - visit_arm: |a,b|v_arm(v.visit_arm, a, b), - visit_pat: |a,b|v_pat(v.visit_pat, a, b), - visit_decl: |a,b|v_decl(v.visit_decl, a, b), - visit_expr: |a,b|v_expr(v.visit_expr, a, b), - visit_expr_post: |a,b| v_expr_post(v.visit_expr_post, a, b), - visit_ty: visit_ty, - visit_generics: |a,b| - v_generics(v.visit_generics, a, b), - visit_fn: |a,b,c,d,e,f| - v_fn(v.visit_fn, a, b, c, d, e, f), - visit_ty_method: |a,b| - v_ty_method(v.visit_ty_method, a, b), - visit_trait_method: |a,b| - v_trait_method(v.visit_trait_method, a, b), - visit_struct_def: |a,b,c,d,e| - v_struct_def(v.visit_struct_def, a, b, c, d, e), - visit_struct_field: |a,b| - v_struct_field(v.visit_struct_field, a, b), - }); +pub trait SimpleVisitor { + fn visit_mod(@mut self, &_mod, span, NodeId); + fn visit_view_item(@mut self, &view_item); + fn visit_foreign_item(@mut self, @foreign_item); + fn visit_item(@mut self, @item); + fn visit_local(@mut self, @Local); + fn visit_block(@mut self, &Block); + fn visit_stmt(@mut self, @stmt); + fn visit_arm(@mut self, &arm); + fn visit_pat(@mut self, @pat); + fn visit_decl(@mut self, @decl); + fn visit_expr(@mut self, @expr); + fn visit_expr_post(@mut self, @expr); + fn visit_ty(@mut self, &Ty); + fn visit_generics(@mut self, &Generics); + fn visit_fn(@mut self, &fn_kind, &fn_decl, &Block, span, NodeId); + fn visit_ty_method(@mut self, &TypeMethod); + fn visit_trait_method(@mut self, &trait_method); + fn visit_struct_def(@mut self, @struct_def, ident, &Generics, NodeId); + fn visit_struct_field(@mut self, @struct_field); + fn visit_struct_method(@mut self, @method); +} + +pub struct SimpleVisitorVisitor { + simple_visitor: @SimpleVisitor, +} + +impl Visitor<()> for SimpleVisitorVisitor { + fn visit_mod(@mut self, + module: &_mod, + span: span, + node_id: NodeId, + env: ()) { + self.simple_visitor.visit_mod(module, span, node_id); + visit_mod(self as @Visitor<()>, module, env) + } + fn visit_view_item(@mut self, view_item: &view_item, env: ()) { + self.simple_visitor.visit_view_item(view_item); + visit_view_item(self as @Visitor<()>, view_item, env) + } + fn visit_foreign_item(@mut self, foreign_item: @foreign_item, env: ()) { + self.simple_visitor.visit_foreign_item(foreign_item); + visit_foreign_item(self as @Visitor<()>, foreign_item, env) + } + fn visit_item(@mut self, item: @item, env: ()) { + self.simple_visitor.visit_item(item); + visit_item(self as @Visitor<()>, item, env) + } + fn visit_local(@mut self, local: @Local, env: ()) { + self.simple_visitor.visit_local(local); + visit_local(self as @Visitor<()>, local, env) + } + fn visit_block(@mut self, block: &Block, env: ()) { + self.simple_visitor.visit_block(block); + visit_block(self as @Visitor<()>, block, env) + } + fn visit_stmt(@mut self, statement: @stmt, env: ()) { + self.simple_visitor.visit_stmt(statement); + visit_stmt(self as @Visitor<()>, statement, env) + } + fn visit_arm(@mut self, arm: &arm, env: ()) { + self.simple_visitor.visit_arm(arm); + visit_arm(self as @Visitor<()>, arm, env) + } + fn visit_pat(@mut self, pattern: @pat, env: ()) { + self.simple_visitor.visit_pat(pattern); + visit_pat(self as @Visitor<()>, pattern, env) + } + fn visit_decl(@mut self, declaration: @decl, env: ()) { + self.simple_visitor.visit_decl(declaration); + visit_decl(self as @Visitor<()>, declaration, env) + } + fn visit_expr(@mut self, expression: @expr, env: ()) { + self.simple_visitor.visit_expr(expression); + visit_expr(self as @Visitor<()>, expression, env) + } + fn visit_expr_post(@mut self, expression: @expr, _: ()) { + self.simple_visitor.visit_expr_post(expression) + } + fn visit_ty(@mut self, typ: &Ty, env: ()) { + self.simple_visitor.visit_ty(typ); + visit_ty(self as @Visitor<()>, typ, env) + } + fn visit_generics(@mut self, generics: &Generics, env: ()) { + self.simple_visitor.visit_generics(generics); + visit_generics(self as @Visitor<()>, generics, env) + } + fn visit_fn(@mut self, + function_kind: &fn_kind, + function_declaration: &fn_decl, + block: &Block, + span: span, + node_id: NodeId, + env: ()) { + self.simple_visitor.visit_fn(function_kind, + function_declaration, + block, + span, + node_id); + visit_fn(self as @Visitor<()>, + function_kind, + function_declaration, + block, + span, + node_id, + env) + } + fn visit_ty_method(@mut self, method_type: &TypeMethod, env: ()) { + self.simple_visitor.visit_ty_method(method_type); + visit_ty_method(self as @Visitor<()>, method_type, env) + } + fn visit_trait_method(@mut self, trait_method: &trait_method, env: ()) { + self.simple_visitor.visit_trait_method(trait_method); + visit_trait_method(self as @Visitor<()>, trait_method, env) + } + fn visit_struct_def(@mut self, + struct_definition: @struct_def, + identifier: ident, + generics: &Generics, + node_id: NodeId, + env: ()) { + self.simple_visitor.visit_struct_def(struct_definition, + identifier, + generics, + node_id); + visit_struct_def(self as @Visitor<()>, + struct_definition, + identifier, + generics, + node_id, + env) + } + fn visit_struct_field(@mut self, struct_field: @struct_field, env: ()) { + self.simple_visitor.visit_struct_field(struct_field); + visit_struct_field(self as @Visitor<()>, struct_field, env) + } } + diff --git a/src/test/bench/noise.rs b/src/test/bench/noise.rs index 6a5f3623d0f..2907496dfa9 100644 --- a/src/test/bench/noise.rs +++ b/src/test/bench/noise.rs @@ -119,7 +119,7 @@ fn main() { foreach y in range(0, 256) { foreach x in range(0, 256) { - print(symbols[pixels[y*256+x] / 0.2f32 as int]); + print((symbols[pixels[y*256+x] / 0.2f32) as int]); } println(""); } diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs index 27db4ff5aaa..6140b81b7d0 100644 --- a/src/test/compile-fail/liveness-unused.rs +++ b/src/test/compile-fail/liveness-unused.rs @@ -1,3 +1,6 @@ +// xfail-test +// xfail'd because lint is messed up with the new visitor transition + // Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. |
