//! HIR pretty-printing is layered on top of AST pretty-printing. A number of
//! the definitions in this file have equivalents in `rustc_ast_pretty`.

// tidy-alphabetical-start
#![recursion_limit = "256"]
// tidy-alphabetical-end

use std::cell::Cell;
use std::vec;

use rustc_abi::ExternAbi;
use rustc_ast::util::parser::{self, ExprPrecedence, Fixity};
use rustc_ast::{DUMMY_NODE_ID, DelimArgs};
use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
use rustc_ast_pretty::pp::{self, BoxMarker, Breaks};
use rustc_ast_pretty::pprust::state::MacHeader;
use rustc_ast_pretty::pprust::{Comments, PrintState};
use rustc_hir::attrs::{AttributeKind, PrintAttribute};
use rustc_hir::{
    BindingMode, ByRef, ConstArgKind, GenericArg, GenericBound, GenericParam, GenericParamKind,
    HirId, ImplicitSelfKind, LifetimeParamKind, Node, PatKind, PreciseCapturingArg, RangeEnd, Term,
    TyPatKind,
};
use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, Ident, Span, Symbol, kw, sym};
use {rustc_ast as ast, rustc_hir as hir};

pub fn id_to_string(cx: &dyn rustc_hir::intravisit::HirTyCtxt<'_>, hir_id: HirId) -> String {
    to_string(&cx, |s| s.print_node(cx.hir_node(hir_id)))
}

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

pub enum Nested {
    Item(hir::ItemId),
    TraitItem(hir::TraitItemId),
    ImplItem(hir::ImplItemId),
    ForeignItem(hir::ForeignItemId),
    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<'_>) {}
}

impl PpAnn for &dyn rustc_hir::intravisit::HirTyCtxt<'_> {
    fn nested(&self, state: &mut State<'_>, nested: Nested) {
        match nested {
            Nested::Item(id) => state.print_item(self.hir_item(id)),
            Nested::TraitItem(id) => state.print_trait_item(self.hir_trait_item(id)),
            Nested::ImplItem(id) => state.print_impl_item(self.hir_impl_item(id)),
            Nested::ForeignItem(id) => state.print_foreign_item(self.hir_foreign_item(id)),
            Nested::Body(id) => state.print_expr(self.hir_body(id).value),
            Nested::BodyParamPat(id, i) => state.print_pat(self.hir_body(id).params[i].pat),
        }
    }
}

pub struct State<'a> {
    pub s: pp::Printer,
    comments: Option<Comments<'a>>,
    attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute],
    ann: &'a (dyn PpAnn + 'a),
}

impl<'a> State<'a> {
    fn attrs(&self, id: HirId) -> &'a [hir::Attribute] {
        (self.attrs)(id)
    }

    fn precedence(&self, expr: &hir::Expr<'_>) -> ExprPrecedence {
        let has_attr = |id: HirId| !self.attrs(id).is_empty();
        expr.precedence(&has_attr)
    }

    fn print_attrs(&mut self, attrs: &[hir::Attribute]) {
        if attrs.is_empty() {
            return;
        }

        for attr in attrs {
            self.print_attribute_as_style(attr, ast::AttrStyle::Outer);
        }
        self.hardbreak_if_not_bol();
    }

    /// Print a single attribute as if it has style `style`, disregarding the
    /// actual style of the attribute.
    fn print_attribute_as_style(&mut self, attr: &hir::Attribute, style: ast::AttrStyle) {
        match &attr {
            hir::Attribute::Unparsed(unparsed) => {
                self.maybe_print_comment(unparsed.span.lo());
                match style {
                    ast::AttrStyle::Inner => self.word("#!["),
                    ast::AttrStyle::Outer => self.word("#["),
                }
                self.print_attr_item(&unparsed, unparsed.span);
                self.word("]");
                self.hardbreak()
            }
            hir::Attribute::Parsed(AttributeKind::DocComment { kind, comment, .. }) => {
                self.word(rustc_ast_pretty::pprust::state::doc_comment_to_string(
                    *kind, style, *comment,
                ));
                self.hardbreak()
            }
            hir::Attribute::Parsed(pa) => {
                match style {
                    ast::AttrStyle::Inner => self.word("#![attr = "),
                    ast::AttrStyle::Outer => self.word("#[attr = "),
                }
                pa.print_attribute(self);
                self.word("]");
                self.hardbreak()
            }
        }
    }

    fn print_attr_item(&mut self, item: &hir::AttrItem, span: Span) {
        let ib = self.ibox(0);
        let path = ast::Path {
            span,
            segments: item
                .path
                .segments
                .iter()
                .map(|i| ast::PathSegment { ident: *i, args: None, id: DUMMY_NODE_ID })
                .collect(),
            tokens: None,
        };

        match &item.args {
            hir::AttrArgs::Delimited(DelimArgs { dspan: _, delim, tokens }) => self
                .print_mac_common(
                    Some(MacHeader::Path(&path)),
                    false,
                    None,
                    *delim,
                    None,
                    &tokens,
                    true,
                    span,
                ),
            hir::AttrArgs::Empty => {
                PrintState::print_path(self, &path, false, 0);
            }
            hir::AttrArgs::Eq { eq_span: _, expr } => {
                PrintState::print_path(self, &path, false, 0);
                self.space();
                self.word_space("=");
                let token_str = self.meta_item_lit_to_string(expr);
                self.word(token_str);
            }
        }
        self.end(ib);
    }

    fn print_node(&mut self, node: Node<'_>) {
        match node {
            Node::Param(a) => self.print_param(a),
            Node::Item(a) => self.print_item(a),
            Node::ForeignItem(a) => self.print_foreign_item(a),
            Node::TraitItem(a) => self.print_trait_item(a),
            Node::ImplItem(a) => self.print_impl_item(a),
            Node::Variant(a) => self.print_variant(a),
            Node::AnonConst(a) => self.print_anon_const(a),
            Node::ConstBlock(a) => self.print_inline_const(a),
            Node::ConstArg(a) => self.print_const_arg(a),
            Node::Expr(a) => self.print_expr(a),
            Node::ExprField(a) => self.print_expr_field(a),
            Node::Stmt(a) => self.print_stmt(a),
            Node::PathSegment(a) => self.print_path_segment(a),
            Node::Ty(a) => self.print_type(a),
            Node::AssocItemConstraint(a) => self.print_assoc_item_constraint(a),
            Node::TraitRef(a) => self.print_trait_ref(a),
            Node::OpaqueTy(_) => panic!("cannot print Node::OpaqueTy"),
            Node::Pat(a) => self.print_pat(a),
            Node::TyPat(a) => self.print_ty_pat(a),
            Node::PatField(a) => self.print_patfield(a),
            Node::PatExpr(a) => self.print_pat_expr(a),
            Node::Arm(a) => self.print_arm(a),
            Node::Infer(_) => self.word("_"),
            Node::PreciseCapturingNonLifetimeArg(param) => self.print_ident(param.ident),
            Node::Block(a) => {
                // Containing cbox, will be closed by print-block at `}`.
                let cb = self.cbox(INDENT_UNIT);
                // Head-ibox, will be closed by print-block after `{`.
                let ib = self.ibox(0);
                self.print_block(a, cb, ib);
            }
            Node::Lifetime(a) => self.print_lifetime(a),
            Node::GenericParam(_) => panic!("cannot print Node::GenericParam"),
            Node::Field(_) => panic!("cannot print Node::Field"),
            // These cases do not carry enough information in the
            // `hir_map` to reconstruct their full structure for pretty
            // printing.
            Node::Ctor(..) => panic!("cannot print isolated Ctor"),
            Node::LetStmt(a) => self.print_local_decl(a),
            Node::Crate(..) => panic!("cannot print Crate"),
            Node::WherePredicate(pred) => self.print_where_predicate(pred),
            Node::Synthetic => unreachable!(),
            Node::Err(_) => self.word("/*ERROR*/"),
        }
    }

    fn print_generic_arg(&mut self, generic_arg: &GenericArg<'_>, elide_lifetimes: bool) {
        match generic_arg {
            GenericArg::Lifetime(lt) if !elide_lifetimes => self.print_lifetime(lt),
            GenericArg::Lifetime(_) => {}
            GenericArg::Type(ty) => self.print_type(ty.as_unambig_ty()),
            GenericArg::Const(ct) => self.print_const_arg(ct.as_unambig_ct()),
            GenericArg::Infer(_inf) => self.word("_"),
        }
    }
}

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(&self) -> Option<&Comments<'a>> {
        self.comments.as_ref()
    }

    fn comments_mut(&mut self) -> Option<&mut Comments<'a>> {
        self.comments.as_mut()
    }

    fn ann_post(&mut self, ident: Ident) {
        self.ann.post(self, AnnNode::Name(&ident.name));
    }

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

