//! A MutVisitor represents an AST modification; it accepts an AST piece and
//! and mutates it in place. So, for instance, macro expansion is a MutVisitor
//! that walks over an AST and modifies it.
//!
//! Note: using a MutVisitor (other than the MacroExpander MutVisitor) on
//! an AST before macro expansion is probably a bad idea. For instance,
//! a MutVisitor renaming item names in a module will miss all of those
//! that are created by the expansion of a macro.

use crate::ast::*;
use crate::source_map::{Spanned, respan};
use crate::parse::token::{self, Token};
use crate::ptr::P;
use crate::ThinVec;
use crate::tokenstream::*;
use crate::util::map_in_place::MapInPlace;

use smallvec::{smallvec, Array, SmallVec};
use syntax_pos::Span;

use rustc_data_structures::sync::Lrc;
use std::ops::DerefMut;
use std::{panic, process, ptr};

#[cfg(test)]
mod tests;

pub trait ExpectOne<A: Array> {
    fn expect_one(self, err: &'static str) -> A::Item;
}

impl<A: Array> ExpectOne<A> for SmallVec<A> {
    fn expect_one(self, err: &'static str) -> A::Item {
        assert!(self.len() == 1, err);
        self.into_iter().next().unwrap()
    }
}

pub trait MutVisitor: Sized {
    // Methods in this trait have one of three forms:
    //
    //   fn visit_t(&mut self, t: &mut T);                      // common
    //   fn flat_map_t(&mut self, t: T) -> SmallVec<[T; 1]>;    // rare
    //   fn filter_map_t(&mut self, t: T) -> Option<T>;         // rarest
    //
    // Any additions to this trait should happen in form of a call to a public
    // `noop_*` function that only calls out to the visitor again, not other
    // `noop_*` functions. This is a necessary API workaround to the problem of
    // not being able to call out to the super default method in an overridden
    // default method.
    //
    // When writing these methods, it is better to use destructuring like this:
    //
    //   fn visit_abc(&mut self, ABC { a, b, c: _ }: &mut ABC) {
    //       visit_a(a);
    //       visit_b(b);
    //   }
    //
    // than to use field access like this:
    //
    //   fn visit_abc(&mut self, abc: &mut ABC) {
    //       visit_a(&mut abc.a);
    //       visit_b(&mut abc.b);
    //       // ignore abc.c
    //   }
    //
    // As well as being more concise, the former is explicit about which fields
    // are skipped. Furthermore, if a new field is added, the destructuring
    // version will cause a compile error, which is good. In comparison, the
    // field access version will continue working and it would be easy to
    // forget to add handling for it.

    fn visit_crate(&mut self, c: &mut Crate) {
        noop_visit_crate(c, self)
    }

    fn visit_meta_list_item(&mut self, list_item: &mut NestedMetaItem) {
        noop_visit_meta_list_item(list_item, self);
    }

    fn visit_meta_item(&mut self, meta_item: &mut MetaItem) {
        noop_visit_meta_item(meta_item, self);
    }

    fn visit_use_tree(&mut self, use_tree: &mut UseTree) {
        noop_visit_use_tree(use_tree, self);
    }

    fn flat_map_foreign_item(&mut self, ni: ForeignItem) -> SmallVec<[ForeignItem; 1]> {
        noop_flat_map_foreign_item(ni, self)
    }

    fn flat_map_item(&mut self, i: P<Item>) -> SmallVec<[P<Item>; 1]> {
        noop_flat_map_item(i, self)
    }

    fn visit_fn_header(&mut self, header: &mut FnHeader) {
        noop_visit_fn_header(header, self);
    }

    fn visit_struct_field(&mut self, sf: &mut StructField) {
        noop_visit_struct_field(sf, self);
    }

    fn visit_item_kind(&mut self, i: &mut ItemKind) {
        noop_visit_item_kind(i, self);
    }

    fn flat_map_trait_item(&mut self, i: TraitItem) -> SmallVec<[TraitItem; 1]> {
        noop_flat_map_trait_item(i, self)
    }

    fn flat_map_impl_item(&mut self, i: ImplItem) -> SmallVec<[ImplItem; 1]> {
        noop_flat_map_impl_item(i, self)
    }

    fn visit_fn_decl(&mut self, d: &mut P<FnDecl>) {
        noop_visit_fn_decl(d, self);
    }

    fn visit_asyncness(&mut self, a: &mut IsAsync) {
        noop_visit_asyncness(a, self);
    }

    fn visit_block(&mut self, b: &mut P<Block>) {
        noop_visit_block(b, self);
    }

    fn flat_map_stmt(&mut self, s: Stmt) -> SmallVec<[Stmt; 1]> {
        noop_flat_map_stmt(s, self)
    }

    fn visit_arm(&mut self, a: &mut Arm) {
        noop_visit_arm(a, self);
    }

    fn visit_pat(&mut self, p: &mut P<Pat>) {
        noop_visit_pat(p, self);
    }

    fn visit_anon_const(&mut self, c: &mut AnonConst) {
        noop_visit_anon_const(c, self);
    }

    fn visit_expr(&mut self, e: &mut P<Expr>) {
        noop_visit_expr(e, self);
    }

    fn filter_map_expr(&mut self, e: P<Expr>) -> Option<P<Expr>> {
        noop_filter_map_expr(e, self)
    }

    fn visit_generic_arg(&mut self, arg: &mut GenericArg) {
        noop_visit_generic_arg(arg, self);
    }

    fn visit_ty(&mut self, t: &mut P<Ty>) {
        noop_visit_ty(t, self);
    }

    fn visit_lifetime(&mut self, l: &mut Lifetime) {
        noop_visit_lifetime(l, self);
    }

    fn visit_ty_constraint(&mut self, t: &mut AssocTyConstraint) {
        noop_visit_ty_constraint(t, self);
    }

    fn visit_mod(&mut self, m: &mut Mod) {
        noop_visit_mod(m, self);
    }

