use rustc_target::spec::abi::Abi;
use syntax::ast;
use syntax::source_map::{SourceMap, Spanned};
use syntax::print::pp::{self, Breaks};
use syntax::print::pp::Breaks::{Consistent, Inconsistent};
use syntax::print::pprust::{self, Comments, PrintState};
use syntax::sess::ParseSess;
use syntax::symbol::kw;
use syntax::util::parser::{self, AssocOp, Fixity};
use syntax_pos::{self, BytePos, FileName};

use crate::hir;
use crate::hir::{PatKind, GenericBound, TraitBoundModifier, RangeEnd};
use crate::hir::{GenericParam, GenericParamKind, GenericArg};
use crate::hir::ptr::P;

use std::borrow::Cow;
use std::cell::Cell;
use std::vec;

pub enum AnnNode<'a> {
    Name(&'a ast::Name),
    Block(&'a hir::Block),
    Item(&'a hir::Item),
    SubItem(hir::HirId),
    Expr(&'a hir::Expr),
    Pat(&'a hir::Pat),
    Arm(&'a hir::Arm),
}

pub enum Nested {
    Item(hir::ItemId),
    TraitItem(hir::TraitItemId),
    ImplItem(hir::ImplItemId),
    Body(hir::BodyId),
    BodyParamPat(hir::BodyId, usize)
}

pub trait PpAnn {
    fn nested(&self, _state: &mut State<'_>, _nested: Nested) {
    }
    fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {
    }
    fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {
    }
    fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item> {
        None
    }
}

pub struct NoAnn;
impl PpAnn for NoAnn {}
pub const NO_ANN: &dyn PpAnn = &NoAnn;

impl PpAnn for hir::Crate {
    fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item> {
        Some(self.item(item))
    }
    fn nested(&self, state: &mut State<'_>, nested: Nested) {
        match nested {
            Nested::Item(id) => state.print_item(self.item(id.id)),
            Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)),
            Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)),
            Nested::Body(id) => state.print_expr(&self.body(id).value),
            Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat)
        }
    }
}

pub struct State<'a> {
    pub s: pp::Printer,
    comments: Option<Comments<'a>>,
    ann: &'a (dyn PpAnn + 'a),
}

impl std::ops::Deref for State<'_> {
    type Target = pp::Printer;
    fn deref(&self) -> &Self::Target {
        &self.s
    }
}

impl std::ops::DerefMut for State<'_> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.s
    }
}

impl<'a> PrintState<'a> for State<'a> {
    fn comments(&mut self) -> &mut Option<Comments<'a>> {
        &mut self.comments
    }

    fn print_ident(&mut self, ident: ast::Ident) {
        self.s.word(pprust::ast_ident_to_string(ident, ident.is_raw_guess()));
        self.ann.post(self, AnnNode::Name(&ident.name))
    }

    fn print_generic_args(&mut self, args: &ast::GenericArgs, _colons_before_params: bool) {
        span_bug!(args.span(), "AST generic args printed by HIR pretty-printer");
    }
}

pub const INDENT_UNIT: usize = 4;

/// Requires you to pass an input filename and reader so that
/// it can scan the input text for comments to copy forward.
pub fn print_crate<'a>(cm: &'a SourceMap,
                       sess: &ParseSess,
                       krate: &hir::Crate,
                       filename: FileName,
                       input: String,
                       ann: &'a dyn PpAnn) -> String {
    let mut s = State::new_from_input(cm, sess, filename, input, ann);

    // When printing the AST, we sometimes need to inject `#[no_std]` here.
    // Since you can't compile the HIR, it's not necessary.

    s.print_mod(&krate.module, &krate.attrs);
    s.print_remaining_comments();
    s.s.eof()
}

impl<'a> State<'a> {
    pub fn new_from_input(cm: &'a SourceMap,
                          sess: &ParseSess,
                          filename: FileName,
                          input: String,
                          ann: &'a dyn PpAnn)
                          -> State<'a> {
        State {
            s: pp::mk_printer(),
            comments: Some(Comments::new(cm, sess, filename, input)),
            ann,
        }
    }
}

pub fn to_string<F>(ann: &dyn PpAnn, f: F) -> String
    where F: FnOnce(&mut State<'_>)
{
    let mut printer = State {
        s: pp::mk_printer(),
        comments: None,
        ann,
    };
    f(&mut printer);
    printer.s.eof()
}

pub fn visibility_qualified<S: Into<Cow<'static, str>>>(vis: &hir::Visibility, w: S) -> String {
    to_string(NO_ANN, |s| {
        s.print_visibility(vis);
        s.s.word(w)
    })
}

impl<'a> State<'a> {
    pub fn cbox(&mut self, u: usize) {
        self.s.cbox(u);
    }

    pub fn nbsp(&mut self) {
        self.s.word(" ")
    }