const INDENT_UNIT: isize = 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>(
    sm: &'a SourceMap,
    krate: &hir::Mod<'_>,
    filename: FileName,
    input: String,
    attrs: &'a dyn Fn(HirId) -> &'a [hir::Attribute],
    ann: &'a dyn PpAnn,
) -> String {
    let mut s = State {
        s: pp::Printer::new(),
        comments: Some(Comments::new(sm, filename, input)),
        attrs,
        ann,
    };

    // Print all attributes, regardless of actual style, as inner attributes
    // since this is the crate root with nothing above it to print outer
    // attributes.
    for attr in s.attrs(hir::CRATE_HIR_ID) {
        s.print_attribute_as_style(attr, ast::AttrStyle::Inner);
    }

    // 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);
    s.print_remaining_comments();
    s.s.eof()
}

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

pub fn attribute_to_string(ann: &dyn PpAnn, attr: &hir::Attribute) -> String {
    to_string(ann, |s| s.print_attribute_as_style(attr, ast::AttrStyle::Outer))
}

pub fn ty_to_string(ann: &dyn PpAnn, ty: &hir::Ty<'_>) -> String {
    to_string(ann, |s| s.print_type(ty))
}

pub fn qpath_to_string(ann: &dyn PpAnn, segment: &hir::QPath<'_>) -> String {
    to_string(ann, |s| s.print_qpath(segment, false))
}

pub fn pat_to_string(ann: &dyn PpAnn, pat: &hir::Pat<'_>) -> String {
    to_string(ann, |s| s.print_pat(pat))
}

pub fn expr_to_string(ann: &dyn PpAnn, pat: &hir::Expr<'_>) -> String {
    to_string(ann, |s| s.print_expr(pat))
}

pub fn item_to_string(ann: &dyn PpAnn, pat: &hir::Item<'_>) -> String {
    to_string(ann, |s| s.print_item(pat))
}

impl<'a> State<'a> {
    fn bclose_maybe_open(&mut self, span: rustc_span::Span, cb: Option<BoxMarker>) {
        self.maybe_print_comment(span.hi());
        self.break_offset_if_not_bol(1, -INDENT_UNIT);
        self.word("}");
        if let Some(cb) = cb {
            self.end(cb);
        }
    }