    fn visit_foreign_mod(&mut self, nm: &mut ForeignMod) {
        noop_visit_foreign_mod(nm, self);
    }

    fn visit_variant(&mut self, v: &mut Variant) {
        noop_visit_variant(v, self);
    }

    fn visit_ident(&mut self, i: &mut Ident) {
        noop_visit_ident(i, self);
    }

    fn visit_path(&mut self, p: &mut Path) {
        noop_visit_path(p, self);
    }

    fn visit_qself(&mut self, qs: &mut Option<QSelf>) {
        noop_visit_qself(qs, self);
    }

    fn visit_generic_args(&mut self, p: &mut GenericArgs) {
        noop_visit_generic_args(p, self);
    }

    fn visit_angle_bracketed_parameter_data(&mut self, p: &mut AngleBracketedArgs) {
        noop_visit_angle_bracketed_parameter_data(p, self);
    }

    fn visit_parenthesized_parameter_data(&mut self, p: &mut ParenthesizedArgs) {
        noop_visit_parenthesized_parameter_data(p, self);
    }

    fn visit_local(&mut self, l: &mut P<Local>) {
        noop_visit_local(l, self);
    }

    fn visit_mac(&mut self, _mac: &mut Mac) {
        panic!("visit_mac disabled by default");
        // N.B., see note about macros above. If you really want a visitor that
        // works on macros, use this definition in your trait impl:
        //   mut_visit::noop_visit_mac(_mac, self);
    }

    fn visit_macro_def(&mut self, def: &mut MacroDef) {
        noop_visit_macro_def(def, self);
    }

    fn visit_label(&mut self, label: &mut Label) {
        noop_visit_label(label, self);
    }

    fn visit_attribute(&mut self, at: &mut Attribute) {
        noop_visit_attribute(at, self);
    }

    fn visit_arg(&mut self, a: &mut Arg) {
        noop_visit_arg(a, self);
    }

    fn visit_generics(&mut self, generics: &mut Generics) {
        noop_visit_generics(generics, self);
    }

    fn visit_trait_ref(&mut self, tr: &mut TraitRef) {
        noop_visit_trait_ref(tr, self);
    }

    fn visit_poly_trait_ref(&mut self, p: &mut PolyTraitRef) {
        noop_visit_poly_trait_ref(p, self);
    }

    fn visit_variant_data(&mut self, vdata: &mut VariantData) {
        noop_visit_variant_data(vdata, self);
    }

    fn visit_generic_param(&mut self, param: &mut GenericParam) {
        noop_visit_generic_param(param, self);
    }

    fn visit_generic_params(&mut self, params: &mut Vec<GenericParam>) {
        noop_visit_generic_params(params, self);
    }

    fn visit_tt(&mut self, tt: &mut TokenTree) {
        noop_visit_tt(tt, self);
    }

    fn visit_tts(&mut self, tts: &mut TokenStream) {
        noop_visit_tts(tts, self);
    }

    fn visit_token(&mut self, t: &mut Token) {
        noop_visit_token(t, self);
    }

    fn visit_interpolated(&mut self, nt: &mut token::Nonterminal) {
        noop_visit_interpolated(nt, self);
    }

    fn visit_param_bound(&mut self, tpb: &mut GenericBound) {
        noop_visit_param_bound(tpb, self);
    }

    fn visit_mt(&mut self, mt: &mut MutTy) {
        noop_visit_mt(mt, self);
    }

    fn visit_field(&mut self, field: &mut Field) {
        noop_visit_field(field, self);
    }

    fn visit_where_clause(&mut self, where_clause: &mut WhereClause) {
        noop_visit_where_clause(where_clause, self);
    }

    fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
        noop_visit_where_predicate(where_predicate, self);
    }

    fn visit_vis(&mut self, vis: &mut Visibility) {
        noop_visit_vis(vis, self);
    }

    fn visit_id(&mut self, _id: &mut NodeId) {
        // Do nothing.
    }

    fn visit_span(&mut self, _sp: &mut Span) {
        // Do nothing.
    }
}

