1
Fork 0

Remove largely unused context from Visitor.

This commit is contained in:
Eduard Burtescu 2014-09-12 13:10:30 +03:00
parent 22e749ded1
commit a09dbf28e6
48 changed files with 1449 additions and 1504 deletions

View file

@ -143,15 +143,15 @@ impl<'a> Context<'a> {
} }
} }
impl<'a> Visitor<()> for Context<'a> { impl<'a> Visitor for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) { fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
if !token::get_ident(id).get().is_ascii() { if !token::get_ident(id).get().is_ascii() {
self.gate_feature("non_ascii_idents", sp, self.gate_feature("non_ascii_idents", sp,
"non-ascii idents are not fully supported."); "non-ascii idents are not fully supported.");
} }
} }
fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.node { match i.node {
ast::ViewItemUse(ref path) => { ast::ViewItemUse(ref path) => {
match path.node { match path.node {
@ -173,10 +173,10 @@ impl<'a> Visitor<()> for Context<'a> {
} }
} }
} }
visit::walk_view_item(self, i, ()) visit::walk_view_item(self, i)
} }
fn visit_item(&mut self, i: &ast::Item, _:()) { fn visit_item(&mut self, i: &ast::Item) {
for attr in i.attrs.iter() { for attr in i.attrs.iter() {
if attr.name().equiv(&("thread_local")) { if attr.name().equiv(&("thread_local")) {
self.gate_feature("thread_local", i.span, self.gate_feature("thread_local", i.span,
@ -252,10 +252,10 @@ impl<'a> Visitor<()> for Context<'a> {
_ => {} _ => {}
} }
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
fn visit_mac(&mut self, macro: &ast::Mac, _: ()) { fn visit_mac(&mut self, macro: &ast::Mac) {
let ast::MacInvocTT(ref path, _, _) = macro.node; let ast::MacInvocTT(ref path, _, _) = macro.node;
let id = path.segments.last().unwrap().identifier; let id = path.segments.last().unwrap().identifier;
let quotes = ["quote_tokens", "quote_expr", "quote_ty", let quotes = ["quote_tokens", "quote_expr", "quote_ty",
@ -299,16 +299,16 @@ impl<'a> Visitor<()> for Context<'a> {
} }
} }
fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
if attr::contains_name(i.attrs.as_slice(), "linkage") { if attr::contains_name(i.attrs.as_slice(), "linkage") {
self.gate_feature("linkage", i.span, self.gate_feature("linkage", i.span,
"the `linkage` attribute is experimental \ "the `linkage` attribute is experimental \
and not portable across platforms") and not portable across platforms")
} }
visit::walk_foreign_item(self, i, ()) visit::walk_foreign_item(self, i)
} }
fn visit_ty(&mut self, t: &ast::Ty, _: ()) { fn visit_ty(&mut self, t: &ast::Ty) {
match t.node { match t.node {
ast::TyClosure(closure) if closure.onceness == ast::Once => { ast::TyClosure(closure) if closure.onceness == ast::Once => {
self.gate_feature("once_fns", t.span, self.gate_feature("once_fns", t.span,
@ -325,10 +325,10 @@ impl<'a> Visitor<()> for Context<'a> {
_ => {} _ => {}
} }
visit::walk_ty(self, t, ()); visit::walk_ty(self, t);
} }
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr) {
match e.node { match e.node {
ast::ExprUnary(ast::UnBox, _) => { ast::ExprUnary(ast::UnBox, _) => {
self.gate_box(e.span); self.gate_box(e.span);
@ -346,10 +346,10 @@ impl<'a> Visitor<()> for Context<'a> {
} }
_ => {} _ => {}
} }
visit::walk_expr(self, e, ()); visit::walk_expr(self, e);
} }
fn visit_generics(&mut self, generics: &ast::Generics, _: ()) { fn visit_generics(&mut self, generics: &ast::Generics) {
for type_parameter in generics.ty_params.iter() { for type_parameter in generics.ty_params.iter() {
match type_parameter.default { match type_parameter.default {
Some(ty) => { Some(ty) => {
@ -360,10 +360,10 @@ impl<'a> Visitor<()> for Context<'a> {
None => {} None => {}
} }
} }
visit::walk_generics(self, generics, ()); visit::walk_generics(self, generics);
} }
fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) { fn visit_attribute(&mut self, attr: &ast::Attribute) {
if attr::contains_name([*attr], "lang") { if attr::contains_name([*attr], "lang") {
self.gate_feature("lang_items", self.gate_feature("lang_items",
attr.span, attr.span,
@ -371,7 +371,7 @@ impl<'a> Visitor<()> for Context<'a> {
} }
} }
fn visit_pat(&mut self, pattern: &ast::Pat, (): ()) { fn visit_pat(&mut self, pattern: &ast::Pat) {
match pattern.node { match pattern.node {
ast::PatVec(_, Some(_), ref last) if !last.is_empty() => { ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
self.gate_feature("advanced_slice_patterns", self.gate_feature("advanced_slice_patterns",
@ -382,7 +382,7 @@ impl<'a> Visitor<()> for Context<'a> {
} }
_ => {} _ => {}
} }
visit::walk_pat(self, pattern, ()) visit::walk_pat(self, pattern)
} }
fn visit_fn(&mut self, fn visit_fn(&mut self,
@ -390,8 +390,7 @@ impl<'a> Visitor<()> for Context<'a> {
fn_decl: &ast::FnDecl, fn_decl: &ast::FnDecl,
block: &ast::Block, block: &ast::Block,
span: Span, span: Span,
_: NodeId, _: NodeId) {
(): ()) {
match *fn_kind { match *fn_kind {
visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => { visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
self.gate_feature("intrinsics", self.gate_feature("intrinsics",
@ -400,7 +399,7 @@ impl<'a> Visitor<()> for Context<'a> {
} }
_ => {} _ => {}
} }
visit::walk_fn(self, fn_kind, fn_decl, block, span, ()); visit::walk_fn(self, fn_kind, fn_decl, block, span);
} }
} }
@ -453,7 +452,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
} }
} }
visit::walk_crate(&mut cx, krate, ()); visit::walk_crate(&mut cx, krate);
sess.abort_if_errors(); sess.abort_if_errors();

View file

@ -23,18 +23,18 @@ struct ShowSpanVisitor<'a> {
sess: &'a Session sess: &'a Session
} }
impl<'a> Visitor<()> for ShowSpanVisitor<'a> { impl<'a> Visitor for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr) {
self.sess.span_note(e.span, "expression"); self.sess.span_note(e.span, "expression");
visit::walk_expr(self, e, ()); visit::walk_expr(self, e);
} }
fn visit_mac(&mut self, macro: &ast::Mac, e: ()) { fn visit_mac(&mut self, macro: &ast::Mac) {
visit::walk_mac(self, macro, e); visit::walk_mac(self, macro);
} }
} }
pub fn run(sess: &Session, krate: &ast::Crate) { pub fn run(sess: &Session, krate: &ast::Crate) {
let mut v = ShowSpanVisitor { sess: sess }; let mut v = ShowSpanVisitor { sess: sess };
visit::walk_crate(&mut v, krate, ()); visit::walk_crate(&mut v, krate);
} }

View file

@ -366,13 +366,13 @@ impl<'a, 'tcx> CTypesVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for CTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for CTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) { fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node { match ty.node {
ast::TyPath(_, _, id) => self.check_def(ty.span, ty.id, id), ast::TyPath(_, _, id) => self.check_def(ty.span, ty.id, id),
_ => (), _ => (),
} }
visit::walk_ty(self, ty, ()); visit::walk_ty(self, ty);
} }
} }
@ -386,7 +386,7 @@ impl LintPass for CTypes {
fn check_item(&mut self, cx: &Context, it: &ast::Item) { fn check_item(&mut self, cx: &Context, it: &ast::Item) {
fn check_ty(cx: &Context, ty: &ast::Ty) { fn check_ty(cx: &Context, ty: &ast::Ty) {
let mut vis = CTypesVisitor { cx: cx }; let mut vis = CTypesVisitor { cx: cx };
vis.visit_ty(ty, ()); vis.visit_ty(ty);
} }
fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) { fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
@ -500,18 +500,18 @@ struct RawPtrDerivingVisitor<'a, 'tcx: 'a> {
cx: &'a Context<'a, 'tcx> cx: &'a Context<'a, 'tcx>
} }
impl<'a, 'tcx> Visitor<()> for RawPtrDerivingVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for RawPtrDerivingVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) { fn visit_ty(&mut self, ty: &ast::Ty) {
static MSG: &'static str = "use of `#[deriving]` with a raw pointer"; static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
match ty.node { match ty.node {
ast::TyPtr(..) => self.cx.span_lint(RAW_POINTER_DERIVING, ty.span, MSG), ast::TyPtr(..) => self.cx.span_lint(RAW_POINTER_DERIVING, ty.span, MSG),
_ => {} _ => {}
} }
visit::walk_ty(self, ty, ()); visit::walk_ty(self, ty);
} }
// explicit override to a no-op to reduce code bloat // explicit override to a no-op to reduce code bloat
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {} fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_block(&mut self, _: &ast::Block, _: ()) {} fn visit_block(&mut self, _: &ast::Block) {}
} }
pub struct RawPointerDeriving { pub struct RawPointerDeriving {
@ -554,7 +554,7 @@ impl LintPass for RawPointerDeriving {
match item.node { match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => { ast::ItemStruct(..) | ast::ItemEnum(..) => {
let mut visitor = RawPtrDerivingVisitor { cx: cx }; let mut visitor = RawPtrDerivingVisitor { cx: cx };
visit::walk_item(&mut visitor, &*item, ()); visit::walk_item(&mut visitor, &*item);
} }
_ => {} _ => {}
} }

View file

@ -492,68 +492,68 @@ impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
} }
} }
impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> { impl<'a, 'tcx> Visitor for Context<'a, 'tcx> {
fn visit_item(&mut self, it: &ast::Item, _: ()) { fn visit_item(&mut self, it: &ast::Item) {
self.with_lint_attrs(it.attrs.as_slice(), |cx| { self.with_lint_attrs(it.attrs.as_slice(), |cx| {
run_lints!(cx, check_item, it); run_lints!(cx, check_item, it);
cx.visit_ids(|v| v.visit_item(it, ())); cx.visit_ids(|v| v.visit_item(it));
visit::walk_item(cx, it, ()); visit::walk_item(cx, it);
}) })
} }
fn visit_foreign_item(&mut self, it: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, it: &ast::ForeignItem) {
self.with_lint_attrs(it.attrs.as_slice(), |cx| { self.with_lint_attrs(it.attrs.as_slice(), |cx| {
run_lints!(cx, check_foreign_item, it); run_lints!(cx, check_foreign_item, it);
visit::walk_foreign_item(cx, it, ()); visit::walk_foreign_item(cx, it);
}) })
} }
fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, i: &ast::ViewItem) {
self.with_lint_attrs(i.attrs.as_slice(), |cx| { self.with_lint_attrs(i.attrs.as_slice(), |cx| {
run_lints!(cx, check_view_item, i); run_lints!(cx, check_view_item, i);
cx.visit_ids(|v| v.visit_view_item(i, ())); cx.visit_ids(|v| v.visit_view_item(i));
visit::walk_view_item(cx, i, ()); visit::walk_view_item(cx, i);
}) })
} }
fn visit_pat(&mut self, p: &ast::Pat, _: ()) { fn visit_pat(&mut self, p: &ast::Pat) {
run_lints!(self, check_pat, p); run_lints!(self, check_pat, p);
visit::walk_pat(self, p, ()); visit::walk_pat(self, p);
} }
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr) {
run_lints!(self, check_expr, e); run_lints!(self, check_expr, e);
visit::walk_expr(self, e, ()); visit::walk_expr(self, e);
} }
fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) { fn visit_stmt(&mut self, s: &ast::Stmt) {
run_lints!(self, check_stmt, s); run_lints!(self, check_stmt, s);
visit::walk_stmt(self, s, ()); visit::walk_stmt(self, s);
} }
fn visit_fn(&mut self, fk: &FnKind, decl: &ast::FnDecl, fn visit_fn(&mut self, fk: &FnKind, decl: &ast::FnDecl,
body: &ast::Block, span: Span, id: ast::NodeId, _: ()) { body: &ast::Block, span: Span, id: ast::NodeId) {
match *fk { match *fk {
visit::FkMethod(_, _, m) => { visit::FkMethod(_, _, m) => {
self.with_lint_attrs(m.attrs.as_slice(), |cx| { self.with_lint_attrs(m.attrs.as_slice(), |cx| {
run_lints!(cx, check_fn, fk, decl, body, span, id); run_lints!(cx, check_fn, fk, decl, body, span, id);
cx.visit_ids(|v| { cx.visit_ids(|v| {
v.visit_fn(fk, decl, body, span, id, ()); v.visit_fn(fk, decl, body, span, id);
}); });
visit::walk_fn(cx, fk, decl, body, span, ()); visit::walk_fn(cx, fk, decl, body, span);
}) })
}, },
_ => { _ => {
run_lints!(self, check_fn, fk, decl, body, span, id); run_lints!(self, check_fn, fk, decl, body, span, id);
visit::walk_fn(self, fk, decl, body, span, ()); visit::walk_fn(self, fk, decl, body, span);
} }
} }
} }
fn visit_ty_method(&mut self, t: &ast::TypeMethod, _: ()) { fn visit_ty_method(&mut self, t: &ast::TypeMethod) {
self.with_lint_attrs(t.attrs.as_slice(), |cx| { self.with_lint_attrs(t.attrs.as_slice(), |cx| {
run_lints!(cx, check_ty_method, t); run_lints!(cx, check_ty_method, t);
visit::walk_ty_method(cx, t, ()); visit::walk_ty_method(cx, t);
}) })
} }
@ -561,103 +561,102 @@ impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
s: &ast::StructDef, s: &ast::StructDef,
ident: ast::Ident, ident: ast::Ident,
g: &ast::Generics, g: &ast::Generics,
id: ast::NodeId, id: ast::NodeId) {
_: ()) {
run_lints!(self, check_struct_def, s, ident, g, id); run_lints!(self, check_struct_def, s, ident, g, id);
visit::walk_struct_def(self, s, ()); visit::walk_struct_def(self, s);
run_lints!(self, check_struct_def_post, s, ident, g, id); run_lints!(self, check_struct_def_post, s, ident, g, id);
} }
fn visit_struct_field(&mut self, s: &ast::StructField, _: ()) { fn visit_struct_field(&mut self, s: &ast::StructField) {
self.with_lint_attrs(s.node.attrs.as_slice(), |cx| { self.with_lint_attrs(s.node.attrs.as_slice(), |cx| {
run_lints!(cx, check_struct_field, s); run_lints!(cx, check_struct_field, s);
visit::walk_struct_field(cx, s, ()); visit::walk_struct_field(cx, s);
}) })
} }
fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics, _: ()) { fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
self.with_lint_attrs(v.node.attrs.as_slice(), |cx| { self.with_lint_attrs(v.node.attrs.as_slice(), |cx| {
run_lints!(cx, check_variant, v, g); run_lints!(cx, check_variant, v, g);
visit::walk_variant(cx, v, g, ()); visit::walk_variant(cx, v, g);
}) })
} }
// FIXME(#10894) should continue recursing // FIXME(#10894) should continue recursing
fn visit_ty(&mut self, t: &ast::Ty, _: ()) { fn visit_ty(&mut self, t: &ast::Ty) {
run_lints!(self, check_ty, t); run_lints!(self, check_ty, t);
} }
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) { fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
run_lints!(self, check_ident, sp, id); run_lints!(self, check_ident, sp, id);
} }
fn visit_mod(&mut self, m: &ast::Mod, s: Span, n: ast::NodeId, _: ()) { fn visit_mod(&mut self, m: &ast::Mod, s: Span, n: ast::NodeId) {
run_lints!(self, check_mod, m, s, n); run_lints!(self, check_mod, m, s, n);
visit::walk_mod(self, m, ()); visit::walk_mod(self, m);
} }
fn visit_local(&mut self, l: &ast::Local, _: ()) { fn visit_local(&mut self, l: &ast::Local) {
run_lints!(self, check_local, l); run_lints!(self, check_local, l);
visit::walk_local(self, l, ()); visit::walk_local(self, l);
} }
fn visit_block(&mut self, b: &ast::Block, _: ()) { fn visit_block(&mut self, b: &ast::Block) {
run_lints!(self, check_block, b); run_lints!(self, check_block, b);
visit::walk_block(self, b, ()); visit::walk_block(self, b);
} }
fn visit_arm(&mut self, a: &ast::Arm, _: ()) { fn visit_arm(&mut self, a: &ast::Arm) {
run_lints!(self, check_arm, a); run_lints!(self, check_arm, a);
visit::walk_arm(self, a, ()); visit::walk_arm(self, a);
} }
fn visit_decl(&mut self, d: &ast::Decl, _: ()) { fn visit_decl(&mut self, d: &ast::Decl) {
run_lints!(self, check_decl, d); run_lints!(self, check_decl, d);
visit::walk_decl(self, d, ()); visit::walk_decl(self, d);
} }
fn visit_expr_post(&mut self, e: &ast::Expr, _: ()) { fn visit_expr_post(&mut self, e: &ast::Expr) {
run_lints!(self, check_expr_post, e); run_lints!(self, check_expr_post, e);
} }
fn visit_generics(&mut self, g: &ast::Generics, _: ()) { fn visit_generics(&mut self, g: &ast::Generics) {
run_lints!(self, check_generics, g); run_lints!(self, check_generics, g);
visit::walk_generics(self, g, ()); visit::walk_generics(self, g);
} }
fn visit_trait_item(&mut self, m: &ast::TraitItem, _: ()) { fn visit_trait_item(&mut self, m: &ast::TraitItem) {
run_lints!(self, check_trait_method, m); run_lints!(self, check_trait_method, m);
visit::walk_trait_item(self, m, ()); visit::walk_trait_item(self, m);
} }
fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>, _: ()) { fn visit_opt_lifetime_ref(&mut self, sp: Span, lt: &Option<ast::Lifetime>) {
run_lints!(self, check_opt_lifetime_ref, sp, lt); run_lints!(self, check_opt_lifetime_ref, sp, lt);
} }
fn visit_lifetime_ref(&mut self, lt: &ast::Lifetime, _: ()) { fn visit_lifetime_ref(&mut self, lt: &ast::Lifetime) {
run_lints!(self, check_lifetime_ref, lt); run_lints!(self, check_lifetime_ref, lt);
} }
fn visit_lifetime_decl(&mut self, lt: &ast::LifetimeDef, _: ()) { fn visit_lifetime_decl(&mut self, lt: &ast::LifetimeDef) {
run_lints!(self, check_lifetime_decl, lt); run_lints!(self, check_lifetime_decl, lt);
} }
fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf, _: ()) { fn visit_explicit_self(&mut self, es: &ast::ExplicitSelf) {
run_lints!(self, check_explicit_self, es); run_lints!(self, check_explicit_self, es);
visit::walk_explicit_self(self, es, ()); visit::walk_explicit_self(self, es);
} }
fn visit_mac(&mut self, mac: &ast::Mac, _: ()) { fn visit_mac(&mut self, mac: &ast::Mac) {
run_lints!(self, check_mac, mac); run_lints!(self, check_mac, mac);
visit::walk_mac(self, mac, ()); visit::walk_mac(self, mac);
} }
fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId, _: ()) { fn visit_path(&mut self, p: &ast::Path, id: ast::NodeId) {
run_lints!(self, check_path, p, id); run_lints!(self, check_path, p, id);
visit::walk_path(self, p, ()); visit::walk_path(self, p);
} }
fn visit_attribute(&mut self, attr: &ast::Attribute, _: ()) { fn visit_attribute(&mut self, attr: &ast::Attribute) {
run_lints!(self, check_attribute, attr); run_lints!(self, check_attribute, attr);
} }
} }
@ -719,14 +718,14 @@ pub fn check_crate(tcx: &ty::ctxt,
cx.visit_id(ast::CRATE_NODE_ID); cx.visit_id(ast::CRATE_NODE_ID);
cx.visit_ids(|v| { cx.visit_ids(|v| {
v.visited_outermost = true; v.visited_outermost = true;
visit::walk_crate(v, krate, ()); visit::walk_crate(v, krate);
}); });
// since the root module isn't visited as an item (because it isn't an // since the root module isn't visited as an item (because it isn't an
// item), warn for it here. // item), warn for it here.
run_lints!(cx, check_crate, krate); run_lints!(cx, check_crate, krate);
visit::walk_crate(cx, krate, ()); visit::walk_crate(cx, krate);
}); });
// If we missed any lints added to the session, then there's a bug somewhere // If we missed any lints added to the session, then there's a bug somewhere

View file

@ -49,19 +49,19 @@ pub fn read_crates(sess: &Session,
next_crate_num: sess.cstore.next_crate_num(), next_crate_num: sess.cstore.next_crate_num(),
}; };
visit_crate(&e, krate); visit_crate(&e, krate);
visit::walk_crate(&mut e, krate, ()); visit::walk_crate(&mut e, krate);
dump_crates(&sess.cstore); dump_crates(&sess.cstore);
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore) warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
} }
impl<'a> visit::Visitor<()> for Env<'a> { impl<'a> visit::Visitor for Env<'a> {
fn visit_view_item(&mut self, a: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, a: &ast::ViewItem) {
visit_view_item(self, a); visit_view_item(self, a);
visit::walk_view_item(self, a, ()); visit::walk_view_item(self, a);
} }
fn visit_item(&mut self, a: &ast::Item, _: ()) { fn visit_item(&mut self, a: &ast::Item) {
visit_item(self, a); visit_item(self, a);
visit::walk_item(self, a, ()); visit::walk_item(self, a);
} }
} }

View file

@ -1473,20 +1473,20 @@ struct EncodeVisitor<'a,'b:'a> {
index: &'a mut Vec<entry<i64>>, index: &'a mut Vec<entry<i64>>,
} }
impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> { impl<'a,'b> visit::Visitor for EncodeVisitor<'a,'b> {
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr) {
visit::walk_expr(self, ex, ()); visit::walk_expr(self, ex);
my_visit_expr(ex); my_visit_expr(ex);
} }
fn visit_item(&mut self, i: &Item, _: ()) { fn visit_item(&mut self, i: &Item) {
visit::walk_item(self, i, ()); visit::walk_item(self, i);
my_visit_item(i, my_visit_item(i,
self.rbml_w_for_visit_item, self.rbml_w_for_visit_item,
self.ecx_ptr, self.ecx_ptr,
self.index); self.index);
} }
fn visit_foreign_item(&mut self, ni: &ForeignItem, _: ()) { fn visit_foreign_item(&mut self, ni: &ForeignItem) {
visit::walk_foreign_item(self, ni, ()); visit::walk_foreign_item(self, ni);
my_visit_foreign_item(ni, my_visit_foreign_item(ni,
self.rbml_w_for_visit_item, self.rbml_w_for_visit_item,
self.ecx_ptr, self.ecx_ptr,
@ -1519,7 +1519,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
index: &mut index, index: &mut index,
ecx_ptr: ecx_ptr, ecx_ptr: ecx_ptr,
rbml_w_for_visit_item: &mut *rbml_w, rbml_w_for_visit_item: &mut *rbml_w,
}, krate, ()); }, krate);
rbml_w.end_tag(); rbml_w.end_tag();
index index
@ -1775,8 +1775,8 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &Crate) {
rbml_w: &'a mut Encoder<'b>, rbml_w: &'a mut Encoder<'b>,
} }
impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> { impl<'a, 'b> Visitor for StructFieldVisitor<'a, 'b> {
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) { fn visit_struct_field(&mut self, field: &ast::StructField) {
self.rbml_w.start_tag(tag_struct_field); self.rbml_w.start_tag(tag_struct_field);
self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id); self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
encode_attributes(self.rbml_w, field.node.attrs.as_slice()); encode_attributes(self.rbml_w, field.node.attrs.as_slice());
@ -1787,7 +1787,7 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &Crate) {
rbml_w.start_tag(tag_struct_fields); rbml_w.start_tag(tag_struct_fields);
visit::walk_crate(&mut StructFieldVisitor { visit::walk_crate(&mut StructFieldVisitor {
rbml_w: rbml_w rbml_w: rbml_w
}, krate, ()); }, krate);
rbml_w.end_tag(); rbml_w.end_tag();
} }
@ -1798,8 +1798,8 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
rbml_w: &'a mut Encoder<'c>, rbml_w: &'a mut Encoder<'c>,
} }
impl<'a, 'b, 'c, 'tcx> Visitor<()> for ImplVisitor<'a, 'b, 'c, 'tcx> { impl<'a, 'b, 'c, 'tcx> Visitor for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) { fn visit_item(&mut self, item: &Item) {
match item.node { match item.node {
ItemImpl(_, Some(ref trait_ref), _, _) => { ItemImpl(_, Some(ref trait_ref), _, _) => {
let def_map = &self.ecx.tcx.def_map; let def_map = &self.ecx.tcx.def_map;
@ -1817,7 +1817,7 @@ impl<'a, 'b, 'c, 'tcx> Visitor<()> for ImplVisitor<'a, 'b, 'c, 'tcx> {
} }
_ => {} _ => {}
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
@ -1841,7 +1841,7 @@ fn encode_impls<'a>(ecx: &'a EncodeContext,
ecx: ecx, ecx: ecx,
rbml_w: rbml_w, rbml_w: rbml_w,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }
rbml_w.end_tag(); rbml_w.end_tag();

View file

@ -26,7 +26,7 @@ use util::ppaux::{Repr};
use syntax::ast; use syntax::ast;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::visit; use syntax::visit;
use syntax::visit::{Visitor}; use syntax::visit::Visitor;
use syntax::ast::{Expr, FnDecl, Block, NodeId, Pat}; use syntax::ast::{Expr, FnDecl, Block, NodeId, Pat};
mod lifetime; mod lifetime;
@ -471,8 +471,8 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx> bccx: &'a BorrowckCtxt<'a, 'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for StaticInitializerCtxt<'a, 'tcx> { impl<'a, 'tcx> Visitor for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr) {
match ex.node { match ex.node {
ast::ExprAddrOf(mutbl, ref base) => { ast::ExprAddrOf(mutbl, ref base) => {
let base_cmt = self.bccx.cat_expr(&**base); let base_cmt = self.bccx.cat_expr(&**base);
@ -486,7 +486,7 @@ impl<'a, 'tcx> visit::Visitor<()> for StaticInitializerCtxt<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, ex, ()); visit::walk_expr(self, ex);
} }
} }
@ -498,5 +498,5 @@ pub fn gather_loans_in_static_initializer(bccx: &mut BorrowckCtxt, expr: &ast::E
bccx: bccx bccx: bccx
}; };
sicx.visit_expr(expr, ()); sicx.visit_expr(expr);
} }

View file

@ -60,13 +60,13 @@ pub struct LoanDataFlowOperator;
pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>; pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
impl<'a, 'tcx> Visitor<()> for BorrowckCtxt<'a, 'tcx> { impl<'a, 'tcx> Visitor for BorrowckCtxt<'a, 'tcx> {
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, _: ()) { b: &Block, s: Span, n: NodeId) {
borrowck_fn(self, fk, fd, b, s, n); borrowck_fn(self, fk, fd, b, s, n);
} }
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
borrowck_item(self, item); borrowck_item(self, item);
} }
} }
@ -83,7 +83,7 @@ pub fn check_crate(tcx: &ty::ctxt,
} }
}; };
visit::walk_crate(&mut bccx, krate, ()); visit::walk_crate(&mut bccx, krate);
if tcx.sess.borrowck_stats() { if tcx.sess.borrowck_stats() {
println!("--- borrowck stats ---"); println!("--- borrowck stats ---");
@ -114,7 +114,7 @@ fn borrowck_item(this: &mut BorrowckCtxt, item: &ast::Item) {
gather_loans::gather_loans_in_static_initializer(this, &*ex); gather_loans::gather_loans_in_static_initializer(this, &*ex);
} }
_ => { _ => {
visit::walk_item(this, item, ()); visit::walk_item(this, item);
} }
} }
} }
@ -142,7 +142,7 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
check_loans::check_loans(this, &loan_dfcx, flowed_moves, check_loans::check_loans(this, &loan_dfcx, flowed_moves,
all_loans.as_slice(), decl, body); all_loans.as_slice(), decl, body);
visit::walk_fn(this, fk, decl, body, sp, ()); visit::walk_fn(this, fk, decl, body, sp);
} }
fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>, fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,

View file

