Add support for the 'full' feature to 'visit'
diff --git a/src/visit.rs b/src/visit.rs
index c073b60..27817bf 100644
--- a/src/visit.rs
+++ b/src/visit.rs
@@ -76,6 +76,60 @@
         walk_const_expr(self, expr)
     }
     fn visit_lit(&mut self, _lit: &Lit) {}
+
+    #[cfg(feature = "type-macros")]
+    fn visit_mac(&mut self, mac: &Mac) {
+        walk_mac(self, mac);
+    }
+
+    #[cfg(feature = "full")]
+    fn visit_crate(&mut self, _crate: &Crate) {
+        walk_crate(self, _crate);
+    }
+    #[cfg(feature = "full")]
+    fn visit_item(&mut self, item: &Item) {
+        walk_item(self, item);
+    }
+    #[cfg(feature = "full")]
+    fn visit_expr(&mut self, expr: &Expr) {
+        walk_expr(self, expr);
+    }
+    #[cfg(feature = "full")]
+    fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) {
+        walk_foreign_item(self, foreign_item);
+    }
+    #[cfg(feature = "full")]
+    fn visit_pat(&mut self, pat: &Pat) {
+        walk_pat(self, pat);
+    }
+    #[cfg(feature = "full")]
+    fn visit_fn_decl(&mut self, fn_decl: &FnDecl) {
+        walk_fn_decl(self, fn_decl);
+    }
+    #[cfg(feature = "full")]
+    fn visit_trait_item(&mut self, trait_item: &TraitItem) {
+        walk_trait_item(self, trait_item);
+    }
+    #[cfg(feature = "full")]
+    fn visit_impl_item(&mut self, impl_item: &ImplItem) {
+        walk_impl_item(self, impl_item);
+    }
+    #[cfg(feature = "full")]
+    fn visit_method_sig(&mut self, method_sig: &MethodSig) {
+        walk_method_sig(self, method_sig);
+    }
+    #[cfg(feature = "full")]
+    fn visit_stmt(&mut self, stmt: &Stmt) {
+        walk_stmt(self, stmt);
+    }
+    #[cfg(feature = "full")]
+    fn visit_local(&mut self, local: &Local) {
+        walk_local(self, local);
+    }
+    #[cfg(feature = "full")]
+    fn visit_view_path(&mut self, view_path: &ViewPath) {
+        walk_view_path(self, view_path);
+    }
 }
 
 #[macro_export]
@@ -171,7 +225,15 @@
         Ty::ImplTrait(ref bounds) => {
             walk_list!(visitor, visit_ty_param_bound, bounds);
         }
-        Ty::Mac(_) => {}
+        Ty::Mac(ref mac) => {
+            #[cfg(feature = "type-macros")]
+            fn walk_tymac<V: Visitor>(visitor: &mut V, mac: &Mac) {
+                visitor.visit_mac(mac);
+            }
+            #[cfg(not(feature = "type-macros"))]
+            fn walk_tymac<V: Visitor>(_: &mut V, _: &super::ty::Mac) {}
+            walk_tymac(visitor, mac);
+        }
     }
 }
 
@@ -291,6 +353,462 @@
         ConstExpr::Paren(ref expr) => {
             visitor.visit_const_expr(expr);
         }