/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
/// when using a `flat_map_*` or `filter_map_*` method within a `visit_`
/// method. Abort the program if the closure panics.
//
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_clobber<T, F>(t: &mut T, f: F) where F: FnOnce(T) -> T {
    unsafe {
        // Safe because `t` is used in a read-only fashion by `read()` before
        // being overwritten by `write()`.
        let old_t = ptr::read(t);
        let new_t = panic::catch_unwind(panic::AssertUnwindSafe(|| f(old_t)))
            .unwrap_or_else(|_| process::abort());
        ptr::write(t, new_t);
    }
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
#[inline]
pub fn visit_vec<T, F>(elems: &mut Vec<T>, mut visit_elem: F) where F: FnMut(&mut T) {
    for elem in elems {
        visit_elem(elem);
    }
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
#[inline]
pub fn visit_opt<T, F>(opt: &mut Option<T>, mut visit_elem: F) where F: FnMut(&mut T) {
    if let Some(elem) = opt {
        visit_elem(elem);
    }
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_attrs<T: MutVisitor>(attrs: &mut Vec<Attribute>, vis: &mut T) {
    visit_vec(attrs, |attr| vis.visit_attribute(attr));
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_thin_attrs<T: MutVisitor>(attrs: &mut ThinVec<Attribute>, vis: &mut T) {
    for attr in attrs.iter_mut() {
        vis.visit_attribute(attr);
    }
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_exprs<T: MutVisitor>(exprs: &mut Vec<P<Expr>>, vis: &mut T) {
    exprs.flat_map_in_place(|expr| vis.filter_map_expr(expr))
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
    visit_vec(bounds, |bound| vis.visit_param_bound(bound));
}

// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_method_sig<T: MutVisitor>(MethodSig { header, decl }: &mut MethodSig, vis: &mut T) {
    vis.visit_fn_header(header);
    vis.visit_fn_decl(decl);
}

pub fn noop_visit_use_tree<T: MutVisitor>(use_tree: &mut UseTree, vis: &mut T) {
    let UseTree { prefix, kind, span } = use_tree;
    vis.visit_path(prefix);
    match kind {
        UseTreeKind::Simple(rename, id1, id2) => {
            visit_opt(rename, |rename| vis.visit_ident(rename));
            vis.visit_id(id1);
            vis.visit_id(id2);
        }
        UseTreeKind::Nested(items) => {
            for (tree, id) in items {
                vis.visit_use_tree(tree);
                vis.visit_id(id);
            }
        }
        UseTreeKind::Glob => {}
    }
    vis.visit_span(span);
}

pub fn noop_visit_arm<T: MutVisitor>(
    Arm { attrs, pats, guard, body, span, id }: &mut Arm,
    vis: &mut T,
) {
    visit_attrs(attrs, vis);
    vis.visit_id(id);
    visit_vec(pats, |pat| vis.visit_pat(pat));
    visit_opt(guard, |guard| vis.visit_expr(guard));
    vis.visit_expr(body);
    vis.visit_span(span);
}

pub fn noop_visit_ty_constraint<T: MutVisitor>(
    AssocTyConstraint { id, ident, kind, span }: &mut AssocTyConstraint,
    vis: &mut T
) {
    vis.visit_id(id);
    vis.visit_ident(ident);
    match kind {
        AssocTyConstraintKind::Equality { ref mut ty } => {
            vis.visit_ty(ty);
        }
        AssocTyConstraintKind::Bound { ref mut bounds } => {
            visit_bounds(bounds, vis);
        }
    }
    vis.visit_span(span);
}

pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
    let Ty { id, node, span } = ty.deref_mut();
    vis.visit_id(id);
    match node {
        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err |
            TyKind::Never | TyKind::CVarArgs => {}
        TyKind::Slice(ty) => vis.visit_ty(ty),
        TyKind::Ptr(mt) => vis.visit_mt(mt),
        TyKind::Rptr(lt, mt) => {
            visit_opt(lt, |lt| noop_visit_lifetime(lt, vis));
            vis.visit_mt(mt);
        }
        TyKind::BareFn(bft) => {
            let BareFnTy { unsafety: _, abi: _, generic_params, decl } = bft.deref_mut();
            vis.visit_generic_params(generic_params);
            vis.visit_fn_decl(decl);
        }
        TyKind::Tup(tys) => visit_vec(tys, |ty| vis.visit_ty(ty)),
        TyKind::Paren(ty) => vis.visit_ty(ty),
        TyKind::Path(qself, path) => {
            vis.visit_qself(qself);
            vis.visit_path(path);
        }
        TyKind::Array(ty, length) => {
            vis.visit_ty(ty);
            vis.visit_anon_const(length);
        }
        TyKind::Typeof(expr) => vis.visit_anon_const(expr),
        TyKind::TraitObject(bounds, _syntax) =>
            visit_vec(bounds, |bound| vis.visit_param_bound(bound)),
        TyKind::ImplTrait(id, bounds) => {
            vis.visit_id(id);
            visit_vec(bounds, |bound| vis.visit_param_bound(bound));
        }
        TyKind::Mac(mac) => vis.visit_mac(mac),
    }
    vis.visit_span(span);
}

pub fn noop_visit_foreign_mod<T: MutVisitor>(foreign_mod: &mut ForeignMod, vis: &mut T) {
    let ForeignMod { abi: _, items} = foreign_mod;
    items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
}

pub fn noop_visit_variant<T: MutVisitor>(variant: &mut Variant, vis: &mut T) {
    let Variant { ident, attrs, id, data, disr_expr, span } = variant;
    vis.visit_ident(ident);
    visit_attrs(attrs, vis);
    vis.visit_id(id);
    vis.visit_variant_data(data);
    visit_opt(disr_expr, |disr_expr| vis.visit_anon_const(disr_expr));
    vis.visit_span(span);
}

pub fn noop_visit_ident<T: MutVisitor>(Ident { name: _, span }: &mut Ident, vis: &mut T) {
    vis.visit_span(span);
}

pub fn noop_visit_path<T: MutVisitor>(Path { segments, span }: &mut Path, vis: &mut T) {
    vis.visit_span(span);
    for PathSegment { ident, id, args } in segments {
        vis.visit_ident(ident);
        vis.visit_id(id);
        visit_opt(args, |args| vis.visit_generic_args(args));
    }
}

pub fn noop_visit_qself<T: MutVisitor>(qself: &mut Option<QSelf>, vis: &mut T) {
    visit_opt(qself, |QSelf { ty, path_span, position: _ }| {
        vis.visit_ty(ty);
        vis.visit_span(path_span);
    })
}

pub fn noop_visit_generic_args<T: MutVisitor>(generic_args: &mut GenericArgs, vis: &mut T) {
    match generic_args {
        GenericArgs::AngleBracketed(data) => vis.visit_angle_bracketed_parameter_data(data),
        GenericArgs::Parenthesized(data) => vis.visit_parenthesized_parameter_data(data),
    }
}

pub fn noop_visit_generic_arg<T: MutVisitor>(arg: &mut GenericArg, vis: &mut T) {
    match arg {
        GenericArg::Lifetime(lt) => vis.visit_lifetime(lt),
        GenericArg::Type(ty) => vis.visit_ty(ty),
        GenericArg::Const(ct) => vis.visit_anon_const(ct),
    }
}

pub fn noop_visit_angle_bracketed_parameter_data<T: MutVisitor>(data: &mut AngleBracketedArgs,
                                                                vis: &mut T) {
    let AngleBracketedArgs { args, constraints, span } = data;
    visit_vec(args, |arg| vis.visit_generic_arg(arg));
    visit_vec(constraints, |constraint| vis.visit_ty_constraint(constraint));
    vis.visit_span(span);
}

pub fn noop_visit_parenthesized_parameter_data<T: MutVisitor>(args: &mut ParenthesizedArgs,
                                                              vis: &mut T) {
    let ParenthesizedArgs { inputs, output, span } = args;
    visit_vec(inputs, |input| vis.visit_ty(input));
    visit_opt(output, |output| vis.visit_ty(output));
    vis.visit_span(span);
}

pub fn noop_visit_local<T: MutVisitor>(local: &mut P<Local>, vis: &mut T) {
    let Local { id, pat, ty, init, span, attrs } = local.deref_mut();
    vis.visit_id(id);
    vis.visit_pat(pat);
    visit_opt(ty, |ty| vis.visit_ty(ty));
    visit_opt(init, |init| vis.visit_expr(init));
    vis.visit_span(span);
    visit_thin_attrs(attrs, vis);
}

pub fn noop_visit_attribute<T: MutVisitor>(attr: &mut Attribute, vis: &mut T) {
    let Attribute { id: _, style: _, path, tokens, is_sugared_doc: _, span } = attr;
    vis.visit_path(path);
    vis.visit_tts(tokens);
    vis.visit_span(span);
}

pub fn noop_visit_mac<T: MutVisitor>(mac: &mut Mac, vis: &mut T) {
    let Mac { path, delim: _, tts, span, prior_type_ascription: _ } = mac;
    vis.visit_path(path);
    vis.visit_tts(tts);
    vis.visit_span(span);
}

pub fn noop_visit_macro_def<T: MutVisitor>(macro_def: &mut MacroDef, vis: &mut T) {
    let MacroDef { tokens, legacy: _ } = macro_def;
    vis.visit_tts(tokens);
}

pub fn noop_visit_meta_list_item<T: MutVisitor>(li: &mut NestedMetaItem, vis: &mut T) {
    match li {
        NestedMetaItem::MetaItem(mi) => vis.visit_meta_item(mi),
        NestedMetaItem::Literal(_lit) => {}
    }
}

pub fn noop_visit_meta_item<T: MutVisitor>(mi: &mut MetaItem, vis: &mut T) {
    let MetaItem { path: _, node, span } = mi;
    match node {
        MetaItemKind::Word => {}
        MetaItemKind::List(mis) => visit_vec(mis, |mi| vis.visit_meta_list_item(mi)),
        MetaItemKind::NameValue(_s) => {}
    }
    vis.visit_span(span);
}

pub fn noop_visit_arg<T: MutVisitor>(Arg { attrs, id, pat, span, ty }: &mut Arg, vis: &mut T) {
    vis.visit_id(id);
    visit_thin_attrs(attrs, vis);
    vis.visit_pat(pat);
    vis.visit_span(span);
    vis.visit_ty(ty);
}

pub fn noop_visit_tt<T: MutVisitor>(tt: &mut TokenTree, vis: &mut T) {
    match tt {
        TokenTree::Token(token) => {
            vis.visit_token(token);
        }
        TokenTree::Delimited(DelimSpan { open, close }, _delim, tts) => {
            vis.visit_span(open);
            vis.visit_span(close);
            vis.visit_tts(tts);
        }
    }
}

pub fn noop_visit_tts<T: MutVisitor>(TokenStream(tts): &mut TokenStream, vis: &mut T) {
    visit_opt(tts, |tts| {
        let tts = Lrc::make_mut(tts);
        visit_vec(tts, |(tree, _is_joint)| vis.visit_tt(tree));
    })
}

// Apply ident visitor if it's an ident, apply other visits to interpolated nodes.
// In practice the ident part is not actually used by specific visitors right now,
// but there's a test below checking that it works.
pub fn noop_visit_token<T: MutVisitor>(t: &mut Token, vis: &mut T) {
    let Token { kind, span } = t;
    match kind {
        token::Ident(name, _) | token::Lifetime(name) => {
            let mut ident = Ident::new(*name, *span);
            vis.visit_ident(&mut ident);
            *name = ident.name;
            *span = ident.span;
            return; // avoid visiting the span for the second time
        }
        token::Interpolated(nt) => {
            let mut nt = Lrc::make_mut(nt);
            vis.visit_interpolated(&mut nt);
        }
        _ => {}
    }
    vis.visit_span(span);
}

/// Apply visitor to elements of interpolated nodes.
//
// N.B., this can occur only when applying a visitor to partially expanded
// code, where parsed pieces have gotten implanted ito *other* macro
// invocations. This is relevant for macro hygiene, but possibly not elsewhere.
//
// One problem here occurs because the types for flat_map_item, flat_map_stmt,
// etc. allow the visitor to return *multiple* items; this is a problem for the
// nodes here, because they insist on having exactly one piece. One solution
// would be to mangle the MutVisitor trait to include one-to-many and
// one-to-one versions of these entry points, but that would probably confuse a
// lot of people and help very few. Instead, I'm just going to put in dynamic
// checks. I think the performance impact of this will be pretty much
// nonexistent. The danger is that someone will apply a MutVisitor to a
// partially expanded node, and will be confused by the fact that their
// "flat_map_item" or "flat_map_stmt" isn't getting called on NtItem or NtStmt
// nodes. Hopefully they'll wind up reading this comment, and doing something
// appropriate.
//
// BTW, design choice: I considered just changing the type of, e.g., NtItem to
// contain multiple items, but decided against it when I looked at
// parse_item_or_view_item and tried to figure out what I would do with
// multiple items there....
pub fn noop_visit_interpolated<T: MutVisitor>(nt: &mut token::Nonterminal, vis: &mut T) {
    match nt {
        token::NtItem(item) =>
            visit_clobber(item, |item| {
                // This is probably okay, because the only visitors likely to
                // peek inside interpolated nodes will be renamings/markings,
                // which map single items to single items.
                vis.flat_map_item(item).expect_one("expected visitor to produce exactly one item")
            }),
        token::NtBlock(block) => vis.visit_block(block),
        token::NtStmt(stmt) =>
            visit_clobber(stmt, |stmt| {
                // See reasoning above.
                vis.flat_map_stmt(stmt).expect_one("expected visitor to produce exactly one item")
            }),
        token::NtPat(pat) => vis.visit_pat(pat),
        token::NtExpr(expr) => vis.visit_expr(expr),
        token::NtTy(ty) => vis.visit_ty(ty),
        token::NtIdent(ident, _is_raw) => vis.visit_ident(ident),
        token::NtLifetime(ident) => vis.visit_ident(ident),
        token::NtLiteral(expr) => vis.visit_expr(expr),
        token::NtMeta(meta) => vis.visit_meta_item(meta),
        token::NtPath(path) => vis.visit_path(path),
        token::NtTT(tt) => vis.visit_tt(tt),
        token::NtImplItem(item) =>
            visit_clobber(item, |item| {
                // See reasoning above.
                vis.flat_map_impl_item(item)
                    .expect_one("expected visitor to produce exactly one item")
            }),
        token::NtTraitItem(item) =>
            visit_clobber(item, |item| {
                // See reasoning above.
                vis.flat_map_trait_item(item)
                    .expect_one("expected visitor to produce exactly one item")
            }),
        token::NtVis(visib) => vis.visit_vis(visib),
        token::NtForeignItem(item) =>
            visit_clobber(item, |item| {
                // See reasoning above.
                vis.flat_map_foreign_item(item)
                    .expect_one("expected visitor to produce exactly one item")
            }),
    }
}

pub fn noop_visit_asyncness<T: MutVisitor>(asyncness: &mut IsAsync, vis: &mut T) {
    match asyncness {
        IsAsync::Async { closure_id, return_impl_trait_id } => {
            vis.visit_id(closure_id);
            vis.visit_id(return_impl_trait_id);
        }
        IsAsync::NotAsync => {}
    }
}

pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
    let FnDecl { inputs, output, c_variadic: _ } = decl.deref_mut();
    visit_vec(inputs, |input| vis.visit_arg(input));
    match output {
        FunctionRetTy::Default(span) => vis.visit_span(span),
        FunctionRetTy::Ty(ty) => vis.visit_ty(ty),
    }
}

pub fn noop_visit_param_bound<T: MutVisitor>(pb: &mut GenericBound, vis: &mut T) {
    match pb {
        GenericBound::Trait(ty, _modifier) => vis.visit_poly_trait_ref(ty),
        GenericBound::Outlives(lifetime) => noop_visit_lifetime(lifetime, vis),
    }
}

pub fn noop_visit_generic_param<T: MutVisitor>(param: &mut GenericParam, vis: &mut T) {
    let GenericParam { id, ident, attrs, bounds, kind } = param;
    vis.visit_id(id);
    vis.visit_ident(ident);
    visit_thin_attrs(attrs, vis);
    visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
    match kind {
        GenericParamKind::Lifetime => {}
        GenericParamKind::Type { default } => {
            visit_opt(default, |default| vis.visit_ty(default));
        }
        GenericParamKind::Const { ty } => {
            vis.visit_ty(ty);
        }
    }
}

pub fn noop_visit_generic_params<T: MutVisitor>(params: &mut Vec<GenericParam>, vis: &mut T){
    visit_vec(params, |param| vis.visit_generic_param(param));
}

pub fn noop_visit_label<T: MutVisitor>(Label { ident }: &mut Label, vis: &mut T) {
    vis.visit_ident(ident);
}

fn noop_visit_lifetime<T: MutVisitor>(Lifetime { id, ident }: &mut Lifetime, vis: &mut T) {
    vis.visit_id(id);
    vis.visit_ident(ident);
}

pub fn noop_visit_generics<T: MutVisitor>(generics: &mut Generics, vis: &mut T) {
    let Generics { params, where_clause, span } = generics;
    vis.visit_generic_params(params);
    vis.visit_where_clause(where_clause);
    vis.visit_span(span);
}

pub fn noop_visit_where_clause<T: MutVisitor>(wc: &mut WhereClause, vis: &mut T) {
    let WhereClause { predicates, span } = wc;
    visit_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
    vis.visit_span(span);
}

pub fn noop_visit_where_predicate<T: MutVisitor>(pred: &mut WherePredicate, vis: &mut T) {
    match pred {
        WherePredicate::BoundPredicate(bp) => {
            let WhereBoundPredicate { span, bound_generic_params, bounded_ty, bounds } = bp;
            vis.visit_span(span);
            vis.visit_generic_params(bound_generic_params);
            vis.visit_ty(bounded_ty);
            visit_vec(bounds, |bound| vis.visit_param_bound(bound));
        }
        WherePredicate::RegionPredicate(rp) => {
            let WhereRegionPredicate { span, lifetime, bounds } = rp;
            vis.visit_span(span);
            noop_visit_lifetime(lifetime, vis);
            visit_vec(bounds, |bound| noop_visit_param_bound(bound, vis));
        }
        WherePredicate::EqPredicate(ep) => {
            let WhereEqPredicate { id, span, lhs_ty, rhs_ty } = ep;
            vis.visit_id(id);
            vis.visit_span(span);
            vis.visit_ty(lhs_ty);
            vis.visit_ty(rhs_ty);
        }
    }
}

pub fn noop_visit_variant_data<T: MutVisitor>(vdata: &mut VariantData, vis: &mut T) {
    match vdata {
        VariantData::Struct(fields, ..) => visit_vec(fields, |field| vis.visit_struct_field(field)),
        VariantData::Tuple(fields, id) => {
            visit_vec(fields, |field| vis.visit_struct_field(field));
            vis.visit_id(id);
        },
        VariantData::Unit(id) => vis.visit_id(id),
    }
}

pub fn noop_visit_trait_ref<T: MutVisitor>(TraitRef { path, ref_id }: &mut TraitRef, vis: &mut T) {
    vis.visit_path(path);
    vis.visit_id(ref_id);
}

pub fn noop_visit_poly_trait_ref<T: MutVisitor>(p: &mut PolyTraitRef, vis: &mut T) {
    let PolyTraitRef { bound_generic_params, trait_ref, span } = p;
    vis.visit_generic_params(bound_generic_params);
    vis.visit_trait_ref(trait_ref);
    vis.visit_span(span);
}

pub fn noop_visit_struct_field<T: MutVisitor>(f: &mut StructField, visitor: &mut T) {
    let StructField { span, ident, vis, id, ty, attrs } = f;
    visitor.visit_span(span);
    visit_opt(ident, |ident| visitor.visit_ident(ident));
    visitor.visit_vis(vis);
    visitor.visit_id(id);
    visitor.visit_ty(ty);
    visit_attrs(attrs, visitor);
}

pub fn noop_visit_field<T: MutVisitor>(f: &mut Field, vis: &mut T) {
    let Field { ident, expr, span, is_shorthand: _, attrs, id } = f;
    vis.visit_ident(ident);
    vis.visit_expr(expr);
    vis.visit_id(id);
    vis.visit_span(span);
    visit_thin_attrs(attrs, vis);
}

pub fn noop_visit_mt<T: MutVisitor>(MutTy { ty, mutbl: _ }: &mut MutTy, vis: &mut T) {
    vis.visit_ty(ty);
}

pub fn noop_visit_block<T: MutVisitor>(block: &mut P<Block>, vis: &mut T) {
    let Block { id, stmts, rules: _, span } = block.deref_mut();
    vis.visit_id(id);
    stmts.flat_map_in_place(|stmt| vis.flat_map_stmt(stmt));
    vis.visit_span(span);
}

pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
    match kind {
        ItemKind::ExternCrate(_orig_name) => {}
        ItemKind::Use(use_tree) => vis.visit_use_tree(use_tree),
        ItemKind::Static(ty, _mut, expr) => {
            vis.visit_ty(ty);
            vis.visit_expr(expr);
        }
        ItemKind::Const(ty, expr) => {
            vis.visit_ty(ty);
            vis.visit_expr(expr);
        }
        ItemKind::Fn(decl, header, generics, body) => {
            vis.visit_fn_decl(decl);
            vis.visit_fn_header(header);
            vis.visit_generics(generics);
            vis.visit_block(body);
        }
        ItemKind::Mod(m) => vis.visit_mod(m),
        ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
        ItemKind::GlobalAsm(_ga) => {}
        ItemKind::TyAlias(ty, generics) => {
            vis.visit_ty(ty);
            vis.visit_generics(generics);
        }
        ItemKind::OpaqueTy(bounds, generics) => {
            visit_bounds(bounds, vis);
            vis.visit_generics(generics);
        }
        ItemKind::Enum(EnumDef { variants }, generics) => {
            visit_vec(variants, |variant| vis.visit_variant(variant));
            vis.visit_generics(generics);
        }
        ItemKind::Struct(variant_data, generics) |
        ItemKind::Union(variant_data, generics) => {
            vis.visit_variant_data(variant_data);
            vis.visit_generics(generics);
        }
        ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => {
            vis.visit_generics(generics);
            visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref));
            vis.visit_ty(ty);
            items.flat_map_in_place(|item| vis.flat_map_impl_item(item));
        }
        ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => {
            vis.visit_generics(generics);
            visit_bounds(bounds, vis);
            items.flat_map_in_place(|item| vis.flat_map_trait_item(item));
        }
        ItemKind::TraitAlias(generics, bounds) => {
            vis.visit_generics(generics);
            visit_bounds(bounds, vis);
        }
        ItemKind::Mac(m) => vis.visit_mac(m),
        ItemKind::MacroDef(def) => vis.visit_macro_def(def),
    }
}

pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, vis: &mut T)
    -> SmallVec<[TraitItem; 1]>
{
    let TraitItem { id, ident, attrs, generics, node, span, tokens: _ } = &mut item;
    vis.visit_id(id);
    vis.visit_ident(ident);
    visit_attrs(attrs, vis);
    vis.visit_generics(generics);
    match node {
        TraitItemKind::Const(ty, default) => {
            vis.visit_ty(ty);
            visit_opt(default, |default| vis.visit_expr(default));
        }
        TraitItemKind::Method(sig, body) => {
            visit_method_sig(sig, vis);
            visit_opt(body, |body| vis.visit_block(body));
        }
        TraitItemKind::Type(bounds, default) => {
            visit_bounds(bounds, vis);
            visit_opt(default, |default| vis.visit_ty(default));
        }
        TraitItemKind::Macro(mac) => {
            vis.visit_mac(mac);
        }
    }
    vis.visit_span(span);

    smallvec![item]
}

pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut T)
                                              -> SmallVec<[ImplItem; 1]>
{
    let ImplItem { id, ident, vis, defaultness: _, attrs, generics, node, span, tokens: _ } =
        &mut item;
    visitor.visit_id(id);
    visitor.visit_ident(ident);
    visitor.visit_vis(vis);
    visit_attrs(attrs, visitor);
    visitor.visit_generics(generics);
    match node  {
        ImplItemKind::Const(ty, expr) => {
            visitor.visit_ty(ty);
            visitor.visit_expr(expr);
        }
        ImplItemKind::Method(sig, body) => {
            visit_method_sig(sig, visitor);
            visitor.visit_block(body);
        }
        ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),
        ImplItemKind::OpaqueTy(bounds) => visit_bounds(bounds, visitor),
        ImplItemKind::Macro(mac) => visitor.visit_mac(mac),
    }
    visitor.visit_span(span);

    smallvec![item]
}