@ -21,45 +21,61 @@ use syntax::{ast_util, ast_map};
use syntax::visit::Visitor; use syntax::visit::Visitor;
use syntax::visit; use syntax::visit;
pub struct CheckCrateVisitor<'a, 'tcx: 'a> { struct CheckCrateVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
in_const: bool
} }
impl<'a, 'tcx> Visitor<bool> for CheckCrateVisitor<'a, 'tcx> { impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &Item, env: bool) { fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
check_item(self, i, env); let was_const = self.in_const;
self.in_const = in_const;
f(self);
self.in_const = was_const;
} }
fn visit_pat(&mut self, p: &Pat, env: bool) { fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
check_pat(self, p, env); self.with_const(true, f);
} }
fn visit_expr(&mut self, ex: &Expr, env: bool) { fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
check_expr(self, ex, env); self.with_const(false, f);
}
}
impl<'a, 'tcx> Visitor for CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &Item) {
check_item(self, i);
}
fn visit_pat(&mut self, p: &Pat) {
check_pat(self, p);
}
fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex);
} }
} }
pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) { pub fn check_crate(krate: &Crate, tcx: &ty::ctxt) {
visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx }, krate, false); visit::walk_crate(&mut CheckCrateVisitor { tcx: tcx, in_const: false }, krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }
fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) { fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
match it.node { match it.node {
ItemStatic(_, _, ex) => { ItemStatic(_, _, ex) => {
v.visit_expr(&*ex, true); v.inside_const(|v| v.visit_expr(&*ex));
check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it); check_item_recursion(&v.tcx.sess, &v.tcx.map, &v.tcx.def_map, it);
} }
ItemEnum(ref enum_definition, _) => { ItemEnum(ref enum_definition, _) => {
for var in (*enum_definition).variants.iter() { for var in (*enum_definition).variants.iter() {
for ex in var.node.disr_expr.iter() { for ex in var.node.disr_expr.iter() {
v.visit_expr(&**ex, true); v.inside_const(|v| v.visit_expr(&**ex));
} }
} }
} }
_ => visit::walk_item(v, it, false) _ => v.outside_const(|v| visit::walk_item(v, it))
} }
} }
fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) { fn check_pat(v: &mut CheckCrateVisitor, p: &Pat) {
fn is_str(e: &Expr) -> bool { fn is_str(e: &Expr) -> bool {
match e.node { match e.node {
ExprBox(_, expr) => { ExprBox(_, expr) => {
@ -72,18 +88,18 @@ fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
} }
} }
match p.node { match p.node {
// Let through plain ~-string literals here // Let through plain ~-string literals here
PatLit(ref a) => if !is_str(&**a) { v.visit_expr(&**a, true); }, PatLit(ref a) => if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); },
PatRange(ref a, ref b) => { PatRange(ref a, ref b) => {
if !is_str(&**a) { v.visit_expr(&**a, true); } if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); }
if !is_str(&**b) { v.visit_expr(&**b, true); } if !is_str(&**b) { v.inside_const(|v| v.visit_expr(&**b)); }
} }
_ => visit::walk_pat(v, p, false) _ => v.outside_const(|v| visit::walk_pat(v, p))
} }
} }
fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) { fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
if is_const { if v.in_const {
match e.node { match e.node {
ExprUnary(UnDeref, _) => { } ExprUnary(UnDeref, _) => { }
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => { ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
@ -165,7 +181,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
} }
} }
match block.expr { match block.expr {
Some(ref expr) => check_expr(v, &**expr, true), Some(ref expr) => check_expr(v, &**expr),
None => {} None => {}
} }
} }
@ -195,7 +211,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
} }
} }
} }
visit::walk_expr(v, e, is_const); visit::walk_expr(v, e);
} }
struct CheckItemRecursionVisitor<'a> { struct CheckItemRecursionVisitor<'a> {
@ -219,32 +235,32 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
def_map: def_map, def_map: def_map,
idstack: Vec::new() idstack: Vec::new()
}; };
visitor.visit_item(it, ()); visitor.visit_item(it);
} }
impl<'a> Visitor<()> for CheckItemRecursionVisitor<'a> { impl<'a> Visitor for CheckItemRecursionVisitor<'a> {
fn visit_item(&mut self, it: &Item, _: ()) { fn visit_item(&mut self, it: &Item) {
if self.idstack.iter().any(|x| x == &(it.id)) { if self.idstack.iter().any(|x| x == &(it.id)) {
self.sess.span_fatal(self.root_it.span, "recursive constant"); self.sess.span_fatal(self.root_it.span, "recursive constant");
} }
self.idstack.push(it.id); self.idstack.push(it.id);
visit::walk_item(self, it, ()); visit::walk_item(self, it);
self.idstack.pop(); self.idstack.pop();
} }
fn visit_expr(&mut self, e: &Expr, _: ()) { fn visit_expr(&mut self, e: &Expr) {
match e.node { match e.node {
ExprPath(..) => { ExprPath(..) => {
match self.def_map.borrow().find(&e.id) { match self.def_map.borrow().find(&e.id) {
Some(&DefStatic(def_id, _)) if Some(&DefStatic(def_id, _)) if
ast_util::is_local(def_id) => { ast_util::is_local(def_id) => {
self.visit_item(&*self.ast_map.expect_item(def_id.node), ()); self.visit_item(&*self.ast_map.expect_item(def_id.node));
} }
_ => () _ => ()
} }
}, },
_ => () _ => ()
} }
visit::walk_expr(self, e, ()); visit::walk_expr(self, e);
} }
} }

View file

@ -22,45 +22,53 @@ enum Context {
struct CheckLoopVisitor<'a> { struct CheckLoopVisitor<'a> {
sess: &'a Session, sess: &'a Session,
cx: Context
} }
pub fn check_crate(sess: &Session, krate: &ast::Crate) { pub fn check_crate(sess: &Session, krate: &ast::Crate) {
visit::walk_crate(&mut CheckLoopVisitor { sess: sess }, krate, Normal) visit::walk_crate(&mut CheckLoopVisitor { sess: sess, cx: Normal }, krate)
} }
impl<'a> Visitor<Context> for CheckLoopVisitor<'a> { impl<'a> Visitor for CheckLoopVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item, _cx: Context) { fn visit_item(&mut self, i: &ast::Item) {
visit::walk_item(self, i, Normal); self.with_context(Normal, |v| visit::walk_item(v, i));
} }
fn visit_expr(&mut self, e: &ast::Expr, cx:Context) { fn visit_expr(&mut self, e: &ast::Expr) {
match e.node { match e.node {
ast::ExprWhile(ref e, ref b, _) => { ast::ExprWhile(ref e, ref b, _) => {
self.visit_expr(&**e, cx); self.visit_expr(&**e);
self.visit_block(&**b, Loop); self.with_context(Loop, |v| v.visit_block(&**b));
} }
ast::ExprLoop(ref b, _) => { ast::ExprLoop(ref b, _) => {
self.visit_block(&**b, Loop); self.with_context(Loop, |v| v.visit_block(&**b));
} }
ast::ExprForLoop(_, ref e, ref b, _) => { ast::ExprForLoop(_, ref e, ref b, _) => {
self.visit_expr(&**e, cx); self.visit_expr(&**e);
self.visit_block(&**b, Loop); self.with_context(Loop, |v| v.visit_block(&**b));
} }
ast::ExprFnBlock(_, _, ref b) | ast::ExprFnBlock(_, _, ref b) |
ast::ExprProc(_, ref b) | ast::ExprProc(_, ref b) |
ast::ExprUnboxedFn(_, _, _, ref b) => { ast::ExprUnboxedFn(_, _, _, ref b) => {
self.visit_block(&**b, Closure); self.with_context(Closure, |v| v.visit_block(&**b));
} }
ast::ExprBreak(_) => self.require_loop("break", cx, e.span), ast::ExprBreak(_) => self.require_loop("break", e.span),
ast::ExprAgain(_) => self.require_loop("continue", cx, e.span), ast::ExprAgain(_) => self.require_loop("continue", e.span),
_ => visit::walk_expr(self, e, cx) _ => visit::walk_expr(self, e)
} }
} }
} }
impl<'a> CheckLoopVisitor<'a> { impl<'a> CheckLoopVisitor<'a> {
fn require_loop(&self, name: &str, cx: Context, span: Span) { fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
match cx { let old_cx = self.cx;
self.cx = cx;
f(self);
self.cx = old_cx;
}
fn require_loop(&self, name: &str, span: Span) {
match self.cx {
Loop => {} Loop => {}
Closure => { Closure => {
self.sess.span_err(span, self.sess.span_err(span,

View file

@ -119,26 +119,26 @@ enum WitnessPreference {
LeaveOutWitness LeaveOutWitness
} }
impl<'a, 'tcx> Visitor<()> for MatchCheckCtxt<'a, 'tcx> { impl<'a, 'tcx> Visitor for MatchCheckCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex); check_expr(self, ex);
} }
fn visit_local(&mut self, l: &Local, _: ()) { fn visit_local(&mut self, l: &Local) {
check_local(self, l); check_local(self, l);
} }
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, _: ()) { fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
check_fn(self, fk, fd, b, s); check_fn(self, fk, fd, b, s);
} }
} }
pub fn check_crate(tcx: &ty::ctxt, krate: &Crate) { pub fn check_crate(tcx: &ty::ctxt, krate: &Crate) {
let mut cx = MatchCheckCtxt { tcx: tcx }; let mut cx = MatchCheckCtxt { tcx: tcx };
visit::walk_crate(&mut cx, krate, ()); visit::walk_crate(&mut cx, krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }
fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) { fn check_expr(cx: &mut MatchCheckCtxt, ex: &Expr) {
visit::walk_expr(cx, ex, ()); visit::walk_expr(cx, ex);
match ex.node { match ex.node {
ExprMatch(scrut, ref arms) => { ExprMatch(scrut, ref arms) => {
// First, check legality of move bindings. // First, check legality of move bindings.
@ -844,7 +844,7 @@ fn default(cx: &MatchCheckCtxt, r: &[Gc<Pat>]) -> Option<Vec<Gc<Pat>>> {
} }
fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) { fn check_local(cx: &mut MatchCheckCtxt, loc: &Local) {
visit::walk_local(cx, loc, ()); visit::walk_local(cx, loc);
let name = match loc.source { let name = match loc.source {
LocalLet => "local", LocalLet => "local",
@ -872,7 +872,7 @@ fn check_fn(cx: &mut MatchCheckCtxt,
decl: &FnDecl, decl: &FnDecl,
body: &Block, body: &Block,
sp: Span) { sp: Span) {
visit::walk_fn(cx, kind, decl, body, sp, ()); visit::walk_fn(cx, kind, decl, body, sp);
for input in decl.inputs.iter() { for input in decl.inputs.iter() {
match is_refutable(cx, input.pat) { match is_refutable(cx, input.pat) {
Some(pat) => { Some(pat) => {
@ -1014,27 +1014,30 @@ impl<'a, 'tcx> Delegate for MutationChecker<'a, 'tcx> {
/// because of the way rvalues are handled in the borrow check. (See issue /// because of the way rvalues are handled in the borrow check. (See issue
/// #14587.) /// #14587.)
fn check_legality_of_bindings_in_at_patterns(cx: &MatchCheckCtxt, pat: &Pat) { fn check_legality_of_bindings_in_at_patterns(cx: &MatchCheckCtxt, pat: &Pat) {
let mut visitor = AtBindingPatternVisitor { AtBindingPatternVisitor { cx: cx, bindings_allowed: true }.visit_pat(pat);
cx: cx,
};
visitor.visit_pat(pat, true);
} }
struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> { struct AtBindingPatternVisitor<'a, 'b:'a, 'tcx:'b> {
cx: &'a MatchCheckCtxt<'b, 'tcx>, cx: &'a MatchCheckCtxt<'b, 'tcx>,
bindings_allowed: bool
} }
impl<'a, 'b, 'tcx> Visitor<bool> for AtBindingPatternVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> Visitor for AtBindingPatternVisitor<'a, 'b, 'tcx> {
fn visit_pat(&mut self, pat: &Pat, bindings_allowed: bool) { fn visit_pat(&mut self, pat: &Pat) {
if !bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) { if !self.bindings_allowed && pat_is_binding(&self.cx.tcx.def_map, pat) {
self.cx.tcx.sess.span_err(pat.span, self.cx.tcx.sess.span_err(pat.span,
"pattern bindings are not allowed \ "pattern bindings are not allowed \
after an `@`"); after an `@`");
} }
match pat.node { match pat.node {
PatIdent(_, _, Some(_)) => visit::walk_pat(self, pat, false), PatIdent(_, _, Some(_)) => {
_ => visit::walk_pat(self, pat, bindings_allowed), let bindings_were_allowed = self.bindings_allowed;
self.bindings_allowed = false;
visit::walk_pat(self, pat);
self.bindings_allowed = bindings_were_allowed;
}
_ => visit::walk_pat(self, pat),
} }
} }
} }

View file

@ -23,21 +23,20 @@ use syntax::visit;
pub fn check_crate(tcx: &ty::ctxt, pub fn check_crate(tcx: &ty::ctxt,
krate: &ast::Crate) { krate: &ast::Crate) {
let mut rvcx = RvalueContext { tcx: tcx }; let mut rvcx = RvalueContext { tcx: tcx };
visit::walk_crate(&mut rvcx, krate, ()); visit::walk_crate(&mut rvcx, krate);
} }
struct RvalueContext<'a, 'tcx: 'a> { struct RvalueContext<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx> tcx: &'a ty::ctxt<'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for RvalueContext<'a, 'tcx> { impl<'a, 'tcx> visit::Visitor for RvalueContext<'a, 'tcx> {
fn visit_fn(&mut self, fn visit_fn(&mut self,
_: &visit::FnKind, _: &visit::FnKind,
fd: &ast::FnDecl, fd: &ast::FnDecl,
b: &ast::Block, b: &ast::Block,
_: Span, _: Span,
_: ast::NodeId, _: ast::NodeId) {
_: ()) {
let mut euv = euv::ExprUseVisitor::new(self, self.tcx); let mut euv = euv::ExprUseVisitor::new(self, self.tcx);
euv.walk_fn(fd, b); euv.walk_fn(fd, b);
} }

View file

@ -27,7 +27,6 @@
use middle::ty; use middle::ty;
use syntax::ast; use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::Visitor; use syntax::visit::Visitor;
use syntax::visit; use syntax::visit;
use syntax::print::pprust; use syntax::print::pprust;
@ -54,41 +53,42 @@ fn safe_type_for_static_mut(cx: &ty::ctxt, e: &ast::Expr) -> Option<String> {
struct CheckStaticVisitor<'a, 'tcx: 'a> { struct CheckStaticVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
in_const: bool
} }
pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) { pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx }, krate, false) visit::walk_crate(&mut CheckStaticVisitor { tcx: tcx, in_const: false }, krate)
} }
impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> { impl<'a, 'tcx> CheckStaticVisitor<'a, 'tcx> {
fn report_error(&self, span: Span, result: Option<String>) -> bool { fn with_const(&mut self, in_const: bool, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
match result { let was_const = self.in_const;
None => { false } self.in_const = in_const;
Some(msg) => { f(self);
self.tcx.sess.span_err(span, msg.as_slice()); self.in_const = was_const;
true
}
}
} }
} }
impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for CheckStaticVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
debug!("visit_item(item={})", pprust::item_to_string(i)); debug!("visit_item(item={})", pprust::item_to_string(i));
match i.node { match i.node {
ast::ItemStatic(_, mutability, ref expr) => { ast::ItemStatic(_, mutability, ref expr) => {
match mutability { match mutability {
ast::MutImmutable => { ast::MutImmutable => {
self.visit_expr(&**expr, true); self.with_const(true, |v| v.visit_expr(&**expr));
} }
ast::MutMutable => { ast::MutMutable => {
let safe = safe_type_for_static_mut(self.tcx, &**expr); match safe_type_for_static_mut(self.tcx, &**expr) {
self.report_error(expr.span, safe); Some(msg) => {
self.tcx.sess.span_err(expr.span, msg.as_slice());
}
None => {}
}
} }
} }
} }
_ => { visit::walk_item(self, i, false) } _ => self.with_const(false, |v| visit::walk_item(v, i))
} }
} }
@ -98,17 +98,17 @@ impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
/// every nested expression. if the expression is not part /// every nested expression. if the expression is not part
/// of a static item, this method does nothing but walking /// of a static item, this method does nothing but walking
/// down through it. /// down through it.
fn visit_expr(&mut self, e: &ast::Expr, is_const: bool) { fn visit_expr(&mut self, e: &ast::Expr) {
debug!("visit_expr(expr={})", pprust::expr_to_string(e)); debug!("visit_expr(expr={})", pprust::expr_to_string(e));
if !is_const { if !self.in_const {
return visit::walk_expr(self, e, is_const); return visit::walk_expr(self, e);
} }
match e.node { match e.node {
ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) | ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
ast::ExprBlock(..) | ast::ExprTup(..) => { ast::ExprBlock(..) | ast::ExprTup(..) => {
visit::walk_expr(self, e, is_const); visit::walk_expr(self, e);
} }
ast::ExprAddrOf(ast::MutMutable, _) => { ast::ExprAddrOf(ast::MutMutable, _) => {
span_err!(self.tcx.sess, e.span, E0020, span_err!(self.tcx.sess, e.span, E0020,
@ -130,15 +130,14 @@ impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
ty::ty_struct(did, _) | ty::ty_struct(did, _) |
ty::ty_enum(did, _) => { ty::ty_enum(did, _) => {
if ty::has_dtor(self.tcx, did) { if ty::has_dtor(self.tcx, did) {
self.report_error(e.span, self.tcx.sess.span_err(e.span,
Some("static items are not allowed to have \ "static items are not allowed to have destructors");
destructors".to_string()));
return; return;
} }
} }
_ => {} _ => {}
} }
visit::walk_expr(self, e, is_const); visit::walk_expr(self, e);
} }
} }
} }

View file

@ -268,8 +268,8 @@ impl<'a, 'tcx> ConstEvalVisitor<'a, 'tcx> {
} }
impl<'a, 'tcx> Visitor<()> for ConstEvalVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for ConstEvalVisitor<'a, 'tcx> {
fn visit_ty(&mut self, t: &Ty, _: ()) { fn visit_ty(&mut self, t: &Ty) {
match t.node { match t.node {
TyFixedLengthVec(_, expr) => { TyFixedLengthVec(_, expr) => {
check::check_const_in_type(self.tcx, &*expr, ty::mk_uint()); check::check_const_in_type(self.tcx, &*expr, ty::mk_uint());
@ -277,10 +277,10 @@ impl<'a, 'tcx> Visitor<()> for ConstEvalVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_ty(self, t, ()); visit::walk_ty(self, t);
} }
fn visit_expr_post(&mut self, e: &Expr, _: ()) { fn visit_expr_post(&mut self, e: &Expr) {
self.classify(e); self.classify(e);
} }
} }
@ -291,7 +291,7 @@ pub fn process_crate(krate: &ast::Crate,
tcx: tcx, tcx: tcx,
ccache: DefIdMap::new(), ccache: DefIdMap::new(),
}; };
visit::walk_crate(&mut v, krate, ()); visit::walk_crate(&mut v, krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }

View file

@ -172,11 +172,11 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
index: &'a mut NodeMap<CFGIndex>, index: &'a mut NodeMap<CFGIndex>,
} }
let mut formals = Formals { entry: entry, index: index }; let mut formals = Formals { entry: entry, index: index };
visit::walk_fn_decl(&mut formals, decl, ()); visit::walk_fn_decl(&mut formals, decl);
impl<'a> visit::Visitor<()> for Formals<'a> { impl<'a> visit::Visitor for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat, e: ()) { fn visit_pat(&mut self, p: &ast::Pat) {
self.index.insert(p.id, self.entry); self.index.insert(p.id, self.entry);
visit::walk_pat(self, p, e) visit::walk_pat(self, p)
} }
} }
} }

View file

@ -51,10 +51,6 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
worklist: Vec<ast::NodeId>, worklist: Vec<ast::NodeId>,
tcx: &'a ty::ctxt<'tcx>, tcx: &'a ty::ctxt<'tcx>,
live_symbols: Box<HashSet<ast::NodeId>>, live_symbols: Box<HashSet<ast::NodeId>>,
}
#[deriving(Clone)]
struct MarkSymbolVisitorContext {
struct_has_extern_repr: bool struct_has_extern_repr: bool
} }
@ -65,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
worklist: worklist, worklist: worklist,
tcx: tcx, tcx: tcx,
live_symbols: box HashSet::new(), live_symbols: box HashSet::new(),
struct_has_extern_repr: false
} }
} }
@ -199,66 +196,64 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
} }
fn visit_node(&mut self, node: &ast_map::Node) { fn visit_node(&mut self, node: &ast_map::Node) {
let ctxt = MarkSymbolVisitorContext { let had_extern_repr = self.struct_has_extern_repr;
struct_has_extern_repr: false self.struct_has_extern_repr = false;
};
match *node { match *node {
ast_map::NodeItem(item) => { ast_map::NodeItem(item) => {
match item.node { match item.node {
ast::ItemStruct(..) => { ast::ItemStruct(..) => {
let has_extern_repr = item.attrs.iter().fold(false, |acc, attr| { self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
acc || attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr) attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
.iter().any(|&x| x == attr::ReprExtern) .contains(&attr::ReprExtern)
}); });
visit::walk_item(self, &*item, MarkSymbolVisitorContext { visit::walk_item(self, &*item);
struct_has_extern_repr: has_extern_repr,
..(ctxt)
});
} }
ast::ItemFn(..) ast::ItemFn(..)
| ast::ItemEnum(..) | ast::ItemEnum(..)
| ast::ItemTy(..) | ast::ItemTy(..)
| ast::ItemStatic(..) => { | ast::ItemStatic(..) => {
visit::walk_item(self, &*item, ctxt); visit::walk_item(self, &*item);
} }
_ => () _ => ()
} }
} }
ast_map::NodeTraitItem(trait_method) => { ast_map::NodeTraitItem(trait_method) => {
visit::walk_trait_item(self, &*trait_method, ctxt); visit::walk_trait_item(self, &*trait_method);
} }
ast_map::NodeImplItem(impl_item) => { ast_map::NodeImplItem(impl_item) => {
match *impl_item { match *impl_item {
ast::MethodImplItem(method) => { ast::MethodImplItem(method) => {
visit::walk_block(self, &*method.pe_body(), ctxt); visit::walk_block(self, &*method.pe_body());
} }
} }
} }
ast_map::NodeForeignItem(foreign_item) => { ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt); visit::walk_foreign_item(self, &*foreign_item);
} }
_ => () _ => ()
} }
self.struct_has_extern_repr = had_extern_repr;
} }
} }
impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for MarkSymbolVisitor<'a, 'tcx> {
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident, _: &ast::Generics, fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
_: ast::NodeId, ctxt: MarkSymbolVisitorContext) { _: &ast::Generics, _: ast::NodeId) {
let has_extern_repr = self.struct_has_extern_repr;
let live_fields = def.fields.iter().filter(|f| { let live_fields = def.fields.iter().filter(|f| {
ctxt.struct_has_extern_repr || match f.node.kind { has_extern_repr || match f.node.kind {
ast::NamedField(_, ast::Public) => true, ast::NamedField(_, ast::Public) => true,
_ => false _ => false
} }
}); });
self.live_symbols.extend(live_fields.map(|f| f.node.id)); self.live_symbols.extend(live_fields.map(|f| f.node.id));
visit::walk_struct_def(self, def, ctxt); visit::walk_struct_def(self, def);
} }
fn visit_expr(&mut self, expr: &ast::Expr, ctxt: MarkSymbolVisitorContext) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprMethodCall(..) => { ast::ExprMethodCall(..) => {
self.lookup_and_handle_method(expr.id, expr.span); self.lookup_and_handle_method(expr.id, expr.span);
@ -272,10 +267,10 @@ impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx>
_ => () _ => ()
} }
visit::walk_expr(self, expr, ctxt); visit::walk_expr(self, expr);
} }
fn visit_pat(&mut self, pat: &ast::Pat, ctxt: MarkSymbolVisitorContext) { fn visit_pat(&mut self, pat: &ast::Pat) {
match pat.node { match pat.node {
ast::PatStruct(_, ref fields, _) => { ast::PatStruct(_, ref fields, _) => {
self.handle_field_pattern_match(pat, fields.as_slice()); self.handle_field_pattern_match(pat, fields.as_slice());
@ -287,15 +282,15 @@ impl<'a, 'tcx> Visitor<MarkSymbolVisitorContext> for MarkSymbolVisitor<'a, 'tcx>
_ => () _ => ()
} }
visit::walk_pat(self, pat, ctxt); visit::walk_pat(self, pat);
} }
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, ctxt: MarkSymbolVisitorContext) { fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
self.lookup_and_handle_definition(&id); self.lookup_and_handle_definition(&id);
visit::walk_path(self, path, ctxt); visit::walk_path(self, path);
} }
fn visit_item(&mut self, _: &ast::Item, _: MarkSymbolVisitorContext) { fn visit_item(&mut self, _: &ast::Item) {
// Do not recurse into items. These items will be added to the // Do not recurse into items. These items will be added to the
// worklist and recursed into manually if necessary. // worklist and recursed into manually if necessary.
} }
@ -334,8 +329,8 @@ struct LifeSeeder {
worklist: Vec<ast::NodeId> , worklist: Vec<ast::NodeId> ,
} }
impl Visitor<()> for LifeSeeder { impl Visitor for LifeSeeder {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) { if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) {
self.worklist.push(item.id); self.worklist.push(item.id);
} }
@ -351,12 +346,12 @@ impl Visitor<()> for LifeSeeder {
} }
_ => () _ => ()
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
fn visit_fn(&mut self, fk: &visit::FnKind, fn visit_fn(&mut self, fk: &visit::FnKind,
_: &ast::FnDecl, block: &ast::Block, _: &ast::FnDecl, block: &ast::Block,
_: codemap::Span, id: ast::NodeId, _: ()) { _: codemap::Span, id: ast::NodeId) {
// Check for method here because methods are not ast::Item // Check for method here because methods are not ast::Item
match *fk { match *fk {
visit::FkMethod(_, _, method) => { visit::FkMethod(_, _, method) => {
@ -366,7 +361,7 @@ impl Visitor<()> for LifeSeeder {
} }
_ => () _ => ()
} }
visit::walk_block(self, block, ()); visit::walk_block(self, block);
} }
} }
@ -398,7 +393,7 @@ fn create_and_seed_worklist(tcx: &ty::ctxt,
let mut life_seeder = LifeSeeder { let mut life_seeder = LifeSeeder {
worklist: worklist worklist: worklist
}; };
visit::walk_crate(&mut life_seeder, krate, ()); visit::walk_crate(&mut life_seeder, krate);
return life_seeder.worklist; return life_seeder.worklist;
} }
@ -504,25 +499,25 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for DeadVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for DeadVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
let ctor_id = get_struct_ctor_id(item); let ctor_id = get_struct_ctor_id(item);
if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) { if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
self.warn_dead_code(item.id, item.span, item.ident); self.warn_dead_code(item.id, item.span, item.ident);
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
if !self.symbol_is_live(fi.id, None) { if !self.symbol_is_live(fi.id, None) {
self.warn_dead_code(fi.id, fi.span, fi.ident); self.warn_dead_code(fi.id, fi.span, fi.ident);
} }
visit::walk_foreign_item(self, fi, ()); visit::walk_foreign_item(self, fi);
} }
fn visit_fn(&mut self, fk: &visit::FnKind, fn visit_fn(&mut self, fk: &visit::FnKind,
_: &ast::FnDecl, block: &ast::Block, _: &ast::FnDecl, block: &ast::Block,
span: codemap::Span, id: ast::NodeId, _: ()) { span: codemap::Span, id: ast::NodeId) {
// Have to warn method here because methods are not ast::Item // Have to warn method here because methods are not ast::Item
match *fk { match *fk {
visit::FkMethod(..) => { visit::FkMethod(..) => {
@ -533,22 +528,22 @@ impl<'a, 'tcx> Visitor<()> for DeadVisitor<'a, 'tcx> {
} }
_ => () _ => ()
} }
visit::walk_block(self, block, ()); visit::walk_block(self, block);
} }
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) { fn visit_struct_field(&mut self, field: &ast::StructField) {
if self.should_warn_about_field(&field.node) { if self.should_warn_about_field(&field.node) {
self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap()); self.warn_dead_code(field.node.id, field.span, field.node.ident().unwrap());
} }
visit::walk_struct_field(self, field, ()); visit::walk_struct_field(self, field);
} }
// Overwrite so that we don't warn the trait method itself. // Overwrite so that we don't warn the trait method itself.
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem, _: ()) { fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
match *trait_method { match *trait_method {
ast::ProvidedMethod(ref method) => { ast::ProvidedMethod(ref method) => {
visit::walk_block(self, &*method.pe_body(), ()) visit::walk_block(self, &*method.pe_body())
} }
ast::RequiredMethod(_) => () ast::RequiredMethod(_) => ()
} }
@ -562,5 +557,5 @@ pub fn check_crate(tcx: &ty::ctxt,
let live_symbols = find_live(tcx, exported_items, let live_symbols = find_live(tcx, exported_items,
reachable_symbols, krate); reachable_symbols, krate);
let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols }; let mut visitor = DeadVisitor { tcx: tcx, live_symbols: live_symbols };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }

View file

