auto merge of #17069 : eddyb/rust/visitor, r=pnkfelix

Few visitors used the context passing feature and it can be easily emulated.
The added lifetime threading allows a visitor to keep safe references to AST
nodes it visits, making a non-owning ast_map design possible, for #13316.
This commit is contained in:
bors 2014-09-12 13:45:41 +00:00
commit 9c68679f2e
49 changed files with 1544 additions and 1613 deletions

View File

@ -143,15 +143,15 @@ impl<'a> Context<'a> {
}
}
impl<'a> Visitor<()> for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident, _: ()) {
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_ident(&mut self, sp: Span, id: ast::Ident) {
if !token::get_ident(id).get().is_ascii() {
self.gate_feature("non_ascii_idents", sp,
"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 {
ast::ViewItemUse(ref path) => {
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() {
if attr.name().equiv(&("thread_local")) {
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 id = path.segments.last().unwrap().identifier;
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") {
self.gate_feature("linkage", i.span,
"the `linkage` attribute is experimental \
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 {
ast::TyClosure(closure) if closure.onceness == ast::Once => {
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 {
ast::ExprUnary(ast::UnBox, _) => {
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() {
match type_parameter.default {
Some(ty) => {
@ -360,10 +360,10 @@ impl<'a> Visitor<()> for Context<'a> {
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") {
self.gate_feature("lang_items",
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 {
ast::PatVec(_, Some(_), ref last) if !last.is_empty() => {
self.gate_feature("advanced_slice_patterns",
@ -382,25 +382,24 @@ impl<'a> Visitor<()> for Context<'a> {
}
_ => {}
}
visit::walk_pat(self, pattern, ())
visit::walk_pat(self, pattern)
}
fn visit_fn(&mut self,
fn_kind: &visit::FnKind,
fn_decl: &ast::FnDecl,
block: &ast::Block,
fn_kind: visit::FnKind<'v>,
fn_decl: &'v ast::FnDecl,
block: &'v ast::Block,
span: Span,
_: NodeId,
(): ()) {
match *fn_kind {
visit::FkItemFn(_, _, _, ref abi) if *abi == RustIntrinsic => {
_: NodeId) {
match fn_kind {
visit::FkItemFn(_, _, _, abi) if abi == RustIntrinsic => {
self.gate_feature("intrinsics",
span,
"intrinsics are subject to change")
}
_ => {}
}
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();

View File

@ -23,18 +23,18 @@ struct ShowSpanVisitor<'a> {
sess: &'a Session
}
impl<'a> Visitor<()> for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr, _: ()) {
impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
fn visit_expr(&mut self, e: &ast::Expr) {
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: ()) {
visit::walk_mac(self, macro, e);
fn visit_mac(&mut self, macro: &ast::Mac) {
visit::walk_mac(self, macro);
}
}
pub fn run(sess: &Session, krate: &ast::Crate) {
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> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for CTypesVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
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_ty(cx: &Context, ty: &ast::Ty) {
let mut vis = CTypesVisitor { cx: cx };
vis.visit_ty(ty, ());
vis.visit_ty(ty);
}
fn check_foreign_fn(cx: &Context, decl: &ast::FnDecl) {
@ -500,18 +500,18 @@ struct RawPtrDerivingVisitor<'a, 'tcx: 'a> {
cx: &'a Context<'a, 'tcx>
}
impl<'a, 'tcx> Visitor<()> for RawPtrDerivingVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDerivingVisitor<'a, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
static MSG: &'static str = "use of `#[deriving]` with a raw pointer";
match ty.node {
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
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
fn visit_block(&mut self, _: &ast::Block, _: ()) {}
fn visit_expr(&mut self, _: &ast::Expr) {}
fn visit_block(&mut self, _: &ast::Block) {}
}
pub struct RawPointerDeriving {
@ -554,7 +554,7 @@ impl LintPass for RawPointerDeriving {
match item.node {
ast::ItemStruct(..) | ast::ItemEnum(..) => {
let mut visitor = RawPtrDerivingVisitor { cx: cx };
visit::walk_item(&mut visitor, &*item, ());
visit::walk_item(&mut visitor, &*item);
}
_ => {}
}
@ -908,9 +908,9 @@ impl LintPass for NonSnakeCase {
}
fn check_fn(&mut self, cx: &Context,
fk: &visit::FnKind, _: &ast::FnDecl,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, _: ast::NodeId) {
match *fk {
match fk {
visit::FkMethod(ident, _, m) => match method_context(cx, m) {
PlainImpl
=> self.check_snake_case(cx, "method", ident, span),
@ -1218,7 +1218,7 @@ impl LintPass for UnusedMut {
}
fn check_fn(&mut self, cx: &Context,
_: &visit::FnKind, decl: &ast::FnDecl,
_: visit::FnKind, decl: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId) {
for a in decl.inputs.iter() {
self.check_unused_mut_pat(cx, &[a.pat]);
@ -1387,9 +1387,9 @@ impl LintPass for MissingDoc {
}
fn check_fn(&mut self, cx: &Context,
fk: &visit::FnKind, _: &ast::FnDecl,
fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId) {
match *fk {
match fk {
visit::FkMethod(_, _, m) => {
// If the method is an impl for a trait, don't doc.
if method_context(cx, m) == TraitImpl { return; }

View File

@ -492,68 +492,68 @@ impl<'a, 'tcx> AstConv<'tcx> for Context<'a, 'tcx>{
}
}
impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
fn visit_item(&mut self, it: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
fn visit_item(&mut self, it: &ast::Item) {
self.with_lint_attrs(it.attrs.as_slice(), |cx| {
run_lints!(cx, check_item, it);
cx.visit_ids(|v| v.visit_item(it, ()));
visit::walk_item(cx, it, ());
cx.visit_ids(|v| v.visit_item(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| {
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| {
run_lints!(cx, check_view_item, i);
cx.visit_ids(|v| v.visit_view_item(i, ()));
visit::walk_view_item(cx, i, ());
cx.visit_ids(|v| v.visit_view_item(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);
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);
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);
visit::walk_stmt(self, s, ());
visit::walk_stmt(self, s);
}
fn visit_fn(&mut self, fk: &FnKind, decl: &ast::FnDecl,
body: &ast::Block, span: Span, id: ast::NodeId, _: ()) {
match *fk {
fn visit_fn(&mut self, fk: FnKind<'v>, decl: &'v ast::FnDecl,
body: &'v ast::Block, span: Span, id: ast::NodeId) {
match fk {
visit::FkMethod(_, _, m) => {
self.with_lint_attrs(m.attrs.as_slice(), |cx| {
run_lints!(cx, check_fn, fk, decl, body, span, id);
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);
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| {
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,
ident: ast::Ident,
g: &ast::Generics,
id: ast::NodeId,
_: ()) {
id: ast::NodeId) {
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);
}
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| {
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| {
run_lints!(cx, check_variant, v, g);
visit::walk_variant(cx, v, g, ());
visit::walk_variant(cx, v, g);
})
}
// 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);
}
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);
}
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);
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);
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);
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);
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);
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);
}
fn visit_generics(&mut self, g: &ast::Generics, _: ()) {
fn visit_generics(&mut self, g: &ast::Generics) {
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);
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);
}
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);
}
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);
}
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);
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);
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);
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);
}
}
@ -719,14 +718,14 @@ pub fn check_crate(tcx: &ty::ctxt,
cx.visit_id(ast::CRATE_NODE_ID);
cx.visit_ids(|v| {
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
// item), warn for it here.
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

View File

@ -139,7 +139,7 @@ pub trait LintPass {
fn check_ty(&mut self, _: &Context, _: &ast::Ty) { }
fn check_generics(&mut self, _: &Context, _: &ast::Generics) { }
fn check_fn(&mut self, _: &Context,
_: &FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
_: FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
fn check_ty_method(&mut self, _: &Context, _: &ast::TypeMethod) { }
fn check_trait_method(&mut self, _: &Context, _: &ast::TraitItem) { }
fn check_struct_def(&mut self, _: &Context,

View File

@ -49,19 +49,19 @@ pub fn read_crates(sess: &Session,
next_crate_num: sess.cstore.next_crate_num(),
};
visit_crate(&e, krate);
visit::walk_crate(&mut e, krate, ());
visit::walk_crate(&mut e, krate);
dump_crates(&sess.cstore);
warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
}
impl<'a> visit::Visitor<()> for Env<'a> {
fn visit_view_item(&mut self, a: &ast::ViewItem, _: ()) {
impl<'a, 'v> visit::Visitor<'v> for Env<'a> {
fn visit_view_item(&mut self, a: &ast::ViewItem) {
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::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>>,
}
impl<'a,'b> visit::Visitor<()> for EncodeVisitor<'a,'b> {
fn visit_expr(&mut self, ex: &Expr, _: ()) {
visit::walk_expr(self, ex, ());
impl<'a, 'b, 'v> Visitor<'v> for EncodeVisitor<'a, 'b> {
fn visit_expr(&mut self, ex: &Expr) {
visit::walk_expr(self, ex);
my_visit_expr(ex);
}
fn visit_item(&mut self, i: &Item, _: ()) {
visit::walk_item(self, i, ());
fn visit_item(&mut self, i: &Item) {
visit::walk_item(self, i);
my_visit_item(i,
self.rbml_w_for_visit_item,
self.ecx_ptr,
self.index);
}
fn visit_foreign_item(&mut self, ni: &ForeignItem, _: ()) {
visit::walk_foreign_item(self, ni, ());
fn visit_foreign_item(&mut self, ni: &ForeignItem) {
visit::walk_foreign_item(self, ni);
my_visit_foreign_item(ni,
self.rbml_w_for_visit_item,
self.ecx_ptr,
@ -1519,7 +1519,7 @@ fn encode_info_for_items(ecx: &EncodeContext,
index: &mut index,
ecx_ptr: ecx_ptr,
rbml_w_for_visit_item: &mut *rbml_w,
}, krate, ());
}, krate);
rbml_w.end_tag();
index
@ -1775,8 +1775,8 @@ fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &Crate) {
rbml_w: &'a mut Encoder<'b>,
}
impl<'a, 'b> Visitor<()> for StructFieldVisitor<'a, 'b> {
fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
impl<'a, 'b, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b> {
fn visit_struct_field(&mut self, field: &ast::StructField) {
self.rbml_w.start_tag(tag_struct_field);
self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
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);
visit::walk_crate(&mut StructFieldVisitor {
rbml_w: rbml_w
}, krate, ());
}, krate);
rbml_w.end_tag();
}
@ -1798,8 +1798,8 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
rbml_w: &'a mut Encoder<'c>,
}
impl<'a, 'b, 'c, 'tcx> Visitor<()> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) {
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &Item) {
match item.node {
ItemImpl(_, Some(ref trait_ref), _, _) => {
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,
rbml_w: rbml_w,
};
visit::walk_crate(&mut visitor, krate, ());
visit::walk_crate(&mut visitor, krate);
}
rbml_w.end_tag();

View File

@ -26,7 +26,7 @@ use util::ppaux::{Repr};
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::{Visitor};
use syntax::visit::Visitor;
use syntax::ast::{Expr, FnDecl, Block, NodeId, Pat};
mod lifetime;
@ -471,8 +471,8 @@ struct StaticInitializerCtxt<'a, 'tcx: 'a> {
bccx: &'a BorrowckCtxt<'a, 'tcx>
}
impl<'a, 'tcx> visit::Visitor<()> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for StaticInitializerCtxt<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
match ex.node {
ast::ExprAddrOf(mutbl, ref 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
};
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>;
impl<'a, 'tcx> Visitor<()> for BorrowckCtxt<'a, 'tcx> {
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, n: NodeId) {
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);
}
}
@ -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() {
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);
}
_ => {
visit::walk_item(this, item, ());
visit::walk_item(this, item);
}
}
}
@ -127,7 +127,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
}
fn borrowck_fn(this: &mut BorrowckCtxt,
fk: &FnKind,
fk: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
sp: Span,
@ -142,11 +142,11 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
check_loans::check_loans(this, &loan_dfcx, flowed_moves,
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>,
fk: &FnKind,
fk: FnKind,
decl: &ast::FnDecl,
cfg: &cfg::CFG,
body: &ast::Block,
@ -217,7 +217,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
let p = input.fn_parts;
let dataflow_data = build_borrowck_dataflow_data(&mut bccx,
&p.kind,
p.kind,
&*p.decl,
input.cfg,
&*p.body,

View File

@ -21,45 +21,61 @@ use syntax::{ast_util, ast_map};
use syntax::visit::Visitor;
use syntax::visit;
pub struct CheckCrateVisitor<'a, 'tcx: 'a> {
struct CheckCrateVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
in_const: bool
}
impl<'a, 'tcx> Visitor<bool> for CheckCrateVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &Item, env: bool) {
check_item(self, i, env);
impl<'a, 'tcx> CheckCrateVisitor<'a, 'tcx> {
fn with_const(&mut self, in_const: bool, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
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) {
check_pat(self, p, env);
fn inside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
self.with_const(true, f);
}
fn visit_expr(&mut self, ex: &Expr, env: bool) {
check_expr(self, ex, env);
fn outside_const(&mut self, f: |&mut CheckCrateVisitor<'a, 'tcx>|) {
self.with_const(false, f);
}
}
impl<'a, 'tcx, 'v> Visitor<'v> 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) {
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();
}
fn check_item(v: &mut CheckCrateVisitor, it: &Item, _is_const: bool) {
fn check_item(v: &mut CheckCrateVisitor, it: &Item) {
match it.node {
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);
}
ItemEnum(ref enum_definition, _) => {
for var in (*enum_definition).variants.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 {
match e.node {
ExprBox(_, expr) => {
@ -72,18 +88,18 @@ fn check_pat(v: &mut CheckCrateVisitor, p: &Pat, _is_const: bool) {
}
}
match p.node {
// Let through plain ~-string literals here
PatLit(ref a) => if !is_str(&**a) { v.visit_expr(&**a, true); },
PatRange(ref a, ref b) => {
if !is_str(&**a) { v.visit_expr(&**a, true); }
if !is_str(&**b) { v.visit_expr(&**b, true); }
}
_ => visit::walk_pat(v, p, false)
// Let through plain ~-string literals here
PatLit(ref a) => if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); },
PatRange(ref a, ref b) => {
if !is_str(&**a) { v.inside_const(|v| v.visit_expr(&**a)); }
if !is_str(&**b) { v.inside_const(|v| v.visit_expr(&**b)); }
}
_ => v.outside_const(|v| visit::walk_pat(v, p))
}
}
fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
if is_const {
fn check_expr(v: &mut CheckCrateVisitor, e: &Expr) {
if v.in_const {
match e.node {
ExprUnary(UnDeref, _) => { }
ExprUnary(UnBox, _) | ExprUnary(UnUniq, _) => {
@ -165,7 +181,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &Expr, is_const: bool) {
}
}
match block.expr {
Some(ref expr) => check_expr(v, &**expr, true),
Some(ref expr) => check_expr(v, &**expr),
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> {
@ -219,32 +235,32 @@ pub fn check_item_recursion<'a>(sess: &'a Session,
def_map: def_map,
idstack: Vec::new()
};
visitor.visit_item(it, ());
visitor.visit_item(it);
}
impl<'a> Visitor<()> for CheckItemRecursionVisitor<'a> {
fn visit_item(&mut self, it: &Item, _: ()) {
impl<'a, 'v> Visitor<'v> for CheckItemRecursionVisitor<'a> {
fn visit_item(&mut self, it: &Item) {
if self.idstack.iter().any(|x| x == &(it.id)) {
self.sess.span_fatal(self.root_it.span, "recursive constant");
}
self.idstack.push(it.id);
visit::walk_item(self, it, ());
visit::walk_item(self, it);
self.idstack.pop();
}
fn visit_expr(&mut self, e: &Expr, _: ()) {
fn visit_expr(&mut self, e: &Expr) {
match e.node {
ExprPath(..) => {
match self.def_map.borrow().find(&e.id) {
Some(&DefStatic(def_id, _)) if
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> {
sess: &'a Session,
cx: Context
}
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> {
fn visit_item(&mut self, i: &ast::Item, _cx: Context) {
visit::walk_item(self, i, Normal);
impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
fn visit_item(&mut self, i: &ast::Item) {
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 {
ast::ExprWhile(ref e, ref b, _) => {
self.visit_expr(&**e, cx);
self.visit_block(&**b, Loop);
self.visit_expr(&**e);
self.with_context(Loop, |v| v.visit_block(&**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, _) => {
self.visit_expr(&**e, cx);
self.visit_block(&**b, Loop);
self.visit_expr(&**e);
self.with_context(Loop, |v| v.visit_block(&**b));
}
ast::ExprFnBlock(_, _, ref b) |
ast::ExprProc(_, 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::ExprAgain(_) => self.require_loop("continue", cx, e.span),
_ => visit::walk_expr(self, e, cx)
ast::ExprBreak(_) => self.require_loop("break", e.span),
ast::ExprAgain(_) => self.require_loop("continue", e.span),
_ => visit::walk_expr(self, e)
}
}
}
impl<'a> CheckLoopVisitor<'a> {
fn require_loop(&self, name: &str, cx: Context, span: Span) {
match cx {
fn with_context(&mut self, cx: Context, f: |&mut CheckLoopVisitor<'a>|) {
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 => {}
Closure => {
self.sess.span_err(span,

View File

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

View File

@ -27,7 +27,6 @@
use middle::ty;
use syntax::ast;
use syntax::codemap::Span;
use syntax::visit::Visitor;
use syntax::visit;
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> {
tcx: &'a ty::ctxt<'tcx>,
in_const: bool
}
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> {
fn report_error(&self, span: Span, result: Option<String>) -> bool {
match result {
None => { false }
Some(msg) => {
self.tcx.sess.span_err(span, msg.as_slice());
true
}
}
fn with_const(&mut self, in_const: bool, f: |&mut CheckStaticVisitor<'a, 'tcx>|) {
let was_const = self.in_const;
self.in_const = in_const;
f(self);
self.in_const = was_const;
}
}
impl<'a, 'tcx> Visitor<bool> for CheckStaticVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _is_const: bool) {
impl<'a, 'tcx, 'v> Visitor<'v> for CheckStaticVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
debug!("visit_item(item={})", pprust::item_to_string(i));
match i.node {
ast::ItemStatic(_, mutability, ref expr) => {
match mutability {
ast::MutImmutable => {
self.visit_expr(&**expr, true);
self.with_const(true, |v| v.visit_expr(&**expr));
}
ast::MutMutable => {
let safe = safe_type_for_static_mut(self.tcx, &**expr);
self.report_error(expr.span, safe);
match safe_type_for_static_mut(self.tcx, &**expr) {
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
/// of a static item, this method does nothing but walking
/// 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));
if !is_const {
return visit::walk_expr(self, e, is_const);
if !self.in_const {
return visit::walk_expr(self, e);
}
match e.node {
ast::ExprField(..) | ast::ExprTupField(..) | ast::ExprVec(..) |
ast::ExprBlock(..) | ast::ExprTup(..) => {
visit::walk_expr(self, e, is_const);
visit::walk_expr(self, e);
}
ast::ExprAddrOf(ast::MutMutable, _) => {
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_enum(did, _) => {
if ty::has_dtor(self.tcx, did) {
self.report_error(e.span,
Some("static items are not allowed to have \
destructors".to_string()));
self.tcx.sess.span_err(e.span,
"static items are not allowed to have destructors");
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> {
fn visit_ty(&mut self, t: &Ty, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for ConstEvalVisitor<'a, 'tcx> {
fn visit_ty(&mut self, t: &Ty) {
match t.node {
TyFixedLengthVec(_, expr) => {
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);
}
}
@ -291,7 +291,7 @@ pub fn process_crate(krate: &ast::Crate,
tcx: tcx,
ccache: DefIdMap::new(),
};
visit::walk_crate(&mut v, krate, ());
visit::walk_crate(&mut v, krate);
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>,
}
let mut formals = Formals { entry: entry, index: index };
visit::walk_fn_decl(&mut formals, decl, ());
impl<'a> visit::Visitor<()> for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat, e: ()) {
visit::walk_fn_decl(&mut formals, decl);
impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat) {
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>,
tcx: &'a ty::ctxt<'tcx>,
live_symbols: Box<HashSet<ast::NodeId>>,
}
#[deriving(Clone)]
struct MarkSymbolVisitorContext {
struct_has_extern_repr: bool
}
@ -65,6 +61,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
worklist: worklist,
tcx: tcx,
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) {
let ctxt = MarkSymbolVisitorContext {
struct_has_extern_repr: false
};
let had_extern_repr = self.struct_has_extern_repr;
self.struct_has_extern_repr = false;
match *node {
ast_map::NodeItem(item) => {
match item.node {
ast::ItemStruct(..) => {
let has_extern_repr = item.attrs.iter().fold(false, |acc, attr| {
acc || attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
.iter().any(|&x| x == attr::ReprExtern)
self.struct_has_extern_repr = item.attrs.iter().any(|attr| {
attr::find_repr_attrs(self.tcx.sess.diagnostic(), attr)
.contains(&attr::ReprExtern)
});
visit::walk_item(self, &*item, MarkSymbolVisitorContext {
struct_has_extern_repr: has_extern_repr,
..(ctxt)
});
visit::walk_item(self, &*item);
}
ast::ItemFn(..)
| ast::ItemEnum(..)
| ast::ItemTy(..)
| ast::ItemStatic(..) => {
visit::walk_item(self, &*item, ctxt);
visit::walk_item(self, &*item);
}
_ => ()
}
}
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) => {
match *impl_item {
ast::MethodImplItem(method) => {
visit::walk_block(self, &*method.pe_body(), ctxt);
visit::walk_block(self, &*method.pe_body());
}
}
}
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, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident, _: &ast::Generics,
_: ast::NodeId, ctxt: MarkSymbolVisitorContext) {
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
_: &ast::Generics, _: ast::NodeId) {
let has_extern_repr = self.struct_has_extern_repr;
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,
_ => false
}
});
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 {
ast::ExprMethodCall(..) => {
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 {
ast::PatStruct(_, ref fields, _) => {
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);
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
// worklist and recursed into manually if necessary.
}
@ -334,8 +329,8 @@ struct LifeSeeder {
worklist: Vec<ast::NodeId> ,
}
impl Visitor<()> for LifeSeeder {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'v> Visitor<'v> for LifeSeeder {
fn visit_item(&mut self, item: &ast::Item) {
if has_allow_dead_code_or_lang_attr(item.attrs.as_slice()) {
self.worklist.push(item.id);
}
@ -351,14 +346,14 @@ impl Visitor<()> for LifeSeeder {
}
_ => ()
}
visit::walk_item(self, item, ());
visit::walk_item(self, item);
}
fn visit_fn(&mut self, fk: &visit::FnKind,
_: &ast::FnDecl, block: &ast::Block,
_: codemap::Span, id: ast::NodeId, _: ()) {
fn visit_fn(&mut self, fk: visit::FnKind<'v>,
_: &'v ast::FnDecl, block: &'v ast::Block,
_: codemap::Span, id: ast::NodeId) {
// Check for method here because methods are not ast::Item
match *fk {
match fk {
visit::FkMethod(_, _, method) => {
if has_allow_dead_code_or_lang_attr(method.attrs.as_slice()) {
self.worklist.push(id);
@ -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 {
worklist: worklist
};
visit::walk_crate(&mut life_seeder, krate, ());
visit::walk_crate(&mut life_seeder, krate);
return life_seeder.worklist;
}
@ -504,51 +499,50 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx> Visitor<()> for DeadVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
let ctor_id = get_struct_ctor_id(item);
if !self.symbol_is_live(item.id, ctor_id) && should_warn(item) {
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) {
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,
_: &ast::FnDecl, block: &ast::Block,
span: codemap::Span, id: ast::NodeId, _: ()) {
fn visit_fn(&mut self, fk: visit::FnKind<'v>,
_: &'v ast::FnDecl, block: &'v ast::Block,
span: codemap::Span, id: ast::NodeId) {
// Have to warn method here because methods are not ast::Item
match *fk {
visit::FkMethod(..) => {
let ident = visit::name_of_fn(fk);
match fk {
visit::FkMethod(name, _, _) => {
if !self.symbol_is_live(id, None) {
self.warn_dead_code(id, span, ident);
self.warn_dead_code(id, span, name);
}
}
_ => ()
}
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) {
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.
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem, _: ()) {
fn visit_trait_item(&mut self, trait_method: &ast::TraitItem) {
match *trait_method {
ast::ProvidedMethod(ref method) => {
visit::walk_block(self, &*method.pe_body(), ())
visit::walk_block(self, &*method.pe_body())
}
ast::RequiredMethod(_) => ()
}
@ -562,5 +556,5 @@ pub fn check_crate(tcx: &ty::ctxt,
let live_symbols = find_live(tcx, exported_items,
reachable_symbols, krate);
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,11 +86,11 @@ impl<'a, 'tcx> EffectCheckVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
block: &ast::Block, span: Span, _: ast::NodeId, _:()) {
impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
fn visit_fn(&mut self, fn_kind: visit::FnKind<'v>, fn_decl: &'v ast::FnDecl,
block: &'v 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, _) =>
(true, fn_style == ast::UnsafeFn),
visit::FkMethod(_, _, method) =>
@ -105,12 +105,12 @@ impl<'a, 'tcx> Visitor<()> for EffectCheckVisitor<'a, 'tcx> {
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
}
fn visit_block(&mut self, block: &ast::Block, _:()) {
fn visit_block(&mut self, block: &ast::Block) {
let old_unsafe_context = self.unsafe_context;
match block.rules {
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
}
fn visit_expr(&mut self, expr: &ast::Expr, _:()) {
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
ast::ExprMethodCall(_, _, _) => {
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,
};
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)> ,
}
impl<'a> Visitor<()> for EntryContext<'a> {
fn visit_item(&mut self, item: &Item, _:()) {
impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
fn visit_item(&mut self, item: &Item) {
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(),
};
visit::walk_crate(&mut ctxt, krate, ());
visit::walk_crate(&mut ctxt, krate);
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) {

View File

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

View File

@ -116,8 +116,8 @@ impl<'a, 'tcx> IntrinsicCheckingVisitor<'a, 'tcx> {
}
}
impl<'a, 'tcx> Visitor<()> for IntrinsicCheckingVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr, (): ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for IntrinsicCheckingVisitor<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
ast::ExprPath(..) => {
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,
};
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>,
}
impl<'a, 'tcx> Visitor<()> for Context<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for Context<'a, 'tcx> {
fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex);
}
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, _: ()) {
fn visit_fn(&mut self, fk: visit::FnKind, fd: &'v FnDecl,
b: &'v Block, s: Span, n: NodeId) {
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);
}
fn visit_item(&mut self, i: &Item, _: ()) {
fn visit_item(&mut self, i: &Item) {
check_item(self, i);
}
fn visit_pat(&mut self, p: &Pat, _: ()) {
fn visit_pat(&mut self, p: &Pat) {
check_pat(self, p);
}
fn visit_local(&mut self, l: &Local, _: ()) {
fn visit_local(&mut self, l: &Local) {
check_local(self, l);
}
}
@ -90,7 +90,7 @@ pub fn check_crate(tcx: &ty::ctxt,
struct_and_enum_bounds_checked: HashSet::new(),
parameter_environments: Vec::new(),
};
visit::walk_crate(&mut ctx, krate, ());
visit::walk_crate(&mut ctx, krate);
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) {
@ -274,7 +274,7 @@ fn check_local(cx: &mut Context, local: &Local) {
local.span,
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
@ -341,7 +341,7 @@ fn with_appropriate_checker(cx: &Context,
// to the copy/move kind bounds. Then recursively check the function body.
fn check_fn(
cx: &mut Context,
fk: &visit::FnKind,
fk: visit::FnKind,
decl: &FnDecl,
body: &Block,
sp: Span,
@ -356,12 +356,12 @@ fn check_fn(
});
});
match *fk {
match fk {
visit::FkFnBlock(..) => {
let ty = ty::node_id_to_type(cx.tcx, fn_id);
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(..) => {
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);
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());
}
}
@ -451,7 +451,7 @@ pub fn check_expr(cx: &mut Context, e: &Expr) {
None => {}
}
visit::walk_expr(cx, e, ());
visit::walk_expr(cx, e);
}
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.
@ -804,5 +804,5 @@ fn check_pat(cx: &mut Context, pat: &Pat) {
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>,
}
impl<'a> Visitor<()> for LanguageItemCollector<'a> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> {
fn visit_item(&mut self, item: &ast::Item) {
match extract(item.attrs.as_slice()) {
Some(value) => {
let item_index = self.item_refs.find_equiv(&value).map(|x| *x);
@ -131,7 +131,7 @@ impl<'a> Visitor<()> for LanguageItemCollector<'a> {
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) {
visit::walk_crate(self, krate, ());
visit::walk_crate(self, krate);
}
pub fn collect_external_language_items(&mut self) {

View File

@ -179,18 +179,19 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, cx: &ty::ctxt) -> String {
}
}
impl<'a, 'tcx> Visitor<()> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block, s: Span, n: NodeId, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for IrMaps<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, n: NodeId) {
visit_fn(self, fk, fd, b, s, n);
}
fn visit_local(&mut self, l: &Local, _: ()) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr, _: ()) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &Arm, _: ()) { visit_arm(self, a); }
fn visit_local(&mut self, l: &Local) { visit_local(self, l); }
fn visit_expr(&mut self, ex: &Expr) { visit_expr(self, ex); }
fn visit_arm(&mut self, a: &Arm) { visit_arm(self, a); }
}
pub fn check_crate(tcx: &ty::ctxt,
krate: &Crate) {
visit::walk_crate(&mut IrMaps::new(tcx), krate, ());
visit::walk_crate(&mut IrMaps::new(tcx), krate);
tcx.sess.abort_if_errors();
}
@ -343,23 +344,23 @@ impl<'a, 'tcx> IrMaps<'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, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for Liveness<'a, 'tcx> {
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: &'v Block, s: Span, n: NodeId) {
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);
}
fn visit_expr(&mut self, ex: &Expr, _: ()) {
fn visit_expr(&mut self, ex: &Expr) {
check_expr(self, ex);
}
fn visit_arm(&mut self, a: &Arm, _: ()) {
fn visit_arm(&mut self, a: &Arm) {
check_arm(self, a);
}
}
fn visit_fn(ir: &mut IrMaps,
fk: &FnKind,
fk: FnKind,
decl: &FnDecl,
body: &Block,
sp: Span,
@ -387,7 +388,7 @@ fn visit_fn(ir: &mut IrMaps,
// gather up the various local variables, significant expressions,
// 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:
// - exit_ln represents the end of the fn, either by return or fail
@ -404,7 +405,7 @@ fn visit_fn(ir: &mut IrMaps,
let entry_ln = lsets.compute(decl, body);
// check for various error conditions
lsets.visit_block(body, ());
lsets.visit_block(body);
lsets.check_ret(id, sp, fk, entry_ln, body);
lsets.warn_about_unused_args(decl, entry_ln);
}
@ -419,7 +420,7 @@ fn visit_local(ir: &mut IrMaps, local: &Local) {
ident: name
}));
});
visit::walk_local(ir, local, ());
visit::walk_local(ir, local);
}
fn visit_arm(ir: &mut IrMaps, arm: &Arm) {
@ -435,7 +436,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> {
@ -457,7 +458,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
if moved_variable_node_id_from_def(def).is_some() {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
}
visit::walk_expr(ir, expr, ());
visit::walk_expr(ir, expr);
}
ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) => {
// Interesting control flow (for loops can contain labeled
@ -483,13 +484,13 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
});
ir.set_captures(expr.id, call_caps);
visit::walk_expr(ir, expr, ());
visit::walk_expr(ir, expr);
}
// live nodes required for interesting control flow:
ExprIf(..) | ExprMatch(..) | ExprWhile(..) | ExprLoop(..) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr, ());
visit::walk_expr(ir, expr);
}
ExprForLoop(ref pat, _, _, _) => {
pat_util::pat_bindings(&ir.tcx.def_map, &**pat, |bm, p_id, sp, path1| {
@ -503,11 +504,11 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
}));
});
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) => {
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:
@ -519,7 +520,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ExprAssign(..) | ExprAssignOp(..) | ExprMac(..) |
ExprStruct(..) | ExprRepeat(..) | ExprParen(..) |
ExprInlineAsm(..) | ExprBox(..) => {
visit::walk_expr(ir, expr, ());
visit::walk_expr(ir, expr);
}
}
}
@ -1408,43 +1409,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) {
this.arm_pats_bindings(arm.pats.as_slice(), |this, ln, var, sp, id| {
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) {
match expr.node {
ExprAssign(ref l, ref r) => {
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, _) => {
this.check_lvalue(&**l);
visit::walk_expr(this, expr, ());
visit::walk_expr(this, expr);
}
ExprInlineAsm(ref ia) => {
for &(_, ref input) in ia.inputs.iter() {
this.visit_expr(&**input, ());
this.visit_expr(&**input);
}
// Output operands must be lvalues
for &(_, ref out, _) in ia.outputs.iter() {
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
@ -1456,13 +1457,13 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) |
ExprPath(..) | ExprBox(..) | ExprForLoop(..) => {
visit::walk_expr(this, expr, ());
visit::walk_expr(this, expr);
}
}
}
fn check_fn(_v: &Liveness,
_fk: &FnKind,
_fk: FnKind,
_decl: &FnDecl,
_body: &Block,
_sp: Span,
@ -1474,7 +1475,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn check_ret(&self,
id: NodeId,
sp: Span,
_fk: &FnKind,
_fk: FnKind,
entry_ln: LiveNode,
body: &Block) {
if self.live_on_entry(entry_ln, self.s.no_ret_var).is_some() {
@ -1546,7 +1547,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
_ => {
// For other kinds of lvalues, no checks are required,
// 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,
}
impl Visitor<()> for ParentVisitor {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'v> Visitor<'v> for ParentVisitor {
fn visit_item(&mut self, item: &ast::Item) {
self.parents.insert(item.id, 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;
}
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);
visit::walk_foreign_item(self, a, ());
visit::walk_foreign_item(self, a);
}
fn visit_fn(&mut self, a: &visit::FnKind, b: &ast::FnDecl,
c: &ast::Block, d: Span, id: ast::NodeId, _: ()) {
fn visit_fn(&mut self, a: visit::FnKind<'v>, b: &'v ast::FnDecl,
c: &'v ast::Block, d: Span, id: ast::NodeId) {
// We already took care of some trait methods above, otherwise things
// like impl methods and pub trait methods are parented to the
// containing module, not the containing trait.
if !self.parents.contains_key(&id) {
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,
_: &ast::Generics, n: ast::NodeId, _: ()) {
_: &'v ast::Generics, n: ast::NodeId) {
// Struct constructors are parented to their struct definitions because
// they essentially are the struct definitions.
match s.ctor_id {
@ -125,7 +125,7 @@ impl Visitor<()> for ParentVisitor {
for field in s.fields.iter() {
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> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for EmbargoVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
let orig_all_pub = self.prev_public;
self.prev_public = orig_all_pub && item.vis == ast::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_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) {
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
// crate module gets processed as well.
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> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
let orig_curitem = replace(&mut self.curitem, item.id);
visit::walk_item(self, item, ());
visit::walk_item(self, item);
self.curitem = orig_curitem;
}
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
ast::ExprField(ref base, ident, _) => {
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 {
ast::ViewItemExternCrate(..) => {}
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,
// 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
@ -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;
visit::walk_foreign_item(self, fi, ());
visit::walk_foreign_item(self, fi);
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);
visit::walk_path(self, path, ());
visit::walk_path(self, path);
}
}
@ -1036,8 +1036,8 @@ struct SanePrivacyVisitor<'a, 'tcx: 'a> {
in_fn: bool,
}
impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for SanePrivacyVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if self.in_fn {
self.check_all_inherited(item);
} else {
@ -1049,19 +1049,19 @@ impl<'a, 'tcx> Visitor<()> for SanePrivacyVisitor<'a, 'tcx> {
ast::ItemMod(..) => false, // modules turn privacy back on
_ => in_fn, // otherwise we inherit
});
visit::walk_item(self, item, ());
visit::walk_item(self, item);
self.in_fn = orig_in_fn;
}
fn visit_fn(&mut self, fk: &visit::FnKind, fd: &ast::FnDecl,
b: &ast::Block, s: Span, _: ast::NodeId, _: ()) {
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) {
// This catches both functions and methods
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;
}
fn visit_view_item(&mut self, i: &ast::ViewItem, _: ()) {
fn visit_view_item(&mut self, i: &ast::ViewItem) {
match i.vis {
ast::Inherited => {}
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> {
fn visit_ty(&mut self, ty: &ast::Ty, _: ()) {
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
fn visit_ty(&mut self, ty: &ast::Ty) {
match ty.node {
ast::TyPath(_, _, 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;
visit::walk_ty(self, ty, ())
visit::walk_ty(self, ty)
}
// 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> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
match item.node {
// contents of a private mod can be reexported, so we need
// to check internals.
@ -1320,7 +1320,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
at_outer_type: true,
outer_type_is_public_path: false,
};
visitor.visit_ty(&*self_, ());
visitor.visit_ty(&*self_);
self_contains_private = visitor.contains_private;
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 &&
trait_or_some_public_method {
visit::walk_generics(self, g, ());
visit::walk_generics(self, g);
match *trait_ref {
None => {
for impl_item in impl_items.iter() {
match *impl_item {
ast::MethodImplItem(method) => {
visit::walk_method_helper(self,
&*method,
())
visit::walk_method_helper(self, &*method)
}
}
}
@ -1386,7 +1384,7 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
//
// Those in 2. are warned via walk_generics and this
// 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 {
@ -1401,15 +1399,13 @@ impl<'a, 'tcx> Visitor<()> for VisiblePrivateTypesVisitor<'a, 'tcx> {
self.exported_items
.contains(&method.id) {
found_pub_static = true;
visit::walk_method_helper(self,
&*method,
());
visit::walk_method_helper(self, &*method);
}
}
}
}
if found_pub_static {
visit::walk_generics(self, g, ())
visit::walk_generics(self, g)
}
}
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
// public signatures, i.e. things that we're interested in for
// 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) {
visit::walk_foreign_item(self, item, ())
visit::walk_foreign_item(self, item)
}
}
fn visit_fn(&mut self,
fk: &visit::FnKind, fd: &ast::FnDecl, b: &ast::Block, s: Span, id: ast::NodeId,
_: ()) {
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, id: ast::NodeId) {
// needs special handling for methods.
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 {
ast::TyPath(ref p, _, 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) {
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 {
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
// from traversing the whole AST without having to be super
// careful about our `walk_...` calls above.)
fn visit_view_item(&mut self, _: &ast::ViewItem, _: ()) {}
fn visit_block(&mut self, _: &ast::Block, _: ()) {}
fn visit_expr(&mut self, _: &ast::Expr, _: ()) {}
fn visit_view_item(&mut self, _: &ast::ViewItem) {}
fn visit_block(&mut self, _: &ast::Block) {}
fn visit_expr(&mut self, _: &ast::Expr) {}
}
pub fn check_crate(tcx: &ty::ctxt,
@ -1499,7 +1494,7 @@ pub fn check_crate(tcx: &ty::ctxt,
parents: NodeMap::new(),
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
let mut visitor = PrivacyVisitor {
@ -1510,7 +1505,7 @@ pub fn check_crate(tcx: &ty::ctxt,
external_exports: external_exports,
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
// reasonable.
@ -1518,7 +1513,7 @@ pub fn check_crate(tcx: &ty::ctxt,
in_fn: false,
tcx: tcx,
};
visit::walk_crate(&mut visitor, krate, ());
visit::walk_crate(&mut visitor, krate);
tcx.sess.abort_if_errors();
@ -1535,7 +1530,7 @@ pub fn check_crate(tcx: &ty::ctxt,
};
loop {
let before = visitor.exported_items.len();
visit::walk_crate(&mut visitor, krate, ());
visit::walk_crate(&mut visitor, krate);
if before == visitor.exported_items.len() {
break
}
@ -1549,7 +1544,7 @@ pub fn check_crate(tcx: &ty::ctxt,
exported_items: &exported_items,
public_items: &public_items
};
visit::walk_crate(&mut visitor, krate, ());
visit::walk_crate(&mut visitor, krate);
}
return (exported_items, public_items);
}

View File

@ -101,9 +101,9 @@ struct ReachableContext<'a, 'tcx: 'a> {
any_library: bool,
}
impl<'a, 'tcx> Visitor<()> for ReachableContext<'a, 'tcx> {
impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
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
// and recursed into manually if necessary.
}
@ -291,7 +291,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
match item.node {
ast::ItemFn(_, _, _, _, ref search_block) => {
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()) {
self.reachable_symbols.remove(&search_item);
}
visit::walk_expr(self, &**init, ());
visit::walk_expr(self, &**init);
}
// These are normal, nothing reachable about these
@ -327,7 +327,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// Keep going, nothing to get exported
}
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) => {
let did = self.tcx.map.get_parent_did(search_item);
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>>,
}
#[deriving(Clone)]
pub struct Context {
var_parent: Option<ast::NodeId>,
@ -97,6 +96,8 @@ struct RegionResolutionVisitor<'a> {
// Generated maps:
region_maps: &'a RegionMaps,
cx: Context
}
@ -370,20 +371,21 @@ impl RegionMaps {
/// Records the current parent (if any) as the parent of `child_id`.
fn record_superlifetime(visitor: &mut RegionResolutionVisitor,
cx: Context,
child_id: ast::NodeId,
_sp: Span) {
for &parent_id in cx.parent.iter() {
visitor.region_maps.record_encl_scope(child_id, parent_id);
match visitor.cx.parent {
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`
fn record_var_lifetime(visitor: &mut RegionResolutionVisitor,
cx: Context,
var_id: ast::NodeId,
_sp: Span) {
match cx.var_parent {
match visitor.cx.var_parent {
Some(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,
blk: &ast::Block,
cx: Context) {
fn resolve_block(visitor: &mut RegionResolutionVisitor, blk: &ast::Block) {
debug!("resolve_block(blk.id={})", blk.id);
// 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
// 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)};
visit::walk_block(visitor, blk, subcx);
let prev_cx = visitor.cx;
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,
arm: &ast::Arm,
cx: Context) {
fn resolve_arm(visitor: &mut RegionResolutionVisitor, arm: &ast::Arm) {
visitor.region_maps.mark_as_terminating_scope(arm.body.id);
match arm.guard {
@ -428,48 +428,44 @@ fn resolve_arm(visitor: &mut RegionResolutionVisitor,
None => { }
}
visit::walk_arm(visitor, arm, cx);
visit::walk_arm(visitor, arm);
}
fn resolve_pat(visitor: &mut RegionResolutionVisitor,
pat: &ast::Pat,
cx: Context) {
record_superlifetime(visitor, cx, pat.id, pat.span);
fn resolve_pat(visitor: &mut RegionResolutionVisitor, pat: &ast::Pat) {
record_superlifetime(visitor, pat.id, pat.span);
// 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.
match pat.node {
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,
stmt: &ast::Stmt,
cx: Context) {
fn resolve_stmt(visitor: &mut RegionResolutionVisitor, stmt: &ast::Stmt) {
let stmt_id = stmt_id(stmt);
debug!("resolve_stmt(stmt.id={})", 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};
visit::walk_stmt(visitor, stmt, subcx);
let prev_parent = visitor.cx.parent;
visitor.cx.parent = Some(stmt_id);
visit::walk_stmt(visitor, stmt);
visitor.cx.parent = prev_parent;
}
fn resolve_expr(visitor: &mut RegionResolutionVisitor,
expr: &ast::Expr,
cx: Context) {
fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
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;
new_cx.parent = Some(expr.id);
let prev_cx = visitor.cx;
visitor.cx.parent = Some(expr.id);
match expr.node {
// Conditional or repeating scopes are always terminating
// 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
// pattern) is the body.
new_cx.var_parent = Some(body.id);
visitor.cx.var_parent = Some(body.id);
}
ast::ExprMatch(..) => {
new_cx.var_parent = Some(expr.id);
visitor.cx.var_parent = Some(expr.id);
}
ast::ExprAssignOp(..) | ast::ExprIndex(..) |
@ -538,17 +534,15 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor,
_ => {}
};
visit::walk_expr(visitor, expr, new_cx);
visit::walk_expr(visitor, expr);
visitor.cx = prev_cx;
}
fn resolve_local(visitor: &mut RegionResolutionVisitor,
local: &ast::Local,
cx: Context) {
fn resolve_local(visitor: &mut RegionResolutionVisitor, local: &ast::Local) {
debug!("resolve_local(local.id={},local.init={})",
local.id,local.init.is_some());
let blk_id = match cx.var_parent {
let blk_id = match visitor.cx.var_parent {
Some(id) => id,
None => {
visitor.sess.span_bug(
@ -635,7 +629,7 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
None => { }
}
visit::walk_local(visitor, local, cx);
visit::walk_local(visitor, local);
fn is_binding_pat(pat: &ast::Pat) -> bool {
/*!
@ -793,21 +787,20 @@ fn resolve_local(visitor: &mut RegionResolutionVisitor,
}
}
fn resolve_item(visitor: &mut RegionResolutionVisitor,
item: &ast::Item,
cx: Context) {
fn resolve_item(visitor: &mut RegionResolutionVisitor, item: &ast::Item) {
// Items create a new outer block scope as far as we're concerned.
let new_cx = Context {var_parent: None, parent: None, ..cx};
visit::walk_item(visitor, item, new_cx);
let prev_cx = visitor.cx;
visitor.cx = Context {var_parent: None, parent: None};
visit::walk_item(visitor, item);
visitor.cx = prev_cx;
}
fn resolve_fn(visitor: &mut RegionResolutionVisitor,
fk: &FnKind,
fk: FnKind,
decl: &ast::FnDecl,
body: &ast::Block,
sp: Span,
id: ast::NodeId,
cx: Context) {
id: ast::NodeId) {
debug!("region::resolve_fn(id={}, \
span={:?}, \
body.id={}, \
@ -815,20 +808,24 @@ fn resolve_fn(visitor: &mut RegionResolutionVisitor,
id,
visitor.sess.codemap().span_to_string(sp),
body.id,
cx.parent);
visitor.cx.parent);
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.
let decl_cx = Context {parent: Some(body.id),
var_parent: Some(body.id)};
visit::walk_fn_decl(visitor, decl, decl_cx);
visitor.cx = Context { parent: Some(body.id),
var_parent: Some(body.id) };
visit::walk_fn_decl(visitor, decl);
// The body of the fn itself is either a root scope (top-level fn)
// or it continues with the inherited scope (closures).
let body_cx = match *fk {
match fk {
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(..) => {
// 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
// that the present approach is unsound -- it may not permit
// 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, 'v> Visitor<'v> for RegionResolutionVisitor<'a> {
fn visit_block(&mut self, b: &Block, cx: Context) {
resolve_block(self, b, cx);
fn visit_block(&mut self, b: &Block) {
resolve_block(self, b);
}
fn visit_item(&mut self, i: &Item, cx: Context) {
resolve_item(self, i, cx);
fn visit_item(&mut self, i: &Item) {
resolve_item(self, i);
}
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl,
b: &Block, s: Span, n: NodeId, cx: Context) {
resolve_fn(self, fk, fd, b, s, n, cx);
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, n: NodeId) {
resolve_fn(self, fk, fd, b, s, n);
}
fn visit_arm(&mut self, a: &Arm, cx: Context) {
resolve_arm(self, a, cx);
fn visit_arm(&mut self, a: &Arm) {
resolve_arm(self, a);
}
fn visit_pat(&mut self, p: &Pat, cx: Context) {
resolve_pat(self, p, cx);
fn visit_pat(&mut self, p: &Pat) {
resolve_pat(self, p);
}
fn visit_stmt(&mut self, s: &Stmt, cx: Context) {
resolve_stmt(self, s, cx);
fn visit_stmt(&mut self, s: &Stmt) {
resolve_stmt(self, s);
}
fn visit_expr(&mut self, ex: &Expr, cx: Context) {
resolve_expr(self, ex, cx);
fn visit_expr(&mut self, ex: &Expr) {
resolve_expr(self, ex);
}
fn visit_local(&mut self, l: &Local, cx: Context) {
resolve_local(self, l, cx);
fn visit_local(&mut self, l: &Local) {
resolve_local(self, l);
}
}
@ -886,10 +883,10 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
{
let mut visitor = RegionResolutionVisitor {
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, cx);
visit::walk_crate(&mut visitor, krate);
}
return maps;
}
@ -897,12 +894,11 @@ pub fn resolve_crate(sess: &Session, krate: &ast::Crate) -> RegionMaps {
pub fn resolve_inlined_item(sess: &Session,
region_maps: &RegionMaps,
item: &ast::InlinedItem) {
let cx = Context {parent: None,
var_parent: None};
let mut visitor = RegionResolutionVisitor {
sess: sess,
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.
}
impl<'a> Visitor<()> for Resolver<'a> {
fn visit_item(&mut self, item: &Item, _: ()) {
impl<'a, 'v> Visitor<'v> for Resolver<'a> {
fn visit_item(&mut self, item: &Item) {
self.resolve_item(item);
}
fn visit_arm(&mut self, arm: &Arm, _: ()) {
fn visit_arm(&mut self, arm: &Arm) {
self.resolve_arm(arm);
}
fn visit_block(&mut self, block: &Block, _: ()) {
fn visit_block(&mut self, block: &Block) {
self.resolve_block(block);
}
fn visit_expr(&mut self, expr: &Expr, _: ()) {
fn visit_expr(&mut self, expr: &Expr) {
self.resolve_expr(expr);
}
fn visit_local(&mut self, local: &Local, _: ()) {
fn visit_local(&mut self, local: &Local) {
self.resolve_local(local);
}
fn visit_ty(&mut self, ty: &Ty, _: ()) {
fn visit_ty(&mut self, ty: &Ty) {
self.resolve_type(ty);
}
}
@ -903,32 +903,40 @@ struct Resolver<'a> {
struct BuildReducedGraphVisitor<'a, 'b:'a> {
resolver: &'a mut Resolver<'b>,
parent: ReducedGraphParent
}
impl<'a, 'b> Visitor<ReducedGraphParent> for BuildReducedGraphVisitor<'a, 'b> {
impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> {
fn visit_item(&mut self, item: &Item, context: ReducedGraphParent) {
let p = self.resolver.build_reduced_graph_for_item(item, context);
visit::walk_item(self, item, p);
fn visit_item(&mut self, item: &Item) {
let p = self.resolver.build_reduced_graph_for_item(item, self.parent.clone());
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,
context: ReducedGraphParent) {
fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
let parent = self.parent.clone();
self.resolver.build_reduced_graph_for_foreign_item(foreign_item,
context.clone(),
parent.clone(),
|r| {
let mut v = BuildReducedGraphVisitor{ resolver: r };
visit::walk_foreign_item(&mut v, foreign_item, context.clone());
let mut v = BuildReducedGraphVisitor {
resolver: r,
parent: parent.clone()
};
visit::walk_foreign_item(&mut v, foreign_item);
})
}
fn visit_view_item(&mut self, view_item: &ViewItem, context: ReducedGraphParent) {
self.resolver.build_reduced_graph_for_view_item(view_item, context);
fn visit_view_item(&mut self, view_item: &ViewItem) {
self.resolver.build_reduced_graph_for_view_item(view_item, self.parent.clone());
}
fn visit_block(&mut self, block: &Block, context: ReducedGraphParent) {
let np = self.resolver.build_reduced_graph_for_block(block, context);
visit::walk_block(self, block, np);
fn visit_block(&mut self, block: &Block) {
let np = self.resolver.build_reduced_graph_for_block(block, self.parent.clone());
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>
}
impl<'a, 'b> Visitor<()> for UnusedImportCheckVisitor<'a, 'b> {
fn visit_view_item(&mut self, vi: &ViewItem, _: ()) {
impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> {
fn visit_view_item(&mut self, vi: &ViewItem) {
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.
fn build_reduced_graph(&mut self, krate: &ast::Crate) {
let initial_parent =
ModuleReducedGraphParent(self.graph_root.get_module());
let mut visitor = BuildReducedGraphVisitor { resolver: self, };
visit::walk_crate(&mut visitor, krate, initial_parent);
let parent = ModuleReducedGraphParent(self.graph_root.get_module());
let mut visitor = BuildReducedGraphVisitor {
resolver: self,
parent: parent
};
visit::walk_crate(&mut visitor, krate);
}
/**
@ -3889,7 +3898,7 @@ impl<'a> Resolver<'a> {
fn resolve_crate(&mut self, krate: &ast::Crate) {
debug!("(resolving crate) starting");
visit::walk_crate(self, krate, ());
visit::walk_crate(self, krate);
}
fn resolve_item(&mut self, item: &Item) {
@ -3921,7 +3930,7 @@ impl<'a> Resolver<'a> {
|this| {
this.resolve_type_parameters(&generics.ty_params);
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),
|this| {
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,
ItemRibKind),
|this| visit::walk_foreign_item(this,
&**foreign_item,
()));
&**foreign_item));
}
ForeignItemStatic(..) => {
visit::walk_foreign_item(this,
&**foreign_item,
());
&**foreign_item);
}
}
}
@ -4074,7 +4081,7 @@ impl<'a> Resolver<'a> {
ItemStatic(..) => {
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) {
// Write the implementations in scope into the module metadata.
debug!("(resolving module) resolving module ID {}", id);
visit::walk_mod(self, module, ());
visit::walk_mod(self, module);
}
fn resolve_local(&mut self, local: &Local) {
@ -4586,7 +4593,7 @@ impl<'a> Resolver<'a> {
// pat_idents are variants
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.value_ribs.borrow_mut().pop();
@ -4608,7 +4615,7 @@ impl<'a> Resolver<'a> {
}
// Descend into the block.
visit::walk_block(self, block, ());
visit::walk_block(self, block);
// Move back up.
self.current_module = orig_module;
@ -4702,12 +4709,12 @@ impl<'a> Resolver<'a> {
TyClosure(c) | TyProc(c) => {
self.resolve_type_parameter_bounds(ty.id, &c.bounds,
TraitBoundingTypeParameter);
visit::walk_ty(self, ty, ());
visit::walk_ty(self, ty);
}
_ => {
// 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) |
@ -5618,7 +5625,7 @@ impl<'a> Resolver<'a> {
}
}
visit::walk_expr(self, expr, ());
visit::walk_expr(self, expr);
}
ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
@ -5633,7 +5640,7 @@ impl<'a> Resolver<'a> {
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) {
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) {

View File

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

View File

@ -83,9 +83,18 @@ struct DxrVisitor<'l, 'tcx: 'l> {
span: SpanUtils<'l>,
fmt: FmtStrs<'l>,
cur_scope: NodeId
}
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) {
// the current crate
self.fmt.crate_str(krate.span, name);
@ -136,19 +145,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
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);
for &(ref span, ref qualname) in sub_paths.iter() {
self.fmt.sub_mod_ref_str(path.span,
*span,
qualname.as_slice(),
scope_id);
self.cur_scope);
}
}
// As write_sub_paths, but does not process the last ident in the path (assuming it
// 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 len = sub_paths.len();
if len <= 1 {
@ -160,13 +169,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.fmt.sub_mod_ref_str(path.span,
*span,
qualname.as_slice(),
scope_id);
self.cur_scope);
}
}
// As write_sub_paths, but expects a path of the form module_path::trait::method
// 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 len = sub_paths.len();
if len <= 1 {
@ -189,7 +198,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.fmt.sub_mod_ref_str(path.span,
*span,
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() {
assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true;
self.visit_pat(&*arg.pat, e);
self.visit_pat(&*arg.pat);
self.collecting = false;
let span_utils = self.span;
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) {
return;
}
@ -361,27 +370,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
decl_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
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
self.visit_block(&*method.pe_body(),
DxrVisitorEnv::new_nested(method.id));
self.nest(method.id, |v| v.visit_block(&*method.pe_body()));
self.process_generic_params(method.pe_generics(),
method.span,
qualname,
method.id,
e);
method.id);
}
fn process_trait_ref(&mut self,
trait_ref: &ast::TraitRef,
e: DxrVisitorEnv,
impl_id: Option<NodeId>) {
match self.lookup_type_ref(trait_ref.ref_id) {
Some(id) => {
@ -390,16 +396,16 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
trait_ref.path.span,
sub_span,
id,
e.cur_scope);
self.cur_scope);
match impl_id {
Some(impl_id) => self.fmt.impl_str(trait_ref.path.span,
sub_span,
impl_id,
id,
e.cur_scope),
self.cur_scope),
None => (),
}
visit::walk_path(self, &trait_ref.path, e);
visit::walk_path(self, &trait_ref.path);
},
None => ()
}
@ -436,8 +442,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
fn process_generic_params(&mut self, generics:&ast::Generics,
full_span: Span,
prefix: &str,
id: NodeId,
e: DxrVisitorEnv) {
id: NodeId) {
// 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.
// 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(),
"");
}
self.visit_generics(generics, e);
self.visit_generics(generics);
}
fn process_fn(&mut self,
item: &ast::Item,
e: DxrVisitorEnv,
decl: ast::P<ast::FnDecl>,
ty_params: &ast::Generics,
body: ast::P<ast::Block>) {
@ -472,25 +476,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
item.id,
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
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
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,
item: &ast::Item,
e: DxrVisitorEnv,
typ: ast::P<ast::Ty>,
mt: ast::Mutability,
expr: &ast::Expr)
@ -511,16 +514,15 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
qualname.as_slice(),
value.as_slice(),
ty_to_string(&*typ).as_slice(),
e.cur_scope);
self.cur_scope);
// walk type and init value
self.visit_ty(&*typ, e);
self.visit_expr(expr, e);
self.visit_ty(&*typ);
self.visit_expr(expr);
}
fn process_struct(&mut self,
item: &ast::Item,
e: DxrVisitorEnv,
def: &ast::StructDef,
ty_params: &ast::Generics) {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@ -535,20 +537,19 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
item.id,
ctor_id,
qualname.as_slice(),
e.cur_scope);
self.cur_scope);
// fields
for field in def.fields.iter() {
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,
item: &ast::Item,
e: DxrVisitorEnv,
enum_definition: &ast::EnumDef,
ty_params: &ast::Generics) {
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),
item.id,
qualname.as_slice(),
e.cur_scope),
self.cur_scope),
None => self.sess.span_bug(item.span,
format!("Could not find subspan for enum {}",
qualname).as_slice()),
@ -578,7 +579,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
val.as_slice(),
item.id);
for arg in args.iter() {
self.visit_ty(&*arg.ty, e);
self.visit_ty(&*arg.ty);
}
}
ast::StructVariantKind(ref struct_def) => {
@ -597,18 +598,17 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
for field in struct_def.fields.iter() {
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,
item: &ast::Item,
e: DxrVisitorEnv,
type_parameters: &ast::Generics,
trait_ref: &Option<ast::TraitRef>,
typ: ast::P<ast::Ty>,
@ -622,29 +622,29 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
path.span,
sub_span,
id,
e.cur_scope);
self.cur_scope);
self.fmt.impl_str(path.span,
sub_span,
item.id,
id,
e.cur_scope);
self.cur_scope);
},
None => ()
}
},
_ => self.visit_ty(&*typ, e),
_ => self.visit_ty(&*typ),
}
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 => (),
}
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() {
match *impl_item {
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,
item: &ast::Item,
e: DxrVisitorEnv,
generics: &ast::Generics,
trait_refs: &OwnedSlice<ast::TyParamBound>,
methods: &Vec<ast::TraitItem>) {
@ -663,7 +662,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
item.id,
qualname.as_slice(),
e.cur_scope);
self.cur_scope);
// super-traits
for super_bound in trait_refs.iter() {
@ -683,7 +682,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
trait_ref.path.span,
sub_span,
id,
e.cur_scope);
self.cur_scope);
self.fmt.inherit_str(trait_ref.path.span,
sub_span,
id,
@ -694,15 +693,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
}
// 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() {
self.visit_trait_item(method, e)
self.visit_trait_item(method)
}
}
fn process_mod(&mut self,
item: &ast::Item, // The module in question, represented as an item.
e: DxrVisitorEnv,
m: &ast::Mod) {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
@ -714,15 +712,14 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
item.id,
qualname.as_slice(),
e.cur_scope,
self.cur_scope,
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,
ex: &ast::Expr,
e: DxrVisitorEnv,
path: &ast::Path) {
if generated_code(path.span) {
return
@ -744,18 +741,18 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
ex.span,
sub_span,
ast_util::local_def(id),
e.cur_scope),
self.cur_scope),
def::DefStatic(def_id,_) |
def::DefVariant(_, def_id, _) => self.fmt.ref_str(recorder::VarRef,
ex.span,
sub_span,
def_id,
e.cur_scope),
self.cur_scope),
def::DefStruct(def_id) => self.fmt.ref_str(recorder::StructRef,
ex.span,
sub_span,
def_id,
e.cur_scope),
self.cur_scope),
def::DefStaticMethod(declid, provenence, _) => {
let sub_span = self.span.sub_span_for_meth_name(ex.span);
let defid = if declid.krate == ast::LOCAL_CRATE {
@ -806,12 +803,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
defid,
Some(declid),
e.cur_scope);
self.cur_scope);
},
def::DefFn(def_id, _) => self.fmt.fn_call_str(ex.span,
sub_span,
def_id,
e.cur_scope),
self.cur_scope),
_ => self.sess.span_bug(ex.span,
format!("Unexpected def kind while looking up path in '{}'",
self.span.snippet(ex.span)).as_slice()),
@ -819,25 +816,24 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
// modules or types in the path prefix
match *def {
def::DefStaticMethod(_, _, _) => {
self.write_sub_path_trait_truncated(path, e.cur_scope);
self.write_sub_path_trait_truncated(path);
},
def::DefLocal(_, _) |
def::DefArg(_, _) |
def::DefStatic(_,_) |
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,
ex: &ast::Expr,
e: DxrVisitorEnv,
path: &ast::Path,
fields: &Vec<ast::Field>,
base: Option<Gc<ast::Expr>>) {
base: &Option<Gc<ast::Expr>>) {
if generated_code(path.span) {
return
}
@ -851,12 +847,12 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
path.span,
sub_span,
id,
e.cur_scope);
self.cur_scope);
},
None => ()
}
self.write_sub_paths_truncated(path, e.cur_scope);
self.write_sub_paths_truncated(path);
for field in fields.iter() {
match struct_def {
@ -873,21 +869,20 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
field.ident.span,
sub_span,
f.id,
e.cur_scope);
self.cur_scope);
}
}
}
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,
ex: &ast::Expr,
e: DxrVisitorEnv,
args: &Vec<Gc<ast::Expr>>) {
let method_map = self.analysis.ty_cx.method_map.borrow();
let method_callee = method_map.get(&typeck::MethodCall::expr(ex.id));
@ -941,13 +936,13 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
sub_span,
def_id,
decl_id,
e.cur_scope);
self.cur_scope);
// 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) {
return
}
@ -955,7 +950,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
match p.node {
ast::PatStruct(ref path, ref fields, _) => {
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) {
Some(sd) => sd,
None => {
@ -976,7 +971,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
).as_slice());
}
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() {
continue;
}
@ -987,7 +982,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
p.span,
span,
f.id,
e.cur_scope);
self.cur_scope);
break;
}
}
@ -995,7 +990,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
}
ast::PatEnum(ref path, _) => {
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) => {
let immut = match bm {
@ -1015,41 +1010,40 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
self.collected_paths.push((p.id, path, immut, recorder::VarRef));
match *optional_subpattern {
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> {
fn visit_item(&mut self, item:&ast::Item, e: DxrVisitorEnv) {
impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if generated_code(item.span) {
return
}
match item.node {
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) =>
self.process_static(item, e, typ, mt, &*expr),
ast::ItemStruct(def, ref ty_params) => self.process_struct(item, e, &*def, ty_params),
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, e, def, ty_params),
self.process_static(item, typ, mt, &*expr),
ast::ItemStruct(def, ref ty_params) => self.process_struct(item, &*def, ty_params),
ast::ItemEnum(ref def, ref ty_params) => self.process_enum(item, def, ty_params),
ast::ItemImpl(ref ty_params,
ref trait_ref,
typ,
ref impl_items) => {
self.process_impl(item,
e,
ty_params,
trait_ref,
typ,
impl_items)
}
ast::ItemTrait(ref generics, _, ref trait_refs, ref methods) =>
self.process_trait(item, e, generics, trait_refs, methods),
ast::ItemMod(ref m) => self.process_mod(item, e, m),
self.process_trait(item, generics, trait_refs, methods),
ast::ItemMod(ref m) => self.process_mod(item, m),
ast::ItemTy(ty, ref ty_params) => {
let qualname = self.analysis.ty_cx.map.path_to_string(item.id);
let value = ty_to_string(&*ty);
@ -1060,26 +1054,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
qualname.as_slice(),
value.as_slice());
self.visit_ty(&*ty, e);
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id, e);
self.visit_ty(&*ty);
self.process_generic_params(ty_params, item.span, qualname.as_slice(), item.id);
},
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 bound in param.bounds.iter() {
match *bound {
ast::TraitTyParamBound(ref trait_ref) => {
self.process_trait_ref(trait_ref, e, None);
self.process_trait_ref(trait_ref, None);
}
_ => {}
}
}
match param.default {
Some(ty) => self.visit_ty(&*ty, e),
Some(ty) => self.visit_ty(&*ty),
None => (),
}
}
@ -1088,23 +1082,22 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
// We don't actually index functions here, that is done in visit_item/ItemFn.
// Here we just visit methods.
fn visit_fn(&mut self,
fk: &visit::FnKind,
fd: &ast::FnDecl,
b: &ast::Block,
fk: visit::FnKind<'v>,
fd: &'v ast::FnDecl,
b: &'v ast::Block,
s: Span,
_: NodeId,
e: DxrVisitorEnv) {
_: NodeId) {
if generated_code(s) {
return;
}
match *fk {
visit::FkMethod(_, _, method) => self.process_method(method, e),
_ => visit::walk_fn(self, fk, fd, b, s, e),
match fk {
visit::FkMethod(_, _, method) => self.process_method(method),
_ => 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 {
ast::RequiredMethod(ref method_type) => {
if generated_code(method_type.span) {
@ -1137,21 +1130,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
// walk arg and return types
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,
method_type.span,
qualname,
method_type.id,
e);
method_type.id);
}
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) {
return
}
@ -1168,7 +1160,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
path.span,
sub_span,
def_id,
e.cur_scope),
self.cur_scope),
None => {},
}
Some(def_id)
@ -1189,11 +1181,11 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
id,
mod_id,
get_ident(ident).get(),
e.cur_scope);
self.write_sub_paths_truncated(path, e.cur_scope);
self.cur_scope);
self.write_sub_paths_truncated(path);
}
ast::ViewPathGlob(ref path, _) => {
self.write_sub_paths(path, e.cur_scope);
self.write_sub_paths(path);
}
ast::ViewPathList(ref path, ref list, _) => {
for plid in list.iter() {
@ -1206,7 +1198,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
self.fmt.ref_str(
kind, plid.span,
Some(plid.span),
def_id, e.cur_scope);
def_id, self.cur_scope);
}
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,
name,
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) {
return
}
@ -1258,20 +1250,20 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
t.span,
sub_span,
id,
e.cur_scope);
self.cur_scope);
},
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) {
return
}
@ -1280,18 +1272,18 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ast::ExprCall(_f, ref _args) => {
// Don't need to do anything for function calls,
// 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::ExprStruct(ref path, ref fields, base) =>
self.process_struct_lit(ex, e, path, fields, base),
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, e, args),
ast::ExprPath(ref path) => self.process_path(ex, path),
ast::ExprStruct(ref path, ref fields, ref base) =>
self.process_struct_lit(ex, path, fields, base),
ast::ExprMethodCall(_, _, ref args) => self.process_method_call(ex, args),
ast::ExprField(sub_ex, ident, _) => {
if generated_code(sub_ex.span) {
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_box = ty::get(t);
@ -1305,7 +1297,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ex.span,
sub_span,
f.id,
e.cur_scope);
self.cur_scope);
break;
}
}
@ -1319,7 +1311,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
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_box = ty::get(t);
@ -1333,7 +1325,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
ex.span,
sub_span,
f.id,
e.cur_scope);
self.cur_scope);
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());
self.process_formals(&decl.inputs, id.as_slice(), e);
self.process_formals(&decl.inputs, id.as_slice());
// walk arg and return types
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
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.
}
fn visit_pat(&mut self, p: &ast::Pat, e: DxrVisitorEnv) {
self.process_pat(p, e);
fn visit_pat(&mut self, p: &ast::Pat) {
self.process_pat(p);
if !self.collecting {
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);
self.collecting = true;
for pattern in arm.pats.iter() {
// collect paths from the arm's patterns
self.visit_pat(&**pattern, e);
self.visit_pat(&**pattern);
}
self.collecting = false;
// process collected paths
@ -1411,26 +1403,26 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
p.span,
sub_span,
id,
e.cur_scope),
self.cur_scope),
// FIXME(nrc) what is this doing here?
def::DefStatic(_, _) => {}
_ => error!("unexpected defintion kind when processing collected paths: {:?}", *def)
}
}
self.collected_paths.clear();
visit::walk_expr_opt(self, arm.guard, e);
self.visit_expr(&*arm.body, e);
visit::walk_expr_opt(self, &arm.guard);
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) {
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) {
return
}
@ -1439,7 +1431,7 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
// pattern and collect them all.
assert!(self.collected_paths.len() == 0 && !self.collecting);
self.collecting = true;
self.visit_pat(&*l.pat, e);
self.visit_pat(&*l.pat);
self.collecting = false;
let value = self.span.snippet(l.span);
@ -1462,22 +1454,8 @@ impl<'l, 'tcx> Visitor<DxrVisitorEnv> for DxrVisitor<'l, 'tcx> {
self.collected_paths.clear();
// Just walk the initialiser and type (don't want to walk the pattern again).
self.visit_ty(&*l.ty, e);
visit::walk_expr_opt(self, l.init, e);
}
}
#[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}
self.visit_ty(&*l.ty);
visit::walk_expr_opt(self, &l.init);
}
}
@ -1532,25 +1510,28 @@ pub fn process_crate(sess: &Session,
};
root_path.pop();
let mut visitor = DxrVisitor{ sess: sess,
analysis: analysis,
collected_paths: vec!(),
collecting: false,
fmt: FmtStrs::new(box Recorder {
out: output_file as Box<Writer+'static>,
dump_spans: false,
},
SpanUtils {
sess: sess,
err_count: Cell::new(0)
},
cratename.clone()),
span: SpanUtils {
sess: sess,
err_count: Cell::new(0)
}};
let mut visitor = DxrVisitor {
sess: sess,
analysis: analysis,
collected_paths: vec!(),
collecting: false,
fmt: FmtStrs::new(box Recorder {
out: output_file as Box<Writer+'static>,
dump_spans: false,
},
SpanUtils {
sess: sess,
err_count: Cell::new(0)
},
cratename.clone()),
span: SpanUtils {
sess: sess,
err_count: Cell::new(0)
},
cur_scope: 0
};
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 metadata::csearch;
use std::mem::replace;
/// A stability index, giving the stability level for items and methods.
pub struct Index {
// stability for crate-local items; unmarked stability == no entry
@ -34,68 +36,69 @@ pub struct Index {
// A private tree-walker for producing an Index.
struct Annotator {
index: Index
index: Index,
parent: Option<Stability>
}
impl Annotator {
// Determine the stability for a node based on its attributes and inherited
// stability. The stability is recorded in the index and returned.
fn annotate(&mut self, id: NodeId, attrs: &[Attribute],
parent: Option<Stability>) -> Option<Stability> {
match attr::find_stability(attrs).or(parent) {
// stability. The stability is recorded in the index and used as the parent.
fn annotate(&mut self, id: NodeId, attrs: &Vec<Attribute>, f: |&mut Annotator|) {
match attr::find_stability(attrs.as_slice()) {
Some(stab) => {
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 {
fn visit_item(&mut self, i: &Item, parent: Option<Stability>) {
let stab = self.annotate(i.id, i.attrs.as_slice(), parent);
visit::walk_item(self, i, stab)
impl<'v> Visitor<'v> for Annotator {
fn visit_item(&mut self, i: &Item) {
self.annotate(i.id, &i.attrs, |v| visit::walk_item(v, i));
}
fn visit_fn(&mut self, fk: &FnKind, fd: &FnDecl, b: &Block,
s: Span, _: NodeId, parent: Option<Stability>) {
let stab = match *fk {
FkMethod(_, _, meth) =>
self.annotate(meth.id, meth.attrs.as_slice(), parent),
_ => parent
};
visit::walk_fn(self, fk, fd, b, s, stab)
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, _: NodeId) {
match fk {
FkMethod(_, _, meth) => {
self.annotate(meth.id, &meth.attrs, |v| visit::walk_fn(v, fk, fd, b, s));
}
_ => visit::walk_fn(self, fk, fd, b, s)
}
}
fn visit_trait_item(&mut self, t: &TraitItem, parent: Option<Stability>) {
let stab = match *t {
RequiredMethod(TypeMethod {attrs: ref attrs, id: id, ..}) =>
self.annotate(id, attrs.as_slice(), parent),
fn visit_trait_item(&mut self, t: &TraitItem) {
let (id, attrs) = match *t {
RequiredMethod(TypeMethod {id, ref attrs, ..}) => (id, attrs),
// work around lack of pattern matching for @ types
ProvidedMethod(method) => match *method {
Method {attrs: ref attrs, id: id, ..} =>
self.annotate(id, attrs.as_slice(), parent)
ProvidedMethod(ref method) => match **method {
Method {id, ref attrs, ..} => (id, attrs)
}
};
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>) {
let stab = self.annotate(v.node.id, v.node.attrs.as_slice(), parent);
visit::walk_variant(self, v, g, stab)
fn visit_variant(&mut self, var: &Variant, g: &'v Generics) {
self.annotate(var.node.id, &var.node.attrs, |v| visit::walk_variant(v, var, g))
}
fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics,
_: NodeId, parent: Option<Stability>) {
s.ctor_id.map(|id| self.annotate(id, &[], parent.clone()));
visit::walk_struct_def(self, s, parent)
fn visit_struct_def(&mut self, s: &StructDef, _: Ident, _: &Generics, _: NodeId) {
match s.ctor_id {
Some(id) => self.annotate(id, &vec![], |v| visit::walk_struct_def(v, s)),
None => visit::walk_struct_def(self, s)
}
}
fn visit_struct_field(&mut self, s: &StructField, parent: Option<Stability>) {
let stab = self.annotate(s.node.id, s.node.attrs.as_slice(), parent);
visit::walk_struct_field(self, s, stab)
fn visit_struct_field(&mut self, s: &StructField) {
self.annotate(s.node.id, &s.node.attrs, |v| visit::walk_struct_field(v, s));
}
}
@ -106,10 +109,10 @@ impl Index {
index: Index {
local: NodeMap::new(),
extern_cache: DefIdMap::new()
}
},
parent: None
};
let stab = annotator.annotate(ast::CRATE_NODE_ID, krate.attrs.as_slice(), None);
visit::walk_crate(&mut annotator, krate, stab);
annotator.annotate(ast::CRATE_NODE_ID, &krate.attrs, |v| visit::walk_crate(v, krate));
annotator.index
}
}

View File

@ -1322,18 +1322,32 @@ pub fn make_return_slot_pointer(fcx: &FunctionContext, output_type: ty::t) -> Va
}
struct CheckForNestedReturnsVisitor {
found: bool
found: bool,
in_return: bool
}
impl Visitor<bool> for CheckForNestedReturnsVisitor {
fn visit_expr(&mut self, e: &ast::Expr, in_return: bool) {
impl CheckForNestedReturnsVisitor {
fn explicit() -> CheckForNestedReturnsVisitor {
CheckForNestedReturnsVisitor { found: false, in_return: false }
}
fn implicit() -> CheckForNestedReturnsVisitor {
CheckForNestedReturnsVisitor { found: false, in_return: true }
}
}
impl<'v> Visitor<'v> for CheckForNestedReturnsVisitor {
fn visit_expr(&mut self, e: &ast::Expr) {
match e.node {
ast::ExprRet(..) if in_return => {
self.found = true;
return;
ast::ExprRet(..) => {
if self.in_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, in_return)
_ => visit::walk_expr(self, e)
}
}
}
@ -1343,10 +1357,10 @@ fn has_nested_returns(tcx: &ty::ctxt, id: ast::NodeId) -> bool {
Some(ast_map::NodeItem(i)) => {
match i.node {
ast::ItemFn(_, _, _, _, blk) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false };
let mut implicit = CheckForNestedReturnsVisitor { found: false };
visit::walk_item(&mut explicit, &*i, false);
visit::walk_expr_opt(&mut implicit, blk.expr, true);
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_item(&mut explicit, &*i);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
_ => 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) => {
match m.node {
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false };
let mut implicit = CheckForNestedReturnsVisitor { found: false };
visit::walk_method_helper(&mut explicit, &*m, false);
visit::walk_expr_opt(&mut implicit, blk.expr, true);
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_method_helper(&mut explicit, &*m);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
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) => {
match m.node {
ast::MethDecl(_, _, _, _, _, _, blk, _) => {
let mut explicit = CheckForNestedReturnsVisitor {
found: false,
};
let mut implicit = CheckForNestedReturnsVisitor {
found: false,
};
visit::walk_method_helper(&mut explicit,
&**m,
false);
visit::walk_expr_opt(&mut implicit,
blk.expr,
true);
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_method_helper(&mut explicit, &**m);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
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::ExprProc(_, blk) |
ast::ExprUnboxedFn(_, _, _, blk) => {
let mut explicit = CheckForNestedReturnsVisitor { found: false };
let mut implicit = CheckForNestedReturnsVisitor { found: false };
visit::walk_expr(&mut explicit, &*e, false);
visit::walk_expr_opt(&mut implicit, blk.expr, true);
let mut explicit = CheckForNestedReturnsVisitor::explicit();
let mut implicit = CheckForNestedReturnsVisitor::implicit();
visit::walk_expr(&mut explicit, &*e);
visit::walk_expr_opt(&mut implicit, &blk.expr);
explicit.found || implicit.found
}
_ => 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>,
}
impl<'a, 'tcx> Visitor<()> for TransItemVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _:()) {
impl<'a, 'tcx, 'v> Visitor<'v> for TransItemVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
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
// items in blocks and such.
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_block(&**body, ());
v.visit_block(&**body);
}
ast::ItemImpl(ref generics, _, _, ref impl_items) => {
meth::trans_impl(ccx,
@ -2254,7 +2260,7 @@ pub fn trans_item(ccx: &CrateContext, item: &ast::Item) {
ast::ItemStatic(_, m, ref expr) => {
// Recurse on the expression to catch items in blocks
let mut v = TransItemVisitor{ ccx: ccx };
v.visit_expr(&**expr, ());
v.visit_expr(&**expr);
let trans_everywhere = attr::requests_inline(item.attrs.as_slice());
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
// metadata time comes around.
let mut v = TransItemVisitor{ ccx: ccx };
visit::walk_item(&mut v, item, ());
visit::walk_item(&mut v, item);
}
_ => {/* fall through */ }
}

View File

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

View File

@ -67,7 +67,7 @@ pub fn trans_impl(ccx: &CrateContext,
for impl_item in impl_items.iter() {
match *impl_item {
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 {
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 CheckTypeWellFormedVisitor<'a, 'tcx: 'a> { ccx: &'a CrateCtxt<'a, 'tcx> }
impl<'a, 'tcx> Visitor<()> for CheckTypeWellFormedVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
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> {
fn visit_item(&mut self, i: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
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>
}
impl<'a, 'tcx> Visitor<()> for CheckItemSizedTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for CheckItemSizedTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
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) {
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
// downstream, so stop reporting errors at this point.
ccx.tcx.sess.abort_if_errors();
let mut visit = CheckItemTypesVisitor { ccx: ccx };
visit::walk_crate(&mut visit, krate, ());
visit::walk_crate(&mut visit, krate);
ccx.tcx.sess.abort_if_errors();
let mut visit = CheckItemSizedTypesVisitor { ccx: ccx };
visit::walk_crate(&mut visit, krate, ());
visit::walk_crate(&mut visit, krate);
}
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, 'v> Visitor<'v> for GatherLocalsVisitor<'a, 'tcx> {
// 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 {
ast::TyInfer => None,
_ => 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.infcx().ty_to_string(
self.fcx.inh.locals.borrow().get_copy(&local.id)));
visit::walk_local(self, local, ());
visit::walk_local(self, local);
}
// Add pattern bindings.
fn visit_pat(&mut self, p: &ast::Pat, _: ()) {
fn visit_pat(&mut self, p: &ast::Pat) {
match p.node {
ast::PatIdent(_, ref path1, _)
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
// we have to keep this up-to-date. 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
// 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 {
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());
}
_ => visit::walk_ty(self, t, ())
_ => visit::walk_ty(self, t)
}
}
// Don't descend into fns and items
fn visit_fn(&mut self, _: &visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, _: Span, _: ast::NodeId, _: ()) { }
fn visit_item(&mut self, _: &ast::Item, _: ()) { }
fn visit_fn(&mut self, _: visit::FnKind<'v>, _: &'v ast::FnDecl,
_: &'v ast::Block, _: Span, _: ast::NodeId) { }
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);
}
visit.visit_block(body, ());
visit.visit_block(body);
}
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,
// but prevents type checking from blowing up before const checking can properly
// emit a error.
GatherLocalsVisitor { fcx: fcx }.visit_expr(e, ());
GatherLocalsVisitor { fcx: fcx }.visit_expr(e);
check_expr_with_hint(fcx, e, declty);
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);
if fcx.err_count_since_creation() == 0 {
// regionck assumes typeck succeeded
rcx.visit_expr(e, ());
rcx.visit_expr(e);
rcx.visit_region_obligations(e.id);
}
fcx.infcx().resolve_regions_and_report_errors();
@ -346,7 +346,7 @@ impl<'a, 'tcx> Rcx<'a, 'tcx> {
let len = self.region_param_pairs.len();
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.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, 'v> Visitor<'v> for Rcx<'a, 'tcx> {
// (..) FIXME(#3238) should use visit_pat, not visit_arm/visit_local,
// However, right now we run into an issue whereby some free
// regions are not properly related if they appear within the
@ -488,22 +488,22 @@ impl<'a, 'tcx> Visitor<()> for Rcx<'a, 'tcx> {
// hierarchy, and in particular the relationships between free
// regions, until regionck, as described in #3238.
fn visit_fn(&mut self, _fk: &visit::FnKind, _fd: &ast::FnDecl,
b: &ast::Block, _s: Span, id: ast::NodeId, _e: ()) {
fn visit_fn(&mut self, _fk: visit::FnKind<'v>, _fd: &'v ast::FnDecl,
b: &'v ast::Block, _s: Span, id: ast::NodeId) {
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
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) {
@ -511,7 +511,7 @@ fn visit_item(_rcx: &mut Rcx, _item: &ast::Item) {
}
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) {
@ -520,14 +520,14 @@ fn visit_arm(rcx: &mut Rcx, arm: &ast::Arm) {
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) {
// see above
constrain_bindings_in_pat(&*l.pat, rcx);
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) {
@ -625,19 +625,19 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
false);
}
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
ast::ExprMethodCall(_, _, ref args) => {
constrain_call(rcx, expr, Some(*args.get(0)),
args.slice_from(1), false);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
ast::ExprAssign(ref 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) => {
@ -648,7 +648,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
adjust_borrow_kind_for_assignment_lhs(rcx, &**lhs);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
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()),
[rhs.clone()], true);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
ast::ExprUnary(_, ref lhs) if has_method_map => {
// As above.
constrain_call(rcx, expr, Some(lhs.clone()), [], true);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
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);
type_must_outlive(rcx, infer::Managed(expr.span),
base_ty, ty::ReStatic);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
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, _) => {
@ -704,7 +704,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
let vec_type = rcx.resolve_expr_type_adjusted(&**vec_expr);
constrain_index(rcx, expr, vec_type);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
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
// the source obeys the trait's region bound.
constrain_cast(rcx, expr, &**source);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
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);
type_must_outlive(rcx, infer::AddrOf(expr.span),
ty0, ty::ReScope(expr.id));
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
ast::ExprMatch(ref discr, ref arms) => {
link_match(rcx, &**discr, arms.as_slice());
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
}
ast::ExprFnBlock(_, _, ref body) |
@ -745,16 +745,16 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
ast::ExprLoop(ref body, _) => {
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);
}
ast::ExprWhile(ref cond, ref body, _) => {
let repeating_scope = rcx.set_repeating_scope(cond.id);
rcx.visit_expr(&**cond, ());
rcx.visit_expr(&**cond);
rcx.set_repeating_scope(body.id);
rcx.visit_block(&**body, ());
rcx.visit_block(&**body);
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);
}
rcx.visit_expr(&**head, ());
rcx.visit_expr(&**head);
type_of_node_must_outlive(rcx,
infer::AddrOf(expr.span),
head.id,
ty::ReScope(expr.id));
let repeating_scope = rcx.set_repeating_scope(body.id);
rcx.visit_block(&**body, ());
rcx.visit_block(&**body);
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);
visit::walk_expr(rcx, expr, ());
visit::walk_expr(rcx, expr);
rcx.set_repeating_scope(repeating_scope);
match ty::get(function_type).sty {

View File

@ -1025,12 +1025,12 @@ pub fn trans_resolve_method(tcx: &ty::ctxt, id: ast::NodeId,
false)
}
impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr, _: ()) {
impl<'a, 'b, 'tcx, 'v> Visitor<'v> for &'a FnCtxt<'b, 'tcx> {
fn visit_expr(&mut self, ex: &ast::Expr) {
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
}
}
@ -1038,7 +1038,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<()> for &'a FnCtxt<'b, 'tcx> {
// Detect points where a trait-bounded type parameter is
// instantiated, resolve the impls for the parameters.
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

View File

@ -41,7 +41,7 @@ use syntax::visit::Visitor;
pub fn resolve_type_vars_in_expr(fcx: &FnCtxt, e: &ast::Expr) {
assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_expr(e, ());
wbcx.visit_expr(e);
wbcx.visit_upvar_borrow_map();
wbcx.visit_unboxed_closures();
}
@ -51,9 +51,9 @@ pub fn resolve_type_vars_in_fn(fcx: &FnCtxt,
blk: &ast::Block) {
assert_eq!(fcx.writeback_errors.get(), false);
let mut wbcx = WritebackCx::new(fcx);
wbcx.visit_block(blk, ());
wbcx.visit_block(blk);
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
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
// traffic in node-ids or update tables in the type context etc.
impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
fn visit_item(&mut self, _: &ast::Item, _: ()) {
impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
fn visit_item(&mut self, _: &ast::Item) {
// Ignore items
}
fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) {
fn visit_stmt(&mut self, s: &ast::Stmt) {
if self.fcx.writeback_errors.get() {
return;
}
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() {
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() {
return;
}
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() {
return;
}
@ -167,10 +167,10 @@ impl<'cx, 'tcx> Visitor<()> for WritebackCx<'cx, 'tcx> {
p.id,
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() {
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.resolve(&var_ty, ResolvingLocal(l.span));
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 {
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());
}
_ => 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>
}
impl<'a, 'tcx> visit::Visitor<()> for CoherenceCheckVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) {
impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item) {
//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>
}
impl<'a, 'tcx> visit::Visitor<()> for PrivilegedScopeVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item, _: ()) {
impl<'a, 'tcx, 'v> visit::Visitor<'v> for PrivilegedScopeVisitor<'a, 'tcx> {
fn visit_item(&mut self, item: &Item) {
match item.node {
ItemMod(ref module_) => {
// Then visit the module items.
visit::walk_mod(self, module_, ());
visit::walk_mod(self, module_);
}
ItemImpl(_, None, ref 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
// builds up the trait inheritance table.
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
self.check_implementation_coherence();
@ -543,7 +543,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
// Privileged scope checking
fn check_privileged_scopes(&self, krate: &Crate) {
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 {

View File

@ -84,10 +84,10 @@ pub fn collect_item_types(ccx: &CrateCtxt, krate: &ast::Crate) {
}
let mut visitor = CollectTraitDefVisitor{ ccx: ccx };
visit::walk_crate(&mut visitor, krate, ());
visit::walk_crate(&mut visitor, krate);
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>
}
impl<'a, 'tcx> visit::Visitor<()> for CollectTraitDefVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectTraitDefVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
match i.node {
ast::ItemTrait(..) => {
// 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>
}
impl<'a, 'tcx> visit::Visitor<()> for CollectItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> visit::Visitor<'v> for CollectItemTypesVisitor<'a, 'tcx> {
fn visit_item(&mut self, i: &ast::Item) {
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);
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
}
@ -337,8 +337,8 @@ impl<'a, 'tcx> TermsContext<'a, 'tcx> {
}
}
impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for TermsContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
debug!("add_inferreds for item {}", item.repr(self.tcx));
let inferreds_on_entry = self.num_inferred();
@ -379,7 +379,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
assert!(newly_added);
}
visit::walk_item(self, item, ());
visit::walk_item(self, item);
}
ast::ItemImpl(..) |
@ -389,7 +389,7 @@ impl<'a, 'tcx> Visitor<()> for TermsContext<'a, 'tcx> {
ast::ItemForeignMod(..) |
ast::ItemTy(..) |
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,
constraints: Vec::new(),
};
visit::walk_crate(&mut constraint_cx, krate, ());
visit::walk_crate(&mut constraint_cx, krate);
constraint_cx
}
impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'a, 'tcx, 'v> Visitor<'v> for ConstraintContext<'a, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
let did = ast_util::local_def(item.id);
let tcx = self.terms_cx.tcx;
@ -533,7 +533,7 @@ impl<'a, 'tcx> Visitor<()> for ConstraintContext<'a, 'tcx> {
ast::ItemTy(..) |
ast::ItemImpl(..) |
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 };
visit::walk_crate(&mut cx, krate, ());
visit::walk_crate(&mut cx, krate);
}
verify(sess, items);
}
@ -105,13 +105,13 @@ impl<'a> Context<'a> {
}
}
impl<'a> Visitor<()> for Context<'a> {
fn visit_foreign_item(&mut self, i: &ast::ForeignItem, _: ()) {
impl<'a, 'v> Visitor<'v> for Context<'a> {
fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
match lang_items::extract(i.attrs.as_slice()) {
None => {}
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)> ,
}
impl Visitor<()> for RegistrarFinder {
fn visit_item(&mut self, item: &ast::Item, _: ()) {
impl<'v> Visitor<'v> for RegistrarFinder {
fn visit_item(&mut self, item: &ast::Item) {
match item.node {
ast::ItemFn(..) => {
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,
krate: &ast::Crate) -> Option<ast::NodeId> {
let mut finder = RegistrarFinder { registrars: Vec::new() };
visit::walk_crate(&mut finder, krate, ());
visit::walk_crate(&mut finder, krate);
match finder.registrars.len() {
0 => None,

View File

@ -69,7 +69,7 @@ impl<'a> PluginLoader<'a> {
pub fn load_plugins(sess: &Session, krate: &ast::Crate,
addl_plugins: Option<Plugins>) -> Plugins {
let mut loader = PluginLoader::new(sess);
visit::walk_crate(&mut loader, krate, ());
visit::walk_crate(&mut loader, krate);
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.
impl<'a> Visitor<()> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem, _: ()) {
impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
fn visit_view_item(&mut self, vi: &ast::ViewItem) {
match vi.node {
ast::ViewItemExternCrate(name, _, _) => {
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.
// do nothing.
}

View File

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

View File

@ -86,7 +86,7 @@ impl Svh {
{
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
@ -322,12 +322,9 @@ mod svh_visitor {
}
fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
// local short-hand eases writing signatures of syntax::visit mod.
type E = ();
impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
impl<'a> Visitor<E> for StrictVersionHashVisitor<'a> {
fn visit_mac(&mut self, macro: &Mac, e: E) {
fn visit_mac(&mut self, macro: &Mac) {
// macro invocations, namely macro_rules definitions,
// *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)));
}
visit::walk_mac(self, macro, e);
visit::walk_mac(self, macro);
fn macro_name(macro: &Mac) -> token::InternedString {
match &macro.node {
@ -364,26 +361,26 @@ mod svh_visitor {
}
fn visit_struct_def(&mut self, s: &StructDef, ident: Ident,
g: &Generics, _: NodeId, e: E) {
g: &Generics, _: NodeId) {
SawStructDef(content(ident)).hash(self.st);
visit::walk_generics(self, g, e.clone());
visit::walk_struct_def(self, s, e)
visit::walk_generics(self, g);
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);
// walk_variant does not call walk_generics, so do it here.
visit::walk_generics(self, g, e.clone());
visit::walk_variant(self, v, g, e)
visit::walk_generics(self, g);
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);
// (This is a strange method in the visitor trait, in that
// it does not expose a walk function to do the subroutine
// calls.)
match *l {
Some(ref l) => self.visit_lifetime_ref(l, env),
Some(ref l) => self.visit_lifetime_ref(l),
None => ()
}
}
@ -402,15 +399,15 @@ mod svh_visitor {
// (If you edit a method such that it deviates from the
// 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);
}
fn visit_lifetime_ref(&mut self, l: &Lifetime, _: E) {
fn visit_lifetime_ref(&mut self, l: &Lifetime) {
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);
}
@ -419,15 +416,15 @@ mod svh_visitor {
// monomorphization and cross-crate inlining generally implies
// that a change to a crate body will require downstream
// crates to be recompiled.
fn visit_expr(&mut self, ex: &Expr, e: E) {
SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex, e)
fn visit_expr(&mut self, ex: &Expr) {
SawExpr(saw_expr(&ex.node)).hash(self.st); visit::walk_expr(self, ex)
}
fn visit_stmt(&mut self, s: &Stmt, e: E) {
SawStmt(saw_stmt(&s.node)).hash(self.st); visit::walk_stmt(self, s, e)
fn visit_stmt(&mut self, s: &Stmt) {
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:
// exported `pub use` view items (since that may expose
// items that downstream crates can call), and `use
@ -437,79 +434,80 @@ mod svh_visitor {
// The simplest approach to handling both of the above is
// just to adopt the same simple-minded (fine-grained)
// 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
// perhaps reachability) somewhere here, so foreign items
// that do not leak into downstream crates would not be
// 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
// analysis somewhere here, so items that never leak into
// downstream crates (e.g. via monomorphisation or
// 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) {
SawMod.hash(self.st); visit::walk_mod(self, m, e)
fn visit_mod(&mut self, m: &Mod, _s: Span, _n: NodeId) {
SawMod.hash(self.st); visit::walk_mod(self, m)
}
fn visit_decl(&mut self, d: &Decl, e: E) {
SawDecl.hash(self.st); visit::walk_decl(self, d, e)
fn visit_decl(&mut self, d: &Decl) {
SawDecl.hash(self.st); visit::walk_decl(self, d)
}
fn visit_ty(&mut self, t: &Ty, e: E) {
SawTy.hash(self.st); visit::walk_ty(self, t, e)
fn visit_ty(&mut self, t: &Ty) {
SawTy.hash(self.st); visit::walk_ty(self, t)
}
fn visit_generics(&mut self, g: &Generics, e: E) {
SawGenerics.hash(self.st); visit::walk_generics(self, g, e)
fn visit_generics(&mut self, g: &Generics) {
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) {
SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s, e)
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl,
b: &'v Block, s: Span, _: NodeId) {
SawFn.hash(self.st); visit::walk_fn(self, fk, fd, b, s)
}
fn visit_ty_method(&mut self, t: &TypeMethod, e: E) {
SawTyMethod.hash(self.st); visit::walk_ty_method(self, t, e)
fn visit_ty_method(&mut self, t: &TypeMethod) {
SawTyMethod.hash(self.st); visit::walk_ty_method(self, t)
}
fn visit_trait_item(&mut self, t: &TraitItem, e: E) {
SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t, e)
fn visit_trait_item(&mut self, t: &TraitItem) {
SawTraitMethod.hash(self.st); visit::walk_trait_item(self, t)
}
fn visit_struct_field(&mut self, s: &StructField, e: E) {
SawStructField.hash(self.st); visit::walk_struct_field(self, s, e)
fn visit_struct_field(&mut self, s: &StructField) {
SawStructField.hash(self.st); visit::walk_struct_field(self, s)
}
fn visit_explicit_self(&mut self, es: &ExplicitSelf, e: E) {
SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es, e)
fn visit_explicit_self(&mut self, es: &ExplicitSelf) {
SawExplicitSelf.hash(self.st); visit::walk_explicit_self(self, es)
}
fn visit_path(&mut self, path: &Path, _: ast::NodeId, e: E) {
SawPath.hash(self.st); visit::walk_path(self, path, e)
fn visit_path(&mut self, path: &Path, _: ast::NodeId) {
SawPath.hash(self.st); visit::walk_path(self, path)
}
fn visit_block(&mut self, b: &Block, e: E) {
SawBlock.hash(self.st); visit::walk_block(self, b, e)
fn visit_block(&mut self, b: &Block) {
SawBlock.hash(self.st); visit::walk_block(self, b)
}
fn visit_pat(&mut self, p: &Pat, e: E) {
SawPat.hash(self.st); visit::walk_pat(self, p, e)
fn visit_pat(&mut self, p: &Pat) {
SawPat.hash(self.st); visit::walk_pat(self, p)
}
fn visit_local(&mut self, l: &Local, e: E) {
SawLocal.hash(self.st); visit::walk_local(self, l, e)
fn visit_local(&mut self, l: &Local) {
SawLocal.hash(self.st); visit::walk_local(self, l)
}
fn visit_arm(&mut self, a: &Arm, e: E) {
SawArm.hash(self.st); visit::walk_arm(self, a, e)
fn visit_arm(&mut self, a: &Arm) {
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, 'v, O: IdVisitingOperation> Visitor<'v> for IdVisitor<'a, O> {
fn visit_mod(&mut self,
module: &Mod,
_: Span,
node_id: NodeId,
env: ()) {
node_id: NodeId) {
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.visited_outermost {
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;
}
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);
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.visited_outermost {
return
@ -431,59 +430,58 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
_ => {}
}
visit::walk_item(self, item, env);
visit::walk_item(self, item);
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);
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);
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));
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);
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);
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);
match typ.node {
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);
visit::walk_generics(self, generics, env)
visit::walk_generics(self, generics)
}
fn visit_fn(&mut self,
function_kind: &visit::FnKind,
function_declaration: &FnDecl,
block: &Block,
function_kind: visit::FnKind<'v>,
function_declaration: &'v FnDecl,
block: &'v Block,
span: Span,
node_id: NodeId,
env: ()) {
node_id: NodeId) {
if !self.pass_through_items {
match *function_kind {
match function_kind {
visit::FkMethod(..) if self.visited_outermost => return,
visit::FkMethod(..) => self.visited_outermost = true,
_ => {}
@ -492,7 +490,7 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
self.operation.visit_id(node_id);
match *function_kind {
match function_kind {
visit::FkItemFn(_, generics, _, _) |
visit::FkMethod(_, generics, _) => {
self.visit_generics_helper(generics)
@ -508,39 +506,37 @@ impl<'a, O: IdVisitingOperation> Visitor<()> for IdVisitor<'a, O> {
function_kind,
function_declaration,
block,
span,
env);
span);
if !self.pass_through_items {
match *function_kind {
match function_kind {
visit::FkMethod(..) => self.visited_outermost = false,
_ => {}
}
}
}
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);
visit::walk_struct_field(self, struct_field, env)
visit::walk_struct_field(self, struct_field)
}
fn visit_struct_def(&mut self,
struct_def: &StructDef,
_: ast::Ident,
_: &ast::Generics,
id: NodeId,
_: ()) {
id: NodeId) {
self.operation.visit_id(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 {
ast::RequiredMethod(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,
};
visit::walk_inlined_item(&mut id_visitor, item, ());
visit::walk_inlined_item(&mut id_visitor, item);
}
struct IdRangeComputingVisitor {
@ -575,7 +571,7 @@ pub fn compute_id_range_for_inlined_item(item: &InlinedItem) -> IdRange {
visitor.result.get()
}
pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
decl: &FnDecl,
body: &Block,
sp: Span,
@ -595,7 +591,7 @@ pub fn compute_id_range_for_fn_body(fk: &visit::FnKind,
pass_through_items: 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()
}
@ -643,8 +639,8 @@ struct EachViewItemData<'a> {
callback: |&ast::ViewItem|: 'a -> bool,
}
impl<'a> Visitor<()> for EachViewItemData<'a> {
fn visit_view_item(&mut self, view_item: &ast::ViewItem, _: ()) {
impl<'a, 'v> Visitor<'v> for EachViewItemData<'a> {
fn visit_view_item(&mut self, view_item: &ast::ViewItem) {
let _ = (self.callback)(view_item);
}
}
@ -654,7 +650,7 @@ impl EachViewItem for ast::Crate {
let mut visit = EachViewItemData {
callback: f,
};
visit::walk_crate(&mut visit, self, ());
visit::walk_crate(&mut visit, self);
true
}
}

View File

@ -648,29 +648,29 @@ fn expand_arm(arm: &ast::Arm, fld: &mut MacroExpander) -> ast::Arm {
/// array
#[deriving(Clone)]
struct PatIdentFinder {
ident_accumulator: Vec<ast::Ident> ,
ident_accumulator: Vec<ast::Ident>
}
impl Visitor<()> for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
impl<'v> Visitor<'v> for PatIdentFinder {
fn visit_pat(&mut self, pattern: &ast::Pat) {
match *pattern {
ast::Pat { id: _, node: ast::PatIdent(_, ref path1, ref inner), span: _ } => {
self.ident_accumulator.push(path1.node);
// visit optional subpattern of PatIdent:
for subpat in inner.iter() {
self.visit_pat(&**subpat, ())
self.visit_pat(&**subpat)
}
}
// use the default traversal for non-PatIdents
_ => visit::walk_pat(self, pattern, ())
_ => visit::walk_pat(self, 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()};
name_finder.visit_pat(pat,());
name_finder.visit_pat(pat);
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> {
let mut pat_idents = PatIdentFinder{ident_accumulator:Vec::new()};
for arg in fn_decl.inputs.iter() {
pat_idents.visit_pat(&*arg.pat, ());
pat_idents.visit_pat(&*arg.pat);
}
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:
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.
@ -1107,8 +1107,8 @@ struct MacroExterminator<'a>{
sess: &'a parse::ParseSess
}
impl<'a> visit::Visitor<()> for MacroExterminator<'a> {
fn visit_mac(&mut self, macro: &ast::Mac, _:()) {
impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
fn visit_mac(&mut self, macro: &ast::Mac) {
self.sess.span_diagnostic.span_bug(macro.span,
"macro exterminator: expected AST \
with no macro invocations");
@ -1144,15 +1144,14 @@ mod test {
path_accumulator: Vec<ast::Path> ,
}
impl Visitor<()> for PathExprFinderContext {
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
match *expr {
ast::Expr{id:_,span:_,node:ast::ExprPath(ref p)} => {
impl<'v> Visitor<'v> for PathExprFinderContext {
fn visit_expr(&mut self, expr: &ast::Expr) {
match expr.node {
ast::ExprPath(ref p) => {
self.path_accumulator.push(p.clone());
// 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
fn crate_varrefs(the_crate : &ast::Crate) -> Vec<ast::Path> {
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
}
/// A Visitor that extracts the identifiers from a thingy.
// as a side note, I'm starting to want to abstract over these....
struct IdentFinder{
struct IdentFinder {
ident_accumulator: Vec<ast::Ident>
}
impl Visitor<()> for IdentFinder {
fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident, _: ()){
impl<'v> Visitor<'v> for IdentFinder {
fn visit_ident(&mut self, _: codemap::Span, id: ast::Ident){
self.ident_accumulator.push(id);
}
}
@ -1179,7 +1178,7 @@ mod test {
/// Find the idents in a crate
fn crate_idents(the_crate: &ast::Crate) -> Vec<ast::Ident> {
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
}
@ -1277,7 +1276,7 @@ mod test {
// find the pat_ident paths in a crate
fn crate_bindings(the_crate : &ast::Crate) -> Vec<ast::Ident> {
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
}

File diff suppressed because it is too large Load Diff