    fn bclose(&mut self, span: rustc_span::Span, cb: BoxMarker) {
        self.bclose_maybe_open(span, Some(cb))
    }

    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) -> rustc_span::Span,
    {
        let rb = 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.word(",");
                self.maybe_print_trailing_comment(get_span(elt), Some(get_span(&elts[i]).hi()));
                self.space_if_not_bol();
            }
        }
        self.end(rb);
    }

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

    fn print_mod(&mut self, _mod: &hir::Mod<'_>) {
        for &item_id in _mod.item_ids {
            self.ann.nested(self, Nested::Item(item_id));
        }
    }

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

    fn print_type(&mut self, ty: &hir::Ty<'_>) {
        self.maybe_print_comment(ty.span.lo());
        let ib = self.ibox(0);
        match ty.kind {
            hir::TyKind::Slice(ty) => {
                self.word("[");
                self.print_type(ty);
                self.word("]");
            }
            hir::TyKind::Ptr(ref mt) => {
                self.word("*");
                self.print_mt(mt, true);
            }
            hir::TyKind::Ref(lifetime, ref mt) => {
                self.word("&");
                self.print_opt_lifetime(lifetime);
                self.print_mt(mt, false);
            }
            hir::TyKind::Never => {
                self.word("!");
            }
            hir::TyKind::Tup(elts) => {
                self.popen();
                self.commasep(Inconsistent, elts, |s, ty| s.print_type(ty));
                if elts.len() == 1 {
                    self.word(",");
                }
                self.pclose();
            }
            hir::TyKind::FnPtr(f) => {
                self.print_ty_fn(f.abi, f.safety, f.decl, None, f.generic_params, f.param_idents);
            }
            hir::TyKind::UnsafeBinder(unsafe_binder) => {
                self.print_unsafe_binder(unsafe_binder);
            }
            hir::TyKind::OpaqueDef(..) => self.word("/*impl Trait*/"),
            hir::TyKind::TraitAscription(bounds) => {
                self.print_bounds("impl", bounds);
            }
            hir::TyKind::Path(ref qpath) => self.print_qpath(qpath, false),
            hir::TyKind::TraitObject(bounds, lifetime) => {
                let syntax = lifetime.tag();
                match syntax {
                    ast::TraitObjectSyntax::Dyn => self.word_nbsp("dyn"),
                    ast::TraitObjectSyntax::None => {}
                }
                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.pointer());
                }
            }
            hir::TyKind::Array(ty, ref length) => {
                self.word("[");
                self.print_type(ty);
                self.word("; ");
                self.print_const_arg(length);
                self.word("]");
            }
            hir::TyKind::Typeof(ref e) => {
                self.word("typeof(");
                self.print_anon_const(e);
                self.word(")");
            }
            hir::TyKind::Err(_) => {
                self.popen();
                self.word("/*ERROR*/");
                self.pclose();
            }
            hir::TyKind::Infer(()) | hir::TyKind::InferDelegation(..) => {
                self.word("_");
            }
            hir::TyKind::Pat(ty, pat) => {
                self.print_type(ty);
                self.word(" is ");
                self.print_ty_pat(pat);
            }
        }
        self.end(ib)
    }

    fn print_unsafe_binder(&mut self, unsafe_binder: &hir::UnsafeBinderTy<'_>) {
        let ib = self.ibox(INDENT_UNIT);
        self.word("unsafe");
        self.print_generic_params(unsafe_binder.generic_params);
        self.nbsp();
        self.print_type(unsafe_binder.inner_ty);
        self.end(ib);
    }

    fn print_foreign_item(&mut self, item: &hir::ForeignItem<'_>) {
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(item.span.lo());
        self.print_attrs(self.attrs(item.hir_id()));
        match item.kind {
            hir::ForeignItemKind::Fn(sig, arg_idents, generics) => {
                let (cb, ib) = self.head("");
                self.print_fn(
                    sig.header,
                    Some(item.ident.name),
                    generics,
                    sig.decl,
                    arg_idents,
                    None,
                );
                self.end(ib);
                self.word(";");
                self.end(cb)
            }
            hir::ForeignItemKind::Static(t, m, safety) => {
                self.print_safety(safety);
                let (cb, ib) = self.head("static");
                if m.is_mut() {
                    self.word_space("mut");
                }
                self.print_ident(item.ident);
                self.word_space(":");
                self.print_type(t);
                self.word(";");
                self.end(ib);
                self.end(cb)
            }
            hir::ForeignItemKind::Type => {
                let (cb, ib) = self.head("type");
                self.print_ident(item.ident);
                self.word(";");
                self.end(ib);
                self.end(cb)
            }
        }
    }

    fn print_associated_const(
        &mut self,
        ident: Ident,
        generics: &hir::Generics<'_>,
        ty: &hir::Ty<'_>,
        default: Option<hir::ConstItemRhs<'_>>,
    ) {
        self.word_space("const");
        self.print_ident(ident);
        self.print_generic_params(generics.params);
        self.word_space(":");
        self.print_type(ty);
        if let Some(ct_rhs) = default {
            self.space();
            self.word_space("=");
            self.print_const_item_rhs(ct_rhs);
        }
        self.print_where_clause(generics);
        self.word(";")
    }

    fn print_associated_type(
        &mut self,
        ident: Ident,
        generics: &hir::Generics<'_>,
        bounds: Option<hir::GenericBounds<'_>>,
        ty: Option<&hir::Ty<'_>>,
    ) {
        self.word_space("type");
        self.print_ident(ident);
        self.print_generic_params(generics.params);
        if let Some(bounds) = bounds {
            self.print_bounds(":", bounds);
        }
        self.print_where_clause(generics);
        if let Some(ty) = ty {
            self.space();
            self.word_space("=");
            self.print_type(ty);
        }
        self.word(";")
    }

    fn print_item(&mut self, item: &hir::Item<'_>) {
        self.hardbreak_if_not_bol();
        self.maybe_print_comment(item.span.lo());
        let attrs = self.attrs(item.hir_id());
        self.print_attrs(attrs);
        self.ann.pre(self, AnnNode::Item(item));
        match item.kind {
            hir::ItemKind::ExternCrate(orig_name, ident) => {
                let (cb, ib) = self.head("extern crate");
                if let Some(orig_name) = orig_name {
                    self.print_name(orig_name);
                    self.space();
                    self.word("as");
                    self.space();
                }
                self.print_ident(ident);
                self.word(";");
                self.end(ib);
                self.end(cb);
            }
            hir::ItemKind::Use(path, kind) => {
                let (cb, ib) = self.head("use");
                self.print_path(path, false);

                match kind {
                    hir::UseKind::Single(ident) => {
                        if path.segments.last().unwrap().ident != ident {
                            self.space();
                            self.word_space("as");
                            self.print_ident(ident);
                        }
                        self.word(";");
                    }
                    hir::UseKind::Glob => self.word("::*;"),
                    hir::UseKind::ListStem => self.word("::{};"),
                }
                self.end(ib);
                self.end(cb);
            }
            hir::ItemKind::Static(m, ident, ty, expr) => {
                let (cb, ib) = self.head("static");
                if m.is_mut() {
                    self.word_space("mut");
                }
                self.print_ident(ident);
                self.word_space(":");
                self.print_type(ty);
                self.space();
                self.end(ib);

                self.word_space("=");
                self.ann.nested(self, Nested::Body(expr));
                self.word(";");
                self.end(cb);
            }
            hir::ItemKind::Const(ident, generics, ty, rhs) => {
                let (cb, ib) = self.head("const");
                self.print_ident(ident);
                self.print_generic_params(generics.params);
                self.word_space(":");
                self.print_type(ty);
                self.space();
                self.end(ib);

                self.word_space("=");
                self.print_const_item_rhs(rhs);
                self.print_where_clause(generics);
                self.word(";");
                self.end(cb);
            }
            hir::ItemKind::Fn { ident, sig, generics, body, .. } => {
                let (cb, ib) = self.head("");
                self.print_fn(sig.header, Some(ident.name), generics, sig.decl, &[], Some(body));
                self.word(" ");
                self.end(ib);
                self.end(cb);
                self.ann.nested(self, Nested::Body(body));
            }
            hir::ItemKind::Macro(ident, macro_def, _) => {
                self.print_mac_def(macro_def, &ident, item.span, |_| {});
            }
            hir::ItemKind::Mod(ident, mod_) => {
                let (cb, ib) = self.head("mod");
                self.print_ident(ident);
                self.nbsp();
                self.bopen(ib);
                self.print_mod(mod_);
                self.bclose(item.span, cb);
            }
            hir::ItemKind::ForeignMod { abi, items } => {
                let (cb, ib) = self.head("extern");
                self.word_nbsp(abi.to_string());
                self.bopen(ib);
                for &foreign_item in items {
                    self.ann.nested(self, Nested::ForeignItem(foreign_item));
                }
                self.bclose(item.span, cb);
            }
            hir::ItemKind::GlobalAsm { asm, .. } => {
                let (cb, ib) = self.head("global_asm!");
                self.print_inline_asm(asm);
                self.word(";");
                self.end(cb);
                self.end(ib);
            }
            hir::ItemKind::TyAlias(ident, generics, ty) => {
                let (cb, ib) = self.head("type");
                self.print_ident(ident);
                self.print_generic_params(generics.params);
                self.end(ib);

                self.print_where_clause(generics);
                self.space();
                self.word_space("=");
                self.print_type(ty);
                self.word(";");
                self.end(cb);
            }
            hir::ItemKind::Enum(ident, generics, ref enum_def) => {
                self.print_enum_def(ident.name, generics, enum_def, item.span);
            }
            hir::ItemKind::Struct(ident, generics, ref struct_def) => {
                let (cb, ib) = self.head("struct");
                self.print_struct(ident.name, generics, struct_def, item.span, true, cb, ib);
            }
            hir::ItemKind::Union(ident, generics, ref struct_def) => {
                let (cb, ib) = self.head("union");
                self.print_struct(ident.name, generics, struct_def, item.span, true, cb, ib);
            }
            hir::ItemKind::Impl(hir::Impl { generics, of_trait, self_ty, items, constness }) => {
                let (cb, ib) = self.head("");

                let impl_generics = |this: &mut Self| {
                    this.word_nbsp("impl");
                    if !generics.params.is_empty() {
                        this.print_generic_params(generics.params);
                        this.space();
                    }
                };

                match of_trait {
                    None => {
                        if let hir::Constness::Const = constness {
                            self.word_nbsp("const");
                        }
                        impl_generics(self)
                    }
                    Some(&hir::TraitImplHeader {
                        safety,
                        polarity,
                        defaultness,
                        defaultness_span: _,
                        ref trait_ref,
                    }) => {
                        self.print_defaultness(defaultness);
                        self.print_safety(safety);

                        impl_generics(self);

                        if let hir::Constness::Const = constness {
                            self.word_nbsp("const");
                        }

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

                        self.print_trait_ref(trait_ref);
                        self.space();
                        self.word_space("for");
                    }
                }

                self.print_type(self_ty);
                self.print_where_clause(generics);

                self.space();
                self.bopen(ib);
                for &impl_item in items {
                    self.ann.nested(self, Nested::ImplItem(impl_item));
                }
                self.bclose(item.span, cb);
            }
            hir::ItemKind::Trait(
                constness,
                is_auto,
                safety,
                ident,
                generics,
                bounds,
                trait_items,
            ) => {
                let (cb, ib) = self.head("");
                self.print_constness(constness);
                self.print_is_auto(is_auto);
                self.print_safety(safety);
                self.word_nbsp("trait");
                self.print_ident(ident);
                self.print_generic_params(generics.params);
                self.print_bounds(":", bounds);
                self.print_where_clause(generics);
                self.word(" ");
                self.bopen(ib);
                for &trait_item in trait_items {
                    self.ann.nested(self, Nested::TraitItem(trait_item));
                }
                self.bclose(item.span, cb);
            }
            hir::ItemKind::TraitAlias(constness, ident, generics, bounds) => {
                let (cb, ib) = self.head("");
                self.print_constness(constness);
                self.word_nbsp("trait");
                self.print_ident(ident);
                self.print_generic_params(generics.params);
                self.nbsp();
                self.print_bounds("=", bounds);
                self.print_where_clause(generics);
                self.word(";");
                self.end(ib);
                self.end(cb);
            }
        }
        self.ann.post(self, AnnNode::Item(item))
    }

    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.word("for");
            self.print_generic_params(generic_params);
            self.nbsp();
        }
    }

    fn print_poly_trait_ref(&mut self, t: &hir::PolyTraitRef<'_>) {
        let hir::TraitBoundModifiers { constness, polarity } = t.modifiers;
        match constness {
            hir::BoundConstness::Never => {}
            hir::BoundConstness::Always(_) => self.word("const"),
            hir::BoundConstness::Maybe(_) => self.word("[const]"),
        }
        match polarity {
            hir::BoundPolarity::Positive => {}
            hir::BoundPolarity::Negative(_) => self.word("!"),
            hir::BoundPolarity::Maybe(_) => self.word("?"),
        }
        self.print_formal_generic_params(t.bound_generic_params);
        self.print_trait_ref(&t.trait_ref);
    }

    fn print_enum_def(
        &mut self,
        name: Symbol,
        generics: &hir::Generics<'_>,
        enum_def: &hir::EnumDef<'_>,
        span: rustc_span::Span,
    ) {
        let (cb, ib) = self.head("enum");
        self.print_name(name);
        self.print_generic_params(generics.params);
        self.print_where_clause(generics);
        self.space();
        self.print_variants(enum_def.variants, span, cb, ib);
    }

    fn print_variants(
        &mut self,
        variants: &[hir::Variant<'_>],
        span: rustc_span::Span,
        cb: BoxMarker,
        ib: BoxMarker,
    ) {
        self.bopen(ib);
        for v in variants {
            self.space_if_not_bol();
            self.maybe_print_comment(v.span.lo());
            self.print_attrs(self.attrs(v.hir_id));
            let ib = self.ibox(INDENT_UNIT);
            self.print_variant(v);
            self.word(",");
            self.end(ib);
            self.maybe_print_trailing_comment(v.span, None);
        }
        self.bclose(span, cb)
    }

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

    fn print_struct(
        &mut self,
        name: Symbol,
        generics: &hir::Generics<'_>,
        struct_def: &hir::VariantData<'_>,
        span: rustc_span::Span,
        print_finalizer: bool,
        cb: BoxMarker,
        ib: BoxMarker,
    ) {
        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_attrs(s.attrs(field.hir_id));
                        s.print_type(field.ty);
                    });
                    self.pclose();
                }
                self.print_where_clause(generics);
                if print_finalizer {
                    self.word(";");
                }
                self.end(ib);
                self.end(cb);
            }
            hir::VariantData::Struct { .. } => {
                self.print_where_clause(generics);
                self.nbsp();
                self.bopen(ib);
                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_attrs(self.attrs(field.hir_id));
                    self.print_ident(field.ident);
                    self.word_nbsp(":");
                    self.print_type(field.ty);
                    self.word(",");
                }

                self.bclose(span, cb)
            }
        }
    }

    pub fn print_variant(&mut self, v: &hir::Variant<'_>) {
        let (cb, ib) = self.head("");
        let generics = hir::Generics::empty();
        self.print_struct(v.ident.name, generics, &v.data, v.span, false, cb, ib);
        if let Some(ref d) = v.disr_expr {
            self.space();
            self.word_space("=");
            self.print_anon_const(d);
        }
    }

    fn print_method_sig(
        &mut self,
        ident: Ident,
        m: &hir::FnSig<'_>,
        generics: &hir::Generics<'_>,
        arg_idents: &[Option<Ident>],
        body_id: Option<hir::BodyId>,
    ) {
        self.print_fn(m.header, Some(ident.name), generics, m.decl, arg_idents, body_id);
    }

    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_attrs(self.attrs(ti.hir_id()));
        match ti.kind {
            hir::TraitItemKind::Const(ty, default) => {
                self.print_associated_const(ti.ident, ti.generics, ty, default);
            }
            hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(arg_idents)) => {
                self.print_method_sig(ti.ident, sig, ti.generics, arg_idents, None);
                self.word(";");
            }
            hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
                let (cb, ib) = self.head("");
                self.print_method_sig(ti.ident, sig, ti.generics, &[], Some(body));
                self.nbsp();
                self.end(ib);
                self.end(cb);
                self.ann.nested(self, Nested::Body(body));
            }
            hir::TraitItemKind::Type(bounds, default) => {
                self.print_associated_type(ti.ident, ti.generics, Some(bounds), default);
            }
        }
        self.ann.post(self, AnnNode::SubItem(ti.hir_id()))
    }

    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_attrs(self.attrs(ii.hir_id()));

        match ii.kind {
            hir::ImplItemKind::Const(ty, expr) => {
                self.print_associated_const(ii.ident, ii.generics, ty, Some(expr));
            }
            hir::ImplItemKind::Fn(ref sig, body) => {
                let (cb, ib) = self.head("");
                self.print_method_sig(ii.ident, sig, ii.generics, &[], Some(body));
                self.nbsp();
                self.end(ib);
                self.end(cb);
                self.ann.nested(self, Nested::Body(body));
            }
            hir::ImplItemKind::Type(ty) => {
                self.print_associated_type(ii.ident, ii.generics, None, Some(ty));
            }
        }
        self.ann.post(self, AnnNode::SubItem(ii.hir_id()))
    }

    fn print_local(
        &mut self,
        super_: bool,
        init: Option<&hir::Expr<'_>>,
        els: Option<&hir::Block<'_>>,
        decl: impl Fn(&mut Self),
    ) {
        self.space_if_not_bol();
        let ibm1 = self.ibox(INDENT_UNIT);
        if super_ {
            self.word_nbsp("super");
        }
        self.word_nbsp("let");

        let ibm2 = self.ibox(INDENT_UNIT);
        decl(self);
        self.end(ibm2);

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

        if let Some(els) = els {
            self.nbsp();
            self.word_space("else");
            // containing cbox, will be closed by print-block at `}`
            let cb = self.cbox(0);
            // head-box, will be closed by print-block after `{`
            let ib = self.ibox(0);
            self.print_block(els, cb, ib);
        }

        self.end(ibm1)
    }

    fn print_stmt(&mut self, st: &hir::Stmt<'_>) {
        self.maybe_print_comment(st.span.lo());
        match st.kind {
            hir::StmtKind::Let(loc) => {
                self.print_local(loc.super_.is_some(), loc.init, loc.els, |this| {
                    this.print_local_decl(loc)
                });
            }
            hir::StmtKind::Item(item) => self.ann.nested(self, Nested::Item(item)),
            hir::StmtKind::Expr(expr) => {
                self.space_if_not_bol();
                self.print_expr(expr);
            }
            hir::StmtKind::Semi(expr) => {
                self.space_if_not_bol();
                self.print_expr(expr);
                self.word(";");
            }
        }
        if stmt_ends_with_semi(&st.kind) {
            self.word(";");
        }
        self.maybe_print_trailing_comment(st.span, None)
    }

    fn print_block(&mut self, blk: &hir::Block<'_>, cb: BoxMarker, ib: BoxMarker) {
        self.print_block_maybe_unclosed(blk, Some(cb), ib)
    }

    fn print_block_unclosed(&mut self, blk: &hir::Block<'_>, ib: BoxMarker) {
        self.print_block_maybe_unclosed(blk, None, ib)
    }

    fn print_block_maybe_unclosed(
        &mut self,
        blk: &hir::Block<'_>,
        cb: Option<BoxMarker>,
        ib: BoxMarker,
    ) {
        match blk.rules {
            hir::BlockCheckMode::UnsafeBlock(..) => self.word_space("unsafe"),
            hir::BlockCheckMode::DefaultBlock => (),
        }
        self.maybe_print_comment(blk.span.lo());
        self.ann.pre(self, AnnNode::Block(blk));
        self.bopen(ib);

        for st in blk.stmts {
            self.print_stmt(st);
        }
        if let Some(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, cb);
        self.ann.post(self, AnnNode::Block(blk))
    }

    fn print_else(&mut self, els: Option<&hir::Expr<'_>>) {
        if let Some(els_inner) = els {
            match els_inner.kind {
                // Another `else if` block.
                hir::ExprKind::If(i, hir::Expr { kind: hir::ExprKind::Block(t, None), .. }, e) => {
                    let cb = self.cbox(0);
                    let ib = self.ibox(0);
                    self.word(" else if ");
                    self.print_expr_as_cond(i);
                    self.space();
                    self.print_block(t, cb, ib);
                    self.print_else(e);
                }
                // Final `else` block.
                hir::ExprKind::Block(b, None) => {
                    let cb = self.cbox(0);
                    let ib = self.ibox(0);
                    self.word(" else ");
                    self.print_block(b, cb, ib);
                }
                // Constraints would be great here!
                _ => {
                    panic!("print_if saw if with weird alternative");
                }
            }
        }
    }

    fn print_if(
        &mut self,
        test: &hir::Expr<'_>,
        blk: &hir::Expr<'_>,
        elseopt: Option<&hir::Expr<'_>>,
    ) {
        match blk.kind {
            hir::ExprKind::Block(blk, None) => {
                let cb = self.cbox(0);
                let ib = self.ibox(0);
                self.word_nbsp("if");
                self.print_expr_as_cond(test);
                self.space();
                self.print_block(blk, cb, ib);
                self.print_else(elseopt)
            }
            _ => panic!("non-block then expr"),
        }
    }

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

    fn print_const_item_rhs(&mut self, ct_rhs: hir::ConstItemRhs<'_>) {
        match ct_rhs {
            hir::ConstItemRhs::Body(body_id) => self.ann.nested(self, Nested::Body(body_id)),
            hir::ConstItemRhs::TypeConst(const_arg) => self.print_const_arg(const_arg),
        }
    }

    fn print_const_arg(&mut self, const_arg: &hir::ConstArg<'_>) {
        match &const_arg.kind {
            ConstArgKind::Path(qpath) => self.print_qpath(qpath, true),
            ConstArgKind::Anon(anon) => self.print_anon_const(anon),
            ConstArgKind::Error(_, _) => self.word("/*ERROR*/"),
            ConstArgKind::Infer(..) => self.word("_"),
        }
    }

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

    /// Prints an expr using syntax that's acceptable in a condition position, such as the `cond` in
    /// `if cond { ... }`.
    fn print_expr_as_cond(&mut self, expr: &hir::Expr<'_>) {
        self.print_expr_cond_paren(expr, Self::cond_needs_par(expr))
    }

    /// Prints `expr` or `(expr)` when `needs_par` holds.
    fn print_expr_cond_paren(&mut self, expr: &hir::Expr<'_>, needs_par: bool) {
        if needs_par {
            self.popen();
        }
        if let hir::ExprKind::DropTemps(actual_expr) = expr.kind {
            self.print_expr(actual_expr);
        } else {
            self.print_expr(expr);
        }
        if needs_par {
            self.pclose();
        }
    }

    /// Print a `let pat = expr` expression.
    fn print_let(&mut self, pat: &hir::Pat<'_>, ty: Option<&hir::Ty<'_>>, init: &hir::Expr<'_>) {
        self.word_space("let");
        self.print_pat(pat);
        if let Some(ty) = ty {
            self.word_space(":");
            self.print_type(ty);
        }
        self.space();
        self.word_space("=");
        let npals = || parser::needs_par_as_let_scrutinee(self.precedence(init));
        self.print_expr_cond_paren(init, Self::cond_needs_par(init) || npals())
    }

    // Does `expr` need parentheses when printed in a condition position?
    //
    // These cases need parens due to the parse error observed in #26461: `if return {}`
    // parses as the erroneous construct `if (return {})`, not `if (return) {}`.
    fn cond_needs_par(expr: &hir::Expr<'_>) -> bool {
        match expr.kind {
            hir::ExprKind::Break(..) | hir::ExprKind::Closure { .. } | hir::ExprKind::Ret(..) => {
                true
            }
            _ => contains_exterior_struct_lit(expr),
        }
    }

    fn print_expr_vec(&mut self, exprs: &[hir::Expr<'_>]) {
        let ib = self.ibox(INDENT_UNIT);
        self.word("[");
        self.commasep_exprs(Inconsistent, exprs);
        self.word("]");
        self.end(ib)
    }

    fn print_inline_const(&mut self, constant: &hir::ConstBlock) {
        let ib = self.ibox(INDENT_UNIT);
        self.word_space("const");
        self.ann.nested(self, Nested::Body(constant.body));
        self.end(ib)
    }

    fn print_expr_repeat(&mut self, element: &hir::Expr<'_>, count: &hir::ConstArg<'_>) {
        let ib = self.ibox(INDENT_UNIT);
        self.word("[");
        self.print_expr(element);
        self.word_space(";");
        self.print_const_arg(count);
        self.word("]");
        self.end(ib)
    }

    fn print_expr_struct(
        &mut self,
        qpath: &hir::QPath<'_>,
        fields: &[hir::ExprField<'_>],
        wth: hir::StructTailExpr<'_>,
    ) {
        self.print_qpath(qpath, true);
        self.nbsp();
        self.word_space("{");
        self.commasep_cmnt(Consistent, fields, |s, field| s.print_expr_field(field), |f| f.span);
        match wth {
            hir::StructTailExpr::Base(expr) => {
                let ib = self.ibox(INDENT_UNIT);
                if !fields.is_empty() {
                    self.word(",");
                    self.space();
                }
                self.word("..");
                self.print_expr(expr);
                self.end(ib);
            }
            hir::StructTailExpr::DefaultFields(_) => {
                let ib = self.ibox(INDENT_UNIT);
                if !fields.is_empty() {
                    self.word(",");
                    self.space();
                }
                self.word("..");
                self.end(ib);
            }
            hir::StructTailExpr::None => {}
        }
        self.space();
        self.word("}");
    }

    fn print_expr_field(&mut self, field: &hir::ExprField<'_>) {
        let cb = self.cbox(INDENT_UNIT);
        self.print_attrs(self.attrs(field.hir_id));
        if !field.is_shorthand {
            self.print_ident(field.ident);
            self.word_space(":");
        }
        self.print_expr(field.expr);
        self.end(cb)
    }

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

    fn print_expr_call(&mut self, func: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
        let needs_paren = match func.kind {
            hir::ExprKind::Field(..) => true,
            _ => self.precedence(func) < ExprPrecedence::Unambiguous,
        };

        self.print_expr_cond_paren(func, needs_paren);
        self.print_call_post(args)
    }

    fn print_expr_method_call(
        &mut self,
        segment: &hir::PathSegment<'_>,
        receiver: &hir::Expr<'_>,
        args: &[hir::Expr<'_>],
    ) {
        let base_args = args;
        self.print_expr_cond_paren(
            receiver,
            self.precedence(receiver) < ExprPrecedence::Unambiguous,
        );
        self.word(".");
        self.print_ident(segment.ident);

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

        self.print_call_post(base_args)
    }

    fn print_expr_binary(&mut self, op: hir::BinOpKind, lhs: &hir::Expr<'_>, rhs: &hir::Expr<'_>) {
        let binop_prec = op.precedence();
        let left_prec = self.precedence(lhs);
        let right_prec = self.precedence(rhs);

        let (mut left_needs_paren, right_needs_paren) = match op.fixity() {
            Fixity::Left => (left_prec < binop_prec, right_prec <= binop_prec),
            Fixity::Right => (left_prec <= binop_prec, right_prec < binop_prec),
            Fixity::None => (left_prec <= binop_prec, right_prec <= binop_prec),
        };

        match (&lhs.kind, op) {
            // 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::BinOpKind::Shl) => {
                left_needs_paren = true;
            }
            (&hir::ExprKind::Let { .. }, _) if !parser::needs_par_as_let_scrutinee(binop_prec) => {
                left_needs_paren = true;
            }
            _ => {}
        }

        self.print_expr_cond_paren(lhs, left_needs_paren);
        self.space();
        self.word_space(op.as_str());
        self.print_expr_cond_paren(rhs, right_needs_paren);
    }

    fn print_expr_unary(&mut self, op: hir::UnOp, expr: &hir::Expr<'_>) {
        self.word(op.as_str());
        self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Prefix);
    }

    fn print_expr_addr_of(
        &mut self,
        kind: hir::BorrowKind,
        mutability: hir::Mutability,
        expr: &hir::Expr<'_>,
    ) {
        self.word("&");
        match kind {
            hir::BorrowKind::Ref => self.print_mutability(mutability, false),
            hir::BorrowKind::Raw => {
                self.word_nbsp("raw");
                self.print_mutability(mutability, true);
            }
            hir::BorrowKind::Pin => {
                self.word_nbsp("pin");
                self.print_mutability(mutability, true);
            }
        }
        self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Prefix);
    }

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

    fn print_inline_asm(&mut self, asm: &hir::InlineAsm<'_>) {
        enum AsmArg<'a> {
            Template(String),
            Operand(&'a hir::InlineAsmOperand<'a>),
            Options(ast::InlineAsmOptions),
        }

        let mut args = vec![AsmArg::Template(ast::InlineAsmTemplatePiece::to_string(asm.template))];
        args.extend(asm.operands.iter().map(|(o, _)| AsmArg::Operand(o)));
        if !asm.options.is_empty() {
            args.push(AsmArg::Options(asm.options));
        }

        self.popen();
        self.commasep(Consistent, &args, |s, arg| match *arg {
            AsmArg::Template(ref template) => s.print_string(template, ast::StrStyle::Cooked),
            AsmArg::Operand(op) => match *op {
                hir::InlineAsmOperand::In { reg, expr } => {
                    s.word("in");
                    s.popen();
                    s.word(format!("{reg}"));
                    s.pclose();
                    s.space();
                    s.print_expr(expr);
                }
                hir::InlineAsmOperand::Out { reg, late, ref expr } => {
                    s.word(if late { "lateout" } else { "out" });
                    s.popen();
                    s.word(format!("{reg}"));
                    s.pclose();
                    s.space();
                    match expr {
                        Some(expr) => s.print_expr(expr),
                        None => s.word("_"),
                    }
                }
                hir::InlineAsmOperand::InOut { reg, late, expr } => {
                    s.word(if late { "inlateout" } else { "inout" });
                    s.popen();
                    s.word(format!("{reg}"));
                    s.pclose();
                    s.space();
                    s.print_expr(expr);
                }
                hir::InlineAsmOperand::SplitInOut { reg, late, in_expr, ref out_expr } => {
                    s.word(if late { "inlateout" } else { "inout" });
                    s.popen();
                    s.word(format!("{reg}"));
                    s.pclose();
                    s.space();
                    s.print_expr(in_expr);
                    s.space();
                    s.word_space("=>");
                    match out_expr {
                        Some(out_expr) => s.print_expr(out_expr),
                        None => s.word("_"),
                    }
                }
                hir::InlineAsmOperand::Const { ref anon_const } => {
                    s.word("const");
                    s.space();
                    // Not using `print_inline_const` to avoid additional `const { ... }`
                    s.ann.nested(s, Nested::Body(anon_const.body))
                }
                hir::InlineAsmOperand::SymFn { ref expr } => {
                    s.word("sym_fn");
                    s.space();
                    s.print_expr(expr);
                }
                hir::InlineAsmOperand::SymStatic { ref path, def_id: _ } => {
                    s.word("sym_static");
                    s.space();
                    s.print_qpath(path, true);
                }
                hir::InlineAsmOperand::Label { block } => {
                    let (cb, ib) = s.head("label");
                    s.print_block(block, cb, ib);
                }
            },
            AsmArg::Options(opts) => {
                s.word("options");
                s.popen();
                s.commasep(Inconsistent, &opts.human_readable_names(), |s, &opt| {
                    s.word(opt);
                });
                s.pclose();
            }
        });
        self.pclose();
    }

    fn print_expr(&mut self, expr: &hir::Expr<'_>) {
        self.maybe_print_comment(expr.span.lo());
        self.print_attrs(self.attrs(expr.hir_id));
        let ib = self.ibox(INDENT_UNIT);
        self.ann.pre(self, AnnNode::Expr(expr));
        match expr.kind {
            hir::ExprKind::Array(exprs) => {
                self.print_expr_vec(exprs);
            }
            hir::ExprKind::ConstBlock(ref anon_const) => {
                self.print_inline_const(anon_const);
            }
            hir::ExprKind::Repeat(element, ref count) => {
                self.print_expr_repeat(element, count);
            }
            hir::ExprKind::Struct(qpath, fields, wth) => {
                self.print_expr_struct(qpath, fields, wth);
            }
            hir::ExprKind::Tup(exprs) => {
                self.print_expr_tup(exprs);
            }
            hir::ExprKind::Call(func, args) => {
                self.print_expr_call(func, args);
            }
            hir::ExprKind::MethodCall(segment, receiver, args, _) => {
                self.print_expr_method_call(segment, receiver, args);
            }
            hir::ExprKind::Use(expr, _) => {
                self.print_expr(expr);
                self.word(".use");
            }
            hir::ExprKind::Binary(op, lhs, rhs) => {
                self.print_expr_binary(op.node, lhs, rhs);
            }
            hir::ExprKind::Unary(op, expr) => {
                self.print_expr_unary(op, expr);
            }
            hir::ExprKind::AddrOf(k, m, expr) => {
                self.print_expr_addr_of(k, m, expr);
            }
            hir::ExprKind::Lit(lit) => {
                self.print_literal(&lit);
            }
            hir::ExprKind::Cast(expr, ty) => {
                self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Cast);
                self.space();
                self.word_space("as");
                self.print_type(ty);
            }
            hir::ExprKind::Type(expr, ty) => {
                self.word("type_ascribe!(");
                let ib = self.ibox(0);
                self.print_expr(expr);

                self.word(",");
                self.space_if_not_bol();
                self.print_type(ty);

                self.end(ib);
                self.word(")");
            }
            hir::ExprKind::DropTemps(init) => {
                // Print `{`:
                let cb = self.cbox(0);
                let ib = self.ibox(0);
                self.bopen(ib);

                // Print `let _t = $init;`:
                let temp = Ident::with_dummy_span(sym::_t);
                self.print_local(false, Some(init), None, |this| this.print_ident(temp));
                self.word(";");

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

                // Print `}`:
                self.bclose_maybe_open(expr.span, Some(cb));
            }
            hir::ExprKind::Let(&hir::LetExpr { pat, ty, init, .. }) => {
                self.print_let(pat, ty, init);
            }
            hir::ExprKind::If(test, blk, elseopt) => {
                self.print_if(test, blk, elseopt);
            }
            hir::ExprKind::Loop(blk, opt_label, _, _) => {
                let cb = self.cbox(0);
                let ib = self.ibox(0);
                if let Some(label) = opt_label {
                    self.print_ident(label.ident);
                    self.word_space(":");
                }
                self.word_nbsp("loop");
                self.print_block(blk, cb, ib);
            }
            hir::ExprKind::Match(expr, arms, _) => {
                let cb = self.cbox(0);
                let ib = self.ibox(0);
                self.word_nbsp("match");
                self.print_expr_as_cond(expr);
                self.space();
                self.bopen(ib);
                for arm in arms {
                    self.print_arm(arm);
                }
                self.bclose(expr.span, cb);
            }
            hir::ExprKind::Closure(&hir::Closure {
                binder,
                constness,
                capture_clause,
                bound_generic_params,
                fn_decl,
                body,
                fn_decl_span: _,
                fn_arg_span: _,
                kind: _,
                def_id: _,
            }) => {
                self.print_closure_binder(binder, bound_generic_params);
                self.print_constness(constness);
                self.print_capture_clause(capture_clause);

                self.print_closure_params(fn_decl, body);
                self.space();

                // This is a bare expression.
                self.ann.nested(self, Nested::Body(body));
            }
            hir::ExprKind::Block(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 `}`
                let cb = self.cbox(0);
                // head-box, will be closed by print-block after `{`
                let ib = self.ibox(0);
                self.print_block(blk, cb, ib);
            }
            hir::ExprKind::Assign(lhs, rhs, _) => {
                self.print_expr_cond_paren(lhs, self.precedence(lhs) <= ExprPrecedence::Assign);
                self.space();
                self.word_space("=");
                self.print_expr_cond_paren(rhs, self.precedence(rhs) < ExprPrecedence::Assign);
            }
            hir::ExprKind::AssignOp(op, lhs, rhs) => {
                self.print_expr_cond_paren(lhs, self.precedence(lhs) <= ExprPrecedence::Assign);
                self.space();
                self.word_space(op.node.as_str());
                self.print_expr_cond_paren(rhs, self.precedence(rhs) < ExprPrecedence::Assign);
            }
            hir::ExprKind::Field(expr, ident) => {
                self.print_expr_cond_paren(
                    expr,
                    self.precedence(expr) < ExprPrecedence::Unambiguous,
                );
                self.word(".");
                self.print_ident(ident);
            }
            hir::ExprKind::Index(expr, index, _) => {
                self.print_expr_cond_paren(
                    expr,
                    self.precedence(expr) < ExprPrecedence::Unambiguous,
                );
                self.word("[");
                self.print_expr(index);
                self.word("]");
            }
            hir::ExprKind::Path(ref qpath) => self.print_qpath(qpath, true),
            hir::ExprKind::Break(destination, opt_expr) => {
                self.word("break");
                if let Some(label) = destination.label {
                    self.space();
                    self.print_ident(label.ident);
                }
                if let Some(expr) = opt_expr {
                    self.space();
                    self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Jump);
                }
            }
            hir::ExprKind::Continue(destination) => {
                self.word("continue");
                if let Some(label) = destination.label {
                    self.space();
                    self.print_ident(label.ident);
                }
            }
            hir::ExprKind::Ret(result) => {
                self.word("return");
                if let Some(expr) = result {
                    self.word(" ");
                    self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Jump);
                }
            }
            hir::ExprKind::Become(result) => {
                self.word("become");
                self.word(" ");
                self.print_expr_cond_paren(result, self.precedence(result) < ExprPrecedence::Jump);
            }
            hir::ExprKind::InlineAsm(asm) => {
                self.word("asm!");
                self.print_inline_asm(asm);
            }
            hir::ExprKind::OffsetOf(container, fields) => {
                self.word("offset_of!(");
                self.print_type(container);
                self.word(",");
                self.space();

                if let Some((&first, rest)) = fields.split_first() {
                    self.print_ident(first);

                    for &field in rest {
                        self.word(".");
                        self.print_ident(field);
                    }
                }

                self.word(")");
            }
            hir::ExprKind::UnsafeBinderCast(kind, expr, ty) => {
                match kind {
                    ast::UnsafeBinderCastKind::Wrap => self.word("wrap_binder!("),
                    ast::UnsafeBinderCastKind::Unwrap => self.word("unwrap_binder!("),
                }
                self.print_expr(expr);
                if let Some(ty) = ty {
                    self.word(",");
                    self.space();
                    self.print_type(ty);
                }
                self.word(")");
            }
            hir::ExprKind::Yield(expr, _) => {
                self.word_space("yield");
                self.print_expr_cond_paren(expr, self.precedence(expr) < ExprPrecedence::Jump);
            }
            hir::ExprKind::Err(_) => {
                self.popen();
                self.word("/*ERROR*/");
                self.pclose();
            }
        }
        self.ann.post(self, AnnNode::Expr(expr));
        self.end(ib)
    }

    fn print_local_decl(&mut self, loc: &hir::LetStmt<'_>) {
        self.print_pat(loc.pat);
        if let Some(ty) = loc.ty {
            self.word_space(":");
            self.print_type(ty);
        }
    }

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

    fn print_path<R>(&mut self, path: &hir::Path<'_, R>, colons_before_params: bool) {
        self.maybe_print_comment(path.span.lo());

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

    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.args(), false);
        }
    }

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

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

                self.word(">");
                self.word("::");
                let item_segment = path.segments.last().unwrap();
                self.print_ident(item_segment.ident);
                self.print_generic_args(item_segment.args(), colons_before_params)
            }
            hir::QPath::TypeRelative(qself, 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.word("<");
                    self.print_type(qself);
                    self.word(">");
                }

                self.word("::");
                self.print_ident(item_segment.ident);
                self.print_generic_args(item_segment.args(), colons_before_params)
            }
        }
    }

    fn print_generic_args(
        &mut self,
        generic_args: &hir::GenericArgs<'_>,
        colons_before_params: bool,
    ) {
        match generic_args.parenthesized {
            hir::GenericArgsParentheses::No => {
                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.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) if lt.is_elided() => true,
                    GenericArg::Lifetime(_) => {
                        nonelided_generic_args = true;
                        false
                    }
                    _ => {
                        nonelided_generic_args = true;
                        true
                    }
                });

                if nonelided_generic_args {
                    start_or_comma(self);
                    self.commasep(Inconsistent, generic_args.args, |s, generic_arg| {
                        s.print_generic_arg(generic_arg, elide_lifetimes)
                    });
                }

                for constraint in generic_args.constraints {
                    start_or_comma(self);
                    self.print_assoc_item_constraint(constraint);
                }

                if !empty.get() {
                    self.word(">")
                }
            }
            hir::GenericArgsParentheses::ParenSugar => {
                let (inputs, output) = generic_args.paren_sugar_inputs_output().unwrap();

                self.word("(");
                self.commasep(Inconsistent, inputs, |s, ty| s.print_type(ty));
                self.word(")");

                self.space_if_not_bol();
                self.word_space("->");
                self.print_type(output);
            }
            hir::GenericArgsParentheses::ReturnTypeNotation => {
                self.word("(..)");
            }
        }
    }

    fn print_assoc_item_constraint(&mut self, constraint: &hir::AssocItemConstraint<'_>) {
        self.print_ident(constraint.ident);
        self.print_generic_args(constraint.gen_args, false);
        self.space();
        match constraint.kind {
            hir::AssocItemConstraintKind::Equality { ref term } => {
                self.word_space("=");
                match term {
                    Term::Ty(ty) => self.print_type(ty),
                    Term::Const(c) => self.print_const_arg(c),
                }
            }
            hir::AssocItemConstraintKind::Bound { bounds } => {
                self.print_bounds(":", bounds);
            }
        }
    }

    fn print_pat_expr(&mut self, expr: &hir::PatExpr<'_>) {
        match &expr.kind {
            hir::PatExprKind::Lit { lit, negated } => {
                if *negated {
                    self.word("-");
                }
                self.print_literal(lit);
            }
            hir::PatExprKind::ConstBlock(c) => self.print_inline_const(c),
            hir::PatExprKind::Path(qpath) => self.print_qpath(qpath, true),
        }
    }

    fn print_ty_pat(&mut self, pat: &hir::TyPat<'_>) {
        self.maybe_print_comment(pat.span.lo());
        self.ann.pre(self, AnnNode::TyPat(pat));
        // Pat isn't normalized, but the beauty of it
        // is that it doesn't matter
        match pat.kind {
            TyPatKind::Range(begin, end) => {
                self.print_const_arg(begin);
                self.word("..=");
                self.print_const_arg(end);
            }
            TyPatKind::NotNull => {
                self.word_space("not");
                self.word("null");
            }
            TyPatKind::Or(patterns) => {
                self.popen();
                let mut first = true;
                for pat in patterns {
                    if first {
                        first = false;
                    } else {
                        self.word(" | ");
                    }
                    self.print_ty_pat(pat);
                }
                self.pclose();
            }
            TyPatKind::Err(_) => {
                self.popen();
                self.word("/*ERROR*/");
                self.pclose();
            }
        }
        self.ann.post(self, AnnNode::TyPat(pat))
    }

    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 {
            // Printing `_` isn't ideal for a missing pattern, but it's easy and good enough.
            // E.g. `fn(u32)` gets printed as `fn(_: u32)`.
            PatKind::Missing => self.word("_"),
            PatKind::Wild => self.word("_"),
            PatKind::Never => self.word("!"),
            PatKind::Binding(BindingMode(by_ref, mutbl), _, ident, sub) => {
                if mutbl.is_mut() {
                    self.word_nbsp("mut");
                }
                if let ByRef::Yes(pinnedness, rmutbl) = by_ref {
                    self.word_nbsp("ref");
                    if pinnedness.is_pinned() {
                        self.word_nbsp("pin");
                    }
                    if rmutbl.is_mut() {
                        self.word_nbsp("mut");
                    } else if pinnedness.is_pinned() {
                        self.word_nbsp("const");
                    }
                }
                self.print_ident(ident);
                if let Some(p) = sub {
                    self.word("@");
                    self.print_pat(p);
                }
            }
            PatKind::TupleStruct(ref qpath, elts, ddpos) => {
                self.print_qpath(qpath, true);
                self.popen();
                if let Some(ddpos) = ddpos.as_opt_usize() {
                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
                    if ddpos != 0 {
                        self.word_space(",");
                    }
                    self.word("..");
                    if ddpos != elts.len() {
                        self.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::Struct(ref qpath, fields, etc) => {
                self.print_qpath(qpath, true);
                self.nbsp();
                self.word("{");
                let empty = fields.is_empty() && etc.is_none();
                if !empty {
                    self.space();
                }
                self.commasep_cmnt(Consistent, fields, |s, f| s.print_patfield(f), |f| f.pat.span);
                if etc.is_some() {
                    if !fields.is_empty() {
                        self.word_space(",");
                    }
                    self.word("..");
                }
                if !empty {
                    self.space();
                }
                self.word("}");
            }
            PatKind::Or(pats) => {
                self.strsep("|", true, Inconsistent, pats, |s, p| s.print_pat(p));
            }
            PatKind::Tuple(elts, ddpos) => {
                self.popen();
                if let Some(ddpos) = ddpos.as_opt_usize() {
                    self.commasep(Inconsistent, &elts[..ddpos], |s, p| s.print_pat(p));
                    if ddpos != 0 {
                        self.word_space(",");
                    }
                    self.word("..");
                    if ddpos != elts.len() {
                        self.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.word(",");
                    }
                }
                self.pclose();
            }
            PatKind::Box(inner) => {
                let is_range_inner = matches!(inner.kind, PatKind::Range(..));
                self.word("box ");
                if is_range_inner {
                    self.popen();
                }
                self.print_pat(inner);
                if is_range_inner {
                    self.pclose();
                }
            }
            PatKind::Deref(inner) => {
                self.word("deref!");
                self.popen();
                self.print_pat(inner);
                self.pclose();
            }
            PatKind::Ref(inner, pinned, mutbl) => {
                let is_range_inner = matches!(inner.kind, PatKind::Range(..));
                self.word("&");
                if pinned.is_pinned() {
                    self.word("pin ");
                    if mutbl.is_not() {
                        self.word("const ");
                    }
                }
                self.word(mutbl.prefix_str());
                if is_range_inner {
                    self.popen();
                }
                self.print_pat(inner);
                if is_range_inner {
                    self.pclose();
                }
            }
            PatKind::Expr(e) => self.print_pat_expr(e),
            PatKind::Range(begin, end, end_kind) => {
                if let Some(expr) = begin {
                    self.print_pat_expr(expr);
                }
                match end_kind {
                    RangeEnd::Included => self.word("..."),
                    RangeEnd::Excluded => self.word(".."),
                }
                if let Some(expr) = end {
                    self.print_pat_expr(expr);
                }
            }
            PatKind::Slice(before, slice, after) => {
                self.word("[");
                self.commasep(Inconsistent, before, |s, p| s.print_pat(p));
                if let Some(p) = slice {
                    if !before.is_empty() {
                        self.word_space(",");
                    }
                    if let PatKind::Wild = p.kind {
                        // Print nothing.
                    } else {
                        self.print_pat(p);
                    }
                    self.word("..");
                    if !after.is_empty() {
                        self.word_space(",");
                    }
                }
                self.commasep(Inconsistent, after, |s, p| s.print_pat(p));
                self.word("]");
            }
            PatKind::Guard(inner, cond) => {
                self.print_pat(inner);
                self.space();
                self.word_space("if");
                self.print_expr(cond);
            }
            PatKind::Err(_) => {
                self.popen();
                self.word("/*ERROR*/");
                self.pclose();
            }
        }
        self.ann.post(self, AnnNode::Pat(pat))
    }

    fn print_patfield(&mut self, field: &hir::PatField<'_>) {
        if self.attrs(field.hir_id).is_empty() {
            self.space();
        }
        let cb = self.cbox(INDENT_UNIT);
        self.print_attrs(self.attrs(field.hir_id));
        if !field.is_shorthand {
            self.print_ident(field.ident);
            self.word_nbsp(":");
        }
        self.print_pat(field.pat);
        self.end(cb);
    }

    fn print_param(&mut self, arg: &hir::Param<'_>) {
        self.print_attrs(self.attrs(arg.hir_id));
        self.print_pat(arg.pat);
    }

    fn print_implicit_self(&mut self, implicit_self_kind: &hir::ImplicitSelfKind) {
        match implicit_self_kind {
            ImplicitSelfKind::Imm => {
                self.word("self");
            }
            ImplicitSelfKind::Mut => {
                self.print_mutability(hir::Mutability::Mut, false);
                self.word("self");
            }
            ImplicitSelfKind::RefImm => {
                self.word("&");
                self.word("self");
            }
            ImplicitSelfKind::RefMut => {
                self.word("&");
                self.print_mutability(hir::Mutability::Mut, false);
                self.word("self");
            }
            ImplicitSelfKind::None => unreachable!(),
        }
    }

    fn print_arm(&mut self, arm: &hir::Arm<'_>) {
        // I have no idea why this check is necessary, but here it
        // is :(
        if self.attrs(arm.hir_id).is_empty() {
            self.space();
        }
        let cb = self.cbox(INDENT_UNIT);
        self.ann.pre(self, AnnNode::Arm(arm));
        let ib = self.ibox(0);
        self.print_attrs(self.attrs(arm.hir_id));
        self.print_pat(arm.pat);
        self.space();
        if let Some(ref g) = arm.guard {
            self.word_space("if");
            self.print_expr(g);
            self.space();
        }
        self.word_space("=>");

        match arm.body.kind {
            hir::ExprKind::Block(blk, opt_label) => {
                if let Some(label) = opt_label {
                    self.print_ident(label.ident);
                    self.word_space(":");
                }
                self.print_block_unclosed(blk, ib);

                // If it is a user-provided unsafe block, print a comma after it
                if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = blk.rules
                {
                    self.word(",");
                }
            }
            _ => {
                self.end(ib);
                self.print_expr(arm.body);
                self.word(",");
            }
        }
        self.ann.post(self, AnnNode::Arm(arm));
        self.end(cb)
    }

    fn print_fn(
        &mut self,
        header: hir::FnHeader,
        name: Option<Symbol>,
        generics: &hir::Generics<'_>,
        decl: &hir::FnDecl<'_>,
        arg_idents: &[Option<Ident>],
        body_id: Option<hir::BodyId>,
    ) {
        self.print_fn_header_info(header);

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

        self.popen();
        // Make sure we aren't supplied *both* `arg_idents` and `body_id`.
        assert!(arg_idents.is_empty() || body_id.is_none());
        let mut i = 0;
        let mut print_arg = |s: &mut Self, ty: Option<&hir::Ty<'_>>| {
            if i == 0 && decl.implicit_self.has_implicit_self() {
                s.print_implicit_self(&decl.implicit_self);
            } else {
                if let Some(arg_ident) = arg_idents.get(i) {
                    if let Some(arg_ident) = arg_ident {
                        s.word(arg_ident.to_string());
                        s.word(":");
                        s.space();
                    }
                } else if let Some(body_id) = body_id {
                    s.ann.nested(s, Nested::BodyParamPat(body_id, i));
                    s.word(":");
                    s.space();
                }
                if let Some(ty) = ty {
                    s.print_type(ty);
                }
            }
            i += 1;
        };
        self.commasep(Inconsistent, decl.inputs, |s, ty| {
            let ib = s.ibox(INDENT_UNIT);
            print_arg(s, Some(ty));
            s.end(ib);
        });
        if decl.c_variadic {
            if !decl.inputs.is_empty() {
                self.word(", ");
            }
            print_arg(self, None);
            self.word("...");
        }
        self.pclose();

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

    fn print_closure_params(&mut self, decl: &hir::FnDecl<'_>, body_id: hir::BodyId) {
        self.word("|");
        let mut i = 0;
        self.commasep(Inconsistent, decl.inputs, |s, ty| {
            let ib = 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.word(":");
                s.space();
                s.print_type(ty);
            }
            s.end(ib);
        });
        self.word("|");

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

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

    fn print_closure_binder(
        &mut self,
        binder: hir::ClosureBinder,
        generic_params: &[GenericParam<'_>],
    ) {
        let generic_params = generic_params
            .iter()
            .filter(|p| {
                matches!(
                    p,
                    GenericParam {
                        kind: GenericParamKind::Lifetime { kind: LifetimeParamKind::Explicit },
                        ..
                    }
                )
            })
            .collect::<Vec<_>>();

        match binder {
            hir::ClosureBinder::Default => {}
            // We need to distinguish `|...| {}` from `for<> |...| {}` as `for<>` adds additional
            // restrictions.
            hir::ClosureBinder::For { .. } if generic_params.is_empty() => self.word("for<>"),
            hir::ClosureBinder::For { .. } => {
                self.word("for");
                self.word("<");

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

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

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

            match bound {
                GenericBound::Trait(tref) => {
                    self.print_poly_trait_ref(tref);
                }
                GenericBound::Outlives(lt) => {
                    self.print_lifetime(lt);
                }
                GenericBound::Use(args, _) => {
                    self.word("use <");

                    self.commasep(Inconsistent, *args, |s, arg| {
                        s.print_precise_capturing_arg(*arg)
                    });

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

    fn print_precise_capturing_arg(&mut self, arg: PreciseCapturingArg<'_>) {
        match arg {
            PreciseCapturingArg::Lifetime(lt) => self.print_lifetime(lt),
            PreciseCapturingArg::Param(arg) => self.print_ident(arg.ident),
        }
    }

    fn print_generic_params(&mut self, generic_params: &[GenericParam<'_>]) {
        let is_lifetime_elided = |generic_param: &GenericParam<'_>| {
            matches!(
                generic_param.kind,
                GenericParamKind::Lifetime { kind: LifetimeParamKind::Elided(_) }
            )
        };

        // We don't want to show elided lifetimes as they are compiler-inserted and not
        // expressible in surface level Rust.
        if !generic_params.is_empty() && !generic_params.iter().all(is_lifetime_elided) {
            self.word("<");

            self.commasep(
                Inconsistent,
                generic_params.iter().filter(|gp| !is_lifetime_elided(gp)),
                |s, param| s.print_generic_param(param),
            );

            self.word(">");
        }
    }

    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 { .. } => {}
            GenericParamKind::Type { default, .. } => {
                if let Some(default) = default {
                    self.space();
                    self.word_space("=");
                    self.print_type(default);
                }
            }
            GenericParamKind::Const { ty, ref default } => {
                self.word_space(":");
                self.print_type(ty);
                if let Some(default) = default {
                    self.space();
                    self.word_space("=");
                    self.print_const_arg(default);
                }
            }
        }
    }

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

    fn print_where_clause(&mut self, generics: &hir::Generics<'_>) {
        if generics.predicates.is_empty() {
            return;
        }

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

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

    fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
        self.print_attrs(self.attrs(predicate.hir_id));
        match *predicate.kind {
            hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                bound_generic_params,
                bounded_ty,
                bounds,
                ..
            }) => {
                self.print_formal_generic_params(bound_generic_params);
                self.print_type(bounded_ty);
                self.print_bounds(":", bounds);
            }
            hir::WherePredicateKind::RegionPredicate(hir::WhereRegionPredicate {
                lifetime,
                bounds,
                ..
            }) => {
                self.print_lifetime(lifetime);
                self.word(":");

                for (i, bound) in bounds.iter().enumerate() {
                    match bound {
                        GenericBound::Outlives(lt) => {
                            self.print_lifetime(lt);
                        }
                        _ => panic!("unexpected bound on lifetime param: {bound:?}"),
                    }

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

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

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

    fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) {
        match decl.output {
            hir::FnRetTy::Return(ty) => {
                self.space_if_not_bol();
                let ib = self.ibox(INDENT_UNIT);
                self.word_space("->");
                self.print_type(ty);
                self.end(ib);

                if let hir::FnRetTy::Return(output) = decl.output {
                    self.maybe_print_comment(output.span.lo());
                }
            }
            hir::FnRetTy::DefaultReturn(..) => {}
        }
    }

    fn print_ty_fn(
        &mut self,
        abi: ExternAbi,
        safety: hir::Safety,
        decl: &hir::FnDecl<'_>,
        name: Option<Symbol>,
        generic_params: &[hir::GenericParam<'_>],
        arg_idents: &[Option<Ident>],
    ) {
        let ib = self.ibox(INDENT_UNIT);
        self.print_formal_generic_params(generic_params);
        let generics = hir::Generics::empty();
        self.print_fn(
            hir::FnHeader {
                safety: safety.into(),
                abi,
                constness: hir::Constness::NotConst,
                asyncness: hir::IsAsync::NotAsync,
            },
            name,
            generics,
            decl,
            arg_idents,
            None,
        );
        self.end(ib);
    }

    fn print_fn_header_info(&mut self, header: hir::FnHeader) {
        self.print_constness(header.constness);

        let safety = match header.safety {
            hir::HeaderSafety::SafeTargetFeatures => {
                self.word_nbsp("#[target_feature]");
                hir::Safety::Safe
            }
            hir::HeaderSafety::Normal(safety) => safety,
        };

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

        self.print_safety(safety);

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

        self.word("fn")
    }

    fn print_constness(&mut self, s: hir::Constness) {
        match s {
            hir::Constness::NotConst => {}
            hir::Constness::Const => self.word_nbsp("const"),
        }
    }

    fn print_safety(&mut self, s: hir::Safety) {
        match s {
            hir::Safety::Safe => {}
            hir::Safety::Unsafe => self.word_nbsp("unsafe"),
        }
    }

    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 {
    !matches!(
        e.kind,
        hir::ExprKind::If(..)
            | hir::ExprKind::Match(..)
            | hir::ExprKind::Block(..)
            | hir::ExprKind::Loop(..)
    )
}

/// 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::Let(_) => true,
        hir::StmtKind::Item(_) => false,
        hir::StmtKind::Expr(e) => expr_requires_semi_to_be_stmt(e),
        hir::StmtKind::Semi(..) => false,
    }
}

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

        hir::ExprKind::MethodCall(_, receiver, ..) => {
            // `X { y: 1 }.bar(...)`
            contains_exterior_struct_lit(receiver)
        }

        _ => false,
    }
}