    pub fn word_nbsp<S: Into<Cow<'static, str>>>(&mut self, w: S) {
        self.s.word(w);
        self.nbsp()
    }

    pub fn head<S: Into<Cow<'static, str>>>(&mut self, w: S) {
        let w = w.into();
        // outer-box is consistent
        self.cbox(INDENT_UNIT);
        // head-box is inconsistent
        self.ibox(w.len() + 1);
        // keyword that starts the head
        if !w.is_empty() {
            self.word_nbsp(w);
        }
    }

    pub fn bopen(&mut self) {
        self.s.word("{");
        self.end(); // close the head-box
    }

    pub fn bclose_maybe_open(&mut self,
                             span: syntax_pos::Span,
                             close_box: bool)
                             {
        self.maybe_print_comment(span.hi());
        self.break_offset_if_not_bol(1, -(INDENT_UNIT as isize));
        self.s.word("}");
        if close_box {
            self.end(); // close the outer-box
        }
    }

    pub fn bclose(&mut self, span: syntax_pos::Span) {
        self.bclose_maybe_open(span, true)
    }

    pub fn space_if_not_bol(&mut self) {
        if !self.s.is_beginning_of_line() {
            self.s.space();
        }
    }

    pub fn break_offset_if_not_bol(&mut self, n: usize, off: isize) {
        if !self.s.is_beginning_of_line() {
            self.s.break_offset(n, off)
        } else {
            if off != 0 && self.s.last_token().is_hardbreak_tok() {
                // We do something pretty sketchy here: tuck the nonzero
                // offset-adjustment we were going to deposit along with the
                // break into the previous hardbreak.
                self.s.replace_last_token(pp::Printer::hardbreak_tok_offset(off));
            }
        }
    }

    // Synthesizes a comment that was not textually present in the original source
    // file.
    pub fn synth_comment(&mut self, text: String) {
        self.s.word("/*");
        self.s.space();
        self.s.word(text);
        self.s.space();
        self.s.word("*/")
    }

    pub fn commasep_cmnt<T, F, G>(&mut self,
                                  b: Breaks,
                                  elts: &[T],
                                  mut op: F,
                                  mut get_span: G)
        where F: FnMut(&mut State<'_>, &T),
              G: FnMut(&T) -> syntax_pos::Span
    {
        self.rbox(0, b);
        let len = elts.len();
        let mut i = 0;
        for elt in elts {
            self.maybe_print_comment(get_span(elt).hi());
            op(self, elt);
            i += 1;
            if i < len {
                self.s.word(",");
                self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()));
                self.space_if_not_bol();
            }
        }
        self.end();
    }

    pub fn commasep_exprs(&mut self, b: Breaks, exprs: &[hir::Expr]) {
        self.commasep_cmnt(b, exprs, |s, e| s.print_expr(&e), |e| e.span)
    }

    pub fn print_mod(&mut self, _mod: &hir::Mod, attrs: &[ast::Attribute]) {
        self.print_inner_attributes(attrs);
        for &item_id in &_mod.item_ids {
            self.ann.nested(self, Nested::Item(item_id));
        }
    }

    pub fn print_foreign_mod(&mut self,
                             nmod: &hir::ForeignMod,
                             attrs: &[ast::Attribute])
                             {
        self.print_inner_attributes(attrs);
        for item in &nmod.items {
            self.print_foreign_item(item);
        }
    }

    pub fn print_opt_lifetime(&mut self, lifetime: &hir::Lifetime) {
        if !lifetime.is_elided() {
            self.print_lifetime(lifetime);
            self.nbsp();
        }
    }

    pub fn print_type(&mut self, ty: &hir::Ty) {
        self.maybe_print_comment(ty.span.lo());
        self.ibox(0);
        match ty.kind {
            hir::TyKind::Slice(ref ty) => {
                self.s.word("[");
                self.print_type(&ty);
                self.s.word("]");
            }
            hir::TyKind::Ptr(ref mt) => {
                self.s.word("*");
                self.print_mt(mt, true);
            }
            hir::TyKind::Rptr(ref lifetime, ref mt) => {
                self.s.word("&");
                self.print_opt_lifetime(lifetime);
                self.print_mt(mt, false);
            }
            hir::TyKind::Never => {
                self.s.word("!");
            },
            hir::TyKind::Tup(ref elts) => {
                self.popen();
                self.commasep(Inconsistent, &elts[..], |s, ty| s.print_type(&ty));
                if elts.len() == 1 {
                    self.s.word(",");
                }
                self.pclose();
            }
            hir::TyKind::BareFn(ref f) => {
                self.print_ty_fn(f.abi, f.unsafety, &f.decl, None, &f.generic_params,
                                 &f.param_names[..]);
            }
            hir::TyKind::Def(..) => {},
            hir::TyKind::Path(ref qpath) => {
                self.print_qpath(qpath, false)
            }
            hir::TyKind::TraitObject(ref bounds, ref lifetime) => {
                let mut first = true;
                for bound in bounds {
                    if first {
                        first = false;
                    } else {
                        self.nbsp();
                        self.word_space("+");
                    }
                    self.print_poly_trait_ref(bound);
                }
                if !lifetime.is_elided() {
                    self.nbsp();
                    self.word_space("+");
                    self.print_lifetime(lifetime);
                }
            }
            hir::TyKind::Array(ref ty, ref length) => {
                self.s.word("[");
                self.print_type(&ty);
                self.s.word("; ");
                self.print_anon_const(length);
                self.s.word("]");
            }
            hir::TyKind::Typeof(ref e) => {
                self.s.word("typeof(");
                self.print_anon_const(e);
                self.s.word(")");
            }
            hir::TyKind::Infer => {
                self.s.word("_");
            }
            hir::TyKind::Err => {
                self.popen();
                self.s.word("/*ERROR*/");
                self.pclose();
            }
        }
        self.end()
    }

    pub fn print_foreign_item(&mut self, item: &hir::ForeignItem) {
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(item.span.lo());
        self.print_outer_attributes(&item.attrs);
        match item.kind {
            hir::ForeignItemKind::Fn(ref decl, ref arg_names, ref generics) => {
                self.head("");
                self.print_fn(decl,
                              hir::FnHeader {
                                  unsafety: hir::Unsafety::Normal,
                                  constness: hir::Constness::NotConst,
                                  abi: Abi::Rust,
                                  asyncness: hir::IsAsync::NotAsync,
                              },
                              Some(item.ident.name),
                              generics,
                              &item.vis,
                              arg_names,
                              None);
                self.end(); // end head-ibox
                self.s.word(";");
                self.end() // end the outer fn box
            }
            hir::ForeignItemKind::Static(ref t, m) => {
                self.head(visibility_qualified(&item.vis, "static"));
                if m == hir::Mutability::Mutable {
                    self.word_space("mut");
                }
                self.print_ident(item.ident);
                self.word_space(":");
                self.print_type(&t);
                self.s.word(";");
                self.end(); // end the head-ibox
                self.end() // end the outer cbox
            }
            hir::ForeignItemKind::Type => {
                self.head(visibility_qualified(&item.vis, "type"));
                self.print_ident(item.ident);
                self.s.word(";");
                self.end(); // end the head-ibox
                self.end() // end the outer cbox
            }
        }
    }

    fn print_associated_const(&mut self,
                              ident: ast::Ident,
                              ty: &hir::Ty,
                              default: Option<hir::BodyId>,
                              vis: &hir::Visibility)
                              {
        self.s.word(visibility_qualified(vis, ""));
        self.word_space("const");
        self.print_ident(ident);
        self.word_space(":");
        self.print_type(ty);
        if let Some(expr) = default {
            self.s.space();
            self.word_space("=");
            self.ann.nested(self, Nested::Body(expr));
        }
        self.s.word(";")
    }

    fn print_associated_type(&mut self,
                             ident: ast::Ident,
                             bounds: Option<&hir::GenericBounds>,
                             ty: Option<&hir::Ty>)
                             {
        self.word_space("type");
        self.print_ident(ident);
        if let Some(bounds) = bounds {
            self.print_bounds(":", bounds);
        }
        if let Some(ty) = ty {
            self.s.space();
            self.word_space("=");
            self.print_type(ty);
        }
        self.s.word(";")
    }

    fn print_item_type(
        &mut self,
        item: &hir::Item,
        generics: &hir::Generics,
        inner: impl Fn(&mut Self),
    ) {
        self.head(visibility_qualified(&item.vis, "type"));
        self.print_ident(item.ident);
        self.print_generic_params(&generics.params);
        self.end(); // end the inner ibox

        self.print_where_clause(&generics.where_clause);
        self.s.space();
        inner(self);
        self.s.word(";");
        self.end(); // end the outer ibox
    }

    /// Pretty-print an item
    pub fn print_item(&mut self, item: &hir::Item) {
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(item.span.lo());
        self.print_outer_attributes(&item.attrs);
        self.ann.pre(self, AnnNode::Item(item));
        match item.kind {
            hir::ItemKind::ExternCrate(orig_name) => {
                self.head(visibility_qualified(&item.vis, "extern crate"));
                if let Some(orig_name) = orig_name {
                    self.print_name(orig_name);
                    self.s.space();
                    self.s.word("as");
                    self.s.space();
                }
                self.print_ident(item.ident);
                self.s.word(";");
                self.end(); // end inner head-block
                self.end(); // end outer head-block
            }
            hir::ItemKind::Use(ref path, kind) => {
                self.head(visibility_qualified(&item.vis, "use"));
                self.print_path(path, false);

                match kind {
                    hir::UseKind::Single => {
                        if path.segments.last().unwrap().ident != item.ident {
                            self.s.space();
                            self.word_space("as");
                            self.print_ident(item.ident);
                        }
                        self.s.word(";");
                    }
                    hir::UseKind::Glob => self.s.word("::*;"),
                    hir::UseKind::ListStem => self.s.word("::{};")
                }
                self.end(); // end inner head-block
                self.end(); // end outer head-block
            }
            hir::ItemKind::Static(ref ty, m, expr) => {
                self.head(visibility_qualified(&item.vis, "static"));
                if m == hir::Mutability::Mutable {
                    self.word_space("mut");
                }
                self.print_ident(item.ident);
                self.word_space(":");
                self.print_type(&ty);
                self.s.space();
                self.end(); // end the head-ibox

                self.word_space("=");
                self.ann.nested(self, Nested::Body(expr));
                self.s.word(";");
                self.end(); // end the outer cbox
            }
            hir::ItemKind::Const(ref ty, expr) => {
                self.head(visibility_qualified(&item.vis, "const"));
                self.print_ident(item.ident);
                self.word_space(":");
                self.print_type(&ty);
                self.s.space();
                self.end(); // end the head-ibox

                self.word_space("=");
                self.ann.nested(self, Nested::Body(expr));
                self.s.word(";");
                self.end(); // end the outer cbox
            }
            hir::ItemKind::Fn(ref sig, ref param_names, body) => {
                self.head("");
                self.print_fn(&sig.decl,
                              sig.header,
                              Some(item.ident.name),
                              param_names,
                              &item.vis,
                              &[],
                              Some(body));
                self.s.word(" ");
                self.end(); // need to close a box
                self.end(); // need to close a box
                self.ann.nested(self, Nested::Body(body));
            }
            hir::ItemKind::Mod(ref _mod) => {
                self.head(visibility_qualified(&item.vis, "mod"));
                self.print_ident(item.ident);
                self.nbsp();
                self.bopen();
                self.print_mod(_mod, &item.attrs);
                self.bclose(item.span);
            }
            hir::ItemKind::ForeignMod(ref nmod) => {
                self.head("extern");
                self.word_nbsp(nmod.abi.to_string());
                self.bopen();
                self.print_foreign_mod(nmod, &item.attrs);
                self.bclose(item.span);
            }
            hir::ItemKind::GlobalAsm(ref ga) => {
                self.head(visibility_qualified(&item.vis, "global asm"));
                self.s.word(ga.asm.to_string());
                self.end()
            }
            hir::ItemKind::TyAlias(ref ty, ref generics) => {
                self.print_item_type(item, &generics, |state| {
                    state.word_space("=");
                    state.print_type(&ty);
                });
            }
            hir::ItemKind::OpaqueTy(ref opaque_ty) => {
                self.print_item_type(item, &opaque_ty.generics, |state| {
                    let mut real_bounds = Vec::with_capacity(opaque_ty.bounds.len());
                    for b in opaque_ty.bounds.iter() {
                        if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                            state.s.space();
                            state.word_space("for ?");
                            state.print_trait_ref(&ptr.trait_ref);
                        } else {
                            real_bounds.push(b);
                        }
                    }
                    state.print_bounds("= impl", real_bounds);
                });
            }
            hir::ItemKind::Enum(ref enum_definition, ref params) => {
                self.print_enum_def(enum_definition, params, item.ident.name, item.span, &item.vis);
            }
            hir::ItemKind::Struct(ref struct_def, ref generics) => {
                self.head(visibility_qualified(&item.vis, "struct"));
                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
            }
            hir::ItemKind::Union(ref struct_def, ref generics) => {
                self.head(visibility_qualified(&item.vis, "union"));
                self.print_struct(struct_def, generics, item.ident.name, item.span, true);
            }
            hir::ItemKind::Impl(unsafety,
                          polarity,
                          defaultness,
                          ref generics,
                          ref opt_trait,
                          ref ty,
                          ref impl_items) => {
                self.head("");
                self.print_visibility(&item.vis);
                self.print_defaultness(defaultness);
                self.print_unsafety(unsafety);
                self.word_nbsp("impl");

                if !generics.params.is_empty() {
                    self.print_generic_params(&generics.params);
                    self.s.space();
                }

                if let hir::ImplPolarity::Negative = polarity {
                    self.s.word("!");
                }

                if let Some(ref t) = opt_trait {
                    self.print_trait_ref(t);
                    self.s.space();
                    self.word_space("for");
                }

                self.print_type(&ty);
                self.print_where_clause(&generics.where_clause);

                self.s.space();
                self.bopen();
                self.print_inner_attributes(&item.attrs);
                for impl_item in impl_items {
                    self.ann.nested(self, Nested::ImplItem(impl_item.id));
                }
                self.bclose(item.span);
            }
            hir::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref trait_items) => {
                self.head("");
                self.print_visibility(&item.vis);
                self.print_is_auto(is_auto);
                self.print_unsafety(unsafety);
                self.word_nbsp("trait");
                self.print_ident(item.ident);
                self.print_generic_params(&generics.params);
                let mut real_bounds = Vec::with_capacity(bounds.len());
                for b in bounds.iter() {
                    if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                        self.s.space();
                        self.word_space("for ?");
                        self.print_trait_ref(&ptr.trait_ref);
                    } else {
                        real_bounds.push(b);
                    }
                }
                self.print_bounds(":", real_bounds);
                self.print_where_clause(&generics.where_clause);
                self.s.word(" ");
                self.bopen();
                for trait_item in trait_items {
                    self.ann.nested(self, Nested::TraitItem(trait_item.id));
                }
                self.bclose(item.span);
            }
            hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
                self.head("");
                self.print_visibility(&item.vis);
                self.word_nbsp("trait");
                self.print_ident(item.ident);
                self.print_generic_params(&generics.params);
                let mut real_bounds = Vec::with_capacity(bounds.len());
                // FIXME(durka) this seems to be some quite outdated syntax
                for b in bounds.iter() {
                    if let GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = *b {
                        self.s.space();
                        self.word_space("for ?");
                        self.print_trait_ref(&ptr.trait_ref);
                    } else {
                        real_bounds.push(b);
                    }
                }
                self.nbsp();
                self.print_bounds("=", real_bounds);
                self.print_where_clause(&generics.where_clause);
                self.s.word(";");
            }
        }
        self.ann.post(self, AnnNode::Item(item))
    }

    pub fn print_trait_ref(&mut self, t: &hir::TraitRef) {
        self.print_path(&t.path, false)
    }

    fn print_formal_generic_params(
        &mut self,
        generic_params: &[hir::GenericParam]
    ) {
        if !generic_params.is_empty() {
            self.s.word("for");
            self.print_generic_params(generic_params);
            self.nbsp();
        }
    }

    fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef) {
        self.print_formal_generic_params(&t.bound_generic_params);
        self.print_trait_ref(&t.trait_ref)
    }

    pub fn print_enum_def(&mut self,
                          enum_definition: &hir::EnumDef,
                          generics: &hir::Generics,
                          name: ast::Name,
                          span: syntax_pos::Span,
                          visibility: &hir::Visibility)
                          {
        self.head(visibility_qualified(visibility, "enum"));
        self.print_name(name);
        self.print_generic_params(&generics.params);
        self.print_where_clause(&generics.where_clause);
        self.s.space();
        self.print_variants(&enum_definition.variants, span)
    }

    pub fn print_variants(&mut self,
                          variants: &[hir::Variant],
                          span: syntax_pos::Span)
                          {
        self.bopen();
        for v in variants {
            self.space_if_not_bol();
            self.maybe_print_comment(v.span.lo());
            self.print_outer_attributes(&v.attrs);
            self.ibox(INDENT_UNIT);
            self.print_variant(v);
            self.s.word(",");
            self.end();
            self.maybe_print_trailing_comment(v.span, None);
        }
        self.bclose(span)
    }

    pub fn print_visibility(&mut self, vis: &hir::Visibility) {
        match vis.node {
            hir::VisibilityKind::Public => self.word_nbsp("pub"),
            hir::VisibilityKind::Crate(ast::CrateSugar::JustCrate) => self.word_nbsp("crate"),
            hir::VisibilityKind::Crate(ast::CrateSugar::PubCrate) => self.word_nbsp("pub(crate)"),
            hir::VisibilityKind::Restricted { ref path, .. } => {
                self.s.word("pub(");
                if path.segments.len() == 1 &&
                   path.segments[0].ident.name == kw::Super {
                    // Special case: `super` can print like `pub(super)`.
                    self.s.word("super");
                } else {
                    // Everything else requires `in` at present.
                    self.word_nbsp("in");
                    self.print_path(path, false);
                }
                self.word_nbsp(")");
            }
            hir::VisibilityKind::Inherited => ()
        }
    }

    pub fn print_defaultness(&mut self, defaultness: hir::Defaultness) {
        match defaultness {
            hir::Defaultness::Default { .. } => self.word_nbsp("default"),
            hir::Defaultness::Final => (),
        }
    }

    pub fn print_struct(&mut self,
                        struct_def: &hir::VariantData,
                        generics: &hir::Generics,
                        name: ast::Name,
                        span: syntax_pos::Span,
                        print_finalizer: bool)
                        {
        self.print_name(name);
        self.print_generic_params(&generics.params);
        match struct_def {
            hir::VariantData::Tuple(..) | hir::VariantData::Unit(..) => {
                if let hir::VariantData::Tuple(..) = struct_def {
                    self.popen();
                    self.commasep(Inconsistent, struct_def.fields(), |s, field| {
                        s.maybe_print_comment(field.span.lo());
                        s.print_outer_attributes(&field.attrs);
                        s.print_visibility(&field.vis);
                        s.print_type(&field.ty)
                    });
                    self.pclose();
                }
                self.print_where_clause(&generics.where_clause);
                if print_finalizer {
                    self.s.word(";");
                }
                self.end();
                self.end() // close the outer-box
            }
            hir::VariantData::Struct(..) => {
                self.print_where_clause(&generics.where_clause);
                self.nbsp();
                self.bopen();
                self.hardbreak_if_not_bol();

                for field in struct_def.fields() {
                    self.hardbreak_if_not_bol();
                    self.maybe_print_comment(field.span.lo());
                    self.print_outer_attributes(&field.attrs);
                    self.print_visibility(&field.vis);
                    self.print_ident(field.ident);
                    self.word_nbsp(":");
                    self.print_type(&field.ty);
                    self.s.word(",");
                }

                self.bclose(span)
            }
        }
    }

    pub fn print_variant(&mut self, v: &hir::Variant) {
        self.head("");
        let generics = hir::Generics::empty();
        self.print_struct(&v.data, &generics, v.ident.name, v.span, false);
        if let Some(ref d) = v.disr_expr {
            self.s.space();
            self.word_space("=");
            self.print_anon_const(d);
        }
    }
    pub fn print_method_sig(&mut self,
                            ident: ast::Ident,
                            m: &hir::FnSig,
                            generics: &hir::Generics,
                            vis: &hir::Visibility,
                            arg_names: &[ast::Ident],
                            body_id: Option<hir::BodyId>)
                            {
        self.print_fn(&m.decl,
                      m.header,
                      Some(ident.name),
                      generics,
                      vis,
                      arg_names,
                      body_id)
    }

    pub fn print_trait_item(&mut self, ti: &hir::TraitItem) {
        self.ann.pre(self, AnnNode::SubItem(ti.hir_id));
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(ti.span.lo());
        self.print_outer_attributes(&ti.attrs);
        match ti.kind {
            hir::TraitItemKind::Const(ref ty, default) => {
                let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                    node: hir::VisibilityKind::Inherited };
                self.print_associated_const(ti.ident, &ty, default, &vis);
            }
            hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref arg_names)) => {
                let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                    node: hir::VisibilityKind::Inherited };
                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, arg_names, None);
                self.s.word(";");
            }
            hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
                let vis = Spanned { span: syntax_pos::DUMMY_SP,
                                    node: hir::VisibilityKind::Inherited };
                self.head("");
                self.print_method_sig(ti.ident, sig, &ti.generics, &vis, &[], Some(body));
                self.nbsp();
                self.end(); // need to close a box
                self.end(); // need to close a box
                self.ann.nested(self, Nested::Body(body));
            }
            hir::TraitItemKind::Type(ref bounds, ref default) => {
                self.print_associated_type(ti.ident,
                                           Some(bounds),
                                           default.as_ref().map(|ty| &**ty));
            }
        }
        self.ann.post(self, AnnNode::SubItem(ti.hir_id))
    }

    pub fn print_impl_item(&mut self, ii: &hir::ImplItem) {
        self.ann.pre(self, AnnNode::SubItem(ii.hir_id));
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(ii.span.lo());
        self.print_outer_attributes(&ii.attrs);
        self.print_defaultness(ii.defaultness);

        match ii.kind {
            hir::ImplItemKind::Const(ref ty, expr) => {
                self.print_associated_const(ii.ident, &ty, Some(expr), &ii.vis);
            }
            hir::ImplItemKind::Method(ref sig, body) => {
                self.head("");
                self.print_method_sig(ii.ident, sig, &ii.generics, &ii.vis, &[], Some(body));
                self.nbsp();
                self.end(); // need to close a box
                self.end(); // need to close a box
                self.ann.nested(self, Nested::Body(body));
            }
            hir::ImplItemKind::TyAlias(ref ty) => {
                self.print_associated_type(ii.ident, None, Some(ty));
            }
            hir::ImplItemKind::OpaqueTy(ref bounds) => {
                self.word_space("type");
                self.print_ident(ii.ident);
                self.print_bounds("= impl", bounds);
                self.s.word(";");
            }
        }
        self.ann.post(self, AnnNode::SubItem(ii.hir_id))
    }

    pub fn print_local(
        &mut self,
        init: Option<&hir::Expr>,
        decl: impl Fn(&mut Self)
    ) {
        self.space_if_not_bol();
        self.ibox(INDENT_UNIT);
        self.word_nbsp("let");

        self.ibox(INDENT_UNIT);
        decl(self);
        self.end();

        if let Some(ref init) = init {
            self.nbsp();
            self.word_space("=");
            self.print_expr(&init);
        }
        self.end()
    }

    pub fn print_stmt(&mut self, st: &hir::Stmt) {
        self.maybe_print_comment(st.span.lo());
        match st.kind {
            hir::StmtKind::Local(ref loc) => {
                self.print_local(loc.init.as_deref(), |this| this.print_local_decl(&loc));
            }
            hir::StmtKind::Item(item) => {
                self.ann.nested(self, Nested::Item(item))
            }
            hir::StmtKind::Expr(ref expr) => {
                self.space_if_not_bol();
                self.print_expr(&expr);
            }
            hir::StmtKind::Semi(ref expr) => {
                self.space_if_not_bol();
                self.print_expr(&expr);
                self.s.word(";");
            }
        }
        if stmt_ends_with_semi(&st.kind) {
            self.s.word(";");
        }
        self.maybe_print_trailing_comment(st.span, None)
    }

    pub fn print_block(&mut self, blk: &hir::Block) {
        self.print_block_with_attrs(blk, &[])
    }

    pub fn print_block_unclosed(&mut self, blk: &hir::Block) {
        self.print_block_maybe_unclosed(blk, &[], false)
    }

    pub fn print_block_with_attrs(&mut self,
                                  blk: &hir::Block,
                                  attrs: &[ast::Attribute])
                                  {
        self.print_block_maybe_unclosed(blk, attrs, true)
    }

    pub fn print_block_maybe_unclosed(&mut self,
                                      blk: &hir::Block,
                                      attrs: &[ast::Attribute],
                                      close_box: bool)
                                      {
        match blk.rules {
            hir::UnsafeBlock(..) => self.word_space("unsafe"),
            hir::PushUnsafeBlock(..) => self.word_space("push_unsafe"),
            hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe"),
            hir::DefaultBlock => (),
        }
        self.maybe_print_comment(blk.span.lo());
        self.ann.pre(self, AnnNode::Block(blk));
        self.bopen();

        self.print_inner_attributes(attrs);

        for st in &blk.stmts {
            self.print_stmt(st);
        }
        if let Some(ref expr) = blk.expr {
            self.space_if_not_bol();
            self.print_expr(&expr);
            self.maybe_print_trailing_comment(expr.span, Some(blk.span.hi()));
        }
        self.bclose_maybe_open(blk.span, close_box);
        self.ann.post(self, AnnNode::Block(blk))
    }

    pub fn print_anon_const(&mut self, constant: &hir::AnonConst) {
        self.ann.nested(self, Nested::Body(constant.body))
    }

    fn print_call_post(&mut self, args: &[hir::Expr]) {
        self.popen();
        self.commasep_exprs(Inconsistent, args);
        self.pclose()
    }

    pub fn print_expr_maybe_paren(&mut self, expr: &hir::Expr, prec: i8) {
        let needs_par = expr.precedence().order() < prec;
        if needs_par {
            self.popen();
        }
        self.print_expr(expr);
        if needs_par {
            self.pclose();
        }
    }

    /// Print an expr using syntax that's acceptable in a condition position, such as the `cond` in
    /// `if cond { ... }`.
    pub fn print_expr_as_cond(&mut self, expr: &hir::Expr) {
        let needs_par = match expr.kind {
            // These cases need parens due to the parse error observed in #26461: `if return {}`
            // parses as the erroneous construct `if (return {})`, not `if (return) {}`.
            hir::ExprKind::Closure(..) |
            hir::ExprKind::Ret(..) |
            hir::ExprKind::Break(..) => true,

            _ => contains_exterior_struct_lit(expr),
        };

        if needs_par {
            self.popen();
        }
        self.print_expr(expr);
        if needs_par {
            self.pclose();
        }
    }

    fn print_expr_vec(&mut self, exprs: &[hir::Expr]) {
        self.ibox(INDENT_UNIT);
        self.s.word("[");
        self.commasep_exprs(Inconsistent, exprs);
        self.s.word("]");
        self.end()
    }

    fn print_expr_repeat(&mut self, element: &hir::Expr, count: &hir::AnonConst) {
        self.ibox(INDENT_UNIT);
        self.s.word("[");
        self.print_expr(element);
        self.word_space(";");
        self.print_anon_const(count);
        self.s.word("]");
        self.end()
    }

    fn print_expr_struct(&mut self,
                         qpath: &hir::QPath,
                         fields: &[hir::Field],
                         wth: &Option<P<hir::Expr>>)
                         {
        self.print_qpath(qpath, true);
        self.s.word("{");
        self.commasep_cmnt(Consistent,
                           &fields[..],
                           |s, field| {
                               s.ibox(INDENT_UNIT);
                               if !field.is_shorthand {
                                    s.print_ident(field.ident);
                                    s.word_space(":");
                               }
                               s.print_expr(&field.expr);
                               s.end()
                           },
                           |f| f.span);
        match *wth {
            Some(ref expr) => {
                self.ibox(INDENT_UNIT);
                if !fields.is_empty() {
                    self.s.word(",");
                    self.s.space();
                }
                self.s.word("..");
                self.print_expr(&expr);
                self.end();
            }
            _ => if !fields.is_empty() {
                self.s.word(",")
            },
        }
        self.s.word("}");
    }

    fn print_expr_tup(&mut self, exprs: &[hir::Expr]) {
        self.popen();
        self.commasep_exprs(Inconsistent, exprs);
        if exprs.len() == 1 {
            self.s.word(",");
        }
        self.pclose()
    }

    fn print_expr_call(&mut self, func: &hir::Expr, args: &[hir::Expr]) {
        let prec = match func.kind {
            hir::ExprKind::Field(..) => parser::PREC_FORCE_PAREN,
            _ => parser::PREC_POSTFIX,
        };

        self.print_expr_maybe_paren(func, prec);
        self.print_call_post(args)
    }

    fn print_expr_method_call(&mut self,
                              segment: &hir::PathSegment,
                              args: &[hir::Expr])
                              {
        let base_args = &args[1..];
        self.print_expr_maybe_paren(&args[0], parser::PREC_POSTFIX);
        self.s.word(".");
        self.print_ident(segment.ident);

        let generic_args = segment.generic_args();
        if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
            self.print_generic_args(generic_args, segment.infer_args, true);
        }

        self.print_call_post(base_args)
    }

    fn print_expr_binary(&mut self,
                         op: hir::BinOp,
                         lhs: &hir::Expr,
                         rhs: &hir::Expr)
                         {
        let assoc_op = bin_op_to_assoc_op(op.node);
        let prec = assoc_op.precedence() as i8;
        let fixity = assoc_op.fixity();

        let (left_prec, right_prec) = match fixity {
            Fixity::Left => (prec, prec + 1),
            Fixity::Right => (prec + 1, prec),
            Fixity::None => (prec + 1, prec + 1),
        };

        let left_prec = match (&lhs.kind, op.node) {
            // These cases need parens: `x as i32 < y` has the parser thinking that `i32 < y` is
            // the beginning of a path type. It starts trying to parse `x as (i32 < y ...` instead
            // of `(x as i32) < ...`. We need to convince it _not_ to do that.
            (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Lt) |
            (&hir::ExprKind::Cast { .. }, hir::BinOpKind::Shl) => parser::PREC_FORCE_PAREN,
            _ => left_prec,
        };

        self.print_expr_maybe_paren(lhs, left_prec);
        self.s.space();
        self.word_space(op.node.as_str());
        self.print_expr_maybe_paren(rhs, right_prec)
    }

    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr) {
        self.s.word(op.as_str());
        self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
    }

    fn print_expr_addr_of(&mut self,
                          kind: hir::BorrowKind,
                          mutability: hir::Mutability,
                          expr: &hir::Expr)
    {
        self.s.word("&");
        match kind {
            hir::BorrowKind::Ref => self.print_mutability(mutability, false),
            hir::BorrowKind::Raw => {
                self.word_nbsp("raw");
                self.print_mutability(mutability, true);
            }
        }
        self.print_expr_maybe_paren(expr, parser::PREC_PREFIX)
    }

    fn print_literal(&mut self, lit: &hir::Lit) {
        self.maybe_print_comment(lit.span.lo());
        self.word(lit.node.to_lit_token().to_string())
    }

    pub fn print_expr(&mut self, expr: &hir::Expr) {
        self.maybe_print_comment(expr.span.lo());
        self.print_outer_attributes(&expr.attrs);
        self.ibox(INDENT_UNIT);
        self.ann.pre(self, AnnNode::Expr(expr));
        match expr.kind {
            hir::ExprKind::Box(ref expr) => {
                self.word_space("box");
                self.print_expr_maybe_paren(expr, parser::PREC_PREFIX);
            }
            hir::ExprKind::Array(ref exprs) => {
                self.print_expr_vec(exprs);
            }
            hir::ExprKind::Repeat(ref element, ref count) => {
                self.print_expr_repeat(&element, count);
            }
            hir::ExprKind::Struct(ref qpath, ref fields, ref wth) => {
                self.print_expr_struct(qpath, &fields[..], wth);
            }
            hir::ExprKind::Tup(ref exprs) => {
                self.print_expr_tup(exprs);
            }
            hir::ExprKind::Call(ref func, ref args) => {
                self.print_expr_call(&func, args);
            }
            hir::ExprKind::MethodCall(ref segment, _, ref args) => {
                self.print_expr_method_call(segment, args);
            }
            hir::ExprKind::Binary(op, ref lhs, ref rhs) => {
                self.print_expr_binary(op, &lhs, &rhs);
            }
            hir::ExprKind::Unary(op, ref expr) => {
                self.print_expr_unary(op, &expr);
            }
            hir::ExprKind::AddrOf(k, m, ref expr) => {
                self.print_expr_addr_of(k, m, &expr);
            }
            hir::ExprKind::Lit(ref lit) => {
                self.print_literal(&lit);
            }
            hir::ExprKind::Cast(ref expr, ref ty) => {
                let prec = AssocOp::As.precedence() as i8;
                self.print_expr_maybe_paren(&expr, prec);
                self.s.space();
                self.word_space("as");
                self.print_type(&ty);
            }
            hir::ExprKind::Type(ref expr, ref ty) => {
                let prec = AssocOp::Colon.precedence() as i8;
                self.print_expr_maybe_paren(&expr, prec);
                self.word_space(":");
                self.print_type(&ty);
            }
            hir::ExprKind::DropTemps(ref init) => {
                // Print `{`:
                self.cbox(INDENT_UNIT);
                self.ibox(0);
                self.bopen();

                // Print `let _t = $init;`:
                let temp = ast::Ident::from_str("_t");
                self.print_local(Some(init), |this| this.print_ident(temp));
                self.s.word(";");

                // Print `_t`:
                self.space_if_not_bol();
                self.print_ident(temp);

                // Print `}`:
                self.bclose_maybe_open(expr.span, true);
            }
            hir::ExprKind::Loop(ref blk, opt_label, _) => {
                if let Some(label) = opt_label {
                    self.print_ident(label.ident);
                    self.word_space(":");
                }
                self.head("loop");
                self.s.space();
                self.print_block(&blk);
            }
            hir::ExprKind::Match(ref expr, ref arms, _) => {
                self.cbox(INDENT_UNIT);
                self.ibox(INDENT_UNIT);
                self.word_nbsp("match");
                self.print_expr_as_cond(&expr);
                self.s.space();
                self.bopen();
                for arm in arms {
                    self.print_arm(arm);
                }
                self.bclose(expr.span);
            }
            hir::ExprKind::Closure(capture_clause, ref decl, body, _fn_decl_span, _gen) => {
                self.print_capture_clause(capture_clause);

                self.print_closure_params(&decl, body);
                self.s.space();

                // This is a bare expression.
                self.ann.nested(self, Nested::Body(body));
                self.end(); // need to close a box

                // A box will be closed by `print_expr`, but we didn't want an overall
                // wrapper so we closed the corresponding opening. so create an
                // empty box to satisfy the close.
                self.ibox(0);
            }
            hir::ExprKind::Block(ref blk, opt_label) => {
                if let Some(label) = opt_label {
                    self.print_ident(label.ident);
                    self.word_space(":");
                }
                // containing cbox, will be closed by print-block at `}`
                self.cbox(INDENT_UNIT);
                // head-box, will be closed by print-block after `{`
                self.ibox(0);
                self.print_block(&blk);
            }
            hir::ExprKind::Assign(ref lhs, ref rhs) => {
                let prec = AssocOp::Assign.precedence() as i8;
                self.print_expr_maybe_paren(&lhs, prec + 1);
                self.s.space();
                self.word_space("=");
                self.print_expr_maybe_paren(&rhs, prec);
            }
            hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => {
                let prec = AssocOp::Assign.precedence() as i8;
                self.print_expr_maybe_paren(&lhs, prec + 1);
                self.s.space();
                self.s.word(op.node.as_str());
                self.word_space("=");
                self.print_expr_maybe_paren(&rhs, prec);
            }
            hir::ExprKind::Field(ref expr, ident) => {
                self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX);
                self.s.word(".");
                self.print_ident(ident);
            }
            hir::ExprKind::Index(ref expr, ref index) => {
                self.print_expr_maybe_paren(&expr, parser::PREC_POSTFIX);
                self.s.word("[");
                self.print_expr(&index);
                self.s.word("]");
            }
            hir::ExprKind::Path(ref qpath) => {
                self.print_qpath(qpath, true)
            }
            hir::ExprKind::Break(destination, ref opt_expr) => {
                self.s.word("break");
                self.s.space();
                if let Some(label) = destination.label {
                    self.print_ident(label.ident);
                    self.s.space();
                }
                if let Some(ref expr) = *opt_expr {
                    self.print_expr_maybe_paren(expr, parser::PREC_JUMP);
                    self.s.space();
                }
            }
            hir::ExprKind::Continue(destination) => {
                self.s.word("continue");
                self.s.space();
                if let Some(label) = destination.label {
                    self.print_ident(label.ident);
                    self.s.space()
                }
            }
            hir::ExprKind::Ret(ref result) => {
                self.s.word("return");
                if let Some(ref expr) = *result {
                    self.s.word(" ");
                    self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
                }
            }
            hir::ExprKind::InlineAsm(ref a) => {
                let i = &a.inner;
                self.s.word("asm!");
                self.popen();
                self.print_string(&i.asm.as_str(), i.asm_str_style);
                self.word_space(":");

                let mut out_idx = 0;
                self.commasep(Inconsistent, &i.outputs, |s, out| {
                    let constraint = out.constraint.as_str();
                    let mut ch = constraint.chars();
                    match ch.next() {
                        Some('=') if out.is_rw => {
                            s.print_string(&format!("+{}", ch.as_str()),
                                           ast::StrStyle::Cooked)
                        }
                        _ => s.print_string(&constraint, ast::StrStyle::Cooked),
                    }
                    s.popen();
                    s.print_expr(&a.outputs_exprs[out_idx]);
                    s.pclose();
                    out_idx += 1;
                });
                self.s.space();
                self.word_space(":");

                let mut in_idx = 0;
                self.commasep(Inconsistent, &i.inputs, |s, co| {
                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
                    s.popen();
                    s.print_expr(&a.inputs_exprs[in_idx]);
                    s.pclose();
                    in_idx += 1;
                });
                self.s.space();
                self.word_space(":");

                self.commasep(Inconsistent, &i.clobbers, |s, co| {
                    s.print_string(&co.as_str(), ast::StrStyle::Cooked);
                });

                let mut options = vec![];
                if i.volatile {
                    options.push("volatile");
                }
                if i.alignstack {
                    options.push("alignstack");
                }
                if i.dialect == ast::AsmDialect::Intel {
                    options.push("intel");
                }

                if !options.is_empty() {
                    self.s.space();
                    self.word_space(":");
                    self.commasep(Inconsistent, &options, |s, &co| {
                        s.print_string(co, ast::StrStyle::Cooked);
                    });
                }

                self.pclose();
            }
            hir::ExprKind::Yield(ref expr, _) => {
                self.word_space("yield");
                self.print_expr_maybe_paren(&expr, parser::PREC_JUMP);
            }
            hir::ExprKind::Err => {
                self.popen();
                self.s.word("/*ERROR*/");
                self.pclose();
            }
        }
        self.ann.post(self, AnnNode::Expr(expr));
        self.end()
    }

    pub fn print_local_decl(&mut self, loc: &hir::Local) {
        self.print_pat(&loc.pat);
        if let Some(ref ty) = loc.ty {
            self.word_space(":");
            self.print_type(&ty);
        }
    }

    pub fn print_usize(&mut self, i: usize) {
        self.s.word(i.to_string())
    }

    pub fn print_name(&mut self, name: ast::Name) {
        self.print_ident(ast::Ident::with_dummy_span(name))
    }

    pub fn print_for_decl(&mut self, loc: &hir::Local, coll: &hir::Expr) {
        self.print_local_decl(loc);
        self.s.space();
        self.word_space("in");
        self.print_expr(coll)
    }

    pub fn print_path(&mut self,
                      path: &hir::Path,
                      colons_before_params: bool)
                      {
        self.maybe_print_comment(path.span.lo());

        for (i, segment) in path.segments.iter().enumerate() {
            if i > 0 {
                self.s.word("::")
            }
            if segment.ident.name != kw::PathRoot {
                self.print_ident(segment.ident);
                self.print_generic_args(segment.generic_args(), segment.infer_args,
                                        colons_before_params);
            }
        }
    }

    pub fn print_path_segment(&mut self, segment: &hir::PathSegment) {
        if segment.ident.name != kw::PathRoot {
            self.print_ident(segment.ident);
            self.print_generic_args(segment.generic_args(), segment.infer_args, false);
        }
    }

    pub fn print_qpath(&mut self,
                       qpath: &hir::QPath,
                       colons_before_params: bool)
                       {
        match *qpath {
            hir::QPath::Resolved(None, ref path) => {
                self.print_path(path, colons_before_params)
            }
            hir::QPath::Resolved(Some(ref qself), ref path) => {
                self.s.word("<");
                self.print_type(qself);
                self.s.space();
                self.word_space("as");

                for (i, segment) in path.segments[..path.segments.len() - 1].iter().enumerate() {
                    if i > 0 {
                        self.s.word("::")
                    }
                    if segment.ident.name != kw::PathRoot {
                        self.print_ident(segment.ident);
                        self.print_generic_args(segment.generic_args(),
                                                segment.infer_args,
                                                colons_before_params);
                    }
                }

                self.s.word(">");
                self.s.word("::");
                let item_segment = path.segments.last().unwrap();
                self.print_ident(item_segment.ident);
                self.print_generic_args(item_segment.generic_args(),
                                        item_segment.infer_args,
                                        colons_before_params)
            }
            hir::QPath::TypeRelative(ref qself, ref item_segment) => {
                // If we've got a compound-qualified-path, let's push an additional pair of angle
                // brackets, so that we pretty-print `<<A::B>::C>` as `<A::B>::C`, instead of just
                // `A::B::C` (since the latter could be ambiguous to the user)
                if let hir::TyKind::Path(hir::QPath::Resolved(None, _)) = &qself.kind {
                    self.print_type(qself);
                } else {
                    self.s.word("<");
                    self.print_type(qself);
                    self.s.word(">");
                }

                self.s.word("::");
                self.print_ident(item_segment.ident);
                self.print_generic_args(item_segment.generic_args(),
                                        item_segment.infer_args,
                                        colons_before_params)
            }
        }
    }

    fn print_generic_args(&mut self,
                             generic_args: &hir::GenericArgs,
                             infer_args: bool,
                             colons_before_params: bool)
                             {
        if generic_args.parenthesized {
            self.s.word("(");
            self.commasep(Inconsistent, generic_args.inputs(), |s, ty| s.print_type(&ty));
            self.s.word(")");

            self.space_if_not_bol();
            self.word_space("->");
            self.print_type(generic_args.bindings[0].ty());
        } else {
            let start = if colons_before_params { "::<" } else { "<" };
            let empty = Cell::new(true);
            let start_or_comma = |this: &mut Self| {
                if empty.get() {
                    empty.set(false);
                    this.s.word(start)
                } else {
                    this.word_space(",")
                }
            };

            let mut nonelided_generic_args: bool = false;
            let elide_lifetimes = generic_args.args.iter().all(|arg| match arg {
                GenericArg::Lifetime(lt) => lt.is_elided(),
                _ => {
                    nonelided_generic_args = true;
                    true
                }
            });

            if nonelided_generic_args {
                start_or_comma(self);
                self.commasep(Inconsistent, &generic_args.args, |s, generic_arg| {
                    match generic_arg {
                        GenericArg::Lifetime(lt) if !elide_lifetimes => s.print_lifetime(lt),
                        GenericArg::Lifetime(_) => {},
                        GenericArg::Type(ty) => s.print_type(ty),
                        GenericArg::Const(ct) => s.print_anon_const(&ct.value),
                    }
                });
            }

            // FIXME(eddyb): this would leak into error messages (e.g.,
            // "non-exhaustive patterns: `Some::<..>(_)` not covered").
            if infer_args && false {
                start_or_comma(self);
                self.s.word("..");
            }

            for binding in generic_args.bindings.iter() {
                start_or_comma(self);
                self.print_ident(binding.ident);
                self.s.space();
                match generic_args.bindings[0].kind {
                    hir::TypeBindingKind::Equality { ref ty } => {
                        self.word_space("=");
                        self.print_type(ty);
                    }
                    hir::TypeBindingKind::Constraint { ref bounds } => {
                        self.print_bounds(":", bounds);
                    }
                }
            }

            if !empty.get() {
                self.s.word(">")
            }
        }
    }

    pub fn print_pat(&mut self, pat: &hir::Pat) {
        self.maybe_print_comment(pat.span.lo());
        self.ann.pre(self, AnnNode::Pat(pat));
        // Pat isn't normalized, but the beauty of it
        // is that it doesn't matter
        match pat.kind {
            PatKind::Wild => self.s.word("_"),
            PatKind::Binding(binding_mode, _, ident, ref sub) => {
                match binding_mode {
                    hir::BindingAnnotation::Ref => {
                        self.word_nbsp("ref");
                        self.print_mutability(hir::Mutability::Immutable, false);
                    }
                    hir::BindingAnnotation::RefMut => {
                        self.word_nbsp("ref");
                        self.print_mutability(hir::Mutability::Mutable, false);
                    }
                    hir::BindingAnnotation::Unannotated => {}
                    hir::BindingAnnotation::Mutable => {
                        self.word_nbsp("mut");
                    }
                }
                self.print_ident(ident);
                if let Some(ref p) = *sub {
                    self.s.word("@");
                    self.print_pat(&p);
                }
            }
            PatKind::TupleStruct(ref qpath, ref elts, ddpos) => {
                self.print_qpath(qpath, true);
                self.popen();
                if let Some(ddpos) = ddpos {
                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
                    if ddpos != 0 {
                        self.word_space(",");
                    }
                    self.s.word("..");
                    if ddpos != elts.len() {
                        self.s.word(",");
                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
                    }
                } else {
                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p));
                }
                self.pclose();
            }
            PatKind::Path(ref qpath) => {
                self.print_qpath(qpath, true);
            }
            PatKind::Struct(ref qpath, ref fields, etc) => {
                self.print_qpath(qpath, true);
                self.nbsp();
                self.word_space("{");
                self.commasep_cmnt(Consistent,
                                   &fields[..],
                                   |s, f| {
                                       s.cbox(INDENT_UNIT);
                                       if !f.is_shorthand {
                                           s.print_ident(f.ident);
                                           s.word_nbsp(":");
                                       }
                                       s.print_pat(&f.pat);
                                       s.end()
                                   },
                                   |f| f.pat.span);
                if etc {
                    if !fields.is_empty() {
                        self.word_space(",");
                    }
                    self.s.word("..");
                }
                self.s.space();
                self.s.word("}");
            }
            PatKind::Or(ref pats) => {
                self.strsep("|", true, Inconsistent, &pats[..], |s, p| s.print_pat(&p));
            }
            PatKind::Tuple(ref elts, ddpos) => {
                self.popen();
                if let Some(ddpos) = ddpos {
                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(&p));
                    if ddpos != 0 {
                        self.word_space(",");
                    }
                    self.s.word("..");
                    if ddpos != elts.len() {
                        self.s.word(",");
                        self.commasep(Inconsistent, &elts[ddpos..], |s, p| s.print_pat(&p));
                    }
                } else {
                    self.commasep(Inconsistent, &elts[..], |s, p| s.print_pat(&p));
                    if elts.len() == 1 {
                        self.s.word(",");
                    }
                }
                self.pclose();
            }
            PatKind::Box(ref inner) => {
                let is_range_inner = match inner.kind {
                    PatKind::Range(..) => true,
                    _ => false,
                };
                self.s.word("box ");
                if is_range_inner {
                    self.popen();
                }
                self.print_pat(&inner);
                if is_range_inner {
                    self.pclose();
                }
            }
            PatKind::Ref(ref inner, mutbl) => {
                let is_range_inner = match inner.kind {
                    PatKind::Range(..) => true,
                    _ => false,
                };
                self.s.word("&");
                self.s.word(mutbl.prefix_str());
                if is_range_inner {
                    self.popen();
                }
                self.print_pat(&inner);
                if is_range_inner {
                    self.pclose();
                }
            }
            PatKind::Lit(ref e) => self.print_expr(&e),
            PatKind::Range(ref begin, ref end, ref end_kind) => {
                self.print_expr(&begin);
                self.s.space();
                match *end_kind {
                    RangeEnd::Included => self.s.word("..."),
                    RangeEnd::Excluded => self.s.word(".."),
                }
                self.print_expr(&end);
            }
            PatKind::Slice(ref before, ref slice, ref after) => {
                self.s.word("[");
                self.commasep(Inconsistent, &before[..], |s, p| s.print_pat(&p));
                if let Some(ref p) = *slice {
                    if !before.is_empty() {
                        self.word_space(",");
                    }
                    if let PatKind::Wild = p.kind {
                        // Print nothing.
                    } else {
                        self.print_pat(&p);
                    }
                    self.s.word("..");
                    if !after.is_empty() {
                        self.word_space(",");
                    }
                }
                self.commasep(Inconsistent, &after[..], |s, p| s.print_pat(&p));
                self.s.word("]");
            }
        }
        self.ann.post(self, AnnNode::Pat(pat))
    }

    pub fn print_param(&mut self, arg: &hir::Param) {
        self.print_outer_attributes(&arg.attrs);
        self.print_pat(&arg.pat);
    }

    pub fn print_arm(&mut self, arm: &hir::Arm) {
        // I have no idea why this check is necessary, but here it
        // is :(
        if arm.attrs.is_empty() {
            self.s.space();
        }
        self.cbox(INDENT_UNIT);
        self.ann.pre(self, AnnNode::Arm(arm));
        self.ibox(0);
        self.print_outer_attributes(&arm.attrs);
        self.print_pat(&arm.pat);
        self.s.space();
        if let Some(ref g) = arm.guard {
            match g {
                hir::Guard::If(e) => {
                    self.word_space("if");
                    self.print_expr(&e);
                    self.s.space();
                }
            }
        }
        self.word_space("=>");

        match arm.body.kind {
            hir::ExprKind::Block(ref blk, opt_label) => {
                if let Some(label) = opt_label {
                    self.print_ident(label.ident);
                    self.word_space(":");
                }
                // the block will close the pattern's ibox
                self.print_block_unclosed(&blk);

                // If it is a user-provided unsafe block, print a comma after it
                if let hir::UnsafeBlock(hir::UserProvided) = blk.rules {
                    self.s.word(",");
                }
            }
            _ => {
                self.end(); // close the ibox for the pattern
                self.print_expr(&arm.body);
                self.s.word(",");
            }
        }
        self.ann.post(self, AnnNode::Arm(arm));
        self.end() // close enclosing cbox
    }

    pub fn print_fn(&mut self,
                    decl: &hir::FnDecl,
                    header: hir::FnHeader,
                    name: Option<ast::Name>,
                    generics: &hir::Generics,
                    vis: &hir::Visibility,
                    arg_names: &[ast::Ident],
                    body_id: Option<hir::BodyId>)
                    {
        self.print_fn_header_info(header, vis);

        if let Some(name) = name {
            self.nbsp();
            self.print_name(name);
        }
        self.print_generic_params(&generics.params);

        self.popen();
        let mut i = 0;
        // Make sure we aren't supplied *both* `arg_names` and `body_id`.
        assert!(arg_names.is_empty() || body_id.is_none());
        self.commasep(Inconsistent, &decl.inputs, |s, ty| {
            s.ibox(INDENT_UNIT);
            if let Some(arg_name) = arg_names.get(i) {
                s.s.word(arg_name.to_string());
                s.s.word(":");
                s.s.space();
            } else if let Some(body_id) = body_id {
                s.ann.nested(s, Nested::BodyParamPat(body_id, i));
                s.s.word(":");
                s.s.space();
            }
            i += 1;
            s.print_type(ty);
            s.end()
        });
        if decl.c_variadic {
            self.s.word(", ...");
        }
        self.pclose();

        self.print_fn_output(decl);
        self.print_where_clause(&generics.where_clause)
    }

    fn print_closure_params(&mut self, decl: &hir::FnDecl, body_id: hir::BodyId) {
        self.s.word("|");
        let mut i = 0;
        self.commasep(Inconsistent, &decl.inputs, |s, ty| {
            s.ibox(INDENT_UNIT);

            s.ann.nested(s, Nested::BodyParamPat(body_id, i));
            i += 1;

            if let hir::TyKind::Infer = ty.kind {
                // Print nothing.
            } else {
                s.s.word(":");
                s.s.space();
                s.print_type(ty);
            }
            s.end();
        });
        self.s.word("|");

        if let hir::DefaultReturn(..) = decl.output {
            return;
        }

        self.space_if_not_bol();
        self.word_space("->");
        match decl.output {
            hir::Return(ref ty) => {
                self.print_type(&ty);
                self.maybe_print_comment(ty.span.lo())
            }
            hir::DefaultReturn(..) => unreachable!(),
        }
    }

    pub fn print_capture_clause(&mut self, capture_clause: hir::CaptureBy) {
        match capture_clause {
            hir::CaptureBy::Value => self.word_space("move"),
            hir::CaptureBy::Ref => {},
        }
    }

    pub fn print_bounds<'b>(
        &mut self,
        prefix: &'static str,
        bounds: impl IntoIterator<Item = &'b hir::GenericBound>,
    ) {
        let mut first = true;
        for bound in bounds {
            if first {
                self.s.word(prefix);
            }
            if !(first && prefix.is_empty()) {
                self.nbsp();
            }
            if first {
                first = false;
            } else {
                self.word_space("+");
            }

            match bound {
                GenericBound::Trait(tref, modifier) => {
                    if modifier == &TraitBoundModifier::Maybe {
                        self.s.word("?");
                    }
                    self.print_poly_trait_ref(tref);
                }
                GenericBound::Outlives(lt) => {
                    self.print_lifetime(lt);
                }
            }
        }
    }

    pub fn print_generic_params(&mut self, generic_params: &[GenericParam]) {
        if !generic_params.is_empty() {
            self.s.word("<");

            self.commasep(Inconsistent, generic_params, |s, param| {
                s.print_generic_param(param)
            });

            self.s.word(">");
        }
    }

    pub fn print_generic_param(&mut self, param: &GenericParam) {
        if let GenericParamKind::Const { .. } = param.kind {
            self.word_space("const");
        }

        self.print_ident(param.name.ident());

        match param.kind {
            GenericParamKind::Lifetime { .. } => {
                let mut sep = ":";
                for bound in &param.bounds {
                    match bound {
                        GenericBound::Outlives(lt) => {
                            self.s.word(sep);
                            self.print_lifetime(lt);
                            sep = "+";
                        }
                        _ => bug!(),
                    }
                }
            }
            GenericParamKind::Type { ref default, .. } => {
                self.print_bounds(":", &param.bounds);
                match default {
                    Some(default) => {
                        self.s.space();
                        self.word_space("=");
                        self.print_type(&default)
                    }
                    _ => {}
                }
            }
            GenericParamKind::Const { ref ty } => {
                self.word_space(":");
                self.print_type(ty)
            }
        }
    }

    pub fn print_lifetime(&mut self, lifetime: &hir::Lifetime) {
        self.print_ident(lifetime.name.ident())
    }

    pub fn print_where_clause(&mut self, where_clause: &hir::WhereClause) {
        if where_clause.predicates.is_empty() {
            return;
        }

        self.s.space();
        self.word_space("where");

        for (i, predicate) in where_clause.predicates.iter().enumerate() {
            if i != 0 {
                self.word_space(",");
            }

            match predicate {
                &hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                    ref bound_generic_params,
                    ref bounded_ty,
                    ref bounds,
                    ..
                }) => {
                    self.print_formal_generic_params(bound_generic_params);
                    self.print_type(&bounded_ty);
                    self.print_bounds(":", bounds);
                }
                &hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate{ref lifetime,
                                                                                ref bounds,
                                                                                ..}) => {
                    self.print_lifetime(lifetime);
                    self.s.word(":");

                    for (i, bound) in bounds.iter().enumerate() {
                        match bound {
                            GenericBound::Outlives(lt) => {
                                self.print_lifetime(lt);
                            }
                            _ => bug!(),
                        }

                        if i != 0 {
                            self.s.word(":");
                        }
                    }
                }
                &hir::WherePredicate::EqPredicate(hir::WhereEqPredicate{ref lhs_ty,
                                                                        ref rhs_ty,
                                                                        ..}) => {
                    self.print_type(lhs_ty);
                    self.s.space();
                    self.word_space("=");
                    self.print_type(rhs_ty);
                }
            }
        }
    }

    pub fn print_mutability(&mut self, mutbl: hir::Mutability, print_const: bool) {
        match mutbl {
            hir::Mutability::Mutable => self.word_nbsp("mut"),
            hir::Mutability::Immutable => if print_const { self.word_nbsp("const") },
        }
    }

    pub fn print_mt(&mut self, mt: &hir::MutTy, print_const: bool) {
        self.print_mutability(mt.mutbl, print_const);
        self.print_type(&mt.ty)
    }

    pub fn print_fn_output(&mut self, decl: &hir::FnDecl) {
        if let hir::DefaultReturn(..) = decl.output {
            return;
        }

        self.space_if_not_bol();
        self.ibox(INDENT_UNIT);
        self.word_space("->");
        match decl.output {
            hir::DefaultReturn(..) => unreachable!(),
            hir::Return(ref ty) => self.print_type(&ty),
        }
        self.end();

        match decl.output {
            hir::Return(ref output) => self.maybe_print_comment(output.span.lo()),
            _ => {},
        }
    }

    pub fn print_ty_fn(&mut self,
                       abi: Abi,
                       unsafety: hir::Unsafety,
                       decl: &hir::FnDecl,
                       name: Option<ast::Name>,
                       generic_params: &[hir::GenericParam],
                       arg_names: &[ast::Ident])
                       {
        self.ibox(INDENT_UNIT);
        if !generic_params.is_empty() {
            self.s.word("for");
            self.print_generic_params(generic_params);
        }
        let generics = hir::Generics {
            params: hir::HirVec::new(),
            where_clause: hir::WhereClause {
                predicates: hir::HirVec::new(),
                span: syntax_pos::DUMMY_SP,
            },
            span: syntax_pos::DUMMY_SP,
        };
        self.print_fn(decl,
                      hir::FnHeader {
                          unsafety,
                          abi,
                          constness: hir::Constness::NotConst,
                          asyncness: hir::IsAsync::NotAsync,
                      },
                      name,
                      &generics,
                      &Spanned { span: syntax_pos::DUMMY_SP,
                                 node: hir::VisibilityKind::Inherited },
                      arg_names,
                      None);
        self.end();
    }

    pub fn maybe_print_trailing_comment(&mut self,
                                        span: syntax_pos::Span,
                                        next_pos: Option<BytePos>)
                                        {
        if let Some(cmnts) = self.comments() {
            if let Some(cmnt) = cmnts.trailing_comment(span, next_pos) {
                self.print_comment(&cmnt);
            }
        }
    }

    pub fn print_remaining_comments(&mut self) {
        // If there aren't any remaining comments, then we need to manually
        // make sure there is a line break at the end.
        if self.next_comment().is_none() {
            self.s.hardbreak();
        }
        while let Some(ref cmnt) = self.next_comment() {
            self.print_comment(cmnt)
        }
    }

    pub fn print_opt_abi_and_extern_if_nondefault(&mut self,
                                                  opt_abi: Option<Abi>)
                                                  {
        match opt_abi {
            Some(Abi::Rust) => {},
            Some(abi) => {
                self.word_nbsp("extern");
                self.word_nbsp(abi.to_string())
            }
            None => {},
        }
    }

    pub fn print_extern_opt_abi(&mut self, opt_abi: Option<Abi>) {
        match opt_abi {
            Some(abi) => {
                self.word_nbsp("extern");
                self.word_nbsp(abi.to_string())
            }
            None => {},
        }
    }

    pub fn print_fn_header_info(&mut self,
                                header: hir::FnHeader,
                                vis: &hir::Visibility)
                                {
        self.s.word(visibility_qualified(vis, ""));

        match header.constness {
            hir::Constness::NotConst => {}
            hir::Constness::Const => self.word_nbsp("const"),
        }

        match header.asyncness {
            hir::IsAsync::NotAsync => {}
            hir::IsAsync::Async => self.word_nbsp("async"),
        }

        self.print_unsafety(header.unsafety);

        if header.abi != Abi::Rust {
            self.word_nbsp("extern");
            self.word_nbsp(header.abi.to_string());
        }

        self.s.word("fn")
    }

    pub fn print_unsafety(&mut self, s: hir::Unsafety) {
        match s {
            hir::Unsafety::Normal => {}
            hir::Unsafety::Unsafe => self.word_nbsp("unsafe"),
        }
    }

    pub fn print_is_auto(&mut self, s: hir::IsAuto) {
        match s {
            hir::IsAuto::Yes => self.word_nbsp("auto"),
            hir::IsAuto::No => {},
        }
    }
}