pub fn noop_visit_fn_header<T: MutVisitor>(header: &mut FnHeader, vis: &mut T) {
    let FnHeader { unsafety: _, asyncness, constness: _, abi: _ } = header;
    vis.visit_asyncness(&mut asyncness.node);
}

pub fn noop_visit_mod<T: MutVisitor>(Mod { inner, items, inline: _ }: &mut Mod, vis: &mut T) {
    vis.visit_span(inner);
    items.flat_map_in_place(|item| vis.flat_map_item(item));
}

pub fn noop_visit_crate<T: MutVisitor>(krate: &mut Crate, vis: &mut T) {
    visit_clobber(krate, |Crate { module, attrs, span }| {
        let item = P(Item {
            ident: Ident::invalid(),
            attrs,
            id: DUMMY_NODE_ID,
            vis: respan(span.shrink_to_lo(), VisibilityKind::Public),
            span,
            node: ItemKind::Mod(module),
            tokens: None,
        });
        let items = vis.flat_map_item(item);

        let len = items.len();
        if len == 0 {
            let module = Mod { inner: span, items: vec![], inline: true };
            Crate { module, attrs: vec![], span }
        } else if len == 1 {
            let Item { attrs, span, node, .. } = items.into_iter().next().unwrap().into_inner();
            match node {
                ItemKind::Mod(module) => Crate { module, attrs, span },
                _ => panic!("visitor converted a module to not a module"),
            }
        } else {
            panic!("a crate cannot expand to more than one item");
        }
    });
}