@ -86,9 +86,9 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl, fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
block: &ast::Block, span: Span, _: ast::NodeId, _:()) { block: &ast::Block, span: Span, _: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match *fn_kind { let (is_item_fn, is_unsafe_fn) = match *fn_kind {
visit::FkItemFn(_, _, fn_style, _) => visit::FkItemFn(_, _, fn_style, _) =>
@ -105,12 +105,12 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
self.unsafe_context = SafeContext self.unsafe_context = SafeContext
} }
visit::walk_fn(self, fn_kind, fn_decl, block, span, ()); visit::walk_fn(self, fn_kind, fn_decl, block, span);
self.unsafe_context = old_unsafe_context self.unsafe_context = old_unsafe_context
} }
fn visit_block(&mut self, block: &ast::Block, _:()) { fn visit_block(&mut self, block: &ast::Block) {
let old_unsafe_context = self.unsafe_context; let old_unsafe_context = self.unsafe_context;
match block.rules { match block.rules {
ast::DefaultBlock => {} ast::DefaultBlock => {}
@ -136,12 +136,12 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
} }
} }
visit::walk_block(self, block, ()); visit::walk_block(self, block);
self.unsafe_context = old_unsafe_context self.unsafe_context = old_unsafe_context
} }
fn visit_expr(&mut self, expr: &ast::Expr, _:()) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprMethodCall(_, _, _) => { ast::ExprMethodCall(_, _, _) => {
let method_call = MethodCall::expr(expr.id); let method_call = MethodCall::expr(expr.id);
@ -193,7 +193,7 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
} }
@ -203,5 +203,5 @@ pub fn check_crate(tcx: &ty::ctxt, krate: &ast::Crate) {
unsafe_context: SafeContext, unsafe_context: SafeContext,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }

View file

@ -41,8 +41,8 @@ struct EntryContext<'a> {
non_main_fns: Vec<(NodeId, Span)> , non_main_fns: Vec<(NodeId, Span)> ,
} }
impl<'a> Visitor<()> for EntryContext<'a> { impl<'a> Visitor for EntryContext<'a> {
fn visit_item(&mut self, item: &Item, _:()) { fn visit_item(&mut self, item: &Item) {
find_item(item, self); find_item(item, self);
} }
} }
@ -72,7 +72,7 @@ pub fn find_entry_point(session: &Session, krate: &Crate, ast_map: &ast_map::Map
non_main_fns: Vec::new(), non_main_fns: Vec::new(),
}; };
visit::walk_crate(&mut ctxt, krate, ()); visit::walk_crate(&mut ctxt, krate);
configure_main(&mut ctxt); configure_main(&mut ctxt);
} }
@ -118,7 +118,7 @@ fn find_item(item: &Item, ctxt: &mut EntryContext) {
_ => () _ => ()
} }
visit::walk_item(ctxt, item, ()); visit::walk_item(ctxt, item);
} }
fn configure_main(this: &mut EntryContext) { fn configure_main(this: &mut EntryContext) {

View file

@ -50,18 +50,21 @@ struct CollectFreevarsVisitor<'a> {
refs: Vec<freevar_entry>, refs: Vec<freevar_entry>,
def_map: &'a resolve::DefMap, def_map: &'a resolve::DefMap,
capture_mode_map: &'a mut CaptureModeMap, capture_mode_map: &'a mut CaptureModeMap,
depth: uint
} }
impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> { impl<'a> Visitor for CollectFreevarsVisitor<'a> {
fn visit_item(&mut self, _: &ast::Item, _: int) { fn visit_item(&mut self, _: &ast::Item) {
// ignore_item // ignore_item
} }
fn visit_expr(&mut self, expr: &ast::Expr, depth: int) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprProc(..) => { ast::ExprProc(..) => {
self.capture_mode_map.insert(expr.id, CaptureByValue); self.capture_mode_map.insert(expr.id, CaptureByValue);
visit::walk_expr(self, expr, depth + 1) self.depth += 1;
visit::walk_expr(self, expr);
self.depth -= 1;
} }
ast::ExprFnBlock(_, _, _) => { ast::ExprFnBlock(_, _, _) => {
// NOTE(stage0): After snapshot, change to: // NOTE(stage0): After snapshot, change to:
@ -72,7 +75,9 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
//}; //};
let capture_mode = CaptureByRef; let capture_mode = CaptureByRef;
self.capture_mode_map.insert(expr.id, capture_mode); self.capture_mode_map.insert(expr.id, capture_mode);
visit::walk_expr(self, expr, depth + 1) self.depth += 1;
visit::walk_expr(self, expr);
self.depth -= 1;
} }
ast::ExprUnboxedFn(capture_clause, _, _, _) => { ast::ExprUnboxedFn(capture_clause, _, _, _) => {
let capture_mode = match capture_clause { let capture_mode = match capture_clause {
@ -80,35 +85,33 @@ impl<'a> Visitor<int> for CollectFreevarsVisitor<'a> {
ast::CaptureByRef => CaptureByRef, ast::CaptureByRef => CaptureByRef,
}; };
self.capture_mode_map.insert(expr.id, capture_mode); self.capture_mode_map.insert(expr.id, capture_mode);
visit::walk_expr(self, expr, depth + 1) self.depth += 1;
visit::walk_expr(self, expr);
self.depth -= 1;
} }
ast::ExprPath(..) => { ast::ExprPath(..) => {
let mut def = *self.def_map.borrow().find(&expr.id)
.expect("path not found");
let mut i = 0; let mut i = 0;
match self.def_map.borrow().find(&expr.id) { while i < self.depth {
None => fail!("path not found"), match def {
Some(&df) => { def::DefUpvar(_, inner, _, _) => { def = *inner; }
let mut def = df; _ => break
while i < depth { }
match def { i += 1;
def::DefUpvar(_, inner, _, _) => { def = *inner; } }
_ => break if i == self.depth { // Made it to end of loop
} let dnum = def.def_id().node;
i += 1; if !self.seen.contains(&dnum) {
} self.refs.push(freevar_entry {
if i == depth { // Made it to end of loop def: def,
let dnum = def.def_id().node; span: expr.span,
if !self.seen.contains(&dnum) { });
self.refs.push(freevar_entry { self.seen.insert(dnum);
def: def,
span: expr.span,
});
self.seen.insert(dnum);
}
}
} }
} }
} }
_ => visit::walk_expr(self, expr, depth) _ => visit::walk_expr(self, expr)
} }
} }
} }
@ -127,9 +130,10 @@ fn collect_freevars(def_map: &resolve::DefMap,
refs: Vec::new(), refs: Vec::new(),
def_map: def_map, def_map: def_map,
capture_mode_map: &mut *capture_mode_map, capture_mode_map: &mut *capture_mode_map,
depth: 1
}; };
v.visit_block(blk, 1); v.visit_block(blk);
v.refs v.refs
} }
@ -140,14 +144,14 @@ struct AnnotateFreevarsVisitor<'a> {
capture_mode_map: CaptureModeMap, capture_mode_map: CaptureModeMap,
} }
impl<'a> Visitor<()> for AnnotateFreevarsVisitor<'a> { impl<'a> Visitor for AnnotateFreevarsVisitor<'a> {
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl, fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
blk: &ast::Block, s: Span, nid: ast::NodeId, _: ()) { blk: &ast::Block, s: Span, nid: ast::NodeId) {
let vars = collect_freevars(self.def_map, let vars = collect_freevars(self.def_map,
blk, blk,
&mut self.capture_mode_map); &mut self.capture_mode_map);
self.freevars.insert(nid, vars); self.freevars.insert(nid, vars);
visit::walk_fn(self, fk, fd, blk, s, ()); visit::walk_fn(self, fk, fd, blk, s);
} }
} }
@ -163,7 +167,7 @@ pub fn annotate_freevars(def_map: &resolve::DefMap, krate: &ast::Crate)
freevars: NodeMap::new(), freevars: NodeMap::new(),
capture_mode_map: NodeMap::new(), capture_mode_map: NodeMap::new(),
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
let AnnotateFreevarsVisitor { let AnnotateFreevarsVisitor {
freevars, freevars,

View file

@ -116,8 +116,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for IntrinsicCheckingVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for IntrinsicCheckingVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr, (): ()) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprPath(..) => { ast::ExprPath(..) => {
match ty::resolve_expr(self.tcx, expr) { match ty::resolve_expr(self.tcx, expr) {
@ -144,7 +144,7 @@ impl<'a, 'tcx> Visitor<()> for IntrinsicCheckingVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
} }
@ -153,6 +153,6 @@ pub fn check_crate(tcx: &ctxt, krate: &ast::Crate) {
tcx: tcx, tcx: tcx,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }

View file

@ -56,29 +56,29 @@ pub struct Context<'a, 'tcx: 'a> {
parameter_environments: Vec<ParameterEnvironment>, parameter_environments: Vec<ParameterEnvironment>,
} }
impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> { impl<'a, 'tcx> Visitor for Context<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex); check_expr(self, ex);
} }
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &FnDecl, fn visit_fn(&mut self, fk: &visit::FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, _: ()) { b: &Block, s: Span, n: NodeId) {
check_fn(self, fk, fd, b, s, n); check_fn(self, fk, fd, b, s, n);
} }
fn visit_ty(&mut self, t: &Ty, _: ()) { fn visit_ty(&mut self, t: &Ty) {
check_ty(self, t); check_ty(self, t);
} }
fn visit_item(&mut self, i: &Item, _: ()) { fn visit_item(&mut self, i: &Item) {
check_item(self, i); check_item(self, i);
} }
fn visit_pat(&mut self, p: &Pat, _: ()) { fn visit_pat(&mut self, p: &Pat) {
check_pat(self, p); check_pat(self, p);
} }
fn visit_local(&mut self, l: &Local, _: ()) { fn visit_local(&mut self, l: &Local) {
check_local(self, l); check_local(self, l);
} }
} }
@ -90,7 +90,7 @@ pub fn check_crate(tcx: &ty::ctxt,
struct_and_enum_bounds_checked: HashSet::new(), struct_and_enum_bounds_checked: HashSet::new(),
parameter_environments: Vec::new(), parameter_environments: Vec::new(),
}; };
visit::walk_crate(&mut ctx, krate, ()); visit::walk_crate(&mut ctx, krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }
@ -265,7 +265,7 @@ fn check_item(cx: &mut Context, item: &Item) {
} }
} }
visit::walk_item(cx, item, ()) visit::walk_item(cx, item)
} }
fn check_local(cx: &mut Context, local: &Local) { fn check_local(cx: &mut Context, local: &Local) {
@ -274,7 +274,7 @@ fn check_local(cx: &mut Context, local: &Local) {
local.span, local.span,
ty::node_id_to_type(cx.tcx, local.id)); ty::node_id_to_type(cx.tcx, local.id));
visit::walk_local(cx, local, ()) visit::walk_local(cx, local)
} }
// Yields the appropriate function to check the kind of closed over // Yields the appropriate function to check the kind of closed over
@ -361,7 +361,7 @@ fn check_fn(
let ty = ty::node_id_to_type(cx.tcx, fn_id); let ty = ty::node_id_to_type(cx.tcx, fn_id);
check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty); check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty);
visit::walk_fn(cx, fk, decl, body, sp, ()) visit::walk_fn(cx, fk, decl, body, sp)
} }
visit::FkItemFn(..) | visit::FkMethod(..) => { visit::FkItemFn(..) | visit::FkMethod(..) => {
let parameter_environment = ParameterEnvironment::for_item(cx.tcx, let parameter_environment = ParameterEnvironment::for_item(cx.tcx,
@ -371,7 +371,7 @@ fn check_fn(
let ty = ty::node_id_to_type(cx.tcx, fn_id); let ty = ty::node_id_to_type(cx.tcx, fn_id);
check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty); check_bounds_on_structs_or_enums_in_type_if_possible(cx, sp, ty);
visit::walk_fn(cx, fk, decl, body, sp, ()); visit::walk_fn(cx, fk, decl, body, sp);
drop(cx.parameter_environments.pop()); drop(cx.parameter_environments.pop());
} }
} }
@ -451,7 +451,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
None => {} None => {}
} }
visit::walk_expr(cx, e, ()); visit::walk_expr(cx, e);
} }
fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) { fn check_bounds_on_type_parameters(cx: &mut Context, e: &Expr) {
@ -616,7 +616,7 @@ fn check_ty(cx: &mut Context, aty: &Ty) {
_ => {} _ => {}
} }
visit::walk_ty(cx, aty, ()); visit::walk_ty(cx, aty);
} }
// Calls "any_missing" if any bounds were missing. // Calls "any_missing" if any bounds were missing.
@ -804,5 +804,5 @@ fn check_pat(cx: &mut Context, pat: &Pat) {
None => {} None => {}
} }
visit::walk_pat(cx, pat, ()); visit::walk_pat(cx, pat);
} }

View file

@ -115,8 +115,8 @@ struct LanguageItemCollector<'a> {
item_refs: HashMap<&'static str, uint>, item_refs: HashMap<&'static str, uint>,
} }
impl<'a> Visitor<()> for LanguageItemCollector<'a> { impl<'a> Visitor for LanguageItemCollector<'a> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
match extract(item.attrs.as_slice()) { match extract(item.attrs.as_slice()) {
Some(value) => { Some(value) => {
let item_index = self.item_refs.find_equiv(&value).map(|x| *x); let item_index = self.item_refs.find_equiv(&value).map(|x| *x);
@ -131,7 +131,7 @@ impl<'a> Visitor<()> for LanguageItemCollector<'a> {
None => {} None => {}
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
@ -166,7 +166,7 @@ impl<'a> LanguageItemCollector<'a> {
} }
pub fn collect_local_language_items(&mut self, krate: &ast::Crate) { pub fn collect_local_language_items(&mut self, krate: &ast::Crate) {
visit::walk_crate(self, krate, ()); visit::walk_crate(self, krate);
} }
pub fn collect_external_language_items(&mut self) { pub fn collect_external_language_items(&mut self) {

View file

@ -179,18 +179,18 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
} }
} }
impl<'a, 'tcx> Visitor<()> for IrMaps<'a, 'tcx> { impl<'a, 'tcx> Visitor for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) { fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId) {
visit_fn(self, fk, fd, b, s, n); visit_fn(self, fk, fd, b, s, n);
} }
fn visit_local(&mut self, l: &Local, _: ()) { visit_local(self, l); } fn visit_local(&mut self, l: &Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr, _: ()) { visit_expr(self, ex); } fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &Arm, _: ()) { visit_arm(self, a); } fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); }
} }
pub fn check_crate(tcx: &ty::ctxt, pub fn check_crate(tcx: &ty::ctxt,
krate: &Crate) { krate: &Crate) {
visit::walk_crate(&mut IrMaps::new(tcx), krate, ()); visit::walk_crate(&mut IrMaps::new(tcx), krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
} }
@ -343,17 +343,17 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for Liveness<'a, 'tcx> { impl<'a, 'tcx> Visitor for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) { fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId) {
check_fn(self, fk, fd, b, s, n); check_fn(self, fk, fd, b, s, n);
} }
fn visit_local(&mut self, l: &Local, _: ()) { fn visit_local(&mut self, l: &Local) {
check_local(self, l); check_local(self, l);
} }
fn visit_expr(&mut self, ex: &Expr, _: ()) { fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex); check_expr(self, ex);
} }
fn visit_arm(&mut self, a: &Arm, _: ()) { fn visit_arm(&mut self, a: &Arm) {
check_arm(self, a); check_arm(self, a);
} }
} }
@ -387,7 +387,7 @@ fn visit_fn(ir: &mut IrMaps,
// gather up the various local variables, significant expressions, // gather up the various local variables, significant expressions,
// and so forth: // and so forth:
visit::walk_fn(&mut fn_maps, fk, decl, body, sp, ()); visit::walk_fn(&mut fn_maps, fk, decl, body, sp);
// Special nodes and variables: // Special nodes and variables:
// - exit_ln represents the end of the fn, either by return or fail // - exit_ln represents the end of the fn, either by return or fail
@ -404,7 +404,7 @@ fn visit_fn(ir: &mut IrMaps,
let entry_ln = lsets.compute(decl, body); let entry_ln = lsets.compute(decl, body);
// check for various error conditions // check for various error conditions
lsets.visit_block(body, ()); lsets.visit_block(body);
lsets.check_ret(id, sp, fk, entry_ln, body); lsets.check_ret(id, sp, fk, entry_ln, body);
lsets.warn_about_unused_args(decl, entry_ln); lsets.warn_about_unused_args(decl, entry_ln);
} }
@ -419,7 +419,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) {
ident: name ident: name
})); }));
}); });
visit::walk_local(ir, local, ()); visit::walk_local(ir, local);
} }
fn visit_arm(ir: &mut IrMaps, arm: &Arm) { fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
@ -435,7 +435,7 @@ fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
})); }));
}) })
} }
visit::walk_arm(ir, arm, ()); visit::walk_arm(ir, arm);
} }
fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> { fn moved_variable_node_id_from_def(def: Def) -> Option<NodeId> {
@ -457,7 +457,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
if moved_variable_node_id_from_def(def).is_some() { if moved_variable_node_id_from_def(def).is_some() {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
} }
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) => { ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) => {
// Interesting control flow (for loops can contain labeled // Interesting control flow (for loops can contain labeled
@ -483,13 +483,13 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
}); });
ir.set_captures(expr.id, call_caps); ir.set_captures(expr.id, call_caps);
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
// live nodes required for interesting control flow: // live nodes required for interesting control flow:
ExprIf(..) | ExprMatch(..) | ExprWhile(..) | ExprLoop(..) => { ExprIf(..) | ExprMatch(..) | ExprWhile(..) | ExprLoop(..) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
ExprForLoop(ref pat, _, _, _) => { ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| { pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
@ -503,11 +503,11 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
})); }));
}); });
ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
ExprBinary(op, _, _) if ast_util::lazy_binop(op) => { ExprBinary(op, _, _) if ast_util::lazy_binop(op) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span)); ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
// otherwise, live nodes are not required: // otherwise, live nodes are not required:
@ -519,7 +519,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) | ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
ExprStruct(..) | ExprRepeat(..) | ExprParen(..) | ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
ExprInlineAsm(..) | ExprBox(..) => { ExprInlineAsm(..) | ExprBox(..) => {
visit::walk_expr(ir, expr, ()); visit::walk_expr(ir, expr);
} }
} }
} }
@ -1408,43 +1408,43 @@ fn check_local(this: &mut Liveness, local: &Local) {
} }
} }
visit::walk_local(this, local, ()); visit::walk_local(this, local);
} }
fn check_arm(this: &mut Liveness, arm: &Arm) { fn check_arm(this: &mut Liveness, arm: &Arm) {
this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| { this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| {
this.warn_about_unused(sp, id, ln, var); this.warn_about_unused(sp, id, ln, var);
}); });
visit::walk_arm(this, arm, ()); visit::walk_arm(this, arm);
} }
fn check_expr(this: &mut Liveness, expr: &Expr) { fn check_expr(this: &mut Liveness, expr: &Expr) {
match expr.node { match expr.node {
ExprAssign(ref l, ref r) => { ExprAssign(ref l, ref r) => {
this.check_lvalue(&**l); this.check_lvalue(&**l);
this.visit_expr(&**r, ()); this.visit_expr(&**r);
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr);
} }
ExprAssignOp(_, ref l, _) => { ExprAssignOp(_, ref l, _) => {
this.check_lvalue(&**l); this.check_lvalue(&**l);
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr);
} }
ExprInlineAsm(ref ia) => { ExprInlineAsm(ref ia) => {
for &(_, ref input) in ia.inputs.iter() { for &(_, ref input) in ia.inputs.iter() {
this.visit_expr(&**input, ()); this.visit_expr(&**input);
} }
// Output operands must be lvalues // Output operands must be lvalues
for &(_, ref out, _) in ia.outputs.iter() { for &(_, ref out, _) in ia.outputs.iter() {
this.check_lvalue(&**out); this.check_lvalue(&**out);
this.visit_expr(&**out, ()); this.visit_expr(&**out);
} }
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr);
} }
// no correctness conditions related to liveness // no correctness conditions related to liveness
@ -1456,7 +1456,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) | ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) | ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) |
ExprPath(..) | ExprBox(..) | ExprForLoop(..) => { ExprPath(..) | ExprBox(..) | ExprForLoop(..) => {
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr);
} }
} }
} }
@ -1546,7 +1546,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
_ => { _ => {
// For other kinds of lvalues, no checks are required, // For other kinds of lvalues, no checks are required,
// and any embedded expressions are actually rvalues // and any embedded expressions are actually rvalues
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
} }
} }

View file

@ -57,8 +57,8 @@ struct ParentVisitor {
curparent: ast::NodeId, curparent: ast::NodeId,
} }
impl Visitor<()> for ParentVisitor { impl Visitor for ParentVisitor {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
self.parents.insert(item.id, self.curparent); self.parents.insert(item.id, self.curparent);
let prev = self.curparent; let prev = self.curparent;
@ -91,28 +91,28 @@ impl Visitor<()> for ParentVisitor {
_ => {} _ => {}
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
self.curparent = prev; self.curparent = prev;
} }
fn visit_foreign_item(&mut self, a: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
self.parents.insert(a.id, self.curparent); self.parents.insert(a.id, self.curparent);
visit::walk_foreign_item(self, a, ()); visit::walk_foreign_item(self, a);
} }
fn visit_fn(&mut self, a: &visit::FnKind, b: &ast::FnDecl, fn visit_fn(&mut self, a: &visit::FnKind, b: &ast::FnDecl,
c: &ast::Block, d: Span, id: ast::NodeId, _: ()) { c: &ast::Block, d: Span, id: ast::NodeId) {
// We already took care of some trait methods above, otherwise things // We already took care of some trait methods above, otherwise things
// like impl methods and pub trait methods are parented to the // like impl methods and pub trait methods are parented to the
// containing module, not the containing trait. // containing module, not the containing trait.
if !self.parents.contains_key(&id) { if !self.parents.contains_key(&id) {
self.parents.insert(id, self.curparent); self.parents.insert(id, self.curparent);
} }
visit::walk_fn(self, a, b, c, d, ()); visit::walk_fn(self, a, b, c, d);
} }
fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident, fn visit_struct_def(&mut self, s: &ast::StructDef, _: ast::Ident,
_: &ast::Generics, n: ast::NodeId, _: ()) { _: &ast::Generics, n: ast::NodeId) {
// Struct constructors are parented to their struct definitions because // Struct constructors are parented to their struct definitions because
// they essentially are the struct definitions. // they essentially are the struct definitions.
match s.ctor_id { match s.ctor_id {
@ -125,7 +125,7 @@ impl Visitor<()> for ParentVisitor {
for field in s.fields.iter() { for field in s.fields.iter() {
self.parents.insert(field.node.id, self.curparent); self.parents.insert(field.node.id, self.curparent);
} }
visit::walk_struct_def(self, s, ()) visit::walk_struct_def(self, s)
} }
} }
@ -180,8 +180,8 @@ impl<'a, 'tcx> EmbargoVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for EmbargoVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
let orig_all_pub = self.prev_public; let orig_all_pub = self.prev_public;
self.prev_public = orig_all_pub && item.vis == ast::Public; self.prev_public = orig_all_pub && item.vis == ast::Public;
if self.prev_public { if self.prev_public {
@ -323,19 +323,19 @@ impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
self.prev_exported = orig_all_exported; self.prev_exported = orig_all_exported;
self.prev_public = orig_all_pub; self.prev_public = orig_all_pub;
} }
fn visit_foreign_item(&mut self, a: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, a: &ast::ForeignItem) {
if (self.prev_exported && a.vis == ast::Public) || self.reexports.contains(&a.id) { if (self.prev_exported && a.vis == ast::Public) || self.reexports.contains(&a.id) {
self.exported_items.insert(a.id); self.exported_items.insert(a.id);
} }
} }
fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId, _: ()) { fn visit_mod(&mut self, m: &ast::Mod, _sp: Span, id: ast::NodeId) {
// This code is here instead of in visit_item so that the // This code is here instead of in visit_item so that the
// crate module gets processed as well. // crate module gets processed as well.
if self.prev_exported { if self.prev_exported {
@ -347,7 +347,7 @@ impl<'a, 'tcx> Visitor<()> for EmbargoVisitor<'a, 'tcx> {
} }
} }
} }
visit::walk_mod(self, m, ()) visit::walk_mod(self, m)
} }
} }
@ -802,14 +802,14 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
let orig_curitem = replace(&mut self.curitem, item.id); let orig_curitem = replace(&mut self.curitem, item.id);
visit::walk_item(self, item, ()); visit::walk_item(self, item);
self.curitem = orig_curitem; self.curitem = orig_curitem;
} }
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprField(ref base, ident, _) => { ast::ExprField(ref base, ident, _) => {
match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty { match ty::get(ty::expr_ty_adjusted(self.tcx, &**base)).sty {
@ -912,10 +912,10 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
fn visit_view_item(&mut self, a: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, a: &ast::ViewItem) {
match a.node { match a.node {
ast::ViewItemExternCrate(..) => {} ast::ViewItemExternCrate(..) => {}
ast::ViewItemUse(ref vpath) => { ast::ViewItemUse(ref vpath) => {
@ -949,10 +949,10 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
} }
} }
} }
visit::walk_view_item(self, a, ()); visit::walk_view_item(self, a);
} }
fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) { fn visit_pat(&mut self, pattern: &ast::Pat) {
// Foreign functions do not have their patterns mapped in the def_map, // Foreign functions do not have their patterns mapped in the def_map,
// and there's nothing really relevant there anyway, so don't bother // and there's nothing really relevant there anyway, so don't bother
// checking privacy. If you can name the type then you can pass it to an // checking privacy. If you can name the type then you can pass it to an
@ -1012,18 +1012,18 @@ impl<'a, 'tcx> Visitor<()> for PrivacyVisitor<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_pat(self, pattern, ()); visit::walk_pat(self, pattern);
} }
fn visit_foreign_item(&mut self, fi: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, fi: &ast::ForeignItem) {
self.in_foreign = true; self.in_foreign = true;
visit::walk_foreign_item(self, fi, ()); visit::walk_foreign_item(self, fi);
self.in_foreign = false; self.in_foreign = false;
} }
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) { fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId) {
self.check_path(path.span, id, path); self.check_path(path.span, id, path);
visit::walk_path(self, path, ()); visit::walk_path(self, path);
} }
} }
@ -1036,8 +1036,8 @@ struct SanePrivacyVisitor<'a, 'tcx: 'a> {
in_fn: bool, in_fn: bool,
} }
impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for SanePrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
if self.in_fn { if self.in_fn {
self.check_all_inherited(item); self.check_all_inherited(item);
} else { } else {
@ -1049,19 +1049,19 @@ impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
ast::ItemMod(..) => false, // modules turn privacy back on ast::ItemMod(..) => false, // modules turn privacy back on
_ => in_fn, // otherwise we inherit _ => in_fn, // otherwise we inherit
}); });
visit::walk_item(self, item, ()); visit::walk_item(self, item);
self.in_fn = orig_in_fn; self.in_fn = orig_in_fn;
} }
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl, fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
b: &ast::Block, s: Span, _: ast::NodeId, _: ()) { b: &ast::Block, s: Span, _: ast::NodeId) {
// This catches both functions and methods // This catches both functions and methods
let orig_in_fn = replace(&mut self.in_fn, true); let orig_in_fn = replace(&mut self.in_fn, true);
visit::walk_fn(self, fk, fd, b, s, ()); visit::walk_fn(self, fk, fd, b, s);
self.in_fn = orig_in_fn; self.in_fn = orig_in_fn;
} }
fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.vis { match i.vis {
ast::Inherited => {} ast::Inherited => {}
ast::Public => { ast::Public => {
@ -1080,7 +1080,7 @@ impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
} }
} }
} }
visit::walk_view_item(self, i, ()); visit::walk_view_item(self, i);
} }
} }
@ -1264,8 +1264,8 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'b, 'tcx> Visitor<()> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { impl<'a, 'b, 'tcx> Visitor for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) { fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node { match ty.node {
ast::TyPath(_, _, path_id) => { ast::TyPath(_, _, path_id) => {
if self.inner.path_is_private_type(path_id) { if self.inner.path_is_private_type(path_id) {
@ -1280,15 +1280,15 @@ impl<'a, 'b, 'tcx> Visitor<()> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx>
_ => {} _ => {}
} }
self.at_outer_type = false; self.at_outer_type = false;
visit::walk_ty(self, ty, ()) visit::walk_ty(self, ty)
} }
// don't want to recurse into [, .. expr] // don't want to recurse into [, .. expr]
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {} fn visit_expr(&mut self, _: &ast::Expr) {}
} }
impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for VisiblePrivateTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
match item.node { match item.node {
// contents of a private mod can be reexported, so we need // contents of a private mod can be reexported, so we need
// to check internals. // to check internals.
@ -1320,7 +1320,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
at_outer_type: true, at_outer_type: true,
outer_type_is_public_path: false, outer_type_is_public_path: false,
}; };
visitor.visit_ty(&*self_, ()); visitor.visit_ty(&*self_);
self_contains_private = visitor.contains_private; self_contains_private = visitor.contains_private;
self_is_public_path = visitor.outer_type_is_public_path; self_is_public_path = visitor.outer_type_is_public_path;
} }
@ -1359,16 +1359,14 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
not_private_trait && not_private_trait &&
trait_or_some_public_method { trait_or_some_public_method {
visit::walk_generics(self, g, ()); visit::walk_generics(self, g);
match *trait_ref { match *trait_ref {
None => { None => {
for impl_item in impl_items.iter() { for impl_item in impl_items.iter() {
match *impl_item { match *impl_item {
ast::MethodImplItem(method) => { ast::MethodImplItem(method) => {
visit::walk_method_helper(self, visit::walk_method_helper(self, &*method)
&*method,
())
} }
} }
} }
@ -1386,7 +1384,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// //
// Those in 2. are warned via walk_generics and this // Those in 2. are warned via walk_generics and this
// call here. // call here.
visit::walk_trait_ref_helper(self, tr, ()) visit::walk_trait_ref_helper(self, tr)
} }
} }
} else if trait_ref.is_none() && self_is_public_path { } else if trait_ref.is_none() && self_is_public_path {
@ -1401,15 +1399,13 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
self.exported_items self.exported_items
.contains(&method.id) { .contains(&method.id) {
found_pub_static = true; found_pub_static = true;
visit::walk_method_helper(self, visit::walk_method_helper(self, &*method);
&*method,
());
} }
} }
} }
} }
if found_pub_static { if found_pub_static {
visit::walk_generics(self, g, ()) visit::walk_generics(self, g)
} }
} }
return return
@ -1429,25 +1425,24 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// any `visit_ty`'s will be called on things that are in // any `visit_ty`'s will be called on things that are in
// public signatures, i.e. things that we're interested in for // public signatures, i.e. things that we're interested in for
// this visitor. // this visitor.
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
fn visit_foreign_item(&mut self, item: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
if self.exported_items.contains(&item.id) { if self.exported_items.contains(&item.id) {
visit::walk_foreign_item(self, item, ()) visit::walk_foreign_item(self, item)
} }
} }
fn visit_fn(&mut self, fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
fk: &visit::FnKind, fd: &ast::FnDecl, b: &ast::Block, s: Span, id: ast::NodeId, b: &ast::Block, s: Span, id: ast::NodeId) {
_: ()) {
// needs special handling for methods. // needs special handling for methods.
if self.exported_items.contains(&id) { if self.exported_items.contains(&id) {
visit::walk_fn(self, fk, fd, b, s, ()); visit::walk_fn(self, fk, fd, b, s);
} }
} }
fn visit_ty(&mut self, t: &ast::Ty, _: ()) { fn visit_ty(&mut self, t: &ast::Ty) {
match t.node { match t.node {
ast::TyPath(ref p, _, path_id) => { ast::TyPath(ref p, _, path_id) => {
if self.path_is_private_type(path_id) { if self.path_is_private_type(path_id) {
@ -1460,19 +1455,19 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
} }
_ => {} _ => {}
} }
visit::walk_ty(self, t, ()) visit::walk_ty(self, t)
} }
fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics, _: ()) { fn visit_variant(&mut self, v: &ast::Variant, g: &ast::Generics) {
if self.exported_items.contains(&v.node.id) { if self.exported_items.contains(&v.node.id) {
visit::walk_variant(self, v, g, ()); visit::walk_variant(self, v, g);
} }
} }
fn visit_struct_field(&mut self, s: &ast::StructField, _: ()) { fn visit_struct_field(&mut self, s: &ast::StructField) {
match s.node.kind { match s.node.kind {
ast::NamedField(_, ast::Public) => { ast::NamedField(_, ast::Public) => {
visit::walk_struct_field(self, s, ()); visit::walk_struct_field(self, s);
} }
_ => {} _ => {}
} }
@ -1484,9 +1479,9 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
// things, and neither do view_items. (Making them no-ops stops us // things, and neither do view_items. (Making them no-ops stops us
// from traversing the whole AST without having to be super // from traversing the whole AST without having to be super
// careful about our `walk_...` calls above.) // careful about our `walk_...` calls above.)
fn visit_view_item(&mut self, _: &ast::ViewItem, _: ()) {} fn visit_view_item(&mut self, _: &ast::ViewItem) {}
fn visit_block(&mut self, _: &ast::Block, _: ()) {} fn visit_block(&mut self, _: &ast::Block) {}
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {} fn visit_expr(&mut self, _: &ast::Expr) {}
} }
pub fn check_crate(tcx: &ty::ctxt, pub fn check_crate(tcx: &ty::ctxt,
@ -1499,7 +1494,7 @@ pub fn check_crate(tcx: &ty::ctxt,
parents: NodeMap::new(), parents: NodeMap::new(),
curparent: ast::DUMMY_NODE_ID, curparent: ast::DUMMY_NODE_ID,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
// Use the parent map to check the privacy of everything // Use the parent map to check the privacy of everything
let mut visitor = PrivacyVisitor { let mut visitor = PrivacyVisitor {
@ -1510,7 +1505,7 @@ pub fn check_crate(tcx: &ty::ctxt,
external_exports: external_exports, external_exports: external_exports,
last_private_map: last_private_map, last_private_map: last_private_map,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
// Sanity check to make sure that all privacy usage and controls are // Sanity check to make sure that all privacy usage and controls are
// reasonable. // reasonable.
@ -1518,7 +1513,7 @@ pub fn check_crate(tcx: &ty::ctxt,
in_fn: false, in_fn: false,
tcx: tcx, tcx: tcx,
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
tcx.sess.abort_if_errors(); tcx.sess.abort_if_errors();
@ -1535,7 +1530,7 @@ pub fn check_crate(tcx: &ty::ctxt,
}; };
loop { loop {
let before = visitor.exported_items.len(); let before = visitor.exported_items.len();
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
if before == visitor.exported_items.len() { if before == visitor.exported_items.len() {
break break
} }
@ -1549,7 +1544,7 @@ pub fn check_crate(tcx: &ty::ctxt,
exported_items: &exported_items, exported_items: &exported_items,
public_items: &public_items public_items: &public_items
}; };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }
return (exported_items, public_items); return (exported_items, public_items);
} }

View file

@ -101,9 +101,9 @@ struct ReachableContext<'a, 'tcx: 'a> {
any_library: bool, any_library: bool,
} }
impl<'a, 'tcx> Visitor<()> for ReachableContext<'a, 'tcx> { impl<'a, 'tcx> Visitor for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) { fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node { match expr.node {
ast::ExprPath(_) => { ast::ExprPath(_) => {
@ -155,10 +155,10 @@ impl<'a, 'tcx> Visitor<()> for ReachableContext<'a, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, expr, ()) visit::walk_expr(self, expr)
} }
fn visit_item(&mut self, _item: &ast::Item, _: ()) { fn visit_item(&mut self, _item: &ast::Item) {
// Do not recurse into items. These items will be added to the worklist // Do not recurse into items. These items will be added to the worklist
// and recursed into manually if necessary. // and recursed into manually if necessary.
} }
@ -291,7 +291,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match item.node { match item.node {
ast::ItemFn(_, _, _, _, ref search_block) => { ast::ItemFn(_, _, _, _, ref search_block) => {
if item_might_be_inlined(&*item) { if item_might_be_inlined(&*item) {
visit::walk_block(self, &**search_block, ()) visit::walk_block(self, &**search_block)
} }
} }
@ -303,7 +303,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
item.attrs.as_slice()) { item.attrs.as_slice()) {
self.reachable_symbols.remove(&search_item); self.reachable_symbols.remove(&search_item);
} }
visit::walk_expr(self, &**init, ()); visit::walk_expr(self, &**init);
} }
// These are normal, nothing reachable about these // These are normal, nothing reachable about these
@ -327,7 +327,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// Keep going, nothing to get exported // Keep going, nothing to get exported
} }
ast::ProvidedMethod(ref method) => { ast::ProvidedMethod(ref method) => {
visit::walk_block(self, &*method.pe_body(), ()) visit::walk_block(self, &*method.pe_body())
} }
} }
} }
@ -336,7 +336,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
ast::MethodImplItem(method) => { ast::MethodImplItem(method) => {
let did = self.tcx.map.get_parent_did(search_item); let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) { if method_might_be_inlined(self.tcx, &*method, did) {
visit::walk_block(self, &*method.pe_body(), ()) visit::walk_block(self, &*method.pe_body())
} }
} }
} }