/// Does this expression require a semicolon to be treated
/// as a statement? The negation of this: 'can this expression
/// be used as a statement without a semicolon' -- is used
/// as an early-bail-out in the parser so that, for instance,
///     if true {...} else {...}
///      |x| 5
/// isn't parsed as (if true {...} else {...} | x) | 5
//
// Duplicated from `parse::classify`, but adapted for the HIR.
fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool {
    match e.kind {
        hir::ExprKind::Match(..) |
        hir::ExprKind::Block(..) |
        hir::ExprKind::Loop(..) => false,
        _ => true,
    }
}

/// This statement requires a semicolon after it.
/// note that in one case (stmt_semi), we've already
/// seen the semicolon, and thus don't need another.
fn stmt_ends_with_semi(stmt: &hir::StmtKind) -> bool {
    match *stmt {
        hir::StmtKind::Local(_) => true,
        hir::StmtKind::Item(_) => false,
        hir::StmtKind::Expr(ref e) => expr_requires_semi_to_be_stmt(&e),
        hir::StmtKind::Semi(..) => false,
    }
}

fn bin_op_to_assoc_op(op: hir::BinOpKind) -> AssocOp {
    use crate::hir::BinOpKind::*;
    match op {
        Add => AssocOp::Add,
        Sub => AssocOp::Subtract,
        Mul => AssocOp::Multiply,
        Div => AssocOp::Divide,
        Rem => AssocOp::Modulus,

        And => AssocOp::LAnd,
        Or => AssocOp::LOr,

        BitXor => AssocOp::BitXor,
        BitAnd => AssocOp::BitAnd,
        BitOr => AssocOp::BitOr,
        Shl => AssocOp::ShiftLeft,
        Shr => AssocOp::ShiftRight,

        Eq => AssocOp::Equal,
        Lt => AssocOp::Less,
        Le => AssocOp::LessEqual,
        Ne => AssocOp::NotEqual,
        Ge => AssocOp::GreaterEqual,
        Gt => AssocOp::Greater,
    }
}

