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:
commit
9c68679f2e
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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 */ }
|
||||
}
|
||||
|
@ -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 { .. }
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 ¯o.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user