// Mutate one item into possibly many items.
pub fn noop_flat_map_item<T: MutVisitor>(mut item: P<Item>, visitor: &mut T)
                                         -> SmallVec<[P<Item>; 1]> {
    let Item { ident, attrs, id, node, vis, span, tokens: _ } = item.deref_mut();
    visitor.visit_ident(ident);
    visit_attrs(attrs, visitor);
    visitor.visit_id(id);
    visitor.visit_item_kind(node);
    visitor.visit_vis(vis);
    visitor.visit_span(span);

    // FIXME: if `tokens` is modified with a call to `vis.visit_tts` it causes
    //        an ICE during resolve... odd!

    smallvec![item]
}

pub fn noop_flat_map_foreign_item<T: MutVisitor>(mut item: ForeignItem, visitor: &mut T)
    -> SmallVec<[ForeignItem; 1]>
{
    let ForeignItem { ident, attrs, node, id, span, vis } = &mut item;
    visitor.visit_ident(ident);
    visit_attrs(attrs, visitor);
    match node {
        ForeignItemKind::Fn(fdec, generics) => {
            visitor.visit_fn_decl(fdec);
            visitor.visit_generics(generics);
        }
        ForeignItemKind::Static(t, _m) => visitor.visit_ty(t),
        ForeignItemKind::Ty => {}
        ForeignItemKind::Macro(mac) => visitor.visit_mac(mac),
    }
    visitor.visit_id(id);
    visitor.visit_span(span);
    visitor.visit_vis(vis);

    smallvec![item]
}