View file

@ -84,7 +84,6 @@ pub struct RegionMaps {
terminating_scopes: RefCell<HashSet<ast::NodeId>>, terminating_scopes: RefCell<HashSet<ast::NodeId>>,
} }
#[deriving(Clone)]
pub struct Context { pub struct Context {
var_parent: Option<ast::NodeId>, var_parent: Option<ast::NodeId>,
@ -97,6 +96,8 @@ struct RegionResolutionVisitor<'a> {
// Generated maps: // Generated maps:
region_maps: &'a RegionMaps, region_maps: &'a RegionMaps,
cx: Context
} }
@ -370,20 +371,21 @@ impl RegionMaps {
/// Records the current parent (if any) as the parent of `child_id`. /// Records the current parent (if any) as the parent of `child_id`.
fn record_superlifetime(visitor: &mut RegionResolutionVisitor, fn record_superlifetime(visitor: &mut RegionResolutionVisitor,
cx: Context,
child_id: ast::NodeId, child_id: ast::NodeId,
_sp: Span) { _sp: Span) {
for &parent_id in cx.parent.iter() { match visitor.cx.parent {
visitor.region_maps.record_encl_scope(child_id, parent_id); Some(parent_id) => {
visitor.region_maps.record_encl_scope(child_id, parent_id);
}
None => {}
} }
} }
/// Records the lifetime of a local variable as `cx.var_parent` /// Records the lifetime of a local variable as `cx.var_parent`
fn record_var_lifetime(visitor: &mut RegionResolutionVisitor, fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
cx: Context,
var_id: ast::NodeId, var_id: ast::NodeId,
_sp: Span) { _sp: Span) {
match cx.var_parent { match visitor.cx.var_parent {
Some(parent_id) => { Some(parent_id) => {
visitor.region_maps.record_var_scope(var_id, parent_id); visitor.region_maps.record_var_scope(var_id, parent_id);
} }
@ -395,13 +397,11 @@ fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
} }
} }
fn resolve_block(visitor: &mut RegionResolutionVisitor, fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
blk: &ast::Block,
cx: Context) {
debug!("resolve_block(blk.id={})", blk.id); debug!("resolve_block(blk.id={})", blk.id);
// Record the parent of this block. // Record the parent of this block.
record_superlifetime(visitor, cx, blk.id, blk.span); record_superlifetime(visitor, blk.id, blk.span);
// We treat the tail expression in the block (if any) somewhat // We treat the tail expression in the block (if any) somewhat
// differently from the statements. The issue has to do with // differently from the statements. The issue has to do with
@ -412,13 +412,13 @@ fn resolve_block(visitor: &mut RegionResolutionVisitor,
// } // }
// //
let subcx = Context {var_parent: Some(blk.id), parent: Some(blk.id)}; let prev_cx = visitor.cx;
visit::walk_block(visitor, blk, subcx); visitor.cx = Context {var_parent: Some(blk.id), parent: Some(blk.id)};
visit::walk_block(visitor, blk);
visitor.cx = prev_cx;
} }
fn resolve_arm(visitor: &mut RegionResolutionVisitor, fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
arm: &ast::Arm,
cx: Context) {
visitor.region_maps.mark_as_terminating_scope(arm.body.id); visitor.region_maps.mark_as_terminating_scope(arm.body.id);
match arm.guard { match arm.guard {
@ -428,48 +428,44 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor,
None => { } None => { }
} }
visit::walk_arm(visitor, arm, cx); visit::walk_arm(visitor, arm);
} }
fn resolve_pat(visitor: &mut RegionResolutionVisitor, fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
pat: &ast::Pat, record_superlifetime(visitor, pat.id, pat.span);
cx: Context) {
record_superlifetime(visitor, cx, pat.id, pat.span);
// If this is a binding (or maybe a binding, I'm too lazy to check // If this is a binding (or maybe a binding, I'm too lazy to check
// the def map) then record the lifetime of that binding. // the def map) then record the lifetime of that binding.
match pat.node { match pat.node {
ast::PatIdent(..) => { ast::PatIdent(..) => {
record_var_lifetime(visitor, cx, pat.id, pat.span); record_var_lifetime(visitor, pat.id, pat.span);
} }
_ => { } _ => { }
} }
visit::walk_pat(visitor, pat, cx); visit::walk_pat(visitor, pat);
} }
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
stmt: &ast::Stmt,
cx: Context) {
let stmt_id = stmt_id(stmt); let stmt_id = stmt_id(stmt);
debug!("resolve_stmt(stmt.id={})", stmt_id); debug!("resolve_stmt(stmt.id={})", stmt_id);
visitor.region_maps.mark_as_terminating_scope(stmt_id); visitor.region_maps.mark_as_terminating_scope(stmt_id);
record_superlifetime(visitor, cx, stmt_id, stmt.span); record_superlifetime(visitor, stmt_id, stmt.span);
let subcx = Context {parent: Some(stmt_id), ..cx}; let prev_parent = visitor.cx.parent;
visit::walk_stmt(visitor, stmt, subcx); visitor.cx.parent = Some(stmt_id);
visit::walk_stmt(visitor, stmt);
visitor.cx.parent = prev_parent;
} }
fn resolve_expr(visitor: &mut RegionResolutionVisitor, fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
expr: &ast::Expr,
cx: Context) {
debug!("resolve_expr(expr.id={})", expr.id); debug!("resolve_expr(expr.id={})", expr.id);
record_superlifetime(visitor, cx, expr.id, expr.span); record_superlifetime(visitor, expr.id, expr.span);
let mut new_cx = cx; let prev_cx = visitor.cx;
new_cx.parent = Some(expr.id); visitor.cx.parent = Some(expr.id);
match expr.node { match expr.node {
// Conditional or repeating scopes are always terminating // Conditional or repeating scopes are always terminating
// scopes, meaning that temporaries cannot outlive them. // scopes, meaning that temporaries cannot outlive them.
@ -506,11 +502,11 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
// The variable parent of everything inside (most importantly, the // The variable parent of everything inside (most importantly, the
// pattern) is the body. // pattern) is the body.
new_cx.var_parent = Some(body.id); visitor.cx.var_parent = Some(body.id);
} }
ast::ExprMatch(..) => { ast::ExprMatch(..) => {
new_cx.var_parent = Some(expr.id); visitor.cx.var_parent = Some(expr.id);
} }
ast::ExprAssignOp(..) | ast::ExprIndex(..) | ast::ExprAssignOp(..) | ast::ExprIndex(..) |
@ -538,17 +534,15 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
_ => {} _ => {}
}; };
visit::walk_expr(visitor, expr);
visit::walk_expr(visitor, expr, new_cx); visitor.cx = prev_cx;
} }
fn resolve_local(visitor: &mut RegionResolutionVisitor, fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
local: &ast::Local,
cx: Context) {
debug!("resolve_local(local.id={},local.init={})", debug!("resolve_local(local.id={},local.init={})",
local.id,local.init.is_some()); local.id,local.init.is_some());
let blk_id = match cx.var_parent { let blk_id = match visitor.cx.var_parent {
Some(id) => id, Some(id) => id,
None => { None => {
visitor.sess.span_bug( visitor.sess.span_bug(
@ -635,7 +629,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
None => { } None => { }
} }
visit::walk_local(visitor, local, cx); visit::walk_local(visitor, local);
fn is_binding_pat(pat: &ast::Pat) -> bool { fn is_binding_pat(pat: &ast::Pat) -> bool {
/*! /*!
@ -793,12 +787,12 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
} }
} }
fn resolve_item(visitor: &mut RegionResolutionVisitor, fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
item: &ast::Item,
cx: Context) {
// Items create a new outer block scope as far as we're concerned. // Items create a new outer block scope as far as we're concerned.
let new_cx = Context {var_parent: None, parent: None, ..cx}; let prev_cx = visitor.cx;
visit::walk_item(visitor, item, new_cx); visitor.cx = Context {var_parent: None, parent: None};
visit::walk_item(visitor, item);
visitor.cx = prev_cx;
} }
fn resolve_fn(visitor: &mut RegionResolutionVisitor, fn resolve_fn(visitor: &mut RegionResolutionVisitor,
@ -806,8 +800,7 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
decl: &ast::FnDecl, decl: &ast::FnDecl,
body: &ast::Block, body: &ast::Block,
sp: Span, sp: Span,
id: ast::NodeId, id: ast::NodeId) {
cx: Context) {
debug!("region::resolve_fn(id={}, \ debug!("region::resolve_fn(id={}, \
span={:?}, \ span={:?}, \
body.id={}, \ body.id={}, \
@ -815,20 +808,24 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
id, id,
visitor.sess.codemap().span_to_string(sp), visitor.sess.codemap().span_to_string(sp),
body.id, body.id,
cx.parent); visitor.cx.parent);
visitor.region_maps.mark_as_terminating_scope(body.id); visitor.region_maps.mark_as_terminating_scope(body.id);
let outer_cx = visitor.cx;
// The arguments and `self` are parented to the body of the fn. // The arguments and `self` are parented to the body of the fn.
let decl_cx = Context {parent: Some(body.id), visitor.cx = Context { parent: Some(body.id),
var_parent: Some(body.id)}; var_parent: Some(body.id) };
visit::walk_fn_decl(visitor, decl, decl_cx); visit::walk_fn_decl(visitor, decl);
// The body of the fn itself is either a root scope (top-level fn) // The body of the fn itself is either a root scope (top-level fn)
// or it continues with the inherited scope (closures). // or it continues with the inherited scope (closures).
let body_cx = match *fk { match *fk {
visit::FkItemFn(..) | visit::FkMethod(..) => { visit::FkItemFn(..) | visit::FkMethod(..) => {
Context {parent: None, var_parent: None, ..cx} visitor.cx = Context { parent: None, var_parent: None };
visitor.visit_block(body);
visitor.cx = outer_cx;
} }
visit::FkFnBlock(..) => { visit::FkFnBlock(..) => {
// FIXME(#3696) -- at present we are place the closure body // FIXME(#3696) -- at present we are place the closure body
@ -838,40 +835,40 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
// but the correct fix is a bit subtle, and I am also not sure // but the correct fix is a bit subtle, and I am also not sure
// that the present approach is unsound -- it may not permit // that the present approach is unsound -- it may not permit
// any illegal programs. See issue for more details. // any illegal programs. See issue for more details.
cx visitor.cx = outer_cx;
visitor.visit_block(body);
} }
}; }
visitor.visit_block(body, body_cx);
} }
impl<'a> Visitor<Context> for RegionResolutionVisitor<'a> { impl<'a> Visitor for RegionResolutionVisitor<'a> {
fn visit_block(&mut self, b: &Block, cx: Context) { fn visit_block(&mut self, b: &Block) {
resolve_block(self, b, cx); resolve_block(self, b);
} }
fn visit_item(&mut self, i: &Item, cx: Context) { fn visit_item(&mut self, i: &Item) {
resolve_item(self, i, cx); resolve_item(self, i);
} }
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, cx: Context) { b: &Block, s: Span, n: NodeId) {
resolve_fn(self, fk, fd, b, s, n, cx); resolve_fn(self, fk, fd, b, s, n);
} }
fn visit_arm(&mut self, a: &Arm, cx: Context) { fn visit_arm(&mut self, a: &Arm) {
resolve_arm(self, a, cx); resolve_arm(self, a);
} }
fn visit_pat(&mut self, p: &Pat, cx: Context) { fn visit_pat(&mut self, p: &Pat) {
resolve_pat(self, p, cx); resolve_pat(self, p);
} }
fn visit_stmt(&mut self, s: &Stmt, cx: Context) { fn visit_stmt(&mut self, s: &Stmt) {
resolve_stmt(self, s, cx); resolve_stmt(self, s);
} }
fn visit_expr(&mut self, ex: &Expr, cx: Context) { fn visit_expr(&mut self, ex: &Expr) {
resolve_expr(self, ex, cx); resolve_expr(self, ex);
} }
fn visit_local(&mut self, l: &Local, cx: Context) { fn visit_local(&mut self, l: &Local) {
resolve_local(self, l, cx); resolve_local(self, l);
} }
} }
@ -886,10 +883,10 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
{ {
let mut visitor = RegionResolutionVisitor { let mut visitor = RegionResolutionVisitor {
sess: sess, sess: sess,
region_maps: &maps region_maps: &maps,
cx: Context { parent: None, var_parent: None }
}; };
let cx = Context { parent: None, var_parent: None }; visit::walk_crate(&mut visitor, krate);
visit::walk_crate(&mut visitor, krate, cx);
} }
return maps; return maps;
} }
@ -897,12 +894,11 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
pub fn resolve_inlined_item(sess: &Session, pub fn resolve_inlined_item(sess: &Session,
region_maps: &RegionMaps, region_maps: &RegionMaps,
item: &ast::InlinedItem) { item: &ast::InlinedItem) {
let cx = Context {parent: None,
var_parent: None};
let mut visitor = RegionResolutionVisitor { let mut visitor = RegionResolutionVisitor {
sess: sess, sess: sess,
region_maps: region_maps, region_maps: region_maps,
cx: Context { parent: None, var_parent: None }
}; };
visit::walk_inlined_item(&mut visitor, item, cx); visit::walk_inlined_item(&mut visitor, item);
} }

View file

@ -185,23 +185,23 @@ enum NameDefinition {
ImportNameDefinition(Def, LastPrivate) //< The name identifies an import. ImportNameDefinition(Def, LastPrivate) //< The name identifies an import.
} }
impl<'a> Visitor<()> for Resolver<'a> { impl<'a> Visitor for Resolver<'a> {
fn visit_item(&mut self, item: &Item, _: ()) { fn visit_item(&mut self, item: &Item) {
self.resolve_item(item); self.resolve_item(item);
} }
fn visit_arm(&mut self, arm: &Arm, _: ()) { fn visit_arm(&mut self, arm: &Arm) {
self.resolve_arm(arm); self.resolve_arm(arm);
} }
fn visit_block(&mut self, block: &Block, _: ()) { fn visit_block(&mut self, block: &Block) {
self.resolve_block(block); self.resolve_block(block);
} }
fn visit_expr(&mut self, expr: &Expr, _: ()) { fn visit_expr(&mut self, expr: &Expr) {
self.resolve_expr(expr); self.resolve_expr(expr);
} }
fn visit_local(&mut self, local: &Local, _: ()) { fn visit_local(&mut self, local: &Local) {
self.resolve_local(local); self.resolve_local(local);
} }
fn visit_ty(&mut self, ty: &Ty, _: ()) { fn visit_ty(&mut self, ty: &Ty) {
self.resolve_type(ty); self.resolve_type(ty);
} }
} }
@ -903,32 +903,40 @@ struct Resolver<'a> {
struct BuildReducedGraphVisitor<'a, 'b:'a> { struct BuildReducedGraphVisitor<'a, 'b:'a> {
resolver: &'a mut Resolver<'b>, resolver: &'a mut Resolver<'b>,
parent: ReducedGraphParent
} }
impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> { impl<'a, 'b> Visitor for BuildReducedGraphVisitor<'a, 'b> {
fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) { fn visit_item(&mut self, item: &Item) {
let p = self.resolver.build_reduced_graph_for_item(item, context); let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
visit::walk_item(self, item, p); let old_parent = replace(&mut self.parent, p);
visit::walk_item(self, item);
self.parent = old_parent;
} }
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem, fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
context: ReducedGraphParent) { let parent = self.parent.clone();
self.resolver.build_reduced_graph_for_foreign_item(foreign_item, self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
context.clone(), parent.clone(),
|r| { |r| {
let mut v = BuildReducedGraphVisitor{ resolver: r }; let mut v = BuildReducedGraphVisitor {
visit::walk_foreign_item(&mut v, foreign_item, context.clone()); resolver: r,
parent: parent.clone()
};
visit::walk_foreign_item(&mut v, foreign_item);
}) })
} }
fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) { fn visit_view_item(&mut self, view_item: &ViewItem) {
self.resolver.build_reduced_graph_for_view_item(view_item, context); self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
} }
fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) { fn visit_block(&mut self, block: &Block) {
let np = self.resolver.build_reduced_graph_for_block(block, context); let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
visit::walk_block(self, block, np); let old_parent = replace(&mut self.parent, np);
visit::walk_block(self, block);
self.parent = old_parent;
} }
} }
@ -937,10 +945,10 @@ struct UnusedImportCheckVisitor<'a, 'b:'a> {
resolver: &'a mut Resolver<'b> resolver: &'a mut Resolver<'b>
} }
impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> { impl<'a, 'b> Visitor for UnusedImportCheckVisitor<'a, 'b> {
fn visit_view_item(&mut self, vi: &ViewItem, _: ()) { fn visit_view_item(&mut self, vi: &ViewItem) {
self.resolver.check_for_item_unused_imports(vi); self.resolver.check_for_item_unused_imports(vi);
visit::walk_view_item(self, vi, ()); visit::walk_view_item(self, vi);
} }
} }
@ -1019,11 +1027,12 @@ impl<'a> Resolver<'a> {
/// Constructs the reduced graph for the entire crate. /// Constructs the reduced graph for the entire crate.
fn build_reduced_graph(&mut self, krate: &ast::Crate) { fn build_reduced_graph(&mut self, krate: &ast::Crate) {
let initial_parent = let parent = ModuleReducedGraphParent(self.graph_root.get_module());
ModuleReducedGraphParent(self.graph_root.get_module()); let mut visitor = BuildReducedGraphVisitor {
resolver: self,
let mut visitor = BuildReducedGraphVisitor { resolver: self, }; parent: parent
visit::walk_crate(&mut visitor, krate, initial_parent); };
visit::walk_crate(&mut visitor, krate);
} }
/** /**
@ -3889,7 +3898,7 @@ impl<'a> Resolver<'a> {
fn resolve_crate(&mut self, krate: &ast::Crate) { fn resolve_crate(&mut self, krate: &ast::Crate) {
debug!("(resolving crate) starting"); debug!("(resolving crate) starting");
visit::walk_crate(self, krate, ()); visit::walk_crate(self, krate);
} }
fn resolve_item(&mut self, item: &Item) { fn resolve_item(&mut self, item: &Item) {
@ -3921,7 +3930,7 @@ impl<'a> Resolver<'a> {
|this| { |this| {
this.resolve_type_parameters(&generics.ty_params); this.resolve_type_parameters(&generics.ty_params);
this.resolve_where_clause(&generics.where_clause); this.resolve_where_clause(&generics.where_clause);
visit::walk_item(this, item, ()); visit::walk_item(this, item);
}); });
} }
@ -3932,7 +3941,7 @@ impl<'a> Resolver<'a> {
ItemRibKind), ItemRibKind),
|this| { |this| {
this.resolve_type_parameters(&generics.ty_params); this.resolve_type_parameters(&generics.ty_params);
visit::walk_item(this, item, ()); visit::walk_item(this, item);
}); });
} }
@ -4048,13 +4057,11 @@ impl<'a> Resolver<'a> {
generics, FnSpace, foreign_item.id, generics, FnSpace, foreign_item.id,
ItemRibKind), ItemRibKind),
|this| visit::walk_foreign_item(this, |this| visit::walk_foreign_item(this,
&**foreign_item, &**foreign_item));
()));
} }
ForeignItemStatic(..) => { ForeignItemStatic(..) => {
visit::walk_foreign_item(this, visit::walk_foreign_item(this,
&**foreign_item, &**foreign_item);
());
} }
} }
} }
@ -4074,7 +4081,7 @@ impl<'a> Resolver<'a> {
ItemStatic(..) => { ItemStatic(..) => {
self.with_constant_rib(|this| { self.with_constant_rib(|this| {
visit::walk_item(this, item, ()); visit::walk_item(this, item);
}); });
} }
@ -4489,7 +4496,7 @@ impl<'a> Resolver<'a> {
_name: Ident, id: NodeId) { _name: Ident, id: NodeId) {
// Write the implementations in scope into the module metadata. // Write the implementations in scope into the module metadata.
debug!("(resolving module) resolving module ID {}", id); debug!("(resolving module) resolving module ID {}", id);
visit::walk_mod(self, module, ()); visit::walk_mod(self, module);
} }
fn resolve_local(&mut self, local: &Local) { fn resolve_local(&mut self, local: &Local) {
@ -4586,7 +4593,7 @@ impl<'a> Resolver<'a> {
// pat_idents are variants // pat_idents are variants
self.check_consistent_bindings(arm); self.check_consistent_bindings(arm);
visit::walk_expr_opt(self, arm.guard, ()); visit::walk_expr_opt(self, arm.guard);
self.resolve_expr(&*arm.body); self.resolve_expr(&*arm.body);
self.value_ribs.borrow_mut().pop(); self.value_ribs.borrow_mut().pop();
@ -4608,7 +4615,7 @@ impl<'a> Resolver<'a> {
} }
// Descend into the block. // Descend into the block.
visit::walk_block(self, block, ()); visit::walk_block(self, block);
// Move back up. // Move back up.
self.current_module = orig_module; self.current_module = orig_module;
@ -4702,12 +4709,12 @@ impl<'a> Resolver<'a> {
TyClosure(c) | TyProc(c) => { TyClosure(c) | TyProc(c) => {
self.resolve_type_parameter_bounds(ty.id, &c.bounds, self.resolve_type_parameter_bounds(ty.id, &c.bounds,
TraitBoundingTypeParameter); TraitBoundingTypeParameter);
visit::walk_ty(self, ty, ()); visit::walk_ty(self, ty);
} }
_ => { _ => {
// Just resolve embedded types. // Just resolve embedded types.
visit::walk_ty(self, ty, ()); visit::walk_ty(self, ty);
} }
} }
} }
@ -5592,7 +5599,7 @@ impl<'a> Resolver<'a> {
} }
} }
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
ExprFnBlock(_, fn_decl, block) | ExprFnBlock(_, fn_decl, block) |
@ -5618,7 +5625,7 @@ impl<'a> Resolver<'a> {
} }
} }
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => { ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
@ -5633,7 +5640,7 @@ impl<'a> Resolver<'a> {
rib.bindings.borrow_mut().insert(renamed, def_like); rib.bindings.borrow_mut().insert(renamed, def_like);
} }
visit::walk_expr(this, expr, ()); visit::walk_expr(this, expr);
}) })
} }
@ -5697,7 +5704,7 @@ impl<'a> Resolver<'a> {
} }
_ => { _ => {
visit::walk_expr(self, expr, ()); visit::walk_expr(self, expr);
} }
} }
} }
@ -5847,7 +5854,7 @@ impl<'a> Resolver<'a> {
fn check_for_unused_imports(&mut self, krate: &ast::Crate) { fn check_for_unused_imports(&mut self, krate: &ast::Crate) {
let mut visitor = UnusedImportCheckVisitor{ resolver: self }; let mut visitor = UnusedImportCheckVisitor{ resolver: self };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }
fn check_for_item_unused_imports(&mut self, vi: &ViewItem) { fn check_for_item_unused_imports(&mut self, vi: &ViewItem) {

View file

@ -52,7 +52,8 @@ fn lifetime_show(lt_name: &ast::Name) -> token::InternedString {
struct LifetimeContext<'a> { struct LifetimeContext<'a> {
sess: &'a Session, sess: &'a Session,
named_region_map: NamedRegionMap, named_region_map: &'a mut NamedRegionMap,
scope: Scope<'a>
} }
enum ScopeChain<'a> { enum ScopeChain<'a> {
@ -70,117 +71,107 @@ enum ScopeChain<'a> {
type Scope<'a> = &'a ScopeChain<'a>; type Scope<'a> = &'a ScopeChain<'a>;
static ROOT_SCOPE: ScopeChain<'static> = RootScope;
pub fn krate(sess: &Session, krate: &ast::Crate) -> NamedRegionMap { pub fn krate(sess: &Session, krate: &ast::Crate) -> NamedRegionMap {
let mut ctxt = LifetimeContext { let mut named_region_map = NodeMap::new();
visit::walk_crate(&mut LifetimeContext {
sess: sess, sess: sess,
named_region_map: NodeMap::new() named_region_map: &mut named_region_map,
}; scope: &ROOT_SCOPE
visit::walk_crate(&mut ctxt, krate, &RootScope); }, krate);
sess.abort_if_errors(); sess.abort_if_errors();
ctxt.named_region_map named_region_map
} }
impl<'a, 'b> Visitor<Scope<'a>> for LifetimeContext<'b> { impl<'a> Visitor for LifetimeContext<'a> {
fn visit_item(&mut self, fn visit_item(&mut self, item: &ast::Item) {
item: &ast::Item, let lifetimes = match item.node {
_: Scope<'a>) {
let root = RootScope;
let scope = match item.node {
ast::ItemFn(..) | // fn lifetimes get added in visit_fn below ast::ItemFn(..) | // fn lifetimes get added in visit_fn below
ast::ItemMod(..) | ast::ItemMod(..) |
ast::ItemMac(..) | ast::ItemMac(..) |
ast::ItemForeignMod(..) | ast::ItemForeignMod(..) |
ast::ItemStatic(..) => { ast::ItemStatic(..) => {
RootScope self.with(|_, f| f(RootScope), |v| visit::walk_item(v, item));
return;
} }
ast::ItemTy(_, ref generics) | ast::ItemTy(_, ref generics) |
ast::ItemEnum(_, ref generics) | ast::ItemEnum(_, ref generics) |
ast::ItemStruct(_, ref generics) | ast::ItemStruct(_, ref generics) |
ast::ItemImpl(ref generics, _, _, _) | ast::ItemImpl(ref generics, _, _, _) |
ast::ItemTrait(ref generics, _, _, _) => { ast::ItemTrait(ref generics, _, _, _) => &generics.lifetimes
let scope: ScopeChain =
EarlyScope(subst::TypeSpace, &generics.lifetimes, &root);
self.check_lifetime_defs(&generics.lifetimes, &scope);
scope
}
}; };
debug!("entering scope {:?}", scope);
visit::walk_item(self, item, &scope); self.with(|_, f| f(EarlyScope(subst::TypeSpace, lifetimes, &ROOT_SCOPE)), |v| {
debug!("exiting scope {:?}", scope); debug!("entering scope {:?}", v.scope);
v.check_lifetime_defs(lifetimes);
visit::walk_item(v, item);
debug!("exiting scope {:?}", v.scope);
});
} }
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl, fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
b: &ast::Block, s: Span, n: ast::NodeId, b: &ast::Block, s: Span, n: ast::NodeId) {
scope: Scope<'a>) {
match *fk { match *fk {
visit::FkItemFn(_, generics, _, _) | visit::FkItemFn(_, generics, _, _) |
visit::FkMethod(_, generics, _) => { visit::FkMethod(_, generics, _) => {
self.visit_fn_decl( self.visit_fn_decl(n, generics, |v| visit::walk_fn(v, fk, fd, b, s))
n, generics, scope,
|this, scope1| visit::walk_fn(this, fk, fd, b, s, scope1))
} }
visit::FkFnBlock(..) => { visit::FkFnBlock(..) => {
visit::walk_fn(self, fk, fd, b, s, scope) visit::walk_fn(self, fk, fd, b, s)
} }
} }
} }
fn visit_ty(&mut self, ty: &ast::Ty, scope: Scope<'a>) { fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node { let lifetimes = match ty.node {
ast::TyClosure(c) | ast::TyProc(c) => { ast::TyClosure(ref c) | ast::TyProc(ref c) => &c.lifetimes,
push_fn_scope(self, ty, scope, &c.lifetimes); ast::TyBareFn(ref c) => &c.lifetimes,
} _ => return visit::walk_ty(self, ty)
ast::TyBareFn(c) => push_fn_scope(self, ty, scope, &c.lifetimes), };
_ => visit::walk_ty(self, ty, scope),
}
fn push_fn_scope(this: &mut LifetimeContext, self.with(|scope, f| f(LateScope(ty.id, lifetimes, scope)), |v| {
ty: &ast::Ty, v.check_lifetime_defs(lifetimes);
scope: Scope,
lifetimes: &Vec<ast::LifetimeDef>) {
let scope1: ScopeChain = LateScope(ty.id, lifetimes, scope);
this.check_lifetime_defs(lifetimes, &scope1);
debug!("pushing fn scope id={} due to type", ty.id); debug!("pushing fn scope id={} due to type", ty.id);
visit::walk_ty(this, ty, &scope1); visit::walk_ty(v, ty);
debug!("popping fn scope id={} due to type", ty.id); debug!("popping fn scope id={} due to type", ty.id);
} });
} }
fn visit_ty_method(&mut self, fn visit_ty_method(&mut self, m: &ast::TypeMethod) {
m: &ast::TypeMethod, self.visit_fn_decl(m.id, &m.generics, |v| visit::walk_ty_method(v, m))
scope: Scope<'a>) {
self.visit_fn_decl(
m.id, &m.generics, scope,
|this, scope1| visit::walk_ty_method(this, m, scope1))
} }
fn visit_block(&mut self, fn visit_block(&mut self, b: &ast::Block) {
b: &ast::Block,
scope: Scope<'a>) {
let scope1 = BlockScope(b.id, scope);
debug!("pushing block scope {}", b.id); debug!("pushing block scope {}", b.id);
visit::walk_block(self, b, &scope1); self.with(|scope, f| f(BlockScope(b.id, scope)), |v| visit::walk_block(v, b));
debug!("popping block scope {}", b.id); debug!("popping block scope {}", b.id);
} }
fn visit_lifetime_ref(&mut self, fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
lifetime_ref: &ast::Lifetime,
scope: Scope<'a>) {
if lifetime_ref.name == special_idents::static_lifetime.name { if lifetime_ref.name == special_idents::static_lifetime.name {
self.insert_lifetime(lifetime_ref, DefStaticRegion); self.insert_lifetime(lifetime_ref, DefStaticRegion);
return; return;
} }
self.resolve_lifetime_ref(lifetime_ref, scope); self.resolve_lifetime_ref(lifetime_ref);
} }
} }
impl<'a> LifetimeContext<'a> { impl<'a> LifetimeContext<'a> {
fn with(&mut self, wrap_scope: |Scope, |ScopeChain||, f: |&mut LifetimeContext|) {
let LifetimeContext { sess, ref mut named_region_map, scope} = *self;
wrap_scope(scope, |scope1| f(&mut LifetimeContext {
sess: sess,
named_region_map: *named_region_map,
scope: &scope1
}))
}
/// Visits self by adding a scope and handling recursive walk over the contents with `walk`. /// Visits self by adding a scope and handling recursive walk over the contents with `walk`.
fn visit_fn_decl(&mut self, fn visit_fn_decl(&mut self,
n: ast::NodeId, n: ast::NodeId,
generics: &ast::Generics, generics: &ast::Generics,
scope: Scope, walk: |&mut LifetimeContext|) {
walk: |&mut LifetimeContext, Scope|) {
/*! /*!
* Handles visiting fns and methods. These are a bit * Handles visiting fns and methods. These are a bit
* complicated because we must distinguish early- vs late-bound * complicated because we must distinguish early- vs late-bound
@ -210,25 +201,27 @@ impl<'a> LifetimeContext<'a> {
referenced_idents={:?}", referenced_idents={:?}",
n, n,
referenced_idents.iter().map(lifetime_show).collect::<Vec<token::InternedString>>()); referenced_idents.iter().map(lifetime_show).collect::<Vec<token::InternedString>>());
let lifetimes = &generics.lifetimes;
if referenced_idents.is_empty() { if referenced_idents.is_empty() {
let scope1: ScopeChain = LateScope(n, &generics.lifetimes, scope); self.with(|scope, f| f(LateScope(n, lifetimes, scope)), |v| {
self.check_lifetime_defs(&generics.lifetimes, &scope1); v.check_lifetime_defs(lifetimes);
walk(self, &scope1); walk(v);
});
} else { } else {
let (early, late) = generics.lifetimes.clone().partition( let (early, late) = lifetimes.clone().partition(
|l| referenced_idents.iter().any(|&i| i == l.lifetime.name)); |l| referenced_idents.iter().any(|&i| i == l.lifetime.name));
let scope1 = EarlyScope(subst::FnSpace, &early, scope); self.with(|scope, f| f(EarlyScope(subst::FnSpace, &early, scope)), |v| {
let scope2: ScopeChain = LateScope(n, &late, &scope1); v.with(|scope1, f| f(LateScope(n, &late, scope1)), |v| {
self.check_lifetime_defs(&generics.lifetimes, &scope2); v.check_lifetime_defs(lifetimes);
walk(self, &scope2); walk(v);
});
});
} }
debug!("popping fn scope id={} due to fn item/method", n); debug!("popping fn scope id={} due to fn item/method", n);
} }
fn resolve_lifetime_ref(&mut self, fn resolve_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
lifetime_ref: &ast::Lifetime,
scope: Scope) {
// Walk up the scope chain, tracking the number of fn scopes // Walk up the scope chain, tracking the number of fn scopes
// that we pass through, until we find a lifetime with the // that we pass through, until we find a lifetime with the
// given name or we run out of scopes. If we encounter a code // given name or we run out of scopes. If we encounter a code
@ -236,7 +229,7 @@ impl<'a> LifetimeContext<'a> {
// over to `resolve_free_lifetime_ref()` to complete the // over to `resolve_free_lifetime_ref()` to complete the
// search. // search.
let mut depth = 0; let mut depth = 0;
let mut scope = scope; let mut scope = self.scope;
loop { loop {
match *scope { match *scope {
BlockScope(id, s) => { BlockScope(id, s) => {
@ -326,17 +319,14 @@ impl<'a> LifetimeContext<'a> {
} }
fn unresolved_lifetime_ref(&self, fn unresolved_lifetime_ref(&self, lifetime_ref: &ast::Lifetime) {
lifetime_ref: &ast::Lifetime) {
self.sess.span_err( self.sess.span_err(
lifetime_ref.span, lifetime_ref.span,
format!("use of undeclared lifetime name `{}`", format!("use of undeclared lifetime name `{}`",
token::get_name(lifetime_ref.name)).as_slice()); token::get_name(lifetime_ref.name)).as_slice());
} }
fn check_lifetime_defs<'b>(&mut self, fn check_lifetime_defs(&mut self, lifetimes: &Vec<ast::LifetimeDef>) {
lifetimes: &Vec<ast::LifetimeDef>,
scope: Scope<'b>) {
for i in range(0, lifetimes.len()) { for i in range(0, lifetimes.len()) {
let lifetime_i = lifetimes.get(i); let lifetime_i = lifetimes.get(i);
@ -365,7 +355,7 @@ impl<'a> LifetimeContext<'a> {
} }
for bound in lifetime_i.bounds.iter() { for bound in lifetime_i.bounds.iter() {
self.resolve_lifetime_ref(bound, scope); self.resolve_lifetime_ref(bound);
} }
} }
} }
@ -434,10 +424,10 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
FreeLifetimeCollector { early_bound: &mut early_bound, FreeLifetimeCollector { early_bound: &mut early_bound,
late_bound: &mut late_bound }; late_bound: &mut late_bound };
for ty_param in generics.ty_params.iter() { for ty_param in generics.ty_params.iter() {
visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds, ()); visit::walk_ty_param_bounds(&mut collector, &ty_param.bounds);
} }
for predicate in generics.where_clause.predicates.iter() { for predicate in generics.where_clause.predicates.iter() {
visit::walk_ty_param_bounds(&mut collector, &predicate.bounds, ()); visit::walk_ty_param_bounds(&mut collector, &predicate.bounds);
} }
} }
@ -460,10 +450,8 @@ fn early_bound_lifetime_names(generics: &ast::Generics) -> Vec<ast::Name> {
late_bound: &'a mut Vec<ast::Name>, late_bound: &'a mut Vec<ast::Name>,
} }
impl<'a> Visitor<()> for FreeLifetimeCollector<'a> { impl<'a> Visitor for FreeLifetimeCollector<'a> {
fn visit_lifetime_ref(&mut self, fn visit_lifetime_ref(&mut self, lifetime_ref: &ast::Lifetime) {
lifetime_ref: &ast::Lifetime,
_: ()) {
shuffle(self.early_bound, self.late_bound, shuffle(self.early_bound, self.late_bound,
lifetime_ref.name); lifetime_ref.name);
} }

View file

@ -83,9 +83,18 @@ struct DxrVisitor<'l, 'tcx: 'l> {
span: SpanUtils<'l>, span: SpanUtils<'l>,
fmt: FmtStrs<'l>, fmt: FmtStrs<'l>,
cur_scope: NodeId
} }
impl <'l, 'tcx> DxrVisitor<'l, 'tcx> { impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
let parent_scope = self.cur_scope;
self.cur_scope = scope_id;
f(self);
self.cur_scope = parent_scope;
}
fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) { fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) {
// the current crate // the current crate
self.fmt.crate_str(krate.span, name); self.fmt.crate_str(krate.span, name);
@ -136,19 +145,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
result result
} }
fn write_sub_paths(&mut self, path: &ast::Path, scope_id: NodeId) { fn write_sub_paths(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path); let sub_paths = self.process_path_prefixes(path);
for &(ref span, ref qualname) in sub_paths.iter() { for &(ref span, ref qualname) in sub_paths.iter() {
self.fmt.sub_mod_ref_str(path.span, self.fmt.sub_mod_ref_str(path.span,
*span, *span,
qualname.as_slice(), qualname.as_slice(),
scope_id); self.cur_scope);
} }
} }
// As write_sub_paths, but does not process the last ident in the path (assuming it // As write_sub_paths, but does not process the last ident in the path (assuming it
// will be processed elsewhere). // will be processed elsewhere).
fn write_sub_paths_truncated(&mut self, path: &ast::Path, scope_id: NodeId) { fn write_sub_paths_truncated(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path); let sub_paths = self.process_path_prefixes(path);
let len = sub_paths.len(); let len = sub_paths.len();
if len <= 1 { if len <= 1 {
@ -160,13 +169,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.fmt.sub_mod_ref_str(path.span, self.fmt.sub_mod_ref_str(path.span,
*span, *span,
qualname.as_slice(), qualname.as_slice(),
scope_id); self.cur_scope);
} }
} }
// As write_sub_paths, but expects a path of the form module_path::trait::method // As write_sub_paths, but expects a path of the form module_path::trait::method
// Where trait could actually be a struct too. // Where trait could actually be a struct too.
fn write_sub_path_trait_truncated(&mut self, path: &ast::Path, scope_id: NodeId) { fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) {
let sub_paths = self.process_path_prefixes(path); let sub_paths = self.process_path_prefixes(path);
let len = sub_paths.len(); let len = sub_paths.len();
if len <= 1 { if len <= 1 {
@ -189,7 +198,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.fmt.sub_mod_ref_str(path.span, self.fmt.sub_mod_ref_str(path.span,
*span, *span,
qualname.as_slice(), qualname.as_slice(),
scope_id); self.cur_scope);
} }
} }
@ -243,11 +252,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} }
} }
fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str, e:DxrVisitorEnv) { fn process_formals(&mut self, formals: &Vec<ast::Arg>, qualname: &str) {
for arg in formals.iter() { for arg in formals.iter() {
assert!(self.collected_paths.len() == 0 && !self.collecting); assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true; self.collecting = true;
self.visit_pat(&*arg.pat, e); self.visit_pat(&*arg.pat);
self.collecting = false; self.collecting = false;
let span_utils = self.span; let span_utils = self.span;
for &(id, ref p, _, _) in self.collected_paths.iter() { for &(id, ref p, _, _) in self.collected_paths.iter() {
@ -266,7 +275,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} }
} }
fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) { fn process_method(&mut self, method: &ast::Method) {
if generated_code(method.span) { if generated_code(method.span) {
return; return;
} }
@ -361,27 +370,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
decl_id, decl_id,
scope_id); scope_id);
self.process_formals(&method.pe_fn_decl().inputs, qualname, e); self.process_formals(&method.pe_fn_decl().inputs, qualname);
// walk arg and return types // walk arg and return types
for arg in method.pe_fn_decl().inputs.iter() { for arg in method.pe_fn_decl().inputs.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty);
} }
self.visit_ty(&*method.pe_fn_decl().output, e); self.visit_ty(&*method.pe_fn_decl().output);
// walk the fn body // walk the fn body
self.visit_block(&*method.pe_body(), self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
DxrVisitorEnv::new_nested(method.id));
self.process_generic_params(method.pe_generics(), self.process_generic_params(method.pe_generics(),
method.span, method.span,
qualname, qualname,
method.id, method.id);
e);
} }
fn process_trait_ref(&mut self, fn process_trait_ref(&mut self,
trait_ref: &ast::TraitRef, trait_ref: &ast::TraitRef,
e: DxrVisitorEnv,
impl_id: Option<NodeId>) { impl_id: Option<NodeId>) {
match self.lookup_type_ref(trait_ref.ref_id) { match self.lookup_type_ref(trait_ref.ref_id) {
Some(id) => { Some(id) => {
@ -390,16 +396,16 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
trait_ref.path.span, trait_ref.path.span,
sub_span, sub_span,
id, id,
e.cur_scope); self.cur_scope);
match impl_id { match impl_id {
Some(impl_id) => self.fmt.impl_str(trait_ref.path.span, Some(impl_id) => self.fmt.impl_str(trait_ref.path.span,
sub_span, sub_span,
impl_id, impl_id,
id, id,
e.cur_scope), self.cur_scope),
None => (), None => (),
} }
visit::walk_path(self, &trait_ref.path, e); visit::walk_path(self, &trait_ref.path);
}, },
None => () None => ()
} }
@ -436,8 +442,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
fn process_generic_params(&mut self, generics:&ast::Generics, fn process_generic_params(&mut self, generics:&ast::Generics,
full_span: Span, full_span: Span,
prefix: &str, prefix: &str,
id: NodeId, id: NodeId) {
e: DxrVisitorEnv) {
// We can't only use visit_generics since we don't have spans for param // We can't only use visit_generics since we don't have spans for param
// bindings, so we reparse the full_span to get those sub spans. // bindings, so we reparse the full_span to get those sub spans.
// However full span is the entire enum/fn/struct block, so we only want // However full span is the entire enum/fn/struct block, so we only want
@ -456,12 +461,11 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
name.as_slice(), name.as_slice(),
""); "");
} }
self.visit_generics(generics, e); self.visit_generics(generics);
} }
fn process_fn(&mut self, fn process_fn(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
decl: ast::P<ast::FnDecl>, decl: ast::P<ast::FnDecl>,
ty_params: &ast::Generics, ty_params: &ast::Generics,
body: ast::P<ast::Block>) { body: ast::P<ast::Block>) {
@ -472,25 +476,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span, sub_span,
item.id, item.id,
qualname.as_slice(), qualname.as_slice(),
e.cur_scope); self.cur_scope);
self.process_formals(&decl.inputs, qualname.as_slice(), e); self.process_formals(&decl.inputs, qualname.as_slice());
// walk arg and return types // walk arg and return types
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty);
} }
self.visit_ty(&*decl.output, e); self.visit_ty(&*decl.output);
// walk the body // walk the body
self.visit_block(&*body, DxrVisitorEnv::new_nested(item.id)); self.nest(item.id, |v| v.visit_block(&*body));
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e); self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
} }
fn process_static(&mut self, fn process_static(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
typ: ast::P<ast::Ty>, typ: ast::P<ast::Ty>,
mt: ast::Mutability, mt: ast::Mutability,
expr: &ast::Expr) expr: &ast::Expr)
@ -511,16 +514,15 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
qualname.as_slice(), qualname.as_slice(),
value.as_slice(), value.as_slice(),
ty_to_string(&*typ).as_slice(), ty_to_string(&*typ).as_slice(),
e.cur_scope); self.cur_scope);
// walk type and init value // walk type and init value
self.visit_ty(&*typ, e); self.visit_ty(&*typ);
self.visit_expr(expr, e); self.visit_expr(expr);
} }
fn process_struct(&mut self, fn process_struct(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
def: &ast::StructDef, def: &ast::StructDef,
ty_params: &ast::Generics) { ty_params: &ast::Generics) {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id); let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@ -535,20 +537,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
item.id, item.id,
ctor_id, ctor_id,
qualname.as_slice(), qualname.as_slice(),
e.cur_scope); self.cur_scope);
// fields // fields
for field in def.fields.iter() { for field in def.fields.iter() {
self.process_struct_field_def(field, qualname.as_slice(), item.id); self.process_struct_field_def(field, qualname.as_slice(), item.id);
self.visit_ty(&*field.node.ty, e); self.visit_ty(&*field.node.ty);
} }
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e); self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
} }
fn process_enum(&mut self, fn process_enum(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
enum_definition: &ast::EnumDef, enum_definition: &ast::EnumDef,
ty_params: &ast::Generics) { ty_params: &ast::Generics) {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id); let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@ -557,7 +558,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
Some(sub_span), Some(sub_span),
item.id, item.id,
qualname.as_slice(), qualname.as_slice(),
e.cur_scope), self.cur_scope),
None => self.sess.span_bug(item.span, None => self.sess.span_bug(item.span,
format!("Could not find subspan for enum {}", format!("Could not find subspan for enum {}",
qualname).as_slice()), qualname).as_slice()),
@ -578,7 +579,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
val.as_slice(), val.as_slice(),
item.id); item.id);
for arg in args.iter() { for arg in args.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty);
} }
} }
ast::StructVariantKind(ref struct_def) => { ast::StructVariantKind(ref struct_def) => {
@ -597,18 +598,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
for field in struct_def.fields.iter() { for field in struct_def.fields.iter() {
self.process_struct_field_def(field, qualname.as_slice(), variant.node.id); self.process_struct_field_def(field, qualname.as_slice(), variant.node.id);
self.visit_ty(&*field.node.ty, e); self.visit_ty(&*field.node.ty);
} }
} }
} }
} }
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e); self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
} }
fn process_impl(&mut self, fn process_impl(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
type_parameters: &ast::Generics, type_parameters: &ast::Generics,
trait_ref: &Option<ast::TraitRef>, trait_ref: &Option<ast::TraitRef>,
typ: ast::P<ast::Ty>, typ: ast::P<ast::Ty>,
@ -622,29 +622,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
path.span, path.span,
sub_span, sub_span,
id, id,
e.cur_scope); self.cur_scope);
self.fmt.impl_str(path.span, self.fmt.impl_str(path.span,
sub_span, sub_span,
item.id, item.id,
id, id,
e.cur_scope); self.cur_scope);
}, },
None => () None => ()
} }
}, },
_ => self.visit_ty(&*typ, e), _ => self.visit_ty(&*typ),
} }
match *trait_ref { match *trait_ref {
Some(ref trait_ref) => self.process_trait_ref(trait_ref, e, Some(item.id)), Some(ref trait_ref) => self.process_trait_ref(trait_ref, Some(item.id)),
None => (), None => (),
} }
self.process_generic_params(type_parameters, item.span, "", item.id, e); self.process_generic_params(type_parameters, item.span, "", item.id);
for impl_item in impl_items.iter() { for impl_item in impl_items.iter() {
match *impl_item { match *impl_item {
ast::MethodImplItem(method) => { ast::MethodImplItem(method) => {
visit::walk_method_helper(self, &*method, e) visit::walk_method_helper(self, &*method)
} }
} }
} }
@ -652,7 +652,6 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
fn process_trait(&mut self, fn process_trait(&mut self,
item: &ast::Item, item: &ast::Item,
e: DxrVisitorEnv,
generics: &ast::Generics, generics: &ast::Generics,
trait_refs: &OwnedSlice<ast::TyParamBound>, trait_refs: &OwnedSlice<ast::TyParamBound>,
methods: &Vec<ast::TraitItem>) { methods: &Vec<ast::TraitItem>) {
@ -663,7 +662,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span, sub_span,
item.id, item.id,
qualname.as_slice(), qualname.as_slice(),
e.cur_scope); self.cur_scope);
// super-traits // super-traits
for super_bound in trait_refs.iter() { for super_bound in trait_refs.iter() {
@ -683,7 +682,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
trait_ref.path.span, trait_ref.path.span,
sub_span, sub_span,
id, id,
e.cur_scope); self.cur_scope);
self.fmt.inherit_str(trait_ref.path.span, self.fmt.inherit_str(trait_ref.path.span,
sub_span, sub_span,
id, id,
@ -694,15 +693,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} }
// walk generics and methods // walk generics and methods
self.process_generic_params(generics, item.span, qualname.as_slice(), item.id, e); self.process_generic_params(generics, item.span, qualname.as_slice(), item.id);
for method in methods.iter() { for method in methods.iter() {
self.visit_trait_item(method, e) self.visit_trait_item(method)
} }
} }
fn process_mod(&mut self, fn process_mod(&mut self,
item: &ast::Item, // The module in question, represented as an item. item: &ast::Item, // The module in question, represented as an item.
e: DxrVisitorEnv,
m: &ast::Mod) { m: &ast::Mod) {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id); let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@ -714,15 +712,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span, sub_span,
item.id, item.id,
qualname.as_slice(), qualname.as_slice(),
e.cur_scope, self.cur_scope,
filename.as_slice()); filename.as_slice());
visit::walk_mod(self, m, DxrVisitorEnv::new_nested(item.id)); self.nest(item.id, |v| visit::walk_mod(v, m));
} }
fn process_path(&mut self, fn process_path(&mut self,
ex: &ast::Expr, ex: &ast::Expr,
e: DxrVisitorEnv,
path: &ast::Path) { path: &ast::Path) {
if generated_code(path.span) { if generated_code(path.span) {
return return
@ -744,18 +741,18 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
ex.span, ex.span,
sub_span, sub_span,
ast_util::local_def(id), ast_util::local_def(id),
e.cur_scope), self.cur_scope),
def::DefStatic(def_id,_) | def::DefStatic(def_id,_) |
def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef, def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef,
ex.span, ex.span,
sub_span, sub_span,
def_id, def_id,
e.cur_scope), self.cur_scope),
def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef, def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
ex.span, ex.span,
sub_span, sub_span,
def_id, def_id,
e.cur_scope), self.cur_scope),
def::DefStaticMethod(declid, provenence, _) => { def::DefStaticMethod(declid, provenence, _) => {
let sub_span = self.span.sub_span_for_meth_name(ex.span); let sub_span = self.span.sub_span_for_meth_name(ex.span);
let defid = if declid.krate == ast::LOCAL_CRATE { let defid = if declid.krate == ast::LOCAL_CRATE {
@ -806,12 +803,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span, sub_span,
defid, defid,
Some(declid), Some(declid),
e.cur_scope); self.cur_scope);
}, },
def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span, def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
sub_span, sub_span,
def_id, def_id,
e.cur_scope), self.cur_scope),
_ => self.sess.span_bug(ex.span, _ => self.sess.span_bug(ex.span,
format!("Unexpected def kind while looking up path in '{}'", format!("Unexpected def kind while looking up path in '{}'",
self.span.snippet(ex.span)).as_slice()), self.span.snippet(ex.span)).as_slice()),
@ -819,22 +816,21 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
// modules or types in the path prefix // modules or types in the path prefix
match *def { match *def {
def::DefStaticMethod(_, _, _) => { def::DefStaticMethod(_, _, _) => {
self.write_sub_path_trait_truncated(path, e.cur_scope); self.write_sub_path_trait_truncated(path);
}, },
def::DefLocal(_, _) | def::DefLocal(_, _) |
def::DefArg(_, _) | def::DefArg(_, _) |
def::DefStatic(_,_) | def::DefStatic(_,_) |
def::DefStruct(_) | def::DefStruct(_) |
def::DefFn(_, _) => self.write_sub_paths_truncated(path, e.cur_scope), def::DefFn(_, _) => self.write_sub_paths_truncated(path),
_ => {}, _ => {},
} }
visit::walk_path(self, path, e); visit::walk_path(self, path);
} }
fn process_struct_lit(&mut self, fn process_struct_lit(&mut self,
ex: &ast::Expr, ex: &ast::Expr,
e: DxrVisitorEnv,
path: &ast::Path, path: &ast::Path,
fields: &Vec<ast::Field>, fields: &Vec<ast::Field>,
base: Option<Gc<ast::Expr>>) { base: Option<Gc<ast::Expr>>) {
@ -851,12 +847,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
path.span, path.span,
sub_span, sub_span,
id, id,
e.cur_scope); self.cur_scope);
}, },
None => () None => ()
} }
self.write_sub_paths_truncated(path, e.cur_scope); self.write_sub_paths_truncated(path);
for field in fields.iter() { for field in fields.iter() {
match struct_def { match struct_def {
@ -873,21 +869,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
field.ident.span, field.ident.span,
sub_span, sub_span,
f.id, f.id,
e.cur_scope); self.cur_scope);
} }
} }
} }
None => {} None => {}
} }
self.visit_expr(&*field.expr, e) self.visit_expr(&*field.expr)
} }
visit::walk_expr_opt(self, base, e) visit::walk_expr_opt(self, base)
} }
fn process_method_call(&mut self, fn process_method_call(&mut self,
ex: &ast::Expr, ex: &ast::Expr,
e: DxrVisitorEnv,
args: &Vec<Gc<ast::Expr>>) { args: &Vec<Gc<ast::Expr>>) {
let method_map = self.analysis.ty_cx.method_map.borrow(); let method_map = self.analysis.ty_cx.method_map.borrow();
let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id)); let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id));
@ -941,13 +936,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span, sub_span,
def_id, def_id,
decl_id, decl_id,
e.cur_scope); self.cur_scope);
// walk receiver and args // walk receiver and args
visit::walk_exprs(self, args.as_slice(), e); visit::walk_exprs(self, args.as_slice());
} }
fn process_pat(&mut self, p:&ast::Pat, e: DxrVisitorEnv) { fn process_pat(&mut self, p:&ast::Pat) {
if generated_code(p.span) { if generated_code(p.span) {
return return
} }
@ -955,7 +950,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
match p.node { match p.node {
ast::PatStruct(ref path, ref fields, _) => { ast::PatStruct(ref path, ref fields, _) => {
self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef)); self.collected_paths.push((p.id, path.clone(), false, recorder::StructRef));
visit::walk_path(self, path, e); visit::walk_path(self, path);
let struct_def = match self.lookup_type_ref(p.id) { let struct_def = match self.lookup_type_ref(p.id) {
Some(sd) => sd, Some(sd) => sd,
None => { None => {
@ -976,7 +971,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
).as_slice()); ).as_slice());
} }
for (field, &span) in fields.iter().zip(field_spans.iter()) { for (field, &span) in fields.iter().zip(field_spans.iter()) {
self.visit_pat(&*field.pat, e); self.visit_pat(&*field.pat);
if span.is_none() { if span.is_none() {
continue; continue;
} }
@ -987,7 +982,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
p.span, p.span,
span, span,
f.id, f.id,
e.cur_scope); self.cur_scope);
break; break;
} }
} }
@ -995,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
} }
ast::PatEnum(ref path, _) => { ast::PatEnum(ref path, _) => {
self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef)); self.collected_paths.push((p.id, path.clone(), false, recorder::VarRef));
visit::walk_pat(self, p, e); visit::walk_pat(self, p);
} }
ast::PatIdent(bm, ref path1, ref optional_subpattern) => { ast::PatIdent(bm, ref path1, ref optional_subpattern) => {
let immut = match bm { let immut = match bm {
@ -1015,41 +1010,40 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.collected_paths.push((p.id, path, immut, recorder::VarRef)); self.collected_paths.push((p.id, path, immut, recorder::VarRef));
match *optional_subpattern { match *optional_subpattern {
None => {} None => {}
Some(subpattern) => self.visit_pat(&*subpattern, e), Some(subpattern) => self.visit_pat(&*subpattern),
} }
} }
_ => visit::walk_pat(self, p, e) _ => visit::walk_pat(self, p)
} }
} }
} }
impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> { impl<'l, 'tcx> Visitor for DxrVisitor<'l, 'tcx> {
fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) { fn visit_item(&mut self, item:&ast::Item) {
if generated_code(item.span) { if generated_code(item.span) {
return return
} }
match item.node { match item.node {
ast::ItemFn(decl, _, _, ref ty_params, body) => ast::ItemFn(decl, _, _, ref ty_params, body) =>
self.process_fn(item, e, decl, ty_params, body), self.process_fn(item, decl, ty_params, body),
ast::ItemStatic(typ, mt, expr) => ast::ItemStatic(typ, mt, expr) =>
self.process_static(item, e, typ, mt, &*expr), self.process_static(item, typ, mt, &*expr),
ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params), ast::ItemStruct(def, ref ty_params) => self.process_struct(item, &*def, ty_params),
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params), ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
ast::ItemImpl(ref ty_params, ast::ItemImpl(ref ty_params,
ref trait_ref, ref trait_ref,
typ, typ,
ref impl_items) => { ref impl_items) => {
self.process_impl(item, self.process_impl(item,
e,
ty_params, ty_params,
trait_ref, trait_ref,
typ, typ,
impl_items) impl_items)
} }
ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) => ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
self.process_trait(item, e, generics, trait_refs, methods), self.process_trait(item, generics, trait_refs, methods),
ast::ItemMod(ref m) => self.process_mod(item, e, m), ast::ItemMod(ref m) => self.process_mod(item, m),
ast::ItemTy(ty, ref ty_params) => { ast::ItemTy(ty, ref ty_params) => {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id); let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let value = ty_to_string(&*ty); let value = ty_to_string(&*ty);
@ -1060,26 +1054,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
qualname.as_slice(), qualname.as_slice(),
value.as_slice()); value.as_slice());
self.visit_ty(&*ty, e); self.visit_ty(&*ty);
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e); self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
}, },
ast::ItemMac(_) => (), ast::ItemMac(_) => (),
_ => visit::walk_item(self, item, e), _ => visit::walk_item(self, item),
} }
} }
fn visit_generics(&mut self, generics: &ast::Generics, e: DxrVisitorEnv) { fn visit_generics(&mut self, generics: &ast::Generics) {
for param in generics.ty_params.iter() { for param in generics.ty_params.iter() {
for bound in param.bounds.iter() { for bound in param.bounds.iter() {
match *bound { match *bound {
ast::TraitTyParamBound(ref trait_ref) => { ast::TraitTyParamBound(ref trait_ref) => {
self.process_trait_ref(trait_ref, e, None); self.process_trait_ref(trait_ref, None);
} }
_ => {} _ => {}
} }
} }
match param.default { match param.default {
Some(ty) => self.visit_ty(&*ty, e), Some(ty) => self.visit_ty(&*ty),
None => (), None => (),
} }
} }
@ -1092,19 +1086,18 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
fd: &ast::FnDecl, fd: &ast::FnDecl,
b: &ast::Block, b: &ast::Block,
s: Span, s: Span,
_: NodeId, _: NodeId) {
e: DxrVisitorEnv) {
if generated_code(s) { if generated_code(s) {
return; return;
} }
match *fk { match *fk {
visit::FkMethod(_, _, method) => self.process_method(method, e), visit::FkMethod(_, _, method) => self.process_method(method),
_ => visit::walk_fn(self, fk, fd, b, s, e), _ => visit::walk_fn(self, fk, fd, b, s),
} }
} }
fn visit_trait_item(&mut self, tm: &ast::TraitItem, e: DxrVisitorEnv) { fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
match *tm { match *tm {
ast::RequiredMethod(ref method_type) => { ast::RequiredMethod(ref method_type) => {
if generated_code(method_type.span) { if generated_code(method_type.span) {
@ -1137,21 +1130,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
// walk arg and return types // walk arg and return types
for arg in method_type.decl.inputs.iter() { for arg in method_type.decl.inputs.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty);
} }
self.visit_ty(&*method_type.decl.output, e); self.visit_ty(&*method_type.decl.output);
self.process_generic_params(&method_type.generics, self.process_generic_params(&method_type.generics,
method_type.span, method_type.span,
qualname, qualname,
method_type.id, method_type.id);
e);
} }
ast::ProvidedMethod(method) => self.process_method(&*method, e), ast::ProvidedMethod(method) => self.process_method(&*method),
} }
} }
fn visit_view_item(&mut self, i:&ast::ViewItem, e:DxrVisitorEnv) { fn visit_view_item(&mut self, i:&ast::ViewItem) {
if generated_code(i.span) { if generated_code(i.span) {
return return
} }
@ -1168,7 +1160,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
path.span, path.span,
sub_span, sub_span,
def_id, def_id,
e.cur_scope), self.cur_scope),
None => {}, None => {},
} }
Some(def_id) Some(def_id)
@ -1189,11 +1181,11 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
id, id,
mod_id, mod_id,
get_ident(ident).get(), get_ident(ident).get(),
e.cur_scope); self.cur_scope);
self.write_sub_paths_truncated(path, e.cur_scope); self.write_sub_paths_truncated(path);
} }
ast::ViewPathGlob(ref path, _) => { ast::ViewPathGlob(ref path, _) => {
self.write_sub_paths(path, e.cur_scope); self.write_sub_paths(path);
} }
ast::ViewPathList(ref path, ref list, _) => { ast::ViewPathList(ref path, ref list, _) => {
for plid in list.iter() { for plid in list.iter() {
@ -1206,7 +1198,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
self.fmt.ref_str( self.fmt.ref_str(
kind, plid.span, kind, plid.span,
Some(plid.span), Some(plid.span),
def_id, e.cur_scope); def_id, self.cur_scope);
} }
None => () None => ()
}, },
@ -1217,7 +1209,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
} }
} }
self.write_sub_paths(path, e.cur_scope); self.write_sub_paths(path);
} }
} }
}, },
@ -1239,12 +1231,12 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
cnum, cnum,
name, name,
s.as_slice(), s.as_slice(),
e.cur_scope); self.cur_scope);
}, },
} }
} }
fn visit_ty(&mut self, t: &ast::Ty, e: DxrVisitorEnv) { fn visit_ty(&mut self, t: &ast::Ty) {
if generated_code(t.span) { if generated_code(t.span) {
return return
} }
@ -1258,20 +1250,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
t.span, t.span,
sub_span, sub_span,
id, id,
e.cur_scope); self.cur_scope);
}, },
None => () None => ()
} }
self.write_sub_paths_truncated(path, e.cur_scope); self.write_sub_paths_truncated(path);
visit::walk_path(self, path, e); visit::walk_path(self, path);
}, },
_ => visit::walk_ty(self, t, e), _ => visit::walk_ty(self, t),
} }
} }
fn visit_expr(&mut self, ex: &ast::Expr, e: DxrVisitorEnv) { fn visit_expr(&mut self, ex: &ast::Expr) {
if generated_code(ex.span) { if generated_code(ex.span) {
return return
} }
@ -1280,18 +1272,18 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ast::ExprCall(_f, ref _args) => { ast::ExprCall(_f, ref _args) => {
// Don't need to do anything for function calls, // Don't need to do anything for function calls,
// because just walking the callee path does what we want. // because just walking the callee path does what we want.
visit::walk_expr(self, ex, e); visit::walk_expr(self, ex);
}, },
ast::ExprPath(ref path) => self.process_path(ex, e, path), ast::ExprPath(ref path) => self.process_path(ex, path),
ast::ExprStruct(ref path, ref fields, base) => ast::ExprStruct(ref path, ref fields, base) =>
self.process_struct_lit(ex, e, path, fields, base), self.process_struct_lit(ex, path, fields, base),
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, e, args), ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
ast::ExprField(sub_ex, ident, _) => { ast::ExprField(sub_ex, ident, _) => {
if generated_code(sub_ex.span) { if generated_code(sub_ex.span) {
return return
} }
self.visit_expr(&*sub_ex, e); self.visit_expr(&*sub_ex);
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex); let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
let t_box = ty::get(t); let t_box = ty::get(t);
@ -1305,7 +1297,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ex.span, ex.span,
sub_span, sub_span,
f.id, f.id,
e.cur_scope); self.cur_scope);
break; break;
} }
} }
@ -1319,7 +1311,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
return return
} }
self.visit_expr(&*sub_ex, e); self.visit_expr(&*sub_ex);
let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex); let t = ty::expr_ty_adjusted(&self.analysis.ty_cx, &*sub_ex);
let t_box = ty::get(t); let t_box = ty::get(t);
@ -1333,7 +1325,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ex.span, ex.span,
sub_span, sub_span,
f.id, f.id,
e.cur_scope); self.cur_scope);
break; break;
} }
} }
@ -1348,41 +1340,41 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
} }
let id = String::from_str("$").append(ex.id.to_string().as_slice()); let id = String::from_str("$").append(ex.id.to_string().as_slice());
self.process_formals(&decl.inputs, id.as_slice(), e); self.process_formals(&decl.inputs, id.as_slice());
// walk arg and return types // walk arg and return types
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
self.visit_ty(&*arg.ty, e); self.visit_ty(&*arg.ty);
} }
self.visit_ty(&*decl.output, e); self.visit_ty(&*decl.output);
// walk the body // walk the body
self.visit_block(&*body, DxrVisitorEnv::new_nested(ex.id)); self.nest(ex.id, |v| v.visit_block(&*body));
}, },
_ => { _ => {
visit::walk_expr(self, ex, e) visit::walk_expr(self, ex)
}, },
} }
} }
fn visit_mac(&mut self, _: &ast::Mac, _: DxrVisitorEnv) { fn visit_mac(&mut self, _: &ast::Mac) {
// Just stop, macros are poison to us. // Just stop, macros are poison to us.
} }
fn visit_pat(&mut self, p: &ast::Pat, e: DxrVisitorEnv) { fn visit_pat(&mut self, p: &ast::Pat) {
self.process_pat(p, e); self.process_pat(p);
if !self.collecting { if !self.collecting {
self.collected_paths.clear(); self.collected_paths.clear();
} }
} }
fn visit_arm(&mut self, arm: &ast::Arm, e: DxrVisitorEnv) { fn visit_arm(&mut self, arm: &ast::Arm) {
assert!(self.collected_paths.len() == 0 && !self.collecting); assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true; self.collecting = true;
for pattern in arm.pats.iter() { for pattern in arm.pats.iter() {
// collect paths from the arm's patterns // collect paths from the arm's patterns
self.visit_pat(&**pattern, e); self.visit_pat(&**pattern);
} }
self.collecting = false; self.collecting = false;
// process collected paths // process collected paths
@ -1411,26 +1403,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
p.span, p.span,
sub_span, sub_span,
id, id,
e.cur_scope), self.cur_scope),
// FIXME(nrc) what is this doing here? // FIXME(nrc) what is this doing here?
def::DefStatic(_, _) => {} def::DefStatic(_, _) => {}
_ => error!("unexpected defintion kind when processing collected paths: {:?}", *def) _ => error!("unexpected defintion kind when processing collected paths: {:?}", *def)
} }
} }
self.collected_paths.clear(); self.collected_paths.clear();
visit::walk_expr_opt(self, arm.guard, e); visit::walk_expr_opt(self, arm.guard);
self.visit_expr(&*arm.body, e); self.visit_expr(&*arm.body);
} }
fn visit_stmt(&mut self, s:&ast::Stmt, e:DxrVisitorEnv) { fn visit_stmt(&mut self, s:&ast::Stmt) {
if generated_code(s.span) { if generated_code(s.span) {
return return
} }
visit::walk_stmt(self, s, e) visit::walk_stmt(self, s)
} }
fn visit_local(&mut self, l:&ast::Local, e: DxrVisitorEnv) { fn visit_local(&mut self, l:&ast::Local) {
if generated_code(l.span) { if generated_code(l.span) {
return return
} }
@ -1439,7 +1431,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
// pattern and collect them all. // pattern and collect them all.
assert!(self.collected_paths.len() == 0 && !self.collecting); assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true; self.collecting = true;
self.visit_pat(&*l.pat, e); self.visit_pat(&*l.pat);
self.collecting = false; self.collecting = false;
let value = self.span.snippet(l.span); let value = self.span.snippet(l.span);
@ -1462,22 +1454,8 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
self.collected_paths.clear(); self.collected_paths.clear();
// Just walk the initialiser and type (don't want to walk the pattern again). // Just walk the initialiser and type (don't want to walk the pattern again).
self.visit_ty(&*l.ty, e); self.visit_ty(&*l.ty);
visit::walk_expr_opt(self, l.init, e); visit::walk_expr_opt(self, l.init);
}
}
#[deriving(Clone)]
struct DxrVisitorEnv {
cur_scope: NodeId,
}
impl DxrVisitorEnv {
fn new() -> DxrVisitorEnv {
DxrVisitorEnv{cur_scope: 0}
}
fn new_nested(new_mod: NodeId) -> DxrVisitorEnv {
DxrVisitorEnv{cur_scope: new_mod}
} }
} }
@ -1532,25 +1510,28 @@ pub fn process_crate(sess: &Session,
}; };
root_path.pop(); root_path.pop();
let mut visitor = DxrVisitor{ sess: sess, let mut visitor = DxrVisitor {
analysis: analysis, sess: sess,
collected_paths: vec!(), analysis: analysis,
collecting: false, collected_paths: vec!(),
fmt: FmtStrs::new(box Recorder { collecting: false,
out: output_file as Box<Writer+'static>, fmt: FmtStrs::new(box Recorder {
dump_spans: false, out: output_file as Box<Writer+'static>,
}, dump_spans: false,
SpanUtils { },
sess: sess, SpanUtils {
err_count: Cell::new(0) sess: sess,
}, err_count: Cell::new(0)
cratename.clone()), },
span: SpanUtils { cratename.clone()),
sess: sess, span: SpanUtils {
err_count: Cell::new(0) sess: sess,
}}; err_count: Cell::new(0)
},
cur_scope: 0
};
visitor.dump_crate_info(cratename.as_slice(), krate); visitor.dump_crate_info(cratename.as_slice(), krate);
visit::walk_crate(&mut visitor, krate, DxrVisitorEnv::new()); visit::walk_crate(&mut visitor, krate);
} }

View file

@ -24,6 +24,8 @@ use syntax::visit::{FnKind, FkMethod, Visitor};
use middle::ty; use middle::ty;
use metadata::csearch; use metadata::csearch;
use std::mem::replace;
/// A stability index, giving the stability level for items and methods. /// A stability index, giving the stability level for items and methods.
pub struct Index { pub struct Index {
// stability for crate-local items; unmarked stability == no entry // stability for crate-local items; unmarked stability == no entry
@ -34,68 +36,68 @@ pub struct Index {
// A private tree-walker for producing an Index. // A private tree-walker for producing an Index.
struct Annotator { struct Annotator {
index: Index index: Index,
parent: Option<Stability>
} }
impl Annotator { impl Annotator {
// Determine the stability for a node based on its attributes and inherited // Determine the stability for a node based on its attributes and inherited
// stability. The stability is recorded in the index and returned. // stability. The stability is recorded in the index and used as the parent.
fn annotate(&mut self, id: NodeId, attrs: &[Attribute], fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
parent: Option<Stability>) -> Option<Stability> { match attr::find_stability(attrs.as_slice()) {
match attr::find_stability(attrs).or(parent) {
Some(stab) => { Some(stab) => {
self.index.local.insert(id, stab.clone()); self.index.local.insert(id, stab.clone());
Some(stab) let parent = replace(&mut self.parent, Some(stab));
f(self);
self.parent = parent;
}
None => {
self.parent.clone().map(|stab| self.index.local.insert(id, stab));
f(self);
} }
None => None
} }
} }
} }
impl Visitor<Option<Stability>> for Annotator { impl Visitor for Annotator {
fn visit_item(&mut self, i: &Item, parent: Option<Stability>) { fn visit_item(&mut self, i: &Item) {
let stab = self.annotate(i.id, i.attrs.as_slice(), parent); self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i));
visit::walk_item(self, i, stab)
} }
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
s: Span, _: NodeId, parent: Option<Stability>) { match *fk {
let stab = match *fk { FkMethod(_, _, meth) => {
FkMethod(_, _, meth) => self.annotate(meth.id, &meth.attrs, |v| visit::walk_fn(v, fk, fd, b, s));
self.annotate(meth.id, meth.attrs.as_slice(), parent), }
_ => parent _ => visit::walk_fn(self, fk, fd, b, s)
}; }
visit::walk_fn(self, fk, fd, b, s, stab)
} }
fn visit_trait_item(&mut self, t: &TraitItem, parent: Option<Stability>) { fn visit_trait_item(&mut self, t: &TraitItem) {
let stab = match *t { let (id, attrs) = match *t {
RequiredMethod(TypeMethod {attrs: ref attrs, id: id, ..}) => RequiredMethod(TypeMethod {id, ref attrs, ..}) => (id, attrs),
self.annotate(id, attrs.as_slice(), parent),
// work around lack of pattern matching for @ types // work around lack of pattern matching for @ types
ProvidedMethod(method) => match *method { ProvidedMethod(ref method) => match **method {
Method {attrs: ref attrs, id: id, ..} => Method {id, ref attrs, ..} => (id, attrs)
self.annotate(id, attrs.as_slice(), parent)
} }
}; };
visit::walk_trait_item(self, t, stab) self.annotate(id, attrs, |v| visit::walk_trait_item(v, t));
} }
fn visit_variant(&mut self, v: &Variant, g: &Generics, parent: Option<Stability>) { fn visit_variant(&mut self, var: &Variant, g: &Generics) {
let stab = self.annotate(v.node.id, v.node.attrs.as_slice(), parent); self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
visit::walk_variant(self, v, g, stab)
} }
fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId) {
_: NodeId, parent: Option<Stability>) { match s.ctor_id {
s.ctor_id.map(|id| self.annotate(id, &[], parent.clone())); Some(id) => self.annotate(id, &vec![], |v| visit::walk_struct_def(v, s)),
visit::walk_struct_def(self, s, parent) None => visit::walk_struct_def(self, s)
}
} }
fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) { fn visit_struct_field(&mut self, s: &StructField) {
let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent); self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
visit::walk_struct_field(self, s, stab)
} }
} }
@ -106,10 +108,10 @@ impl Index {
index: Index { index: Index {
local: NodeMap::new(), local: NodeMap::new(),
extern_cache: DefIdMap::new() extern_cache: DefIdMap::new()
} },
parent: None
}; };
let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None); annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate));
visit::walk_crate(&mut annotator, krate, stab);
annotator.index annotator.index
} }
} }

View file

@ -1322,18 +1322,32 @@ pub fn make_return_slot_pointer(fcx: &FunctionContext, output_type: ty::t) -> Va
} }
struct CheckForNestedReturnsVisitor { struct CheckForNestedReturnsVisitor {
found: bool found: bool,
in_return: bool
} }
impl Visitor<bool> for CheckForNestedReturnsVisitor { impl CheckForNestedReturnsVisitor {
fn visit_expr(&mut self, e: &ast::Expr, in_return: bool) { fn explicit() -> CheckForNestedReturnsVisitor {
CheckForNestedReturnsVisitor { found: false, in_return: false }
}
fn implicit() -> CheckForNestedReturnsVisitor {
CheckForNestedReturnsVisitor { found: false, in_return: true }
}
}
impl Visitor for CheckForNestedReturnsVisitor {
fn visit_expr(&mut self, e: &ast::Expr) {
match e.node { match e.node {
ast::ExprRet(..) if in_return => { ast::ExprRet(..) => {
self.found = true; if self.in_return {
return; self.found = true;
} else {
self.in_return = true;
visit::walk_expr(self, e);
self.in_return = false;
}
} }
ast::ExprRet(..) => visit::walk_expr(self, e, true), _ => visit::walk_expr(self, e)
_ => visit::walk_expr(self, e, in_return)
} }
} }
} }
@ -1343,10 +1357,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
Some(ast_map::NodeItem(i)) => { Some(ast_map::NodeItem(i)) => {
match i.node { match i.node {
ast::ItemFn(_, _, _, _, blk) => { ast::ItemFn(_, _, _, _, blk) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false }; let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor { found: false }; let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_item(&mut explicit, &*i, false); visit::walk_item(&mut explicit, &*i);
visit::walk_expr_opt(&mut implicit, blk.expr, true); visit::walk_expr_opt(&mut implicit, blk.expr);
explicit.found || implicit.found explicit.found || implicit.found
} }
_ => tcx.sess.bug("unexpected item variant in has_nested_returns") _ => tcx.sess.bug("unexpected item variant in has_nested_returns")
@ -1357,10 +1371,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
ast::ProvidedMethod(m) => { ast::ProvidedMethod(m) => {
match m.node { match m.node {
ast::MethDecl(_, _, _, _, _, _, blk, _) => { ast::MethDecl(_, _, _, _, _, _, blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false }; let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor { found: false }; let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_method_helper(&mut explicit, &*m, false); visit::walk_method_helper(&mut explicit, &*m);
visit::walk_expr_opt(&mut implicit, blk.expr, true); visit::walk_expr_opt(&mut implicit, blk.expr);
explicit.found || implicit.found explicit.found || implicit.found
} }
ast::MethMac(_) => tcx.sess.bug("unexpanded macro") ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
@ -1377,18 +1391,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
ast::MethodImplItem(ref m) => { ast::MethodImplItem(ref m) => {
match m.node { match m.node {
ast::MethDecl(_, _, _, _, _, _, blk, _) => { ast::MethDecl(_, _, _, _, _, _, blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor { let mut explicit = CheckForNestedReturnsVisitor::explicit();
found: false, let mut implicit = CheckForNestedReturnsVisitor::implicit();
}; visit::walk_method_helper(&mut explicit, &**m);
let mut implicit = CheckForNestedReturnsVisitor { visit::walk_expr_opt(&mut implicit, blk.expr);
found: false,
};
visit::walk_method_helper(&mut explicit,
&**m,
false);
visit::walk_expr_opt(&mut implicit,
blk.expr,
true);
explicit.found || implicit.found explicit.found || implicit.found
} }
ast::MethMac(_) => tcx.sess.bug("unexpanded macro") ast::MethMac(_) => tcx.sess.bug("unexpanded macro")
@ -1401,10 +1407,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
ast::ExprFnBlock(_, _, blk) | ast::ExprFnBlock(_, _, blk) |
ast::ExprProc(_, blk) | ast::ExprProc(_, blk) |
ast::ExprUnboxedFn(_, _, _, blk) => { ast::ExprUnboxedFn(_, _, _, blk) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false }; let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor { found: false }; let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_expr(&mut explicit, &*e, false); visit::walk_expr(&mut explicit, &*e);
visit::walk_expr_opt(&mut implicit, blk.expr, true); visit::walk_expr_opt(&mut implicit, blk.expr);
explicit.found || implicit.found explicit.found || implicit.found
} }
_ => tcx.sess.bug("unexpected expr variant in has_nested_returns") _ => tcx.sess.bug("unexpected expr variant in has_nested_returns")
@ -2135,8 +2141,8 @@ pub struct TransItemVisitor<'a, 'tcx: 'a> {
pub ccx: &'a CrateContext<'a, 'tcx>, pub ccx: &'a CrateContext<'a, 'tcx>,
} }
impl<'a, 'tcx> Visitor<()> for TransItemVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for TransItemVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _:()) { fn visit_item(&mut self, i: &ast::Item) {
trans_item(self.ccx, i); trans_item(self.ccx, i);
} }
} }
@ -2236,7 +2242,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
// Be sure to travel more than just one layer deep to catch nested // Be sure to travel more than just one layer deep to catch nested
// items in blocks and such. // items in blocks and such.
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
v.visit_block(&**body, ()); v.visit_block(&**body);
} }
ast::ItemImpl(ref generics, _, _, ref impl_items) => { ast::ItemImpl(ref generics, _, _, ref impl_items) => {
meth::trans_impl(ccx, meth::trans_impl(ccx,
@ -2254,7 +2260,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
ast::ItemStatic(_, m, ref expr) => { ast::ItemStatic(_, m, ref expr) => {
// Recurse on the expression to catch items in blocks // Recurse on the expression to catch items in blocks
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
v.visit_expr(&**expr, ()); v.visit_expr(&**expr);
let trans_everywhere = attr::requests_inline(item.attrs.as_slice()); let trans_everywhere = attr::requests_inline(item.attrs.as_slice());
for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) { for (ref ccx, is_origin) in ccx.maybe_iter(!from_external && trans_everywhere) {
@ -2293,7 +2299,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
// methods with items will not get translated and will cause ICE's when // methods with items will not get translated and will cause ICE's when
// metadata time comes around. // metadata time comes around.
let mut v = TransItemVisitor{ ccx: ccx }; let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_item(&mut v, item, ()); visit::walk_item(&mut v, item);
} }
_ => {/* fall through */ } _ => {/* fall through */ }
} }

View file

@ -150,7 +150,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match els { match els {
Some(elexpr) => { Some(elexpr) => {
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx }; let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx };
trans.visit_expr(&*elexpr, ()); trans.visit_expr(&*elexpr);
} }
None => {} None => {}
} }
@ -159,7 +159,7 @@ pub fn trans_if<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
trans::debuginfo::clear_source_location(bcx.fcx); trans::debuginfo::clear_source_location(bcx.fcx);
} else { } else {
let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ; let mut trans = TransItemVisitor { ccx: bcx.fcx.ccx } ;
trans.visit_block(&*thn, ()); trans.visit_block(&*thn);
match els { match els {
// if false { .. } else { .. } // if false { .. } else { .. }

View file

@ -67,7 +67,7 @@ pub fn trans_impl(ccx: &CrateContext,
for impl_item in impl_items.iter() { for impl_item in impl_items.iter() {
match *impl_item { match *impl_item {
ast::MethodImplItem(method) => { ast::MethodImplItem(method) => {
visit::walk_method_helper(&mut v, &*method, ()); visit::walk_method_helper(&mut v, &*method);
} }
} }
} }
@ -96,7 +96,7 @@ pub fn trans_impl(ccx: &CrateContext,
let mut v = TransItemVisitor { let mut v = TransItemVisitor {
ccx: ccx, ccx: ccx,
}; };
visit::walk_method_helper(&mut v, &*method, ()); visit::walk_method_helper(&mut v, &*method);
} }
} }
} }