/// Expressions that syntactically contain an "exterior" struct literal, i.e., not surrounded by any
/// parens or other delimiters, e.g., `X { y: 1 }`, `X { y: 1 }.method()`, `foo == X { y: 1 }` and
/// `X { y: 1 } == foo` all do, but `(X { y: 1 }) == foo` does not.
fn contains_exterior_struct_lit(value: &hir::Expr) -> bool {
    match value.kind {
        hir::ExprKind::Struct(..) => true,

        hir::ExprKind::Assign(ref lhs, ref rhs) |
        hir::ExprKind::AssignOp(_, ref lhs, ref rhs) |
        hir::ExprKind::Binary(_, ref lhs, ref rhs) => {
            // `X { y: 1 } + X { y: 2 }`
            contains_exterior_struct_lit(&lhs) || contains_exterior_struct_lit(&rhs)
        }
        hir::ExprKind::Unary(_, ref x) |
        hir::ExprKind::Cast(ref x, _) |
        hir::ExprKind::Type(ref x, _) |
        hir::ExprKind::Field(ref x, _) |
        hir::ExprKind::Index(ref x, _) => {
            // `&X { y: 1 }, X { y: 1 }.y`
            contains_exterior_struct_lit(&x)
        }

        hir::ExprKind::MethodCall(.., ref exprs) => {
            // `X { y: 1 }.bar(...)`
            contains_exterior_struct_lit(&exprs[0])
        }

        _ => false,
    }
}