pub fn noop_visit_pat<T: MutVisitor>(pat: &mut P<Pat>, vis: &mut T) {
    let Pat { id, node, span } = pat.deref_mut();
    vis.visit_id(id);
    match node {
        PatKind::Wild | PatKind::Rest => {}
        PatKind::Ident(_binding_mode, ident, sub) => {
            vis.visit_ident(ident);
            visit_opt(sub, |sub| vis.visit_pat(sub));
        }
        PatKind::Lit(e) => vis.visit_expr(e),
        PatKind::TupleStruct(path, elems) => {
            vis.visit_path(path);
            visit_vec(elems, |elem| vis.visit_pat(elem));
        }
        PatKind::Path(qself, path) => {
            vis.visit_qself(qself);
            vis.visit_path(path);
        }
        PatKind::Struct(path, fields, _etc) => {
            vis.visit_path(path);
            for FieldPat { ident, pat, is_shorthand: _, attrs, id, span } in fields {
                vis.visit_ident(ident);
                vis.visit_id(id);
                vis.visit_pat(pat);
                visit_thin_attrs(attrs, vis);
                vis.visit_span(span);
            };
        }
        PatKind::Tuple(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)),
        PatKind::Box(inner) => vis.visit_pat(inner),
        PatKind::Ref(inner, _mutbl) => vis.visit_pat(inner),
        PatKind::Range(e1, e2, Spanned { span: _, node: _ }) => {
            vis.visit_expr(e1);
            vis.visit_expr(e2);
            vis.visit_span(span);
        }
        PatKind::Slice(elems) => visit_vec(elems, |elem| vis.visit_pat(elem)),
        PatKind::Paren(inner) => vis.visit_pat(inner),
        PatKind::Mac(mac) => vis.visit_mac(mac),
    }
    vis.visit_span(span);
}

pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonConst, vis: &mut T) {
    vis.visit_id(id);
    vis.visit_expr(value);
}