View file

@ -375,18 +375,18 @@ fn static_inherited_fields<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>)
struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } struct CheckItemTypesVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> } struct CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
impl<'a, 'tcx> Visitor<()> for CheckTypeWellFormedVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for CheckTypeWellFormedVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) { fn visit_item(&mut self, i: &ast::Item) {
check_type_well_formed(self.ccx, i); check_type_well_formed(self.ccx, i);
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
} }
impl<'a, 'tcx> Visitor<()> for CheckItemTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for CheckItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) { fn visit_item(&mut self, i: &ast::Item) {
check_item(self.ccx, i); check_item(self.ccx, i);
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
} }
@ -394,28 +394,28 @@ struct CheckItemSizedTypesVisitor<'a, 'tcx: 'a> {
ccx: &'a CrateCtxt<'a, 'tcx> ccx: &'a CrateCtxt<'a, 'tcx>
} }
impl<'a, 'tcx> Visitor<()> for CheckItemSizedTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for CheckItemSizedTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) { fn visit_item(&mut self, i: &ast::Item) {
check_item_sized(self.ccx, i); check_item_sized(self.ccx, i);
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
} }
pub fn check_item_types(ccx: &CrateCtxt, krate: &ast::Crate) { pub fn check_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
let mut visit = CheckTypeWellFormedVisitor { ccx: ccx }; let mut visit = CheckTypeWellFormedVisitor { ccx: ccx };
visit::walk_crate(&mut visit, krate, ()); visit::walk_crate(&mut visit, krate);
// If types are not well-formed, it leads to all manner of errors // If types are not well-formed, it leads to all manner of errors
// downstream, so stop reporting errors at this point. // downstream, so stop reporting errors at this point.
ccx.tcx.sess.abort_if_errors(); ccx.tcx.sess.abort_if_errors();
let mut visit = CheckItemTypesVisitor { ccx: ccx }; let mut visit = CheckItemTypesVisitor { ccx: ccx };
visit::walk_crate(&mut visit, krate, ()); visit::walk_crate(&mut visit, krate);
ccx.tcx.sess.abort_if_errors(); ccx.tcx.sess.abort_if_errors();
let mut visit = CheckItemSizedTypesVisitor { ccx: ccx }; let mut visit = CheckItemSizedTypesVisitor { ccx: ccx };
visit::walk_crate(&mut visit, krate, ()); visit::walk_crate(&mut visit, krate);
} }
fn check_bare_fn(ccx: &CrateCtxt, fn check_bare_fn(ccx: &CrateCtxt,
@ -464,9 +464,9 @@ impl<'a, 'tcx> GatherLocalsVisitor<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> { impl<'a, 'tcx> Visitor for GatherLocalsVisitor<'a, 'tcx> {
// Add explicitly-declared locals. // Add explicitly-declared locals.
fn visit_local(&mut self, local: &ast::Local, _: ()) { fn visit_local(&mut self, local: &ast::Local) {
let o_ty = match local.ty.node { let o_ty = match local.ty.node {
ast::TyInfer => None, ast::TyInfer => None,
_ => Some(self.fcx.to_ty(&*local.ty)) _ => Some(self.fcx.to_ty(&*local.ty))
@ -476,11 +476,11 @@ impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> {
self.fcx.pat_to_string(&*local.pat), self.fcx.pat_to_string(&*local.pat),
self.fcx.infcx().ty_to_string( self.fcx.infcx().ty_to_string(
self.fcx.inh.locals.borrow().get_copy(&local.id))); self.fcx.inh.locals.borrow().get_copy(&local.id)));
visit::walk_local(self, local, ()); visit::walk_local(self, local);
} }
// Add pattern bindings. // Add pattern bindings.
fn visit_pat(&mut self, p: &ast::Pat, _: ()) { fn visit_pat(&mut self, p: &ast::Pat) {
match p.node { match p.node {
ast::PatIdent(_, ref path1, _) ast::PatIdent(_, ref path1, _)
if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => { if pat_util::pat_is_binding(&self.fcx.ccx.tcx.def_map, p) => {
@ -492,33 +492,33 @@ impl<'a, 'tcx> Visitor<()> for GatherLocalsVisitor<'a, 'tcx> {
} }
_ => {} _ => {}
} }
visit::walk_pat(self, p, ()); visit::walk_pat(self, p);
} }
fn visit_block(&mut self, b: &ast::Block, _: ()) { fn visit_block(&mut self, b: &ast::Block) {
// non-obvious: the `blk` variable maps to region lb, so // non-obvious: the `blk` variable maps to region lb, so
// we have to keep this up-to-date. This // we have to keep this up-to-date. This
// is... unfortunate. It'd be nice to not need this. // is... unfortunate. It'd be nice to not need this.
visit::walk_block(self, b, ()); visit::walk_block(self, b);
} }
// Since an expr occurs as part of the type fixed size arrays we // Since an expr occurs as part of the type fixed size arrays we
// need to record the type for that node // need to record the type for that node
fn visit_ty(&mut self, t: &ast::Ty, _: ()) { fn visit_ty(&mut self, t: &ast::Ty) {
match t.node { match t.node {
ast::TyFixedLengthVec(ref ty, ref count_expr) => { ast::TyFixedLengthVec(ref ty, ref count_expr) => {
self.visit_ty(&**ty, ()); self.visit_ty(&**ty);
check_expr_with_hint(self.fcx, &**count_expr, ty::mk_uint()); check_expr_with_hint(self.fcx, &**count_expr, ty::mk_uint());
} }
_ => visit::walk_ty(self, t, ()) _ => visit::walk_ty(self, t)
} }
} }
// Don't descend into fns and items // Don't descend into fns and items
fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl, fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId, _: ()) { } _: &ast::Block, _: Span, _: ast::NodeId) { }
fn visit_item(&mut self, _: &ast::Item, _: ()) { } fn visit_item(&mut self, _: &ast::Item) { }
} }
@ -603,7 +603,7 @@ fn check_fn<'a, 'tcx>(ccx: &'a CrateCtxt<'a, 'tcx>,
_match::check_pat(&pcx, &*input.pat, *arg_ty); _match::check_pat(&pcx, &*input.pat, *arg_ty);
} }
visit.visit_block(body, ()); visit.visit_block(body);
} }
check_block_with_expected(&fcx, body, ExpectHasType(ret_ty)); check_block_with_expected(&fcx, body, ExpectHasType(ret_ty));
@ -4508,7 +4508,7 @@ pub fn check_const_with_ty(fcx: &FnCtxt,
// This is technically unnecessary because locals in static items are forbidden, // This is technically unnecessary because locals in static items are forbidden,
// but prevents type checking from blowing up before const checking can properly // but prevents type checking from blowing up before const checking can properly
// emit a error. // emit a error.
GatherLocalsVisitor { fcx: fcx }.visit_expr(e, ()); GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
check_expr_with_hint(fcx, e, declty); check_expr_with_hint(fcx, e, declty);
demand::coerce(fcx, e.span, declty, e); demand::coerce(fcx, e.span, declty, e);

View file

@ -150,7 +150,7 @@ pub fn regionck_expr(fcx: &FnCtxt, e: &ast::Expr) {
let mut rcx = Rcx::new(fcx, e.id); let mut rcx = Rcx::new(fcx, e.id);
if fcx.err_count_since_creation() == 0 { if fcx.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded // regionck assumes typeck succeeded
rcx.visit_expr(e, ()); rcx.visit_expr(e);
rcx.visit_region_obligations(e.id); rcx.visit_region_obligations(e.id);
} }
fcx.infcx().resolve_regions_and_report_errors(); fcx.infcx().resolve_regions_and_report_errors();
@ -346,7 +346,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
let len = self.region_param_pairs.len(); let len = self.region_param_pairs.len();
self.relate_free_regions(fn_sig.as_slice(), body.id); self.relate_free_regions(fn_sig.as_slice(), body.id);
self.visit_block(body, ()); self.visit_block(body);
self.visit_region_obligations(body.id); self.visit_region_obligations(body.id);
self.region_param_pairs.truncate(len); self.region_param_pairs.truncate(len);
} }
@ -479,7 +479,7 @@ impl<'fcx, 'tcx> mc::Typer<'tcx> for Rcx<'fcx, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for Rcx<'a, 'tcx> { impl<'a, 'tcx> Visitor for Rcx<'a, 'tcx> {
// (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local, // (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
// However, right now we run into an issue whereby some free // However, right now we run into an issue whereby some free
// regions are not properly related if they appear within the // regions are not properly related if they appear within the
@ -489,21 +489,21 @@ impl<'a, 'tcx> Visitor<()> for Rcx<'a, 'tcx> {
// regions, until regionck, as described in #3238. // regions, until regionck, as described in #3238.
fn visit_fn(&mut self, _fk: &visit::FnKind, _fd: &ast::FnDecl, fn visit_fn(&mut self, _fk: &visit::FnKind, _fd: &ast::FnDecl,
b: &ast::Block, _s: Span, id: ast::NodeId, _e: ()) { b: &ast::Block, _s: Span, id: ast::NodeId) {
self.visit_fn_body(id, b) self.visit_fn_body(id, b)
} }
fn visit_item(&mut self, i: &ast::Item, _: ()) { visit_item(self, i); } fn visit_item(&mut self, i: &ast::Item) { visit_item(self, i); }
fn visit_expr(&mut self, ex: &ast::Expr, _: ()) { visit_expr(self, ex); } fn visit_expr(&mut self, ex: &ast::Expr) { visit_expr(self, ex); }
//visit_pat: visit_pat, // (..) see above //visit_pat: visit_pat, // (..) see above
fn visit_arm(&mut self, a: &ast::Arm, _: ()) { visit_arm(self, a); } fn visit_arm(&mut self, a: &ast::Arm) { visit_arm(self, a); }
fn visit_local(&mut self, l: &ast::Local, _: ()) { visit_local(self, l); } fn visit_local(&mut self, l: &ast::Local) { visit_local(self, l); }
fn visit_block(&mut self, b: &ast::Block, _: ()) { visit_block(self, b); } fn visit_block(&mut self, b: &ast::Block) { visit_block(self, b); }
} }
fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) { fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) {
@ -511,7 +511,7 @@ fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) {
} }
fn visit_block(rcx: &mut Rcx, b: &ast::Block) { fn visit_block(rcx: &mut Rcx, b: &ast::Block) {
visit::walk_block(rcx, b, ()); visit::walk_block(rcx, b);
} }
fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) { fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
@ -520,14 +520,14 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
constrain_bindings_in_pat(&**p, rcx); constrain_bindings_in_pat(&**p, rcx);
} }
visit::walk_arm(rcx, arm, ()); visit::walk_arm(rcx, arm);
} }
fn visit_local(rcx: &mut Rcx, l: &ast::Local) { fn visit_local(rcx: &mut Rcx, l: &ast::Local) {
// see above // see above
constrain_bindings_in_pat(&*l.pat, rcx); constrain_bindings_in_pat(&*l.pat, rcx);
link_local(rcx, l); link_local(rcx, l);
visit::walk_local(rcx, l, ()); visit::walk_local(rcx, l);
} }
fn constrain_bindings_in_pat(pat: &ast::Pat, rcx: &mut Rcx) { fn constrain_bindings_in_pat(pat: &ast::Pat, rcx: &mut Rcx) {
@ -625,19 +625,19 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
false); false);
} }
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprMethodCall(_, _, ref args) => { ast::ExprMethodCall(_, _, ref args) => {
constrain_call(rcx, expr, Some(*args.get(0)), constrain_call(rcx, expr, Some(*args.get(0)),
args.slice_from(1), false); args.slice_from(1), false);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprAssign(ref lhs, _) => { ast::ExprAssign(ref lhs, _) => {
adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs); adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprAssignOp(_, ref lhs, ref rhs) => { ast::ExprAssignOp(_, ref lhs, ref rhs) => {
@ -648,7 +648,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs); adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprIndex(ref lhs, ref rhs) | ast::ExprIndex(ref lhs, ref rhs) |
@ -660,14 +660,14 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
constrain_call(rcx, expr, Some(lhs.clone()), constrain_call(rcx, expr, Some(lhs.clone()),
[rhs.clone()], true); [rhs.clone()], true);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprUnary(_, ref lhs) if has_method_map => { ast::ExprUnary(_, ref lhs) if has_method_map => {
// As above. // As above.
constrain_call(rcx, expr, Some(lhs.clone()), [], true); constrain_call(rcx, expr, Some(lhs.clone()), [], true);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprUnary(ast::UnBox, ref base) => { ast::ExprUnary(ast::UnBox, ref base) => {
@ -675,7 +675,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
let base_ty = rcx.resolve_node_type(base.id); let base_ty = rcx.resolve_node_type(base.id);
type_must_outlive(rcx, infer::Managed(expr.span), type_must_outlive(rcx, infer::Managed(expr.span),
base_ty, ty::ReStatic); base_ty, ty::ReStatic);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprUnary(ast::UnDeref, ref base) => { ast::ExprUnary(ast::UnDeref, ref base) => {
@ -696,7 +696,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
_ => {} _ => {}
} }
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprIndex(ref vec_expr, _) => { ast::ExprIndex(ref vec_expr, _) => {
@ -704,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr); let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr);
constrain_index(rcx, expr, vec_type); constrain_index(rcx, expr, vec_type);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprCast(ref source, _) => { ast::ExprCast(ref source, _) => {
@ -712,7 +712,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
// instance. If so, we have to be sure that the type of // instance. If so, we have to be sure that the type of
// the source obeys the trait's region bound. // the source obeys the trait's region bound.
constrain_cast(rcx, expr, &**source); constrain_cast(rcx, expr, &**source);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprAddrOf(m, ref base) => { ast::ExprAddrOf(m, ref base) => {
@ -728,13 +728,13 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
let ty0 = rcx.resolve_node_type(expr.id); let ty0 = rcx.resolve_node_type(expr.id);
type_must_outlive(rcx, infer::AddrOf(expr.span), type_must_outlive(rcx, infer::AddrOf(expr.span),
ty0, ty::ReScope(expr.id)); ty0, ty::ReScope(expr.id));
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprMatch(ref discr, ref arms) => { ast::ExprMatch(ref discr, ref arms) => {
link_match(rcx, &**discr, arms.as_slice()); link_match(rcx, &**discr, arms.as_slice());
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
ast::ExprFnBlock(_, _, ref body) | ast::ExprFnBlock(_, _, ref body) |
@ -745,16 +745,16 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
ast::ExprLoop(ref body, _) => { ast::ExprLoop(ref body, _) => {
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
ast::ExprWhile(ref cond, ref body, _) => { ast::ExprWhile(ref cond, ref body, _) => {
let repeating_scope = rcx.set_repeating_scope(cond.id); let repeating_scope = rcx.set_repeating_scope(cond.id);
rcx.visit_expr(&**cond, ()); rcx.visit_expr(&**cond);
rcx.set_repeating_scope(body.id); rcx.set_repeating_scope(body.id);
rcx.visit_block(&**body, ()); rcx.visit_block(&**body);
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
@ -768,19 +768,19 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
link_pattern(rcx, mc, head_cmt, &**pat); link_pattern(rcx, mc, head_cmt, &**pat);
} }
rcx.visit_expr(&**head, ()); rcx.visit_expr(&**head);
type_of_node_must_outlive(rcx, type_of_node_must_outlive(rcx,
infer::AddrOf(expr.span), infer::AddrOf(expr.span),
head.id, head.id,
ty::ReScope(expr.id)); ty::ReScope(expr.id));
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
rcx.visit_block(&**body, ()); rcx.visit_block(&**body);
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
} }
_ => { _ => {
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
} }
} }
} }
@ -890,7 +890,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
} }
let repeating_scope = rcx.set_repeating_scope(body.id); let repeating_scope = rcx.set_repeating_scope(body.id);
visit::walk_expr(rcx, expr, ()); visit::walk_expr(rcx, expr);
rcx.set_repeating_scope(repeating_scope); rcx.set_repeating_scope(repeating_scope);
match ty::get(function_type).sty { match ty::get(function_type).sty {

View file

@ -1025,12 +1025,12 @@ pub fn trans_resolve_method(tcx: &ty::ctxt, id: ast::NodeId,
false) false)
} }
impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> { impl<'a, 'b, 'tcx> visit::Visitor for &'a FnCtxt<'b, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr, _: ()) { fn visit_expr(&mut self, ex: &ast::Expr) {
early_resolve_expr(ex, *self, false); early_resolve_expr(ex, *self, false);
visit::walk_expr(self, ex, ()); visit::walk_expr(self, ex);
} }
fn visit_item(&mut self, _: &ast::Item, _: ()) { fn visit_item(&mut self, _: &ast::Item) {
// no-op // no-op
} }
} }
@ -1038,7 +1038,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> {
// Detect points where a trait-bounded type parameter is // Detect points where a trait-bounded type parameter is
// instantiated, resolve the impls for the parameters. // instantiated, resolve the impls for the parameters.
pub fn resolve_in_block(mut fcx: &FnCtxt, bl: &ast::Block) { pub fn resolve_in_block(mut fcx: &FnCtxt, bl: &ast::Block) {
visit::walk_block(&mut fcx, bl, ()); visit::walk_block(&mut fcx, bl);
} }
/// Used in the kind checker after typechecking has finished. Calls /// Used in the kind checker after typechecking has finished. Calls

View file

@ -41,7 +41,7 @@ use syntax::visit::Visitor;
pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) { pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
assert_eq!(fcx.writeback_errors.get(), false); assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx); let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_expr(e, ()); wbcx.visit_expr(e);
wbcx.visit_upvar_borrow_map(); wbcx.visit_upvar_borrow_map();
wbcx.visit_unboxed_closures(); wbcx.visit_unboxed_closures();
} }
@ -51,9 +51,9 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
blk: &ast::Block) { blk: &ast::Block) {
assert_eq!(fcx.writeback_errors.get(), false); assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx); let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_block(blk, ()); wbcx.visit_block(blk);
for arg in decl.inputs.iter() { for arg in decl.inputs.iter() {
wbcx.visit_pat(&*arg.pat, ()); wbcx.visit_pat(&*arg.pat);
// Privacy needs the type for the whole pattern, not just each binding // Privacy needs the type for the whole pattern, not just each binding
if !pat_util::pat_is_binding(&fcx.tcx().def_map, &*arg.pat) { if !pat_util::pat_is_binding(&fcx.tcx().def_map, &*arg.pat) {
@ -106,21 +106,21 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
// below. In general, a function is made into a `visitor` if it must // below. In general, a function is made into a `visitor` if it must
// traffic in node-ids or update tables in the type context etc. // traffic in node-ids or update tables in the type context etc.
impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> { impl<'cx, 'tcx> Visitor for WritebackCx<'cx, 'tcx> {
fn visit_item(&mut self, _: &ast::Item, _: ()) { fn visit_item(&mut self, _: &ast::Item) {
// Ignore items // Ignore items
} }
fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) { fn visit_stmt(&mut self, s: &ast::Stmt) {
if self.fcx.writeback_errors.get() { if self.fcx.writeback_errors.get() {
return; return;
} }
self.visit_node_id(ResolvingExpr(s.span), ty::stmt_node_id(s)); self.visit_node_id(ResolvingExpr(s.span), ty::stmt_node_id(s));
visit::walk_stmt(self, s, ()); visit::walk_stmt(self, s);
} }
fn visit_expr(&mut self, e:&ast::Expr, _: ()) { fn visit_expr(&mut self, e:&ast::Expr) {
if self.fcx.writeback_errors.get() { if self.fcx.writeback_errors.get() {
return; return;
} }
@ -143,19 +143,19 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
_ => {} _ => {}
} }
visit::walk_expr(self, e, ()); visit::walk_expr(self, e);
} }
fn visit_block(&mut self, b: &ast::Block, _: ()) { fn visit_block(&mut self, b: &ast::Block) {
if self.fcx.writeback_errors.get() { if self.fcx.writeback_errors.get() {
return; return;
} }
self.visit_node_id(ResolvingExpr(b.span), b.id); self.visit_node_id(ResolvingExpr(b.span), b.id);
visit::walk_block(self, b, ()); visit::walk_block(self, b);
} }
fn visit_pat(&mut self, p: &ast::Pat, _: ()) { fn visit_pat(&mut self, p: &ast::Pat) {
if self.fcx.writeback_errors.get() { if self.fcx.writeback_errors.get() {
return; return;
} }
@ -167,10 +167,10 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
p.id, p.id,
ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx())); ty::node_id_to_type(self.tcx(), p.id).repr(self.tcx()));
visit::walk_pat(self, p, ()); visit::walk_pat(self, p);
} }
fn visit_local(&mut self, l: &ast::Local, _: ()) { fn visit_local(&mut self, l: &ast::Local) {
if self.fcx.writeback_errors.get() { if self.fcx.writeback_errors.get() {
return; return;
} }
@ -178,16 +178,16 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
let var_ty = self.fcx.local_ty(l.span, l.id); let var_ty = self.fcx.local_ty(l.span, l.id);
let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span)); let var_ty = self.resolve(&var_ty, ResolvingLocal(l.span));
write_ty_to_tcx(self.tcx(), l.id, var_ty); write_ty_to_tcx(self.tcx(), l.id, var_ty);
visit::walk_local(self, l, ()); visit::walk_local(self, l);
} }
fn visit_ty(&mut self, t: &ast::Ty, _: ()) { fn visit_ty(&mut self, t: &ast::Ty) {
match t.node { match t.node {
ast::TyFixedLengthVec(ref ty, ref count_expr) => { ast::TyFixedLengthVec(ref ty, ref count_expr) => {
self.visit_ty(&**ty, ()); self.visit_ty(&**ty);
write_ty_to_tcx(self.tcx(), count_expr.id, ty::mk_uint()); write_ty_to_tcx(self.tcx(), count_expr.id, ty::mk_uint());
} }
_ => visit::walk_ty(self, t, ()) _ => visit::walk_ty(self, t)
} }
} }
} }