-        ConstExpr::Other(_) => {}
+        ConstExpr::Other(ref other) => {
+            #[cfg(feature = "full")]
+            fn walk_other<V: Visitor>(visitor: &mut V, other: &Expr) {
+                visitor.visit_expr(other);
+            }
+            #[cfg(not(feature = "full"))]
+            fn walk_other<V: Visitor>(_: &mut V, _: &super::constant::Other) {}
+            walk_other(visitor, other);
+        }
+    }
+}
+
+#[cfg(feature = "type-macros")]
+pub fn walk_mac<V: Visitor>(visitor: &mut V, mac: &Mac) {
+    visitor.visit_path(&mac.path);
+}
+
+#[cfg(feature = "full")]
+pub fn walk_crate<V: Visitor>(visitor: &mut V, _crate: &Crate) {
+    walk_list!(visitor, visit_attribute, &_crate.attrs);
+    walk_list!(visitor, visit_item, &_crate.items);
+}
+
+#[cfg(feature = "full")]
+pub fn walk_item<V: Visitor>(visitor: &mut V, item: &Item) {
+    visitor.visit_ident(&item.ident);
+    walk_list!(visitor, visit_attribute, &item.attrs);
+    match item.node {
+        ItemKind::ExternCrate(ref ident) => {
+            walk_opt_ident(visitor, ident);
+        }
+        ItemKind::Use(ref view_path) => {
+            visitor.visit_view_path(view_path);
+        }
+        ItemKind::Static(ref ty, _, ref expr) => {
+            visitor.visit_ty(ty);
+            visitor.visit_expr(expr);
+        }
+        ItemKind::Const(ref ty, ref expr) => {
+            visitor.visit_ty(ty);
+            visitor.visit_expr(expr);
+        }
+        ItemKind::Fn(ref decl, _, _, _, ref generics, ref body) => {
+            visitor.visit_fn_decl(decl);
+            visitor.visit_generics(generics);
+            walk_list!(visitor, visit_stmt, &body.stmts);
+        }
+        ItemKind::Mod(ref maybe_items) => {
+            if let Some(ref items) = *maybe_items {
+                walk_list!(visitor, visit_item, items);
+            }
+        }
+        ItemKind::ForeignMod(ref foreign_mod) => {
+            walk_list!(visitor, visit_foreign_item, &foreign_mod.items);
+        }
+        ItemKind::Ty(ref ty, ref generics) => {
+            visitor.visit_ty(ty);
+            visitor.visit_generics(generics);
+        }
+        ItemKind::Enum(ref variant, ref generics) => {
+            walk_list!(visitor, visit_variant, variant, generics);
+        }
+        ItemKind::Struct(ref variant_data, ref generics) => {
+            visitor.visit_variant_data(variant_data, &item.ident, generics);
+        }
+        ItemKind::Union(ref variant_data, ref generics) => {
+            visitor.visit_variant_data(variant_data, &item.ident, generics);
+        }
+        ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => {
+            visitor.visit_generics(generics);
+            walk_list!(visitor, visit_ty_param_bound, bounds);
+            walk_list!(visitor, visit_trait_item, trait_items);
+        }
+        ItemKind::DefaultImpl(_, ref path) => {
+            visitor.visit_path(path);
+        }
+        ItemKind::Impl(_, _, ref generics, ref maybe_path, ref ty, ref impl_items) => {
+            visitor.visit_generics(generics);
+            if let Some(ref path) = *maybe_path {
+                visitor.visit_path(path);
+            }
+            visitor.visit_ty(ty);
+            walk_list!(visitor, visit_impl_item, impl_items);
+        }
+        ItemKind::Mac(ref mac) => {
+            visitor.visit_mac(mac)
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &Expr) {
+    walk_list!(visitor, visit_attribute, &expr.attrs);
+    match expr.node {
+        ExprKind::Box(ref expr) => {
+            visitor.visit_expr(expr);
+        }
+        ExprKind::InPlace(ref place, ref value) => {
+            visitor.visit_expr(place);
+            visitor.visit_expr(value);
+        }
+        ExprKind::Vec(ref exprs) => {
+            walk_list!(visitor, visit_expr, exprs);
+        }
+        ExprKind::Call(ref callee, ref args) => {
+            visitor.visit_expr(callee);
+            walk_list!(visitor, visit_expr, args);
+        }
+        ExprKind::MethodCall(ref name, ref ty_args, ref args) => {
+            visitor.visit_ident(name);
+            walk_list!(visitor, visit_ty, ty_args);
+            walk_list!(visitor, visit_expr, args);
+        }
+        ExprKind::Tup(ref exprs) => {
+            walk_list!(visitor, visit_expr, exprs);
+        }
+        ExprKind::Binary(_, ref lhs, ref rhs) => {
+            visitor.visit_expr(lhs);
+            visitor.visit_expr(rhs);
+        }
+        ExprKind::Unary(_, ref operand) => {
+            visitor.visit_expr(operand);
+        }
+        ExprKind::Lit(ref lit) => {
+            visitor.visit_lit(lit);
+        }
+        ExprKind::Cast(ref expr, ref ty) => {
+            visitor.visit_expr(expr);
+            visitor.visit_ty(ty);
+        }
+        ExprKind::Type(ref expr, ref ty) => {
+            visitor.visit_expr(expr);
+            visitor.visit_ty(ty);
+        }
+        ExprKind::If(ref cond, ref cons, ref maybe_alt) => {
+            visitor.visit_expr(cond);
+            walk_list!(visitor, visit_stmt, &cons.stmts);
+            if let Some(ref alt) = *maybe_alt {
+                visitor.visit_expr(alt);
+            }
+        }
+        ExprKind::IfLet(ref pat, ref cond, ref cons, ref maybe_alt) => {
+            visitor.visit_pat(pat);
+            visitor.visit_expr(cond);
+            walk_list!(visitor, visit_stmt, &cons.stmts);
+            if let Some(ref alt) = *maybe_alt {
+                visitor.visit_expr(alt);
+            }
+        }
+        ExprKind::While(ref cond, ref body, ref label) => {
+            visitor.visit_expr(cond);
+            walk_list!(visitor, visit_stmt, &body.stmts);
+            walk_opt_ident(visitor, label);
+        }
+        ExprKind::WhileLet(ref pat, ref cond, ref body, ref label) => {
+            visitor.visit_pat(pat);
+            visitor.visit_expr(cond);
+            walk_list!(visitor, visit_stmt, &body.stmts);
+            walk_opt_ident(visitor, label);
+        }
+        ExprKind::ForLoop(ref pat, ref expr, ref body, ref label) => {
+            visitor.visit_pat(pat);
+            visitor.visit_expr(expr);
+            walk_list!(visitor, visit_stmt, &body.stmts);
+            walk_opt_ident(visitor, label);
+        }
+        ExprKind::Loop(ref body, ref label) => {
+            walk_list!(visitor, visit_stmt, &body.stmts);
+            walk_opt_ident(visitor, label);
+        }
+        ExprKind::Match(ref expr, ref arms) => {
+            visitor.visit_expr(expr);
+            for &Arm{ref attrs, ref pats, ref guard, ref body} in arms {
+                walk_list!(visitor, visit_attribute, attrs);
+                walk_list!(visitor, visit_pat, pats);
+                if let Some(ref guard) = *guard {
+                    visitor.visit_expr(guard);
+                }
+                visitor.visit_expr(body);
+            }
+        }
+        ExprKind::Closure(_, ref decl, ref expr) => {
+            visitor.visit_fn_decl(decl);
+            visitor.visit_expr(expr);
+        }
+        ExprKind::Block(_, ref block) => {
+            walk_list!(visitor, visit_stmt, &block.stmts);
+        }
+        ExprKind::Assign(ref lhs, ref rhs) => {
+            visitor.visit_expr(lhs);
+            visitor.visit_expr(rhs);
+        }
+        ExprKind::AssignOp(_, ref lhs, ref rhs) => {
+            visitor.visit_expr(lhs);
+            visitor.visit_expr(rhs);
+        }
+        ExprKind::Field(ref obj, ref field) => {
+            visitor.visit_expr(obj);
+            visitor.visit_ident(field);
+        }
+        ExprKind::TupField(ref obj, _) => {
+            visitor.visit_expr(obj);
+        }
+        ExprKind::Index(ref obj, ref idx) => {
+            visitor.visit_expr(obj);
+            visitor.visit_expr(idx);
+        }
+        ExprKind::Range(ref maybe_start, ref maybe_end, _) => {
+            if let Some(ref start) = *maybe_start {
+                visitor.visit_expr(start);
+            }
+            if let Some(ref end) = *maybe_end {
+                visitor.visit_expr(end);
+            }
+        }
+        ExprKind::Path(ref maybe_qself, ref path) => {
+            if let Some(ref qself) = *maybe_qself {
+                visitor.visit_ty(&qself.ty);
+            }
+            visitor.visit_path(path);
+        }
+        ExprKind::AddrOf(_, ref expr) => {
+            visitor.visit_expr(expr);
+        }
+        ExprKind::Break(ref maybe_label, ref maybe_expr) => {
+            walk_opt_ident(visitor, maybe_label);
+            if let Some(ref expr) = *maybe_expr {
+                visitor.visit_expr(expr);
+            }
+        }
+        ExprKind::Continue(ref maybe_label) => {
+            walk_opt_ident(visitor, maybe_label);
+        }
+        ExprKind::Ret(ref maybe_expr) => {
+            if let Some(ref expr) = *maybe_expr {
+                visitor.visit_expr(expr);
+            }
+        }
+        ExprKind::Mac(ref mac) => {
+            visitor.visit_mac(mac);
+        }
+        ExprKind::Struct(ref path, ref fields, ref maybe_base) => {
+            visitor.visit_path(path);
+            for &FieldValue{ref ident, ref expr, ..} in fields {
+                visitor.visit_ident(ident);
+                visitor.visit_expr(expr);
+            }
+            if let Some(ref base) = *maybe_base {
+                visitor.visit_expr(base);
+            }
+        }
+        ExprKind::Repeat(ref value, ref times) => {
+            visitor.visit_expr(value);
+            visitor.visit_expr(times);
+        }
+        ExprKind::Paren(ref expr) => {
+            visitor.visit_expr(expr);
+        }
+        ExprKind::Try(ref expr) => {
+            visitor.visit_expr(expr);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_foreign_item<V: Visitor>(visitor: &mut V, foreign_item: &ForeignItem) {
+    visitor.visit_ident(&foreign_item.ident);
+    walk_list!(visitor, visit_attribute, &foreign_item.attrs);
+    match foreign_item.node {
+        ForeignItemKind::Fn(ref decl, ref generics) => {
+            visitor.visit_fn_decl(decl);
+            visitor.visit_generics(generics);
+        }
+        ForeignItemKind::Static(ref ty, _) => {
+            visitor.visit_ty(ty);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_pat<V: Visitor>(visitor: &mut V, pat: &Pat) {
+    match *pat {
+        Pat::Wild => {}
+        Pat::Ident(_, ref ident, ref maybe_pat) => {
+            visitor.visit_ident(ident);
+            if let Some(ref pat) = *maybe_pat {
+                visitor.visit_pat(pat);
+            }
+        }
+        Pat::Struct(ref path, ref field_pats, _) => {
+            visitor.visit_path(path);
+            for &FieldPat{ref ident, ref pat, ..} in field_pats {
+                visitor.visit_ident(ident);
+                visitor.visit_pat(pat);
+            }
+        }
+        Pat::TupleStruct(ref path, ref pats, _) => {
+            visitor.visit_path(path);
+            walk_list!(visitor, visit_pat, pats);
+        }
+        Pat::Path(ref maybe_qself, ref path) => {
+            if let Some(ref qself) = *maybe_qself {
+                visitor.visit_ty(&qself.ty);
+            }
+            visitor.visit_path(path);
+        }
+        Pat::Tuple(ref pats, _) => {
+            walk_list!(visitor, visit_pat, pats);
+        }
+        Pat::Box(ref pat) |
+        Pat::Ref(ref pat, _) => {
+            visitor.visit_pat(pat);
+        }
+        Pat::Lit(ref expr) => {
+            visitor.visit_expr(expr);
+        }
+        Pat::Range(ref start, ref end) => {
+            visitor.visit_expr(start);
+            visitor.visit_expr(end);
+        }
+        Pat::Slice(ref start, ref maybe_mid, ref end) => {
+            walk_list!(visitor, visit_pat, start);
+            if let Some(ref mid) = *maybe_mid {
+                visitor.visit_pat(mid);
+            }
+            walk_list!(visitor, visit_pat, end);
+        }
+        Pat::Mac(ref mac) => {
+            visitor.visit_mac(mac);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_fn_decl<V: Visitor>(visitor: &mut V, fn_decl: &FnDecl) {
+    for input in &fn_decl.inputs {
+        match *input {
+            FnArg::SelfRef(_, _) | FnArg::SelfValue(_) => {}
+            FnArg::Captured(ref pat, ref ty) => {
+                visitor.visit_pat(pat);
+                visitor.visit_ty(ty);
+            }
+            FnArg::Ignored(ref ty) => {
+                visitor.visit_ty(ty);
+            }
+        }
+    }
+    visitor.visit_fn_ret_ty(&fn_decl.output);
+}
+
+#[cfg(feature = "full")]
+pub fn walk_trait_item<V: Visitor>(visitor: &mut V, trait_item: &TraitItem) {
+    visitor.visit_ident(&trait_item.ident);
+    walk_list!(visitor, visit_attribute, &trait_item.attrs);
+    match trait_item.node {
+        TraitItemKind::Const(ref ty, ref maybe_expr) => {
+            visitor.visit_ty(ty);
+            if let Some(ref expr) = *maybe_expr {
+                visitor.visit_expr(expr);
+            }
+        }
+        TraitItemKind::Method(ref method_sig, ref maybe_block) => {
+            visitor.visit_method_sig(method_sig);
+            if let Some(ref block) = *maybe_block {
+                walk_list!(visitor, visit_stmt, &block.stmts);
+            }
+        }
+        TraitItemKind::Type(ref bounds, ref maybe_ty) => {
+            walk_list!(visitor, visit_ty_param_bound, bounds);
+            if let Some(ref ty) = *maybe_ty {
+                visitor.visit_ty(ty);
+            }
+        }
+        TraitItemKind::Macro(ref mac) => {
+            visitor.visit_mac(mac);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_impl_item<V: Visitor>(visitor: &mut V, impl_item: &ImplItem) {
+    visitor.visit_ident(&impl_item.ident);
+    walk_list!(visitor, visit_attribute, &impl_item.attrs);
+    match impl_item.node {
+        ImplItemKind::Const(ref ty, ref expr) => {
+            visitor.visit_ty(ty);
+            visitor.visit_expr(expr);
+        }
+        ImplItemKind::Method(ref method_sig, ref block) => {
+            visitor.visit_method_sig(method_sig);
+            walk_list!(visitor, visit_stmt, &block.stmts);
+        }
+        ImplItemKind::Type(ref ty) => {
+            visitor.visit_ty(ty);
+        }
+        ImplItemKind::Macro(ref mac) => {
+            visitor.visit_mac(mac);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_method_sig<V: Visitor>(visitor: &mut V, method_sig: &MethodSig) {
+    visitor.visit_fn_decl(&method_sig.decl);
+    visitor.visit_generics(&method_sig.generics);
+}
+
+#[cfg(feature = "full")]
+pub fn walk_stmt<V: Visitor>(visitor: &mut V, stmt: &Stmt) {
+    match *stmt {
+        Stmt::Local(ref local) => {
+            visitor.visit_local(local);
+        }
+        Stmt::Item(ref item) => {
+            visitor.visit_item(item);
+        }
+        Stmt::Expr(ref expr) |
+        Stmt::Semi(ref expr) => {
+            visitor.visit_expr(expr);
+        }
+        Stmt::Mac(ref details) => {
+            let (ref mac, _, ref attrs) = **details;
+            visitor.visit_mac(mac);
+            walk_list!(visitor, visit_attribute, attrs);
+        }
+    }
+}
+
+#[cfg(feature = "full")]
+pub fn walk_local<V: Visitor>(visitor: &mut V, local: &Local) {
+    visitor.visit_pat(&local.pat);
+    if let Some(ref ty) = local.ty {
+        visitor.visit_ty(ty);
+    }
+    if let Some(ref init) = local.init {
+        visitor.visit_expr(init);
+    }
+    walk_list!(visitor, visit_attribute, &local.attrs);
+}
+
+#[cfg(feature = "full")]
+pub fn walk_view_path<V: Visitor>(visitor: &mut V, view_path: &ViewPath) {
+    match *view_path {
+        ViewPath::Simple(ref path, ref maybe_ident) => {
+            visitor.visit_path(path);
+            walk_opt_ident(visitor, maybe_ident);
+        }
+        ViewPath::Glob(ref path) => {
+            visitor.visit_path(path);
+        }
+        ViewPath::List(ref path, ref items) => {
+            visitor.visit_path(path);
+            for &PathListItem{ref name, ref rename} in items {
+                visitor.visit_ident(name);
+                walk_opt_ident(visitor, rename);
+            }
+        }
     }
 }