pub fn noop_visit_expr<T: MutVisitor>(Expr { node, id, span, attrs }: &mut Expr, vis: &mut T) {
    match node {
        ExprKind::Box(expr) => vis.visit_expr(expr),
        ExprKind::Array(exprs) => visit_exprs(exprs, vis),
        ExprKind::Repeat(expr, count) => {
            vis.visit_expr(expr);
            vis.visit_anon_const(count);
        }
        ExprKind::Tup(exprs) => visit_exprs(exprs, vis),
        ExprKind::Call(f, args) => {
            vis.visit_expr(f);
            visit_exprs(args, vis);
        }
        ExprKind::MethodCall(PathSegment { ident, id, args }, exprs) => {
            vis.visit_ident(ident);
            vis.visit_id(id);
            visit_opt(args, |args| vis.visit_generic_args(args));
            visit_exprs(exprs, vis);
        }
        ExprKind::Binary(_binop, lhs, rhs) => {
            vis.visit_expr(lhs);
            vis.visit_expr(rhs);
        }
        ExprKind::Unary(_unop, ohs) => vis.visit_expr(ohs),
        ExprKind::Cast(expr, ty) => {
            vis.visit_expr(expr);
            vis.visit_ty(ty);
        }
        ExprKind::Type(expr, ty) => {
            vis.visit_expr(expr);
            vis.visit_ty(ty);
        }
        ExprKind::AddrOf(_m, ohs) => vis.visit_expr(ohs),
        ExprKind::Let(pats, scrutinee) => {
            visit_vec(pats, |pat| vis.visit_pat(pat));
            vis.visit_expr(scrutinee);
        }
        ExprKind::If(cond, tr, fl) => {
            vis.visit_expr(cond);
            vis.visit_block(tr);
            visit_opt(fl, |fl| vis.visit_expr(fl));
        }
        ExprKind::While(cond, body, label) => {
            vis.visit_expr(cond);
            vis.visit_block(body);
            visit_opt(label, |label| vis.visit_label(label));
        }
        ExprKind::ForLoop(pat, iter, body, label) => {
            vis.visit_pat(pat);
            vis.visit_expr(iter);
            vis.visit_block(body);
            visit_opt(label, |label| vis.visit_label(label));
        }
        ExprKind::Loop(body, label) => {
            vis.visit_block(body);
            visit_opt(label, |label| vis.visit_label(label));
        }
        ExprKind::Match(expr, arms) => {
            vis.visit_expr(expr);
            visit_vec(arms, |arm| vis.visit_arm(arm));
        }
        ExprKind::Closure(_capture_by, asyncness, _movability, decl, body, span) => {
            vis.visit_asyncness(asyncness);
            vis.visit_fn_decl(decl);
            vis.visit_expr(body);
            vis.visit_span(span);
        }
        ExprKind::Block(blk, label) => {
            vis.visit_block(blk);
            visit_opt(label, |label| vis.visit_label(label));
        }
        ExprKind::Async(_capture_by, node_id, body) => {
            vis.visit_id(node_id);
            vis.visit_block(body);
        }
        ExprKind::Await(expr) => vis.visit_expr(expr),
        ExprKind::Assign(el, er) => {
            vis.visit_expr(el);
            vis.visit_expr(er);
        }
        ExprKind::AssignOp(_op, el, er) => {
            vis.visit_expr(el);
            vis.visit_expr(er);
        }
        ExprKind::Field(el, ident) => {
            vis.visit_expr(el);
            vis.visit_ident(ident);
        }
        ExprKind::Index(el, er) => {
            vis.visit_expr(el);
            vis.visit_expr(er);
        }
        ExprKind::Range(e1, e2, _lim) => {
            visit_opt(e1, |e1| vis.visit_expr(e1));
            visit_opt(e2, |e2| vis.visit_expr(e2));
        }
        ExprKind::Path(qself, path) => {
            vis.visit_qself(qself);
            vis.visit_path(path);
        }
        ExprKind::Break(label, expr) => {
            visit_opt(label, |label| vis.visit_label(label));
            visit_opt(expr, |expr| vis.visit_expr(expr));
        }
        ExprKind::Continue(label) => {
            visit_opt(label, |label| vis.visit_label(label));
        }
        ExprKind::Ret(expr) => {
            visit_opt(expr, |expr| vis.visit_expr(expr));
        }
        ExprKind::InlineAsm(asm) => {
            let InlineAsm { asm: _, asm_str_style: _, outputs, inputs, clobbers: _, volatile: _,
                            alignstack: _, dialect: _, ctxt: _ } = asm.deref_mut();
            for out in outputs {
                let InlineAsmOutput { constraint: _, expr, is_rw: _, is_indirect: _ } = out;
                vis.visit_expr(expr);
            }
            visit_vec(inputs, |(_c, expr)| vis.visit_expr(expr));
        }
        ExprKind::Mac(mac) => vis.visit_mac(mac),
        ExprKind::Struct(path, fields, expr) => {
            vis.visit_path(path);
            visit_vec(fields, |field| vis.visit_field(field));
            visit_opt(expr, |expr| vis.visit_expr(expr));
        },
        ExprKind::Paren(expr) => {
            vis.visit_expr(expr);

            // Nodes that are equal modulo `Paren` sugar no-ops should have the same ids.
            *id = expr.id;
            vis.visit_span(span);
            visit_thin_attrs(attrs, vis);
            return;
        }
        ExprKind::Yield(expr) => {
            visit_opt(expr, |expr| vis.visit_expr(expr));
        }
        ExprKind::Try(expr) => vis.visit_expr(expr),
        ExprKind::TryBlock(body) => vis.visit_block(body),
        ExprKind::Lit(_) | ExprKind::Err => {}
    }
    vis.visit_id(id);
    vis.visit_span(span);
    visit_thin_attrs(attrs, vis);
}

pub fn noop_filter_map_expr<T: MutVisitor>(mut e: P<Expr>, vis: &mut T) -> Option<P<Expr>> {
    Some({ vis.visit_expr(&mut e); e })
}

pub fn noop_flat_map_stmt<T: MutVisitor>(Stmt { node, mut span, mut id }: Stmt, vis: &mut T)
    -> SmallVec<[Stmt; 1]>
{
    vis.visit_id(&mut id);
    vis.visit_span(&mut span);
    noop_flat_map_stmt_kind(node, vis).into_iter().map(|node| {
        Stmt { id, node, span }
    }).collect()
}

pub fn noop_flat_map_stmt_kind<T: MutVisitor>(node: StmtKind, vis: &mut T)
                                              -> SmallVec<[StmtKind; 1]> {
    match node {
        StmtKind::Local(mut local) =>
            smallvec![StmtKind::Local({ vis.visit_local(&mut local); local })],
        StmtKind::Item(item) => vis.flat_map_item(item).into_iter().map(StmtKind::Item).collect(),
        StmtKind::Expr(expr) => {
            vis.filter_map_expr(expr).into_iter().map(StmtKind::Expr).collect()
        }
        StmtKind::Semi(expr) => {
            vis.filter_map_expr(expr).into_iter().map(StmtKind::Semi).collect()
        }
        StmtKind::Mac(mut mac) => {
            let (mac_, _semi, attrs) = mac.deref_mut();
            vis.visit_mac(mac_);
            visit_thin_attrs(attrs, vis);
            smallvec![StmtKind::Mac(mac)]
        }
    }
}

pub fn noop_visit_vis<T: MutVisitor>(Spanned { node, span }: &mut Visibility, vis: &mut T) {
    match node {
        VisibilityKind::Public | VisibilityKind::Crate(_) | VisibilityKind::Inherited => {}
        VisibilityKind::Restricted { path, id } => {
            vis.visit_path(path);
            vis.visit_id(id);
        }
    }
    vis.visit_span(span);
}