View file

@ -191,8 +191,8 @@ struct CoherenceCheckVisitor<'a, 'tcx: 'a> {
cc: &'a CoherenceChecker<'a, 'tcx> cc: &'a CoherenceChecker<'a, 'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for CoherenceCheckVisitor<'a, 'tcx> { impl<'a, 'tcx> visit::Visitor for CoherenceCheckVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) { fn visit_item(&mut self, item: &Item) {
//debug!("(checking coherence) item '{}'", token::get_ident(item.ident)); //debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
@ -210,7 +210,7 @@ impl<'a, 'tcx> visit::Visitor<()> for CoherenceCheckVisitor<'a, 'tcx> {
} }
}; };
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
@ -218,13 +218,13 @@ struct PrivilegedScopeVisitor<'a, 'tcx: 'a> {
cc: &'a CoherenceChecker<'a, 'tcx> cc: &'a CoherenceChecker<'a, 'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for PrivilegedScopeVisitor<'a, 'tcx> { impl<'a, 'tcx> visit::Visitor for PrivilegedScopeVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) { fn visit_item(&mut self, item: &Item) {
match item.node { match item.node {
ItemMod(ref module_) => { ItemMod(ref module_) => {
// Then visit the module items. // Then visit the module items.
visit::walk_mod(self, module_, ()); visit::walk_mod(self, module_);
} }
ItemImpl(_, None, ref ast_ty, _) => { ItemImpl(_, None, ref ast_ty, _) => {
if !self.cc.ast_type_is_defined_in_local_crate(&**ast_ty) { if !self.cc.ast_type_is_defined_in_local_crate(&**ast_ty) {
@ -256,10 +256,10 @@ impl<'a, 'tcx> visit::Visitor<()> for PrivilegedScopeVisitor<'a, 'tcx> {
} }
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
_ => { _ => {
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
} }
@ -271,7 +271,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// containing the inherent methods and extension methods. It also // containing the inherent methods and extension methods. It also
// builds up the trait inheritance table. // builds up the trait inheritance table.
let mut visitor = CoherenceCheckVisitor { cc: self }; let mut visitor = CoherenceCheckVisitor { cc: self };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
// Check that there are no overlapping trait instances // Check that there are no overlapping trait instances
self.check_implementation_coherence(); self.check_implementation_coherence();
@ -543,7 +543,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Privileged scope checking // Privileged scope checking
fn check_privileged_scopes(&self, krate: &Crate) { fn check_privileged_scopes(&self, krate: &Crate) {
let mut visitor = PrivilegedScopeVisitor{ cc: self }; let mut visitor = PrivilegedScopeVisitor{ cc: self };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }
fn trait_ref_to_trait_def_id(&self, trait_ref: &TraitRef) -> DefId { fn trait_ref_to_trait_def_id(&self, trait_ref: &TraitRef) -> DefId {

View file

@ -84,10 +84,10 @@ pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
} }
let mut visitor = CollectTraitDefVisitor{ ccx: ccx }; let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
let mut visitor = CollectItemTypesVisitor{ ccx: ccx }; let mut visitor = CollectItemTypesVisitor{ ccx: ccx };
visit::walk_crate(&mut visitor, krate, ()); visit::walk_crate(&mut visitor, krate);
} }
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -99,8 +99,8 @@ struct CollectTraitDefVisitor<'a, 'tcx: 'a> {
ccx: &'a CrateCtxt<'a, 'tcx> ccx: &'a CrateCtxt<'a, 'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for CollectTraitDefVisitor<'a, 'tcx> { impl<'a, 'tcx> visit::Visitor for CollectTraitDefVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) { fn visit_item(&mut self, i: &ast::Item) {
match i.node { match i.node {
ast::ItemTrait(..) => { ast::ItemTrait(..) => {
// computing the trait def also fills in the table // computing the trait def also fills in the table
@ -109,7 +109,7 @@ impl<'a, 'tcx> visit::Visitor<()> for CollectTraitDefVisitor<'a, 'tcx> {
_ => { } _ => { }
} }
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
} }
@ -120,14 +120,14 @@ struct CollectItemTypesVisitor<'a, 'tcx: 'a> {
ccx: &'a CrateCtxt<'a, 'tcx> ccx: &'a CrateCtxt<'a, 'tcx>
} }
impl<'a, 'tcx> visit::Visitor<()> for CollectItemTypesVisitor<'a, 'tcx> { impl<'a, 'tcx> visit::Visitor for CollectItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) { fn visit_item(&mut self, i: &ast::Item) {
convert(self.ccx, i); convert(self.ccx, i);
visit::walk_item(self, i, ()); visit::walk_item(self, i);
} }
fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
convert_foreign(self.ccx, i); convert_foreign(self.ccx, i);
visit::walk_foreign_item(self, i, ()); visit::walk_foreign_item(self, i);
} }
} }

View file

@ -301,7 +301,7 @@ fn determine_parameters_to_be_inferred<'a, 'tcx>(tcx: &'a ty::ctxt<'tcx>,
}) })
}; };
visit::walk_crate(&mut terms_cx, krate, ()); visit::walk_crate(&mut terms_cx, krate);
terms_cx terms_cx
} }
@ -337,8 +337,8 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
} }
} }
impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> { impl<'a, 'tcx> Visitor for TermsContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
debug!("add_inferreds for item {}", item.repr(self.tcx)); debug!("add_inferreds for item {}", item.repr(self.tcx));
let inferreds_on_entry = self.num_inferred(); let inferreds_on_entry = self.num_inferred();
@ -379,7 +379,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
assert!(newly_added); assert!(newly_added);
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
ast::ItemImpl(..) | ast::ItemImpl(..) |
@ -389,7 +389,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
ast::ItemForeignMod(..) | ast::ItemForeignMod(..) |
ast::ItemTy(..) | ast::ItemTy(..) |
ast::ItemMac(..) => { ast::ItemMac(..) => {
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
} }
@ -473,12 +473,12 @@ fn add_constraints_from_crate<'a, 'tcx>(terms_cx: TermsContext<'a, 'tcx>,
bivariant: bivariant, bivariant: bivariant,
constraints: Vec::new(), constraints: Vec::new(),
}; };
visit::walk_crate(&mut constraint_cx, krate, ()); visit::walk_crate(&mut constraint_cx, krate);
constraint_cx constraint_cx
} }
impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> { impl<'a, 'tcx> Visitor for ConstraintContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
let did = ast_util::local_def(item.id); let did = ast_util::local_def(item.id);
let tcx = self.terms_cx.tcx; let tcx = self.terms_cx.tcx;
@ -533,7 +533,7 @@ impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> {
ast::ItemTy(..) | ast::ItemTy(..) |
ast::ItemImpl(..) | ast::ItemImpl(..) |
ast::ItemMac(..) => { ast::ItemMac(..) => {
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
} }

View file

@ -47,7 +47,7 @@ pub fn check_crate(krate: &ast::Crate,
{ {
let mut cx = Context { sess: sess, items: items }; let mut cx = Context { sess: sess, items: items };
visit::walk_crate(&mut cx, krate, ()); visit::walk_crate(&mut cx, krate);
} }
verify(sess, items); verify(sess, items);
} }
@ -105,13 +105,13 @@ impl<'a> Context<'a> {
} }
} }
impl<'a> Visitor<()> for Context<'a> { impl<'a> Visitor for Context<'a> {
fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) { fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
match lang_items::extract(i.attrs.as_slice()) { match lang_items::extract(i.attrs.as_slice()) {
None => {} None => {}
Some(lang_item) => self.register(lang_item.get(), i.span), Some(lang_item) => self.register(lang_item.get(), i.span),
} }
visit::walk_foreign_item(self, i, ()) visit::walk_foreign_item(self, i)
} }
} }

