auto merge of #8619 : pnkfelix/rust/fsk-visitor-vpar-defaults-step3, r=nmatsakis
Follow up to #8539 (step 2 of 5). (See #8527, which was step 1 of 5, for the full outline.) Part of #7081.
This commit is contained in:
commit
2246d56e71
@ -119,9 +119,8 @@ 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::oldvisit::{fk_anon, fk_fn_block, fk_item_fn, fk_method};
|
||||
use syntax::oldvisit::{vt};
|
||||
use syntax::{oldvisit, ast_util};
|
||||
use syntax::{visit, ast_util};
|
||||
use syntax::visit::{Visitor,fn_kind};
|
||||
|
||||
#[deriving(Eq)]
|
||||
struct Variable(uint);
|
||||
@ -152,22 +151,27 @@ fn live_node_kind_to_str(lnk: LiveNodeKind, cx: ty::ctxt) -> ~str {
|
||||
}
|
||||
}
|
||||
|
||||
struct LivenessVisitor;
|
||||
|
||||
impl Visitor<@mut IrMaps> for LivenessVisitor {
|
||||
fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:span, n:NodeId, e:@mut IrMaps) {
|
||||
visit_fn(self, fk, fd, b, s, n, e);
|
||||
}
|
||||
fn visit_local(&mut self, l:@Local, e:@mut IrMaps) { visit_local(self, l, e); }
|
||||
fn visit_expr(&mut self, ex:@expr, e:@mut IrMaps) { visit_expr(self, ex, e); }
|
||||
fn visit_arm(&mut self, a:&arm, e:@mut IrMaps) { visit_arm(self, a, e); }
|
||||
}
|
||||
|
||||
pub fn check_crate(tcx: ty::ctxt,
|
||||
method_map: typeck::method_map,
|
||||
capture_map: moves::CaptureMap,
|
||||
crate: &Crate) {
|
||||
let visitor = oldvisit::mk_vt(@oldvisit::Visitor {
|
||||
visit_fn: visit_fn,
|
||||
visit_local: visit_local,
|
||||
visit_expr: visit_expr,
|
||||
visit_arm: visit_arm,
|
||||
.. *oldvisit::default_visitor()
|
||||
});
|
||||
let mut visitor = LivenessVisitor;
|
||||
|
||||
let initial_maps = @mut IrMaps(tcx,
|
||||
method_map,
|
||||
capture_map);
|
||||
oldvisit::visit_crate(crate, (initial_maps, visitor));
|
||||
visit::walk_crate(&mut visitor, crate, initial_maps);
|
||||
tcx.sess.abort_if_errors();
|
||||
}
|
||||
|
||||
@ -341,13 +345,30 @@ impl IrMaps {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn(fk: &oldvisit::fn_kind,
|
||||
struct ErrorCheckVisitor;
|
||||
|
||||
impl Visitor<@Liveness> for ErrorCheckVisitor {
|
||||
fn visit_fn(&mut self, fk:&fn_kind, fd:&fn_decl, b:&Block, s:span, n:NodeId, e:@Liveness) {
|
||||
check_fn(self, fk, fd, b, s, n, e);
|
||||
}
|
||||
fn visit_local(&mut self, l:@Local, e:@Liveness) {
|
||||
check_local(self, l, e);
|
||||
}
|
||||
fn visit_expr(&mut self, ex:@expr, e:@Liveness) {
|
||||
check_expr(self, ex, e);
|
||||
}
|
||||
fn visit_arm(&mut self, a:&arm, e:@Liveness) {
|
||||
check_arm(self, a, e);
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_fn(v: &mut LivenessVisitor,
|
||||
fk: &visit::fn_kind,
|
||||
decl: &fn_decl,
|
||||
body: &Block,
|
||||
sp: span,
|
||||
id: NodeId,
|
||||
(this, v): (@mut IrMaps,
|
||||
vt<@mut IrMaps>)) {
|
||||
this: @mut IrMaps) {
|
||||
debug!("visit_fn: id=%d", id);
|
||||
let _i = ::util::common::indenter();
|
||||
|
||||
@ -371,7 +392,7 @@ fn visit_fn(fk: &oldvisit::fn_kind,
|
||||
|
||||
// Add `this`, whether explicit or implicit.
|
||||
match *fk {
|
||||
fk_method(_, _, method) => {
|
||||
visit::fk_method(_, _, method) => {
|
||||
match method.explicit_self.node {
|
||||
sty_value | sty_region(*) | sty_box(_) | sty_uniq => {
|
||||
fn_maps.add_variable(Arg(method.self_id,
|
||||
@ -380,12 +401,12 @@ fn visit_fn(fk: &oldvisit::fn_kind,
|
||||
sty_static => {}
|
||||
}
|
||||
}
|
||||
fk_item_fn(*) | fk_anon(*) | fk_fn_block(*) => {}
|
||||
visit::fk_item_fn(*) | visit::fk_anon(*) | visit::fk_fn_block(*) => {}
|
||||
}
|
||||
|
||||
// gather up the various local variables, significant expressions,
|
||||
// and so forth:
|
||||
oldvisit::visit_fn(fk, decl, body, sp, id, (fn_maps, v));
|
||||
visit::walk_fn(v, fk, decl, body, sp, id, fn_maps);
|
||||
|
||||
// Special nodes and variables:
|
||||
// - exit_ln represents the end of the fn, either by return or fail
|
||||
@ -402,19 +423,13 @@ fn visit_fn(fk: &oldvisit::fn_kind,
|
||||
let entry_ln = (*lsets).compute(decl, body);
|
||||
|
||||
// check for various error conditions
|
||||
let check_vt = oldvisit::mk_vt(@oldvisit::Visitor {
|
||||
visit_fn: check_fn,
|
||||
visit_local: check_local,
|
||||
visit_expr: check_expr,
|
||||
visit_arm: check_arm,
|
||||
.. *oldvisit::default_visitor()
|
||||
});
|
||||
(check_vt.visit_block)(body, (lsets, check_vt));
|
||||
let mut check_vt = ErrorCheckVisitor;
|
||||
check_vt.visit_block(body, lsets);
|
||||
lsets.check_ret(id, sp, fk, entry_ln);
|
||||
lsets.warn_about_unused_args(decl, entry_ln);
|
||||
}
|
||||
|
||||
fn visit_local(local: @Local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
fn visit_local(v: &mut LivenessVisitor, local: @Local, this: @mut IrMaps) {
|
||||
let def_map = this.tcx.def_map;
|
||||
do pat_util::pat_bindings(def_map, local.pat) |_bm, p_id, sp, path| {
|
||||
debug!("adding local variable %d", p_id);
|
||||
@ -431,10 +446,10 @@ fn visit_local(local: @Local, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
kind: kind
|
||||
}));
|
||||
}
|
||||
oldvisit::visit_local(local, (this, vt));
|
||||
visit::walk_local(v, local, this);
|
||||
}
|
||||
|
||||
fn visit_arm(arm: &arm, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
fn visit_arm(v: &mut LivenessVisitor, arm: &arm, this: @mut IrMaps) {
|
||||
let def_map = this.tcx.def_map;
|
||||
for pat in arm.pats.iter() {
|
||||
do pat_util::pat_bindings(def_map, *pat) |bm, p_id, sp, path| {
|
||||
@ -450,10 +465,10 @@ fn visit_arm(arm: &arm, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
}));
|
||||
}
|
||||
}
|
||||
oldvisit::visit_arm(arm, (this, vt));
|
||||
visit::walk_arm(v, arm, this);
|
||||
}
|
||||
|
||||
fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
fn visit_expr(v: &mut LivenessVisitor, expr: @expr, this: @mut IrMaps) {
|
||||
match expr.node {
|
||||
// live nodes required for uses or definitions of variables:
|
||||
expr_path(_) | expr_self => {
|
||||
@ -462,7 +477,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));
|
||||
}
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
expr_fn_block(*) => {
|
||||
// Interesting control flow (for loops can contain labeled
|
||||
@ -495,18 +510,18 @@ fn visit_expr(expr: @expr, (this, vt): (@mut IrMaps, vt<@mut IrMaps>)) {
|
||||
}
|
||||
this.set_captures(expr.id, call_caps);
|
||||
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
|
||||
// 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));
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
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));
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
|
||||
// otherwise, live nodes are not required:
|
||||
@ -518,7 +533,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(*) => {
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(v, expr, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1408,7 +1423,7 @@ impl Liveness {
|
||||
// _______________________________________________________________________
|
||||
// Checking for error conditions
|
||||
|
||||
fn check_local(local: @Local, (this, vt): (@Liveness, vt<@Liveness>)) {
|
||||
fn check_local(vt: &mut ErrorCheckVisitor, local: @Local, this: @Liveness) {
|
||||
match local.init {
|
||||
Some(_) => {
|
||||
this.warn_about_unused_or_dead_vars_in_pat(local.pat);
|
||||
@ -1434,34 +1449,34 @@ fn check_local(local: @Local, (this, vt): (@Liveness, vt<@Liveness>)) {
|
||||
}
|
||||
}
|
||||
|
||||
oldvisit::visit_local(local, (this, vt));
|
||||
visit::walk_local(vt, local, this);
|
||||
}
|
||||
|
||||
fn check_arm(arm: &arm, (this, vt): (@Liveness, vt<@Liveness>)) {
|
||||
fn check_arm(vt: &mut ErrorCheckVisitor, arm: &arm, this: @Liveness) {
|
||||
do this.arm_pats_bindings(arm.pats) |ln, var, sp, id| {
|
||||
this.warn_about_unused(sp, id, ln, var);
|
||||
}
|
||||
oldvisit::visit_arm(arm, (this, vt));
|
||||
visit::walk_arm(vt, arm, this);
|
||||
}
|
||||
|
||||
fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) {
|
||||
fn check_expr(vt: &mut ErrorCheckVisitor, expr: @expr, this: @Liveness) {
|
||||
match expr.node {
|
||||
expr_assign(l, r) => {
|
||||
this.check_lvalue(l, vt);
|
||||
(vt.visit_expr)(r, (this, vt));
|
||||
vt.visit_expr(r, this);
|
||||
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(vt, expr, this);
|
||||
}
|
||||
|
||||
expr_assign_op(_, _, l, _) => {
|
||||
this.check_lvalue(l, vt);
|
||||
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(vt, expr, this);
|
||||
}
|
||||
|
||||
expr_inline_asm(ref ia) => {
|
||||
for &(_, input) in ia.inputs.iter() {
|
||||
(vt.visit_expr)(input, (this, vt));
|
||||
vt.visit_expr(input, this);
|
||||
}
|
||||
|
||||
// Output operands must be lvalues
|
||||
@ -1472,10 +1487,10 @@ fn check_expr(expr: @expr, (this, vt): (@Liveness, vt<@Liveness>)) {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
(vt.visit_expr)(out, (this, vt));
|
||||
vt.visit_expr(out, this);
|
||||
}
|
||||
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(vt, expr, this);
|
||||
}
|
||||
|
||||
// no correctness conditions related to liveness
|
||||
@ -1487,18 +1502,19 @@ 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(*) => {
|
||||
oldvisit::visit_expr(expr, (this, vt));
|
||||
visit::walk_expr(vt, expr, this);
|
||||
}
|
||||
expr_for_loop(*) => fail!("non-desugared expr_for_loop")
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(_fk: &oldvisit::fn_kind,
|
||||
fn check_fn(_v: &mut ErrorCheckVisitor,
|
||||
_fk: &visit::fn_kind,
|
||||
_decl: &fn_decl,
|
||||
_body: &Block,
|
||||
_sp: span,
|
||||
_id: NodeId,
|
||||
(_self, _v): (@Liveness, vt<@Liveness>)) {
|
||||
_self: @Liveness) {
|
||||
// do not check contents of nested fns
|
||||
}
|
||||
|
||||
@ -1513,7 +1529,7 @@ impl Liveness {
|
||||
pub fn check_ret(&self,
|
||||
id: NodeId,
|
||||
sp: span,
|
||||
_fk: &oldvisit::fn_kind,
|
||||
_fk: &visit::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
|
||||
@ -1533,7 +1549,7 @@ impl Liveness {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_lvalue(@self, expr: @expr, vt: vt<@Liveness>) {
|
||||
pub fn check_lvalue(@self, expr: @expr, vt: &mut ErrorCheckVisitor) {
|
||||
match expr.node {
|
||||
expr_path(_) => {
|
||||
match self.tcx.def_map.get_copy(&expr.id) {
|
||||
@ -1562,7 +1578,7 @@ impl Liveness {
|
||||
_ => {
|
||||
// For other kinds of lvalues, no checks are required,
|
||||
// and any embedded expressions are actually rvalues
|
||||
oldvisit::visit_expr(expr, (self, vt));
|
||||
visit::walk_expr(vt, expr, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,17 +27,14 @@ 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::opt_vec::OptVec;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
use std::str;
|
||||
use std::uint;
|
||||
@ -131,7 +128,30 @@ pub enum SelfBinding {
|
||||
HasSelfBinding(NodeId, bool /* is implicit */)
|
||||
}
|
||||
|
||||
pub type ResolveVisitor = vt<()>;
|
||||
struct ResolveVisitor {
|
||||
resolver: @mut Resolver,
|
||||
}
|
||||
|
||||
impl Visitor<()> for ResolveVisitor {
|
||||
fn visit_item(&mut self, item:@item, _:()) {
|
||||
self.resolver.resolve_item(item, self);
|
||||
}
|
||||
fn visit_arm(&mut self, arm:&arm, _:()) {
|
||||
self.resolver.resolve_arm(arm, self);
|
||||
}
|
||||
fn visit_block(&mut self, block:&Block, _:()) {
|
||||
self.resolver.resolve_block(block, self);
|
||||
}
|
||||
fn visit_expr(&mut self, expr:@expr, _:()) {
|
||||
self.resolver.resolve_expr(expr, self);
|
||||
}
|
||||
fn visit_local(&mut self, local:@Local, _:()) {
|
||||
self.resolver.resolve_local(local, self);
|
||||
}
|
||||
fn visit_ty(&mut self, ty:&Ty, _:()) {
|
||||
self.resolver.resolve_type(ty, self);
|
||||
}
|
||||
}
|
||||
|
||||
/// Contains data for specific types of import directives.
|
||||
pub enum ImportDirectiveSubclass {
|
||||
@ -871,6 +891,45 @@ pub struct Resolver {
|
||||
used_imports: HashSet<NodeId>,
|
||||
}
|
||||
|
||||
struct BuildReducedGraphVisitor {
|
||||
resolver: @mut Resolver,
|
||||
}
|
||||
|
||||
impl Visitor<ReducedGraphParent> for BuildReducedGraphVisitor {
|
||||
|
||||
fn visit_item(&mut self, item:@item, context:ReducedGraphParent) {
|
||||
self.resolver.build_reduced_graph_for_item(item, (context, self));
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, foreign_item:@foreign_item, context:ReducedGraphParent) {
|
||||
self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
|
||||
(context,
|
||||
self));
|
||||
}
|
||||
|
||||
fn visit_view_item(&mut self, view_item:&view_item, context:ReducedGraphParent) {
|
||||
self.resolver.build_reduced_graph_for_view_item(view_item,
|
||||
(context,
|
||||
self));
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, block:&Block, context:ReducedGraphParent) {
|
||||
self.resolver.build_reduced_graph_for_block(block,
|
||||
(context,
|
||||
self));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct UnusedImportCheckVisitor { resolver: @mut Resolver }
|
||||
|
||||
impl Visitor<()> for UnusedImportCheckVisitor {
|
||||
fn visit_view_item(&mut self, vi:&view_item, _:()) {
|
||||
self.resolver.check_for_item_unused_imports(vi);
|
||||
visit::walk_view_item(self, vi, ());
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolver {
|
||||
/// The main name resolution procedure.
|
||||
pub fn resolve(@mut self) {
|
||||
@ -900,27 +959,9 @@ impl Resolver {
|
||||
pub fn build_reduced_graph(@mut self) {
|
||||
let initial_parent =
|
||||
ModuleReducedGraphParent(self.graph_root.get_module());
|
||||
visit_crate(self.crate, (initial_parent, mk_vt(@Visitor {
|
||||
visit_item: |item, (context, visitor)|
|
||||
self.build_reduced_graph_for_item(item, (context, visitor)),
|
||||
|
||||
visit_foreign_item: |foreign_item, (context, visitor)|
|
||||
self.build_reduced_graph_for_foreign_item(foreign_item,
|
||||
(context,
|
||||
visitor)),
|
||||
|
||||
visit_view_item: |view_item, (context, visitor)|
|
||||
self.build_reduced_graph_for_view_item(view_item,
|
||||
(context,
|
||||
visitor)),
|
||||
|
||||
visit_block: |block, (context, visitor)|
|
||||
self.build_reduced_graph_for_block(block,
|
||||
(context,
|
||||
visitor)),
|
||||
|
||||
.. *default_visitor()
|
||||
})));
|
||||
let mut visitor = BuildReducedGraphVisitor { resolver: self, };
|
||||
visit::walk_crate(&mut visitor, self.crate, initial_parent);
|
||||
}
|
||||
|
||||
/// Returns the current module tracked by the reduced graph parent.
|
||||
@ -1094,7 +1135,7 @@ impl Resolver {
|
||||
pub fn build_reduced_graph_for_item(@mut self,
|
||||
item: @item,
|
||||
(parent, visitor): (ReducedGraphParent,
|
||||
vt<ReducedGraphParent>)) {
|
||||
&mut BuildReducedGraphVisitor)) {
|
||||
let ident = item.ident;
|
||||
let sp = item.span;
|
||||
let privacy = visibility_to_privacy(item.vis);
|
||||
@ -1115,7 +1156,7 @@ impl Resolver {
|
||||
let new_parent =
|
||||
ModuleReducedGraphParent(name_bindings.get_module());
|
||||
|
||||
visit_mod(module_, sp, item.id, (new_parent, visitor));
|
||||
visit::walk_mod(visitor, module_, new_parent);
|
||||
}
|
||||
|
||||
item_foreign_mod(ref fm) => {
|
||||
@ -1142,7 +1183,7 @@ impl Resolver {
|
||||
anonymous => parent
|
||||
};
|
||||
|
||||
visit_item(item, (new_parent, visitor));
|
||||
visit::walk_item(visitor, item, new_parent);
|
||||
}
|
||||
|
||||
// These items live in the value namespace.
|
||||
@ -1160,7 +1201,7 @@ impl Resolver {
|
||||
|
||||
let def = def_fn(local_def(item.id), purity);
|
||||
name_bindings.define_value(privacy, def, sp);
|
||||
visit_item(item, (new_parent, visitor));
|
||||
visit::walk_item(visitor, item, new_parent);
|
||||
}
|
||||
|
||||
// These items live in the type namespace.
|
||||
@ -1186,7 +1227,7 @@ impl Resolver {
|
||||
// inherited => privacy of the enum item
|
||||
variant_visibility_to_privacy(variant.node.vis,
|
||||
privacy == Public),
|
||||
(new_parent, visitor));
|
||||
new_parent, visitor);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1213,7 +1254,7 @@ impl Resolver {
|
||||
// Record the def ID of this struct.
|
||||
self.structs.insert(local_def(item.id));
|
||||
|
||||
visit_item(item, (new_parent, visitor));
|
||||
visit::walk_item(visitor, item, new_parent);
|
||||
}
|
||||
|
||||
item_impl(_, None, ref ty, ref methods) => {
|
||||
@ -1293,11 +1334,11 @@ impl Resolver {
|
||||
_ => {}
|
||||
}
|
||||
|
||||
visit_item(item, (parent, visitor));
|
||||
visit::walk_item(visitor, item, parent);
|
||||
}
|
||||
|
||||
item_impl(_, Some(_), _, _) => {
|
||||
visit_item(item, (parent, visitor));
|
||||
visit::walk_item(visitor, item, parent);
|
||||
}
|
||||
|
||||
item_trait(_, _, ref methods) => {
|
||||
@ -1364,7 +1405,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
name_bindings.define_type(privacy, def_trait(def_id), sp);
|
||||
visit_item(item, (new_parent, visitor));
|
||||
visit::walk_item(visitor, item, new_parent);
|
||||
}
|
||||
|
||||
item_mac(*) => {
|
||||
@ -1379,9 +1420,8 @@ impl Resolver {
|
||||
variant: &variant,
|
||||
item_id: def_id,
|
||||
parent_privacy: Privacy,
|
||||
(parent, _visitor):
|
||||
(ReducedGraphParent,
|
||||
vt<ReducedGraphParent>)) {
|
||||
parent: ReducedGraphParent,
|
||||
_: &mut BuildReducedGraphVisitor) {
|
||||
let ident = variant.node.name;
|
||||
|
||||
let privacy =
|
||||
@ -1418,7 +1458,7 @@ impl Resolver {
|
||||
view_item: &view_item,
|
||||
(parent, _):
|
||||
(ReducedGraphParent,
|
||||
vt<ReducedGraphParent>)) {
|
||||
&mut BuildReducedGraphVisitor)) {
|
||||
let privacy = visibility_to_privacy(view_item.vis);
|
||||
match view_item.node {
|
||||
view_item_use(ref view_paths) => {
|
||||
@ -1517,7 +1557,7 @@ impl Resolver {
|
||||
foreign_item: @foreign_item,
|
||||
(parent, visitor):
|
||||
(ReducedGraphParent,
|
||||
vt<ReducedGraphParent>)) {
|
||||
&mut BuildReducedGraphVisitor)) {
|
||||
let name = foreign_item.ident;
|
||||
let (name_bindings, new_parent) =
|
||||
self.add_child(name, parent, ForbidDuplicateValues,
|
||||
@ -1532,14 +1572,14 @@ impl Resolver {
|
||||
HasTypeParameters(
|
||||
generics, foreign_item.id, 0, NormalRibKind))
|
||||
{
|
||||
visit_foreign_item(foreign_item, (new_parent, visitor));
|
||||
visit::walk_foreign_item(visitor, foreign_item, new_parent);
|
||||
}
|
||||
}
|
||||
foreign_item_static(_, m) => {
|
||||
let def = def_static(local_def(foreign_item.id), m);
|
||||
name_bindings.define_value(Public, def, foreign_item.span);
|
||||
|
||||
visit_foreign_item(foreign_item, (new_parent, visitor));
|
||||
visit::walk_foreign_item(visitor, foreign_item, new_parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1548,7 +1588,7 @@ impl Resolver {
|
||||
block: &Block,
|
||||
(parent, visitor):
|
||||
(ReducedGraphParent,
|
||||
vt<ReducedGraphParent>)) {
|
||||
&mut BuildReducedGraphVisitor)) {
|
||||
let new_parent;
|
||||
if self.block_needs_anonymous_module(block) {
|
||||
let block_id = block.id;
|
||||
@ -1568,7 +1608,7 @@ impl Resolver {
|
||||
new_parent = parent;
|
||||
}
|
||||
|
||||
visit_block(block, (new_parent, visitor));
|
||||
visit::walk_block(visitor, block, new_parent);
|
||||
}
|
||||
|
||||
pub fn handle_external_def(@mut self,
|
||||
@ -3454,24 +3494,11 @@ impl Resolver {
|
||||
pub fn resolve_crate(@mut self) {
|
||||
debug!("(resolving crate) starting");
|
||||
|
||||
visit_crate(self.crate, ((), mk_vt(@Visitor {
|
||||
visit_item: |item, (_context, visitor)|
|
||||
self.resolve_item(item, visitor),
|
||||
visit_arm: |arm, (_context, visitor)|
|
||||
self.resolve_arm(arm, visitor),
|
||||
visit_block: |block, (_context, visitor)|
|
||||
self.resolve_block(block, visitor),
|
||||
visit_expr: |expr, (_context, visitor)|
|
||||
self.resolve_expr(expr, visitor),
|
||||
visit_local: |local, (_context, visitor)|
|
||||
self.resolve_local(local, visitor),
|
||||
visit_ty: |ty, (_context, visitor)|
|
||||
self.resolve_type(ty, visitor),
|
||||
.. *default_visitor()
|
||||
})));
|
||||
let mut visitor = ResolveVisitor{ resolver: self };
|
||||
visit::walk_crate(&mut visitor, self.crate, ());
|
||||
}
|
||||
|
||||
pub fn resolve_item(@mut self, item: @item, visitor: ResolveVisitor) {
|
||||
pub fn resolve_item(@mut self, item: @item, visitor: &mut ResolveVisitor) {
|
||||
debug!("(resolving item) resolving %s",
|
||||
self.session.str_of(item.ident));
|
||||
|
||||
@ -3503,7 +3530,7 @@ impl Resolver {
|
||||
do self.with_type_parameter_rib(
|
||||
HasTypeParameters(
|
||||
generics, item.id, 0, NormalRibKind)) {
|
||||
visit_item(item, ((), visitor));
|
||||
visit::walk_item(visitor, item, ());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3513,7 +3540,7 @@ impl Resolver {
|
||||
NormalRibKind))
|
||||
|| {
|
||||
|
||||
visit_item(item, ((), visitor));
|
||||
visit::walk_item(visitor, item, ());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3613,12 +3640,14 @@ impl Resolver {
|
||||
HasTypeParameters(
|
||||
generics, foreign_item.id, 0,
|
||||
NormalRibKind),
|
||||
|| visit_foreign_item(*foreign_item,
|
||||
((), visitor)));
|
||||
|| visit::walk_foreign_item(visitor,
|
||||
*foreign_item,
|
||||
()));
|
||||
}
|
||||
foreign_item_static(*) => {
|
||||
visit_foreign_item(*foreign_item,
|
||||
((), visitor));
|
||||
visit::walk_foreign_item(visitor,
|
||||
*foreign_item,
|
||||
());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3640,7 +3669,7 @@ impl Resolver {
|
||||
|
||||
item_static(*) => {
|
||||
self.with_constant_rib(|| {
|
||||
visit_item(item, ((), visitor));
|
||||
visit::walk_item(visitor, item, ());
|
||||
});
|
||||
}
|
||||
|
||||
@ -3713,7 +3742,7 @@ impl Resolver {
|
||||
type_parameters: TypeParameters,
|
||||
block: &Block,
|
||||
self_binding: SelfBinding,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
// Create a value rib for the function.
|
||||
let function_value_rib = @Rib(rib_kind);
|
||||
self.value_ribs.push(function_value_rib);
|
||||
@ -3784,7 +3813,7 @@ impl Resolver {
|
||||
|
||||
pub fn resolve_type_parameters(@mut self,
|
||||
type_parameters: &OptVec<TyParam>,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
for type_parameter in type_parameters.iter() {
|
||||
for bound in type_parameter.bounds.iter() {
|
||||
self.resolve_type_parameter_bound(type_parameter.id, bound, visitor);
|
||||
@ -3795,7 +3824,7 @@ impl Resolver {
|
||||
pub fn resolve_type_parameter_bound(@mut self,
|
||||
id: NodeId,
|
||||
type_parameter_bound: &TyParamBound,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
match *type_parameter_bound {
|
||||
TraitTyParamBound(ref tref) => {
|
||||
self.resolve_trait_reference(id, tref, visitor, TraitBoundingTypeParameter)
|
||||
@ -3807,7 +3836,7 @@ impl Resolver {
|
||||
pub fn resolve_trait_reference(@mut self,
|
||||
id: NodeId,
|
||||
trait_reference: &trait_ref,
|
||||
visitor: ResolveVisitor,
|
||||
visitor: &mut ResolveVisitor,
|
||||
reference_type: TraitReferenceType) {
|
||||
match self.resolve_path(id, &trait_reference.path, TypeNS, true, visitor) {
|
||||
None => {
|
||||
@ -3833,7 +3862,7 @@ impl Resolver {
|
||||
id: NodeId,
|
||||
generics: &Generics,
|
||||
fields: &[@struct_field],
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
let mut ident_map = HashMap::new::<ast::ident, @struct_field>();
|
||||
for &field in fields.iter() {
|
||||
match field.node.kind {
|
||||
@ -3876,7 +3905,7 @@ impl Resolver {
|
||||
rib_kind: RibKind,
|
||||
method: @method,
|
||||
outer_type_parameter_count: uint,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
let method_generics = &method.generics;
|
||||
let type_parameters =
|
||||
HasTypeParameters(method_generics,
|
||||
@ -3903,7 +3932,7 @@ impl Resolver {
|
||||
opt_trait_reference: &Option<trait_ref>,
|
||||
self_type: &Ty,
|
||||
methods: &[@method],
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
// If applicable, create a rib for the type parameters.
|
||||
let outer_type_parameter_count = generics.ty_params.len();
|
||||
do self.with_type_parameter_rib(HasTypeParameters
|
||||
@ -3976,16 +4005,16 @@ impl Resolver {
|
||||
|
||||
pub fn resolve_module(@mut self,
|
||||
module_: &_mod,
|
||||
span: span,
|
||||
_span: span,
|
||||
_name: ident,
|
||||
id: NodeId,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
// Write the implementations in scope into the module metadata.
|
||||
debug!("(resolving module) resolving module ID %d", id);
|
||||
visit_mod(module_, span, id, ((), visitor));
|
||||
visit::walk_mod(visitor, module_, ());
|
||||
}
|
||||
|
||||
pub fn resolve_local(@mut self, local: @Local, visitor: ResolveVisitor) {
|
||||
pub fn resolve_local(@mut self, local: @Local, visitor: &mut ResolveVisitor) {
|
||||
let mutability = if local.is_mutbl {Mutable} else {Immutable};
|
||||
|
||||
// Resolve the type.
|
||||
@ -4056,7 +4085,7 @@ impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_arm(@mut self, arm: &arm, visitor: ResolveVisitor) {
|
||||
pub fn resolve_arm(@mut self, arm: &arm, visitor: &mut ResolveVisitor) {
|
||||
self.value_ribs.push(@Rib(NormalRibKind));
|
||||
|
||||
let bindings_list = @mut HashMap::new();
|
||||
@ -4069,13 +4098,13 @@ impl Resolver {
|
||||
// pat_idents are variants
|
||||
self.check_consistent_bindings(arm);
|
||||
|
||||
visit_expr_opt(arm.guard, ((), visitor));
|
||||
visit::walk_expr_opt(visitor, arm.guard, ());
|
||||
self.resolve_block(&arm.body, visitor);
|
||||
|
||||
self.value_ribs.pop();
|
||||
}
|
||||
|
||||
pub fn resolve_block(@mut self, block: &Block, visitor: ResolveVisitor) {
|
||||
pub fn resolve_block(@mut self, block: &Block, visitor: &mut ResolveVisitor) {
|
||||
debug!("(resolving block) entering block");
|
||||
self.value_ribs.push(@Rib(NormalRibKind));
|
||||
|
||||
@ -4091,7 +4120,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
// Descend into the block.
|
||||
visit_block(block, ((), visitor));
|
||||
visit::walk_block(visitor, block, ());
|
||||
|
||||
// Move back up.
|
||||
self.current_module = orig_module;
|
||||
@ -4100,7 +4129,7 @@ impl Resolver {
|
||||
debug!("(resolving block) leaving block");
|
||||
}
|
||||
|
||||
pub fn resolve_type(@mut self, ty: &Ty, visitor: ResolveVisitor) {
|
||||
pub fn resolve_type(@mut self, ty: &Ty, visitor: &mut ResolveVisitor) {
|
||||
match ty.node {
|
||||
// Like path expressions, the interpretation of path types depends
|
||||
// on whether the path has multiple elements in it or not.
|
||||
@ -4178,12 +4207,12 @@ impl Resolver {
|
||||
self.resolve_type_parameter_bound(ty.id, bound, visitor);
|
||||
}
|
||||
};
|
||||
visit_ty(ty, ((), visitor));
|
||||
visit::walk_ty(visitor, ty, ());
|
||||
}
|
||||
|
||||
_ => {
|
||||
// Just resolve embedded types.
|
||||
visit_ty(ty, ((), visitor));
|
||||
visit::walk_ty(visitor, ty, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4195,7 +4224,7 @@ impl Resolver {
|
||||
// Maps idents to the node ID for the (outermost)
|
||||
// pattern that binds them
|
||||
bindings_list: Option<@mut HashMap<ident,NodeId>>,
|
||||
visitor: ResolveVisitor) {
|
||||
visitor: &mut ResolveVisitor) {
|
||||
let pat_id = pattern.id;
|
||||
do walk_pat(pattern) |pattern| {
|
||||
match pattern.node {
|
||||
@ -4477,7 +4506,7 @@ impl Resolver {
|
||||
path: &Path,
|
||||
namespace: Namespace,
|
||||
check_ribs: bool,
|
||||
visitor: ResolveVisitor)
|
||||
visitor: &mut ResolveVisitor)
|
||||
-> Option<def> {
|
||||
// First, resolve the types.
|
||||
for ty in path.types.iter() {
|
||||
@ -4903,7 +4932,7 @@ impl Resolver {
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn resolve_expr(@mut self, expr: @expr, visitor: ResolveVisitor) {
|
||||
pub fn resolve_expr(@mut self, expr: @expr, visitor: &mut ResolveVisitor) {
|
||||
// First, record candidate traits for this expression if it could
|
||||
// result in the invocation of a method call.
|
||||
|
||||
@ -4971,7 +5000,7 @@ impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
visit_expr(expr, ((), visitor));
|
||||
visit::walk_expr(visitor, expr, ());
|
||||
}
|
||||
|
||||
expr_fn_block(ref fn_decl, ref block) => {
|
||||
@ -5005,7 +5034,7 @@ impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
visit_expr(expr, ((), visitor));
|
||||
visit::walk_expr(visitor, expr, ());
|
||||
}
|
||||
|
||||
expr_loop(_, Some(label)) => {
|
||||
@ -5017,7 +5046,7 @@ impl Resolver {
|
||||
rib.bindings.insert(label, def_like);
|
||||
}
|
||||
|
||||
visit_expr(expr, ((), visitor));
|
||||
visit::walk_expr(visitor, expr, ());
|
||||
}
|
||||
}
|
||||
|
||||
@ -5055,7 +5084,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
_ => {
|
||||
visit_expr(expr, ((), visitor));
|
||||
visit::walk_expr(visitor, expr, ());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5293,11 +5322,8 @@ impl Resolver {
|
||||
//
|
||||
|
||||
pub fn check_for_unused_imports(@mut self) {
|
||||
let vt = mk_simple_visitor(@SimpleVisitor {
|
||||
visit_view_item: |vi| self.check_for_item_unused_imports(vi),
|
||||
.. *default_simple_visitor()
|
||||
});
|
||||
visit_crate(self.crate, ((), vt));
|
||||
let mut visitor = UnusedImportCheckVisitor{ resolver: self };
|
||||
visit::walk_crate(&mut visitor, self.crate, ());
|
||||
}
|
||||
|
||||
pub fn check_for_item_unused_imports(&mut self, vi: &view_item) {
|
||||
|
@ -85,7 +85,7 @@ use syntax::codemap::span;
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::{special_idents};
|
||||
use syntax::print::pprust::stmt_to_str;
|
||||
use syntax::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::{ast, ast_util, codemap, ast_map};
|
||||
use syntax::abi::{X86, X86_64, Arm, Mips};
|
||||
|
||||
@ -2646,13 +2646,18 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
|
||||
}
|
||||
}
|
||||
|
||||
struct TransConstantsVisitor { ccx: @mut CrateContext }
|
||||
|
||||
impl visit::Visitor<()> for TransConstantsVisitor {
|
||||
fn visit_item(&mut self, i:@ast::item, _:()) {
|
||||
trans_constant(self.ccx, i);
|
||||
visit::walk_item(self, i, ());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn trans_constants(ccx: @mut CrateContext, crate: &ast::Crate) {
|
||||
oldvisit::visit_crate(
|
||||
crate, ((),
|
||||
oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor {
|
||||
visit_item: |a| trans_constant(ccx, a),
|
||||
..*oldvisit::default_simple_visitor()
|
||||
})));
|
||||
let mut v = TransConstantsVisitor { ccx: ccx };
|
||||
visit::walk_crate(&mut v, crate, ());
|
||||
}
|
||||
|
||||
pub fn vp2i(cx: @mut Block, v: ValueRef) -> ValueRef {
|
||||
|
@ -49,7 +49,8 @@ use middle::trans::type_::Type;
|
||||
use syntax::ast;
|
||||
use syntax::abi::AbiSet;
|
||||
use syntax::ast_map;
|
||||
use syntax::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
// 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
|
||||
@ -556,21 +557,29 @@ pub fn trans_lang_call_with_type_params(bcx: @mut Block,
|
||||
ArgVals(args), Some(dest), DontAutorefArg).bcx;
|
||||
}
|
||||
|
||||
pub fn body_contains_ret(body: &ast::Block) -> bool {
|
||||
let cx = @mut false;
|
||||
oldvisit::visit_block(body, (cx, oldvisit::mk_vt(@oldvisit::Visitor {
|
||||
visit_item: |_i, (_cx, _v)| { },
|
||||
visit_expr: |e: @ast::expr,
|
||||
(cx, v): (@mut bool, oldvisit::vt<@mut bool>)| {
|
||||
|
||||
struct CalleeTranslationVisitor;
|
||||
|
||||
impl Visitor<@mut bool> for CalleeTranslationVisitor {
|
||||
|
||||
fn visit_item(&mut self, _:@ast::item, _:@mut bool) { }
|
||||
|
||||
fn visit_expr(&mut self, e:@ast::expr, cx:@mut bool) {
|
||||
|
||||
if !*cx {
|
||||
match e.node {
|
||||
ast::expr_ret(_) => *cx = true,
|
||||
_ => oldvisit::visit_expr(e, (cx, v)),
|
||||
_ => visit::walk_expr(self, e, cx),
|
||||
}
|
||||
}
|
||||
},
|
||||
..*oldvisit::default_visitor()
|
||||
})));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn body_contains_ret(body: &ast::Block) -> bool {
|
||||
let cx = @mut false;
|
||||
let mut v = CalleeTranslationVisitor;
|
||||
visit::walk_block(&mut v, body, cx);
|
||||
*cx
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,8 @@ use syntax::ast::*;
|
||||
use syntax::ast_map;
|
||||
use syntax::ast_util;
|
||||
use syntax::parse::token;
|
||||
use syntax::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
pub type type_uses = uint; // Bitmask
|
||||
pub static use_repr: uint = 1; /* Dependency on size/alignment/mode and
|
||||
@ -50,7 +51,7 @@ pub static use_repr: uint = 1; /* Dependency on size/alignment/mode and
|
||||
pub static use_tydesc: uint = 2; /* Takes the tydesc, or compares */
|
||||
pub static use_all: uint = use_repr|use_tydesc;
|
||||
|
||||
|
||||
#[deriving(Clone)]
|
||||
pub struct Context {
|
||||
ccx: @mut CrateContext,
|
||||
uses: @mut ~[type_uses]
|
||||
@ -416,28 +417,39 @@ pub fn mark_for_expr(cx: &Context, e: &expr) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_body(cx: &Context, body: &Block) {
|
||||
let v = oldvisit::mk_vt(@oldvisit::Visitor {
|
||||
visit_expr: |e, (cx, v)| {
|
||||
oldvisit::visit_expr(e, (cx, v));
|
||||
struct TypeUseVisitor;
|
||||
|
||||
impl<'self> Visitor<&'self Context> for TypeUseVisitor {
|
||||
|
||||
fn visit_expr<'a>(&mut self, e:@expr, cx: &'a Context) {
|
||||
visit::walk_expr(self, e, cx);
|
||||
mark_for_expr(cx, e);
|
||||
},
|
||||
visit_local: |l, (cx, v)| {
|
||||
oldvisit::visit_local(l, (cx, v));
|
||||
}
|
||||
|
||||
fn visit_local<'a>(&mut self, l:@Local, cx: &'a Context) {
|
||||
visit::walk_local(self, l, cx);
|
||||
node_type_needs(cx, use_repr, l.id);
|
||||
},
|
||||
visit_pat: |p, (cx, v)| {
|
||||
oldvisit::visit_pat(p, (cx, v));
|
||||
}
|
||||
|
||||
fn visit_pat<'a>(&mut self, p:@pat, cx: &'a Context) {
|
||||
visit::walk_pat(self, p, cx);
|
||||
node_type_needs(cx, use_repr, p.id);
|
||||
},
|
||||
visit_block: |b, (cx, v)| {
|
||||
oldvisit::visit_block(b, (cx, v));
|
||||
}
|
||||
|
||||
fn visit_block<'a>(&mut self, b:&Block, cx: &'a Context) {
|
||||
visit::walk_block(self, b, cx);
|
||||
for e in b.expr.iter() {
|
||||
node_type_needs(cx, use_repr, e.id);
|
||||
}
|
||||
},
|
||||
visit_item: |_i, (_cx, _v)| { },
|
||||
..*oldvisit::default_visitor()
|
||||
});
|
||||
(v.visit_block)(body, (cx, v));
|
||||
}
|
||||
|
||||
fn visit_item<'a>(&mut self, _:@item, _: &'a Context) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn handle_body(cx: &Context, body: &Block) {
|
||||
let mut v = TypeUseVisitor;
|
||||
v.visit_block(body, cx);
|
||||
}
|
||||
|
@ -129,7 +129,8 @@ use syntax::opt_vec;
|
||||
use syntax::parse::token;
|
||||
use syntax::parse::token::special_idents;
|
||||
use syntax::print::pprust;
|
||||
use syntax::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax;
|
||||
|
||||
pub mod _match;
|
||||
@ -296,12 +297,18 @@ impl ExprTyProvider for FnCtxt {
|
||||
}
|
||||
}
|
||||
|
||||
struct CheckItemTypesVisitor { ccx: @mut CrateCtxt }
|
||||
|
||||
impl Visitor<()> for CheckItemTypesVisitor {
|
||||
fn visit_item(&mut self, i:@ast::item, _:()) {
|
||||
check_item(self.ccx, i);
|
||||
visit::walk_item(self, i, ());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
|
||||
let visit = oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor {
|
||||
visit_item: |a| check_item(ccx, a),
|
||||
.. *oldvisit::default_simple_visitor()
|
||||
});
|
||||
oldvisit::visit_crate(crate, ((), visit));
|
||||
let mut visit = CheckItemTypesVisitor { ccx: ccx };
|
||||
visit::walk_crate(&mut visit, crate, ());
|
||||
}
|
||||
|
||||
pub fn check_bare_fn(ccx: @mut CrateCtxt,
|
||||
@ -326,6 +333,76 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt,
|
||||
}
|
||||
}
|
||||
|
||||
struct GatherLocalsVisitor {
|
||||
fcx: @mut FnCtxt,
|
||||
tcx: ty::ctxt,
|
||||
}
|
||||
|
||||
impl GatherLocalsVisitor {
|
||||
fn assign(&mut self, nid: ast::NodeId, ty_opt: Option<ty::t>) {
|
||||
match ty_opt {
|
||||
None => {
|
||||
// infer the variable's type
|
||||
let var_id = self.fcx.infcx().next_ty_var_id();
|
||||
let var_ty = ty::mk_var(self.fcx.tcx(), var_id);
|
||||
self.fcx.inh.locals.insert(nid, var_ty);
|
||||
}
|
||||
Some(typ) => {
|
||||
// take type that the user specified
|
||||
self.fcx.inh.locals.insert(nid, typ);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Visitor<()> for GatherLocalsVisitor {
|
||||
// Add explicitly-declared locals.
|
||||
fn visit_local(&mut self, local:@ast::Local, _:()) {
|
||||
let o_ty = match local.ty.node {
|
||||
ast::ty_infer => None,
|
||||
_ => Some(self.fcx.to_ty(&local.ty))
|
||||
};
|
||||
self.assign(local.id, o_ty);
|
||||
debug!("Local variable %s is assigned type %s",
|
||||
self.fcx.pat_to_str(local.pat),
|
||||
self.fcx.infcx().ty_to_str(
|
||||
self.fcx.inh.locals.get_copy(&local.id)));
|
||||
visit::walk_local(self, local, ());
|
||||
|
||||
}
|
||||
// Add pattern bindings.
|
||||
fn visit_pat(&mut self, p:@ast::pat, _:()) {
|
||||
match p.node {
|
||||
ast::pat_ident(_, ref path, _)
|
||||
if pat_util::pat_is_binding(self.fcx.ccx.tcx.def_map, p) => {
|
||||
self.assign(p.id, None);
|
||||
debug!("Pattern binding %s is assigned to %s",
|
||||
self.tcx.sess.str_of(path.idents[0]),
|
||||
self.fcx.infcx().ty_to_str(
|
||||
self.fcx.inh.locals.get_copy(&p.id)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_pat(self, p, ());
|
||||
|
||||
}
|
||||
|
||||
fn visit_block(&mut self, b:&ast::Block, _:()) {
|
||||
// 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 self.fcx.with_region_lb(b.id) {
|
||||
visit::walk_block(self, b, ());
|
||||
}
|
||||
}
|
||||
|
||||
// Don't descend into fns and items
|
||||
fn visit_fn(&mut self, _:&visit::fn_kind, _:&ast::fn_decl,
|
||||
_:&ast::Block, _:span, _:ast::NodeId, _:()) { }
|
||||
fn visit_item(&mut self, _:@ast::item, _:()) { }
|
||||
|
||||
}
|
||||
|
||||
pub fn check_fn(ccx: @mut CrateCtxt,
|
||||
opt_self_info: Option<SelfInfo>,
|
||||
purity: ast::purity,
|
||||
@ -429,24 +506,11 @@ pub fn check_fn(ccx: @mut CrateCtxt,
|
||||
opt_self_info: Option<SelfInfo>) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
let assign: @fn(ast::NodeId, Option<ty::t>) = |nid, ty_opt| {
|
||||
match ty_opt {
|
||||
None => {
|
||||
// infer the variable's type
|
||||
let var_id = fcx.infcx().next_ty_var_id();
|
||||
let var_ty = ty::mk_var(fcx.tcx(), var_id);
|
||||
fcx.inh.locals.insert(nid, var_ty);
|
||||
}
|
||||
Some(typ) => {
|
||||
// take type that the user specified
|
||||
fcx.inh.locals.insert(nid, typ);
|
||||
}
|
||||
}
|
||||
};
|
||||
let mut visit = GatherLocalsVisitor { fcx: fcx, tcx: tcx, };
|
||||
|
||||
// Add the self parameter
|
||||
for self_info in opt_self_info.iter() {
|
||||
assign(self_info.self_id, Some(self_info.self_ty));
|
||||
visit.assign(self_info.self_id, Some(self_info.self_ty));
|
||||
debug!("self is assigned to %s",
|
||||
fcx.infcx().ty_to_str(
|
||||
fcx.inh.locals.get_copy(&self_info.self_id)));
|
||||
@ -457,7 +521,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
|
||||
// Create type variables for each argument.
|
||||
do pat_util::pat_bindings(tcx.def_map, input.pat)
|
||||
|_bm, pat_id, _sp, _path| {
|
||||
assign(pat_id, None);
|
||||
visit.assign(pat_id, None);
|
||||
}
|
||||
|
||||
// Check the pattern.
|
||||
@ -468,66 +532,7 @@ pub fn check_fn(ccx: @mut CrateCtxt,
|
||||
_match::check_pat(&pcx, input.pat, *arg_ty);
|
||||
}
|
||||
|
||||
// Add explicitly-declared locals.
|
||||
let visit_local: @fn(@ast::Local, ((), oldvisit::vt<()>)) =
|
||||
|local, (e, v)| {
|
||||
let o_ty = match local.ty.node {
|
||||
ast::ty_infer => None,
|
||||
_ => Some(fcx.to_ty(&local.ty))
|
||||
};
|
||||
assign(local.id, o_ty);
|
||||
debug!("Local variable %s is assigned type %s",
|
||||
fcx.pat_to_str(local.pat),
|
||||
fcx.infcx().ty_to_str(
|
||||
fcx.inh.locals.get_copy(&local.id)));
|
||||
oldvisit::visit_local(local, (e, v));
|
||||
};
|
||||
|
||||
// Add pattern bindings.
|
||||
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) => {
|
||||
assign(p.id, None);
|
||||
debug!("Pattern binding %s is assigned to %s",
|
||||
tcx.sess.str_of(path.idents[0]),
|
||||
fcx.infcx().ty_to_str(
|
||||
fcx.inh.locals.get_copy(&p.id)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
oldvisit::visit_pat(p, (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) {
|
||||
oldvisit::visit_block(b, (e, v));
|
||||
}
|
||||
};
|
||||
|
||||
// Don't descend into fns and items
|
||||
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): ((), oldvisit::vt<()>)) { }
|
||||
|
||||
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,
|
||||
..*oldvisit::default_visitor()});
|
||||
|
||||
(visit.visit_block)(body, ((), visit));
|
||||
visit.visit_block(body, ());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,8 @@ 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::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
|
||||
pub struct Rcx {
|
||||
fcx: @mut FnCtxt,
|
||||
@ -53,8 +54,6 @@ pub struct Rcx {
|
||||
repeating_scope: ast::NodeId,
|
||||
}
|
||||
|
||||
pub type rvt = oldvisit::vt<@mut Rcx>;
|
||||
|
||||
fn encl_region_of_def(fcx: @mut FnCtxt, def: ast::def) -> ty::Region {
|
||||
let tcx = fcx.tcx();
|
||||
match def {
|
||||
@ -146,8 +145,8 @@ pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) {
|
||||
repeating_scope: e.id };
|
||||
if fcx.err_count_since_creation() == 0 {
|
||||
// regionck assumes typeck succeeded
|
||||
let v = regionck_visitor();
|
||||
(v.visit_expr)(e, (rcx, v));
|
||||
let mut v = regionck_visitor();
|
||||
v.visit_expr(e, rcx);
|
||||
}
|
||||
fcx.infcx().resolve_regions();
|
||||
}
|
||||
@ -157,13 +156,15 @@ pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::Block) {
|
||||
repeating_scope: blk.id };
|
||||
if fcx.err_count_since_creation() == 0 {
|
||||
// regionck assumes typeck succeeded
|
||||
let v = regionck_visitor();
|
||||
(v.visit_block)(blk, (rcx, v));
|
||||
let mut v = regionck_visitor();
|
||||
v.visit_block(blk, rcx);
|
||||
}
|
||||
fcx.infcx().resolve_regions();
|
||||
}
|
||||
|
||||
fn regionck_visitor() -> rvt {
|
||||
struct RegionckVisitor;
|
||||
|
||||
impl Visitor<@mut Rcx> for RegionckVisitor {
|
||||
// (*) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
|
||||
// However, right now we run into an issue whereby some free
|
||||
// regions are not properly related if they appear within the
|
||||
@ -171,41 +172,46 @@ 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.
|
||||
oldvisit::mk_vt(@oldvisit::Visitor {
|
||||
visit_item: visit_item,
|
||||
visit_expr: visit_expr,
|
||||
|
||||
fn visit_item(&mut self, i:@ast::item, e:@mut Rcx) { visit_item(self, i, e); }
|
||||
|
||||
fn visit_expr(&mut self, ex:@ast::expr, e:@mut Rcx) { visit_expr(self, ex, e); }
|
||||
|
||||
//visit_pat: visit_pat, // (*) see above
|
||||
visit_arm: visit_arm,
|
||||
visit_local: visit_local,
|
||||
|
||||
visit_block: visit_block,
|
||||
.. *oldvisit::default_visitor()
|
||||
})
|
||||
fn visit_arm(&mut self, a:&ast::arm, e:@mut Rcx) { visit_arm(self, a, e); }
|
||||
|
||||
fn visit_local(&mut self, l:@ast::Local, e:@mut Rcx) { visit_local(self, l, e); }
|
||||
|
||||
fn visit_block(&mut self, b:&ast::Block, e:@mut Rcx) { visit_block(self, b, e); }
|
||||
}
|
||||
|
||||
fn visit_item(_item: @ast::item, (_rcx, _v): (@mut Rcx, rvt)) {
|
||||
fn regionck_visitor() -> RegionckVisitor {
|
||||
RegionckVisitor
|
||||
}
|
||||
|
||||
fn visit_item(_v: &mut RegionckVisitor, _item: @ast::item, _rcx: @mut Rcx) {
|
||||
// Ignore items
|
||||
}
|
||||
|
||||
fn visit_block(b: &ast::Block, (rcx, v): (@mut Rcx, rvt)) {
|
||||
fn visit_block(v: &mut RegionckVisitor, b: &ast::Block, rcx: @mut Rcx) {
|
||||
rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id);
|
||||
oldvisit::visit_block(b, (rcx, v));
|
||||
visit::walk_block(v, b, rcx);
|
||||
}
|
||||
|
||||
fn visit_arm(arm: &ast::arm, (rcx, v): (@mut Rcx, rvt)) {
|
||||
fn visit_arm(v: &mut RegionckVisitor, arm: &ast::arm, rcx: @mut Rcx) {
|
||||
// see above
|
||||
for &p in arm.pats.iter() {
|
||||
constrain_bindings_in_pat(p, rcx);
|
||||
}
|
||||
|
||||
oldvisit::visit_arm(arm, (rcx, v));
|
||||
visit::walk_arm(v, arm, rcx);
|
||||
}
|
||||
|
||||
fn visit_local(l: @ast::Local, (rcx, v): (@mut Rcx, rvt)) {
|
||||
fn visit_local(v: &mut RegionckVisitor, l: @ast::Local, rcx: @mut Rcx) {
|
||||
// see above
|
||||
constrain_bindings_in_pat(l.pat, rcx);
|
||||
oldvisit::visit_local(l, (rcx, v));
|
||||
visit::walk_local(v, l, rcx);
|
||||
}
|
||||
|
||||
fn constrain_bindings_in_pat(pat: @ast::pat, rcx: @mut Rcx) {
|
||||
@ -242,7 +248,7 @@ fn constrain_bindings_in_pat(pat: @ast::pat, rcx: @mut Rcx) {
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
|
||||
fn visit_expr(v: &mut RegionckVisitor, expr: @ast::expr, rcx: @mut Rcx) {
|
||||
debug!("regionck::visit_expr(e=%s, repeating_scope=%?)",
|
||||
expr.repr(rcx.fcx.tcx()), rcx.repeating_scope);
|
||||
|
||||
@ -330,13 +336,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);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_method_call(callee_id, arg0, _, _, ref args, _) => {
|
||||
constrain_call(rcx, callee_id, expr, Some(arg0), *args, false);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v,expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_index(callee_id, lhs, rhs) |
|
||||
@ -348,14 +354,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);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_unary(callee_id, _, lhs) if has_method_map => {
|
||||
// As above.
|
||||
constrain_call(rcx, callee_id, expr, Some(lhs), [], true);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_unary(_, ast::deref, base) => {
|
||||
@ -363,7 +369,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);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_index(_, vec_expr, _) => {
|
||||
@ -371,7 +377,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);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_cast(source, _) => {
|
||||
@ -401,7 +407,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) {
|
||||
_ => ()
|
||||
}
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_addr_of(_, base) => {
|
||||
@ -417,13 +423,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);
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_match(discr, ref arms) => {
|
||||
guarantor::for_match(rcx, discr, *arms);
|
||||
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
|
||||
ast::expr_fn_block(*) => {
|
||||
@ -432,29 +438,29 @@ 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);
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
}
|
||||
|
||||
ast::expr_while(cond, ref body) => {
|
||||
let repeating_scope = rcx.set_repeating_scope(cond.id);
|
||||
(v.visit_expr)(cond, (rcx, v));
|
||||
v.visit_expr(cond, rcx);
|
||||
|
||||
rcx.set_repeating_scope(body.id);
|
||||
(v.visit_block)(body, (rcx, v));
|
||||
v.visit_block(body, rcx);
|
||||
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
}
|
||||
|
||||
_ => {
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn check_expr_fn_block(rcx: @mut Rcx,
|
||||
expr: @ast::expr,
|
||||
v: rvt) {
|
||||
v: &mut RegionckVisitor) {
|
||||
let tcx = rcx.fcx.tcx();
|
||||
match expr.node {
|
||||
ast::expr_fn_block(_, ref body) => {
|
||||
@ -483,7 +489,7 @@ fn check_expr_fn_block(rcx: @mut Rcx,
|
||||
}
|
||||
|
||||
let repeating_scope = rcx.set_repeating_scope(body.id);
|
||||
oldvisit::visit_expr(expr, (rcx, v));
|
||||
visit::walk_expr(v, expr, rcx);
|
||||
rcx.set_repeating_scope(repeating_scope);
|
||||
}
|
||||
|
||||
|
@ -56,11 +56,26 @@ 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::oldvisit;
|
||||
use syntax::visit;
|
||||
use syntax::opt_vec::OptVec;
|
||||
use syntax::opt_vec;
|
||||
use syntax::parse::token::special_idents;
|
||||
|
||||
struct CollectItemTypesVisitor {
|
||||
ccx: @mut CrateCtxt
|
||||
}
|
||||
|
||||
impl visit::Visitor<()> for CollectItemTypesVisitor {
|
||||
fn visit_item(&mut self, i:@ast::item, _:()) {
|
||||
convert(self.ccx, i);
|
||||
visit::walk_item(self, i, ());
|
||||
}
|
||||
fn visit_foreign_item(&mut self, i:@ast::foreign_item, _:()) {
|
||||
convert_foreign(self.ccx, i);
|
||||
visit::walk_foreign_item(self, i, ());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
|
||||
fn collect_intrinsic_type(ccx: &CrateCtxt,
|
||||
lang_item: ast::def_id) {
|
||||
@ -76,13 +91,8 @@ pub fn collect_item_types(ccx: @mut CrateCtxt, crate: &ast::Crate) {
|
||||
Some(id) => { collect_intrinsic_type(ccx, id); } None => {}
|
||||
}
|
||||
|
||||
oldvisit::visit_crate(
|
||||
crate, ((),
|
||||
oldvisit::mk_simple_visitor(@oldvisit::SimpleVisitor {
|
||||
visit_item: |a| convert(ccx, a),
|
||||
visit_foreign_item: |a|convert_foreign(ccx, a),
|
||||
.. *oldvisit::default_simple_visitor()
|
||||
})));
|
||||
let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
|
||||
visit::walk_crate(&mut visitor, crate, ());
|
||||
}
|
||||
|
||||
pub trait ToTy {
|
||||
|
Loading…
x
Reference in New Issue
Block a user