View file

@ -21,8 +21,8 @@ struct RegistrarFinder {
registrars: Vec<(ast::NodeId, Span)> , registrars: Vec<(ast::NodeId, Span)> ,
} }
impl Visitor<()> for RegistrarFinder { impl Visitor for RegistrarFinder {
fn visit_item(&mut self, item: &ast::Item, _: ()) { fn visit_item(&mut self, item: &ast::Item) {
match item.node { match item.node {
ast::ItemFn(..) => { ast::ItemFn(..) => {
if attr::contains_name(item.attrs.as_slice(), if attr::contains_name(item.attrs.as_slice(),
@ -33,7 +33,7 @@ impl Visitor<()> for RegistrarFinder {
_ => {} _ => {}
} }
visit::walk_item(self, item, ()); visit::walk_item(self, item);
} }
} }
@ -41,7 +41,7 @@ impl Visitor<()> for RegistrarFinder {
pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler, pub fn find_plugin_registrar(diagnostic: &diagnostic::SpanHandler,
krate: &ast::Crate) -> Option<ast::NodeId> { krate: &ast::Crate) -> Option<ast::NodeId> {
let mut finder = RegistrarFinder { registrars: Vec::new() }; let mut finder = RegistrarFinder { registrars: Vec::new() };
visit::walk_crate(&mut finder, krate, ()); visit::walk_crate(&mut finder, krate);
match finder.registrars.len() { match finder.registrars.len() {
0 => None, 0 => None,

View file

@ -69,7 +69,7 @@ impl<'a> PluginLoader<'a> {
pub fn load_plugins(sess: &Session, krate: &ast::Crate, pub fn load_plugins(sess: &Session, krate: &ast::Crate,
addl_plugins: Option<Plugins>) -> Plugins { addl_plugins: Option<Plugins>) -> Plugins {
let mut loader = PluginLoader::new(sess); let mut loader = PluginLoader::new(sess);
visit::walk_crate(&mut loader, krate, ()); visit::walk_crate(&mut loader, krate);
let mut plugins = loader.plugins; let mut plugins = loader.plugins;
@ -87,8 +87,8 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
} }
// note that macros aren't expanded yet, and therefore macros can't add plugins. // note that macros aren't expanded yet, and therefore macros can't add plugins.
impl<'a> Visitor<()> for PluginLoader<'a> { impl<'a> Visitor for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, vi: &ast::ViewItem) {
match vi.node { match vi.node {
ast::ViewItemExternCrate(name, _, _) => { ast::ViewItemExternCrate(name, _, _) => {
let mut plugin_phase = false; let mut plugin_phase = false;
@ -124,7 +124,7 @@ impl<'a> Visitor<()> for PluginLoader<'a> {
_ => (), _ => (),
} }
} }
fn visit_mac(&mut self, _: &ast::Mac, _:()) { fn visit_mac(&mut self, _: &ast::Mac) {
// bummer... can't see plugins inside macros. // bummer... can't see plugins inside macros.
// do nothing. // do nothing.
} }

View file

@ -62,14 +62,14 @@ struct LoopQueryVisitor<'a> {
flag: bool, flag: bool,
} }
impl<'a> Visitor<()> for LoopQueryVisitor<'a> { impl<'a> Visitor for LoopQueryVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr) {
self.flag |= (self.p)(&e.node); self.flag |= (self.p)(&e.node);
match e.node { match e.node {
// Skip inner loops, since a break in the inner loop isn't a // Skip inner loops, since a break in the inner loop isn't a
// break inside the outer loop // break inside the outer loop
ast::ExprLoop(..) | ast::ExprWhile(..) | ast::ExprForLoop(..) => {} ast::ExprLoop(..) | ast::ExprWhile(..) | ast::ExprForLoop(..) => {}
_ => visit::walk_expr(self, e, ()) _ => visit::walk_expr(self, e)
} }
} }
} }
@ -81,7 +81,7 @@ pub fn loop_query(b: &ast::Block, p: |&ast::Expr_| -> bool) -> bool {
p: p, p: p,
flag: false, flag: false,
}; };
visit::walk_block(&mut v, b, ()); visit::walk_block(&mut v, b);
return v.flag; return v.flag;
} }
@ -90,10 +90,10 @@ struct BlockQueryVisitor<'a> {
flag: bool, flag: bool,
} }
impl<'a> Visitor<()> for BlockQueryVisitor<'a> { impl<'a> Visitor for BlockQueryVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) { fn visit_expr(&mut self, e: &ast::Expr) {
self.flag |= (self.p)(e); self.flag |= (self.p)(e);
visit::walk_expr(self, e, ()) visit::walk_expr(self, e)
} }
} }
@ -104,7 +104,7 @@ pub fn block_query(b: ast::P<ast::Block>, p: |&ast::Expr| -> bool) -> bool {
p: p, p: p,
flag: false, flag: false,
}; };
visit::walk_block(&mut v, &*b, ()); visit::walk_block(&mut v, &*b);
return v.flag; return v.flag;
} }

View file

@ -86,7 +86,7 @@ impl Svh {
{ {
let mut visit = svh_visitor::make(&mut state); let mut visit = svh_visitor::make(&mut state);
visit::walk_crate(&mut visit, krate, ()); visit::walk_crate(&mut visit, krate);
} }
// FIXME (#14132): This hash is still sensitive to e.g. the // FIXME (#14132): This hash is still sensitive to e.g. the
@ -322,12 +322,9 @@ mod svh_visitor {
} }
fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() } fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
// local short-hand eases writing signatures of syntax::visit mod. impl<'a> Visitor for StrictVersionHashVisitor<'a> {
type E = ();
impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> { fn visit_mac(&mut self, macro: &Mac) {
fn visit_mac(&mut self, macro: &Mac, e: E) {
// macro invocations, namely macro_rules definitions, // macro invocations, namely macro_rules definitions,
// *can* appear as items, even in the expanded crate AST. // *can* appear as items, even in the expanded crate AST.
@ -350,7 +347,7 @@ mod svh_visitor {
pprust::to_string(|pp_state| pp_state.print_mac(macro))); pprust::to_string(|pp_state| pp_state.print_mac(macro)));
} }
visit::walk_mac(self, macro, e); visit::walk_mac(self, macro);
fn macro_name(macro: &Mac) -> token::InternedString { fn macro_name(macro: &Mac) -> token::InternedString {
match &macro.node { match &macro.node {
@ -364,26 +361,26 @@ mod svh_visitor {
} }
fn visit_struct_def(&mut self, s: &StructDef, ident: Ident, fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
g: &Generics, _: NodeId, e: E) { g: &Generics, _: NodeId) {
SawStructDef(content(ident)).hash(self.st); SawStructDef(content(ident)).hash(self.st);
visit::walk_generics(self, g, e.clone()); visit::walk_generics(self, g);
visit::walk_struct_def(self, s, e) visit::walk_struct_def(self, s)
} }
fn visit_variant(&mut self, v: &Variant, g: &Generics, e: E) { fn visit_variant(&mut self, v: &Variant, g: &Generics) {
SawVariant.hash(self.st); SawVariant.hash(self.st);
// walk_variant does not call walk_generics, so do it here. // walk_variant does not call walk_generics, so do it here.
visit::walk_generics(self, g, e.clone()); visit::walk_generics(self, g);
visit::walk_variant(self, v, g, e) visit::walk_variant(self, v, g)
} }
fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>, env: E) { fn visit_opt_lifetime_ref(&mut self, _: Span, l: &Option<Lifetime>) {
SawOptLifetimeRef.hash(self.st); SawOptLifetimeRef.hash(self.st);
// (This is a strange method in the visitor trait, in that // (This is a strange method in the visitor trait, in that
// it does not expose a walk function to do the subroutine // it does not expose a walk function to do the subroutine
// calls.) // calls.)
match *l { match *l {
Some(ref l) => self.visit_lifetime_ref(l, env), Some(ref l) => self.visit_lifetime_ref(l),
None => () None => ()
} }
} }
@ -402,15 +399,15 @@ mod svh_visitor {
// (If you edit a method such that it deviates from the // (If you edit a method such that it deviates from the
// pattern, please move that method up above this comment.) // pattern, please move that method up above this comment.)
fn visit_ident(&mut self, _: Span, ident: Ident, _: E) { fn visit_ident(&mut self, _: Span, ident: Ident) {
SawIdent(content(ident)).hash(self.st); SawIdent(content(ident)).hash(self.st);
} }
fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) { fn visit_lifetime_ref(&mut self, l: &Lifetime) {
SawLifetimeRef(content(l.name)).hash(self.st); SawLifetimeRef(content(l.name)).hash(self.st);
} }
fn visit_lifetime_decl(&mut self, l: &LifetimeDef, _: E) { fn visit_lifetime_decl(&mut self, l: &LifetimeDef) {
SawLifetimeDecl(content(l.lifetime.name)).hash(self.st); SawLifetimeDecl(content(l.lifetime.name)).hash(self.st);
} }
@ -419,15 +416,15 @@ mod svh_visitor {
// monomorphization and cross-crate inlining generally implies // monomorphization and cross-crate inlining generally implies
// that a change to a crate body will require downstream // that a change to a crate body will require downstream
// crates to be recompiled. // crates to be recompiled.
fn visit_expr(&mut self, ex: &Expr, e: E) { fn visit_expr(&mut self, ex: &Expr) {
SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e) SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex)
} }
fn visit_stmt(&mut self, s: &Stmt, e: E) { fn visit_stmt(&mut self, s: &Stmt) {
SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e) SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s)
} }
fn visit_view_item(&mut self, i: &ViewItem, e: E) { fn visit_view_item(&mut self, i: &ViewItem) {
// Two kinds of view items can affect the ABI for a crate: // Two kinds of view items can affect the ABI for a crate:
// exported `pub use` view items (since that may expose // exported `pub use` view items (since that may expose
// items that downstream crates can call), and `use // items that downstream crates can call), and `use
@ -437,79 +434,79 @@ mod svh_visitor {
// The simplest approach to handling both of the above is // The simplest approach to handling both of the above is
// just to adopt the same simple-minded (fine-grained) // just to adopt the same simple-minded (fine-grained)
// hash that I am deploying elsewhere here. // hash that I am deploying elsewhere here.
SawViewItem.hash(self.st); visit::walk_view_item(self, i, e) SawViewItem.hash(self.st); visit::walk_view_item(self, i)
} }
fn visit_foreign_item(&mut self, i: &ForeignItem, e: E) { fn visit_foreign_item(&mut self, i: &ForeignItem) {
// FIXME (#14132) ideally we would incorporate privacy (or // FIXME (#14132) ideally we would incorporate privacy (or
// perhaps reachability) somewhere here, so foreign items // perhaps reachability) somewhere here, so foreign items
// that do not leak into downstream crates would not be // that do not leak into downstream crates would not be
// part of the ABI. // part of the ABI.
SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i, e) SawForeignItem.hash(self.st); visit::walk_foreign_item(self, i)
} }
fn visit_item(&mut self, i: &Item, e: E) { fn visit_item(&mut self, i: &Item) {
// FIXME (#14132) ideally would incorporate reachability // FIXME (#14132) ideally would incorporate reachability
// analysis somewhere here, so items that never leak into // analysis somewhere here, so items that never leak into
// downstream crates (e.g. via monomorphisation or // downstream crates (e.g. via monomorphisation or
// inlining) would not be part of the ABI. // inlining) would not be part of the ABI.
SawItem.hash(self.st); visit::walk_item(self, i, e) SawItem.hash(self.st); visit::walk_item(self, i)
} }
fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId, e: E) { fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) {
SawMod.hash(self.st); visit::walk_mod(self, m, e) SawMod.hash(self.st); visit::walk_mod(self, m)
} }
fn visit_decl(&mut self, d: &Decl, e: E) { fn visit_decl(&mut self, d: &Decl) {
SawDecl.hash(self.st); visit::walk_decl(self, d, e) SawDecl.hash(self.st); visit::walk_decl(self, d)
} }
fn visit_ty(&mut self, t: &Ty, e: E) { fn visit_ty(&mut self, t: &Ty) {
SawTy.hash(self.st); visit::walk_ty(self, t, e) SawTy.hash(self.st); visit::walk_ty(self, t)
} }
fn visit_generics(&mut self, g: &Generics, e: E) { fn visit_generics(&mut self, g: &Generics) {
SawGenerics.hash(self.st); visit::walk_generics(self, g, e) SawGenerics.hash(self.st); visit::walk_generics(self, g)
} }
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId, e: E) { fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, _: NodeId) {
SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e) SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
} }
fn visit_ty_method(&mut self, t: &TypeMethod, e: E) { fn visit_ty_method(&mut self, t: &TypeMethod) {
SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e) SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
} }
fn visit_trait_item(&mut self, t: &TraitItem, e: E) { fn visit_trait_item(&mut self, t: &TraitItem) {
SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t, e) SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
} }
fn visit_struct_field(&mut self, s: &StructField, e: E) { fn visit_struct_field(&mut self, s: &StructField) {
SawStructField.hash(self.st); visit::walk_struct_field(self, s, e) SawStructField.hash(self.st); visit::walk_struct_field(self, s)
} }
fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) { fn visit_explicit_self(&mut self, es: &ExplicitSelf) {
SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e) SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es)
} }
fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) { fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
SawPath.hash(self.st); visit::walk_path(self, path, e) SawPath.hash(self.st); visit::walk_path(self, path)
} }
fn visit_block(&mut self, b: &Block, e: E) { fn visit_block(&mut self, b: &Block) {
SawBlock.hash(self.st); visit::walk_block(self, b, e) SawBlock.hash(self.st); visit::walk_block(self, b)
} }
fn visit_pat(&mut self, p: &Pat, e: E) { fn visit_pat(&mut self, p: &Pat) {
SawPat.hash(self.st); visit::walk_pat(self, p, e) SawPat.hash(self.st); visit::walk_pat(self, p)
} }
fn visit_local(&mut self, l: &Local, e: E) { fn visit_local(&mut self, l: &Local) {
SawLocal.hash(self.st); visit::walk_local(self, l, e) SawLocal.hash(self.st); visit::walk_local(self, l)
} }
fn visit_arm(&mut self, a: &Arm, e: E) { fn visit_arm(&mut self, a: &Arm) {
SawArm.hash(self.st); visit::walk_arm(self, a, e) SawArm.hash(self.st); visit::walk_arm(self, a)
} }
} }
} }

View file

@ -366,17 +366,16 @@ impl<'a, O: IdVisitingOperation> IdVisitor<'a, O> {
} }
} }
impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> { impl<'a, O: IdVisitingOperation> Visitor for IdVisitor<'a, O> {
fn visit_mod(&mut self, fn visit_mod(&mut self,
module: &Mod, module: &Mod,
_: Span, _: Span,
node_id: NodeId, node_id: NodeId) {
env: ()) {
self.operation.visit_id(node_id); self.operation.visit_id(node_id);
visit::walk_mod(self, module, env) visit::walk_mod(self, module)
} }
fn visit_view_item(&mut self, view_item: &ViewItem, env: ()) { fn visit_view_item(&mut self, view_item: &ViewItem) {
if !self.pass_through_items { if !self.pass_through_items {
if self.visited_outermost { if self.visited_outermost {
return; return;
@ -403,16 +402,16 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
} }
} }
} }
visit::walk_view_item(self, view_item, env); visit::walk_view_item(self, view_item);
self.visited_outermost = false; self.visited_outermost = false;
} }
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem, env: ()) { fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
self.operation.visit_id(foreign_item.id); self.operation.visit_id(foreign_item.id);
visit::walk_foreign_item(self, foreign_item, env) visit::walk_foreign_item(self, foreign_item)
} }
fn visit_item(&mut self, item: &Item, env: ()) { fn visit_item(&mut self, item: &Item) {
if !self.pass_through_items { if !self.pass_through_items {
if self.visited_outermost { if self.visited_outermost {
return return
@ -431,48 +430,48 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
_ => {} _ => {}
} }
visit::walk_item(self, item, env); visit::walk_item(self, item);
self.visited_outermost = false self.visited_outermost = false
} }
fn visit_local(&mut self, local: &Local, env: ()) { fn visit_local(&mut self, local: &Local) {
self.operation.visit_id(local.id); self.operation.visit_id(local.id);
visit::walk_local(self, local, env) visit::walk_local(self, local)
} }
fn visit_block(&mut self, block: &Block, env: ()) { fn visit_block(&mut self, block: &Block) {
self.operation.visit_id(block.id); self.operation.visit_id(block.id);
visit::walk_block(self, block, env) visit::walk_block(self, block)
} }
fn visit_stmt(&mut self, statement: &Stmt, env: ()) { fn visit_stmt(&mut self, statement: &Stmt) {
self.operation.visit_id(ast_util::stmt_id(statement)); self.operation.visit_id(ast_util::stmt_id(statement));
visit::walk_stmt(self, statement, env) visit::walk_stmt(self, statement)
} }
fn visit_pat(&mut self, pattern: &Pat, env: ()) { fn visit_pat(&mut self, pattern: &Pat) {
self.operation.visit_id(pattern.id); self.operation.visit_id(pattern.id);
visit::walk_pat(self, pattern, env) visit::walk_pat(self, pattern)
} }
fn visit_expr(&mut self, expression: &Expr, env: ()) { fn visit_expr(&mut self, expression: &Expr) {
self.operation.visit_id(expression.id); self.operation.visit_id(expression.id);
visit::walk_expr(self, expression, env) visit::walk_expr(self, expression)
} }
fn visit_ty(&mut self, typ: &Ty, env: ()) { fn visit_ty(&mut self, typ: &Ty) {
self.operation.visit_id(typ.id); self.operation.visit_id(typ.id);
match typ.node { match typ.node {
TyPath(_, _, id) => self.operation.visit_id(id), TyPath(_, _, id) => self.operation.visit_id(id),
_ => {} _ => {}
} }
visit::walk_ty(self, typ, env) visit::walk_ty(self, typ)
} }
fn visit_generics(&mut self, generics: &Generics, env: ()) { fn visit_generics(&mut self, generics: &Generics) {
self.visit_generics_helper(generics); self.visit_generics_helper(generics);
visit::walk_generics(self, generics, env) visit::walk_generics(self, generics)
} }
fn visit_fn(&mut self, fn visit_fn(&mut self,
@ -480,8 +479,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
function_declaration: &FnDecl, function_declaration: &FnDecl,
block: &Block, block: &Block,
span: Span, span: Span,
node_id: NodeId, node_id: NodeId) {
env: ()) {
if !self.pass_through_items { if !self.pass_through_items {
match *function_kind { match *function_kind {
visit::FkMethod(..) if self.visited_outermost => return, visit::FkMethod(..) if self.visited_outermost => return,
@ -508,8 +506,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
function_kind, function_kind,
function_declaration, function_declaration,
block, block,
span, span);
env);
if !self.pass_through_items { if !self.pass_through_items {
match *function_kind { match *function_kind {
@ -519,28 +516,27 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
} }
} }
fn visit_struct_field(&mut self, struct_field: &StructField, env: ()) { fn visit_struct_field(&mut self, struct_field: &StructField) {
self.operation.visit_id(struct_field.node.id); self.operation.visit_id(struct_field.node.id);
visit::walk_struct_field(self, struct_field, env) visit::walk_struct_field(self, struct_field)
} }
fn visit_struct_def(&mut self, fn visit_struct_def(&mut self,
struct_def: &StructDef, struct_def: &StructDef,
_: ast::Ident, _: ast::Ident,
_: &ast::Generics, _: &ast::Generics,
id: NodeId, id: NodeId) {
_: ()) {
self.operation.visit_id(id); self.operation.visit_id(id);
struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id)); struct_def.ctor_id.map(|ctor_id| self.operation.visit_id(ctor_id));
visit::walk_struct_def(self, struct_def, ()); visit::walk_struct_def(self, struct_def);
} }
fn visit_trait_item(&mut self, tm: &ast::TraitItem, _: ()) { fn visit_trait_item(&mut self, tm: &ast::TraitItem) {
match *tm { match *tm {
ast::RequiredMethod(ref m) => self.operation.visit_id(m.id), ast::RequiredMethod(ref m) => self.operation.visit_id(m.id),
ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id), ast::ProvidedMethod(ref m) => self.operation.visit_id(m.id),
} }
visit::walk_trait_item(self, tm, ()); visit::walk_trait_item(self, tm);
} }
} }
@ -552,7 +548,7 @@ pub fn visit_ids_for_inlined_item<O: IdVisitingOperation>(item: &InlinedItem,
visited_outermost: false, visited_outermost: false,
}; };
visit::walk_inlined_item(&mut id_visitor, item, ()); visit::walk_inlined_item(&mut id_visitor, item);
} }
struct IdRangeComputingVisitor { struct IdRangeComputingVisitor {
@ -595,7 +591,7 @@ pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
pass_through_items: false, pass_through_items: false,
visited_outermost: false, visited_outermost: false,
}; };
id_visitor.visit_fn(fk, decl, body, sp, id, ()); id_visitor.visit_fn(fk, decl, body, sp, id);
visitor.result.get() visitor.result.get()
} }
@ -643,8 +639,8 @@ struct EachViewItemData<'a> {
callback: |&ast::ViewItem|: 'a -> bool, callback: |&ast::ViewItem|: 'a -> bool,
} }
impl<'a> Visitor<()> for EachViewItemData<'a> { impl<'a> Visitor for EachViewItemData<'a> {
fn visit_view_item(&mut self, view_item: &ast::ViewItem, _: ()) { fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
let _ = (self.callback)(view_item); let _ = (self.callback)(view_item);
} }
} }
@ -654,7 +650,7 @@ impl EachViewItem for ast::Crate {
let mut visit = EachViewItemData { let mut visit = EachViewItemData {
callback: f, callback: f,
}; };
visit::walk_crate(&mut visit, self, ()); visit::walk_crate(&mut visit, self);
true true
} }
} }

View file

@ -648,29 +648,29 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
/// array /// array
#[deriving(Clone)] #[deriving(Clone)]
struct PatIdentFinder { struct PatIdentFinder {
ident_accumulator: Vec<ast::Ident> , ident_accumulator: Vec<ast::Ident>
} }
impl Visitor<()> for PatIdentFinder { impl Visitor for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) { fn visit_pat(&mut self, pattern: &ast::Pat) {
match *pattern { match *pattern {
ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => { ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
self.ident_accumulator.push(path1.node); self.ident_accumulator.push(path1.node);
// visit optional subpattern of PatIdent: // visit optional subpattern of PatIdent:
for subpat in inner.iter() { for subpat in inner.iter() {
self.visit_pat(&**subpat, ()) self.visit_pat(&**subpat)
} }
} }
// use the default traversal for non-PatIdents // use the default traversal for non-PatIdents
_ => visit::walk_pat(self, pattern, ()) _ => visit::walk_pat(self, pattern)
} }
} }
} }
/// find the PatIdent paths in a pattern /// find the PatIdent paths in a pattern
fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> { fn pattern_bindings(pat: &ast::Pat) -> Vec<ast::Ident> {
let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()}; let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
name_finder.visit_pat(pat,()); name_finder.visit_pat(pat);
name_finder.ident_accumulator name_finder.ident_accumulator
} }
@ -678,7 +678,7 @@ fn pattern_bindings(pat : &ast::Pat) -> Vec<ast::Ident> {
fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> { fn fn_decl_arg_bindings(fn_decl: &ast::FnDecl) -> Vec<ast::Ident> {
let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()}; let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
for arg in fn_decl.inputs.iter() { for arg in fn_decl.inputs.iter() {
pat_idents.visit_pat(&*arg.pat, ()); pat_idents.visit_pat(&*arg.pat);
} }
pat_idents.ident_accumulator pat_idents.ident_accumulator
} }
@ -1099,7 +1099,7 @@ fn original_span(cx: &ExtCtxt) -> Gc<codemap::ExpnInfo> {
/// Check that there are no macro invocations left in the AST: /// Check that there are no macro invocations left in the AST:
pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) { pub fn check_for_macros(sess: &parse::ParseSess, krate: &ast::Crate) {
visit::walk_crate(&mut MacroExterminator{sess:sess}, krate, ()); visit::walk_crate(&mut MacroExterminator{sess:sess}, krate);
} }
/// A visitor that ensures that no macro invocations remain in an AST. /// A visitor that ensures that no macro invocations remain in an AST.
@ -1107,8 +1107,8 @@ struct MacroExterminator<'a>{
sess: &'a parse::ParseSess sess: &'a parse::ParseSess
} }
impl<'a> visit::Visitor<()> for MacroExterminator<'a> { impl<'a> Visitor for MacroExterminator<'a> {
fn visit_mac(&mut self, macro: &ast::Mac, _:()) { fn visit_mac(&mut self, macro: &ast::Mac) {
self.sess.span_diagnostic.span_bug(macro.span, self.sess.span_diagnostic.span_bug(macro.span,
"macro exterminator: expected AST \ "macro exterminator: expected AST \
with no macro invocations"); with no macro invocations");
@ -1144,15 +1144,14 @@ mod test {
path_accumulator: Vec<ast::Path> , path_accumulator: Vec<ast::Path> ,
} }
impl Visitor<()> for PathExprFinderContext { impl Visitor for PathExprFinderContext {
fn visit_expr(&mut self, expr: &ast::Expr) {
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) { match expr.node {
match *expr { ast::ExprPath(ref p) => {
ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
self.path_accumulator.push(p.clone()); self.path_accumulator.push(p.clone());
// not calling visit_path, but it should be fine. // not calling visit_path, but it should be fine.
} }
_ => visit::walk_expr(self,expr,()) _ => visit::walk_expr(self, expr)
} }
} }
} }
@ -1160,18 +1159,18 @@ mod test {
// find the variable references in a crate // find the variable references in a crate
fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> { fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
let mut path_finder = PathExprFinderContext{path_accumulator:Vec::new()}; let mut path_finder = PathExprFinderContext{path_accumulator:Vec::new()};
visit::walk_crate(&mut path_finder, the_crate, ()); visit::walk_crate(&mut path_finder, the_crate);
path_finder.path_accumulator path_finder.path_accumulator
} }
/// A Visitor that extracts the identifiers from a thingy. /// A Visitor that extracts the identifiers from a thingy.
// as a side note, I'm starting to want to abstract over these.... // as a side note, I'm starting to want to abstract over these....
struct IdentFinder{ struct IdentFinder {
ident_accumulator: Vec<ast::Ident> ident_accumulator: Vec<ast::Ident>
} }
impl Visitor<()> for IdentFinder { impl Visitor for IdentFinder {
fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){ fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
self.ident_accumulator.push(id); self.ident_accumulator.push(id);
} }
} }
@ -1179,7 +1178,7 @@ mod test {
/// Find the idents in a crate /// Find the idents in a crate
fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> { fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()}; let mut ident_finder = IdentFinder{ident_accumulator: Vec::new()};
visit::walk_crate(&mut ident_finder, the_crate, ()); visit::walk_crate(&mut ident_finder, the_crate);
ident_finder.ident_accumulator ident_finder.ident_accumulator
} }
@ -1277,7 +1276,7 @@ mod test {
// find the pat_ident paths in a crate // find the pat_ident paths in a crate
fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> { fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()}; let mut name_finder = PatIdentFinder{ident_accumulator:Vec::new()};
visit::walk_crate(&mut name_finder, the_crate, ()); visit::walk_crate(&mut name_finder, the_crate);
name_finder.ident_accumulator name_finder.ident_accumulator
} }

File diff suppressed because it is too large Load diff