use crate::middle::cstore::{ExternCrate, ExternCrateSource};
use crate::mir::interpret::{AllocId, ConstValue, GlobalAlloc, Pointer, Scalar};
use crate::ty::layout::IntegerExt;
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, Ty, TyCtxt, TypeFoldable};
use rustc_apfloat::ieee::{Double, Single};
use rustc_apfloat::Float;
use rustc_ast::ast;
use rustc_attr::{SignedInt, UnsignedInt};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Namespace};
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_span::symbol::{kw, Ident, Symbol};
use rustc_target::abi::{Integer, Size};
use rustc_target::spec::abi::Abi;

use std::cell::Cell;
use std::char;
use std::collections::BTreeMap;
use std::fmt::{self, Write as _};
use std::ops::{Deref, DerefMut};

// `pretty` is a separate module only for organization.
use super::*;

macro_rules! p {
    (@write($($data:expr),+)) => {
        write!(scoped_cx!(), $($data),+)?
    };
    (@print($x:expr)) => {
        scoped_cx!() = $x.print(scoped_cx!())?
    };
    (@$method:ident($($arg:expr),*)) => {
        scoped_cx!() = scoped_cx!().$method($($arg),*)?
    };
    ($($kind:ident $data:tt),+) => {{
        $(p!(@$kind $data);)+
    }};
}
macro_rules! define_scoped_cx {
    ($cx:ident) => {
        #[allow(unused_macros)]
        macro_rules! scoped_cx {
            () => {
                $cx
            };
        }
    };
}

thread_local! {
    static FORCE_IMPL_FILENAME_LINE: Cell<bool> = Cell::new(false);
    static SHOULD_PREFIX_WITH_CRATE: Cell<bool> = Cell::new(false);
    static NO_QUERIES: Cell<bool> = Cell::new(false);
}

/// Avoids running any queries during any prints that occur
/// during the closure. This may alter the appearance of some
/// types (e.g. forcing verbose printing for opaque types).
/// This method is used during some queries (e.g. `predicates_of`
/// for opaque types), to ensure that any debug printing that
/// occurs during the query computation does not end up recursively
/// calling the same query.
pub fn with_no_queries<F: FnOnce() -> R, R>(f: F) -> R {
    NO_QUERIES.with(|no_queries| {
        let old = no_queries.replace(true);
        let result = f();
        no_queries.set(old);
        result
    })
}

/// Force us to name impls with just the filename/line number. We
/// normally try to use types. But at some points, notably while printing
/// cycle errors, this can result in extra or suboptimal error output,
/// so this variable disables that check.
pub fn with_forced_impl_filename_line<F: FnOnce() -> R, R>(f: F) -> R {
    FORCE_IMPL_FILENAME_LINE.with(|force| {
        let old = force.replace(true);
        let result = f();
        force.set(old);
        result
    })
}

/// Adds the `crate::` prefix to paths where appropriate.
pub fn with_crate_prefix<F: FnOnce() -> R, R>(f: F) -> R {
    SHOULD_PREFIX_WITH_CRATE.with(|flag| {
        let old = flag.replace(true);
        let result = f();
        flag.set(old);
        result
    })
}

/// The "region highlights" are used to control region printing during
/// specific error messages. When a "region highlight" is enabled, it
/// gives an alternate way to print specific regions. For now, we
/// always print those regions using a number, so something like "`'0`".
///
/// Regions not selected by the region highlight mode are presently
/// unaffected.
#[derive(Copy, Clone, Default)]
pub struct RegionHighlightMode {
    /// If enabled, when we see the selected region, use "`'N`"
    /// instead of the ordinary behavior.
    highlight_regions: [Option<(ty::RegionKind, usize)>; 3],

    /// If enabled, when printing a "free region" that originated from
    /// the given `ty::BoundRegion`, print it as "`'1`". Free regions that would ordinarily
    /// have names print as normal.
    ///
    /// This is used when you have a signature like `fn foo(x: &u32,
    /// y: &'a u32)` and we want to give a name to the region of the
    /// reference `x`.
    highlight_bound_region: Option<(ty::BoundRegion, usize)>,
}

impl RegionHighlightMode {
    /// If `region` and `number` are both `Some`, invokes
    /// `highlighting_region`.
    pub fn maybe_highlighting_region(
        &mut self,
        region: Option<ty::Region<'_>>,
        number: Option<usize>,
    ) {
        if let Some(k) = region {
            if let Some(n) = number {
                self.highlighting_region(k, n);
            }
        }
    }

    /// Highlights the region inference variable `vid` as `'N`.
    pub fn highlighting_region(&mut self, region: ty::Region<'_>, number: usize) {
        let num_slots = self.highlight_regions.len();
        let first_avail_slot =
            self.highlight_regions.iter_mut().find(|s| s.is_none()).unwrap_or_else(|| {
                bug!("can only highlight {} placeholders at a time", num_slots,)
            });
        *first_avail_slot = Some((*region, number));
    }

    /// Convenience wrapper for `highlighting_region`.
    pub fn highlighting_region_vid(&mut self, vid: ty::RegionVid, number: usize) {
        self.highlighting_region(&ty::ReVar(vid), number)
    }

    /// Returns `Some(n)` with the number to use for the given region, if any.
    fn region_highlighted(&self, region: ty::Region<'_>) -> Option<usize> {
        self.highlight_regions.iter().find_map(|h| match h {
            Some((r, n)) if r == region => Some(*n),
            _ => None,
        })
    }

    /// Highlight the given bound region.
    /// We can only highlight one bound region at a time. See
    /// the field `highlight_bound_region` for more detailed notes.
    pub fn highlighting_bound_region(&mut self, br: ty::BoundRegion, number: usize) {
        assert!(self.highlight_bound_region.is_none());
        self.highlight_bound_region = Some((br, number));
    }
}

/// Trait for printers that pretty-print using `fmt::Write` to the printer.
pub trait PrettyPrinter<'tcx>:
    Printer<
        'tcx,
        Error = fmt::Error,
        Path = Self,
        Region = Self,
        Type = Self,
        DynExistential = Self,
        Const = Self,
    > + fmt::Write
{
    /// Like `print_def_path` but for value paths.
    fn print_value_path(
        self,
        def_id: DefId,
        substs: &'tcx [GenericArg<'tcx>],
    ) -> Result<Self::Path, Self::Error> {
        self.print_def_path(def_id, substs)
    }

    fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
    where
        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
    {
        value.as_ref().skip_binder().print(self)
    }

    /// Prints comma-separated elements.
    fn comma_sep<T>(mut self, mut elems: impl Iterator<Item = T>) -> Result<Self, Self::Error>
    where
        T: Print<'tcx, Self, Output = Self, Error = Self::Error>,
    {
        if let Some(first) = elems.next() {
            self = first.print(self)?;
            for elem in elems {
                self.write_str(", ")?;
                self = elem.print(self)?;
            }
        }
        Ok(self)
    }

    /// Prints `{f: t}` or `{f as t}` depending on the `cast` argument
    fn typed_value(
        mut self,
        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
        t: impl FnOnce(Self) -> Result<Self, Self::Error>,
        conversion: &str,
    ) -> Result<Self::Const, Self::Error> {
        self.write_str("{")?;
        self = f(self)?;
        self.write_str(conversion)?;
        self = t(self)?;
        self.write_str("}")?;
        Ok(self)
    }

    /// Prints `<...>` around what `f` prints.
    fn generic_delimiters(
        self,
        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
    ) -> Result<Self, Self::Error>;

    /// Returns `true` if the region should be printed in
    /// optional positions, e.g., `&'a T` or `dyn Tr + 'b`.
    /// This is typically the case for all non-`'_` regions.
    fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool;

    // Defaults (should not be overridden):

    /// If possible, this returns a global path resolving to `def_id` that is visible
    /// from at least one local module, and returns `true`. If the crate defining `def_id` is
    /// declared with an `extern crate`, the path is guaranteed to use the `extern crate`.
    fn try_print_visible_def_path(self, def_id: DefId) -> Result<(Self, bool), Self::Error> {
        let mut callers = Vec::new();
        self.try_print_visible_def_path_recur(def_id, &mut callers)
    }

    /// Does the work of `try_print_visible_def_path`, building the
    /// full definition path recursively before attempting to
    /// post-process it into the valid and visible version that
    /// accounts for re-exports.
    ///
    /// This method should only be called by itself or
    /// `try_print_visible_def_path`.
    ///
    /// `callers` is a chain of visible_parent's leading to `def_id`,
    /// to support cycle detection during recursion.
    fn try_print_visible_def_path_recur(
        mut self,
        def_id: DefId,
        callers: &mut Vec<DefId>,
    ) -> Result<(Self, bool), Self::Error> {
        define_scoped_cx!(self);

        debug!("try_print_visible_def_path: def_id={:?}", def_id);

        // If `def_id` is a direct or injected extern crate, return the
        // path to the crate followed by the path to the item within the crate.
        if def_id.index == CRATE_DEF_INDEX {
            let cnum = def_id.krate;

            if cnum == LOCAL_CRATE {
                return Ok((self.path_crate(cnum)?, true));
            }

            // In local mode, when we encounter a crate other than
            // LOCAL_CRATE, execution proceeds in one of two ways:
            //
            // 1. For a direct dependency, where user added an
            //    `extern crate` manually, we put the `extern
            //    crate` as the parent. So you wind up with
            //    something relative to the current crate.
            // 2. For an extern inferred from a path or an indirect crate,
            //    where there is no explicit `extern crate`, we just prepend
            //    the crate name.
            match self.tcx().extern_crate(def_id) {
                Some(&ExternCrate { src, dependency_of, span, .. }) => match (src, dependency_of) {
                    (ExternCrateSource::Extern(def_id), LOCAL_CRATE) => {
                        debug!("try_print_visible_def_path: def_id={:?}", def_id);
                        return Ok((
                            if !span.is_dummy() {
                                self.print_def_path(def_id, &[])?
                            } else {
                                self.path_crate(cnum)?
                            },
                            true,
                        ));
                    }
                    (ExternCrateSource::Path, LOCAL_CRATE) => {
                        debug!("try_print_visible_def_path: def_id={:?}", def_id);
                        return Ok((self.path_crate(cnum)?, true));
                    }
                    _ => {}
                },
                None => {
                    return Ok((self.path_crate(cnum)?, true));
                }
            }
        }

        if def_id.is_local() {
            return Ok((self, false));
        }

        let visible_parent_map = self.tcx().visible_parent_map(LOCAL_CRATE);

        let mut cur_def_key = self.tcx().def_key(def_id);
        debug!("try_print_visible_def_path: cur_def_key={:?}", cur_def_key);

        // For a constructor, we want the name of its parent rather than <unnamed>.
        if let DefPathData::Ctor = cur_def_key.disambiguated_data.data {
            let parent = DefId {
                krate: def_id.krate,
                index: cur_def_key
                    .parent
                    .expect("`DefPathData::Ctor` / `VariantData` missing a parent"),
            };

            cur_def_key = self.tcx().def_key(parent);
        }

        let visible_parent = match visible_parent_map.get(&def_id).cloned() {
            Some(parent) => parent,
            None => return Ok((self, false)),
        };
        if callers.contains(&visible_parent) {
            return Ok((self, false));
        }
        callers.push(visible_parent);
        // HACK(eddyb) this bypasses `path_append`'s prefix printing to avoid
        // knowing ahead of time whether the entire path will succeed or not.
        // To support printers that do not implement `PrettyPrinter`, a `Vec` or
        // linked list on the stack would need to be built, before any printing.
        match self.try_print_visible_def_path_recur(visible_parent, callers)? {
            (cx, false) => return Ok((cx, false)),
            (cx, true) => self = cx,
        }
        callers.pop();
        let actual_parent = self.tcx().parent(def_id);
        debug!(
            "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}",
            visible_parent, actual_parent,
        );

        let mut data = cur_def_key.disambiguated_data.data;
        debug!(
            "try_print_visible_def_path: data={:?} visible_parent={:?} actual_parent={:?}",
            data, visible_parent, actual_parent,
        );

        match data {
            // In order to output a path that could actually be imported (valid and visible),
            // we need to handle re-exports correctly.
            //
            // For example, take `std::os::unix::process::CommandExt`, this trait is actually
            // defined at `std::sys::unix::ext::process::CommandExt` (at time of writing).
            //
            // `std::os::unix` rexports the contents of `std::sys::unix::ext`. `std::sys` is
            // private so the "true" path to `CommandExt` isn't accessible.
            //
            // In this case, the `visible_parent_map` will look something like this:
            //
            // (child) -> (parent)
            // `std::sys::unix::ext::process::CommandExt` -> `std::sys::unix::ext::process`
            // `std::sys::unix::ext::process` -> `std::sys::unix::ext`
            // `std::sys::unix::ext` -> `std::os`
            //
            // This is correct, as the visible parent of `std::sys::unix::ext` is in fact
            // `std::os`.
            //
            // When printing the path to `CommandExt` and looking at the `cur_def_key` that
            // corresponds to `std::sys::unix::ext`, we would normally print `ext` and then go
            // to the parent - resulting in a mangled path like
            // `std::os::ext::process::CommandExt`.
            //
            // Instead, we must detect that there was a re-export and instead print `unix`
            // (which is the name `std::sys::unix::ext` was re-exported as in `std::os`). To
            // do this, we compare the parent of `std::sys::unix::ext` (`std::sys::unix`) with
            // the visible parent (`std::os`). If these do not match, then we iterate over
            // the children of the visible parent (as was done when computing
            // `visible_parent_map`), looking for the specific child we currently have and then
            // have access to the re-exported name.
            DefPathData::TypeNs(ref mut name) if Some(visible_parent) != actual_parent => {
                let reexport = self
                    .tcx()
                    .item_children(visible_parent)
                    .iter()
                    .find(|child| child.res.def_id() == def_id)
                    .map(|child| child.ident.name);
                if let Some(reexport) = reexport {
                    *name = reexport;
                }
            }
            // Re-exported `extern crate` (#43189).
            DefPathData::CrateRoot => {
                data = DefPathData::TypeNs(self.tcx().original_crate_name(def_id.krate));
            }
            _ => {}
        }
        debug!("try_print_visible_def_path: data={:?}", data);

        Ok((self.path_append(Ok, &DisambiguatedDefPathData { data, disambiguator: 0 })?, true))
    }

    fn pretty_path_qualified(
        self,
        self_ty: Ty<'tcx>,
        trait_ref: Option<ty::TraitRef<'tcx>>,
    ) -> Result<Self::Path, Self::Error> {
        if trait_ref.is_none() {
            // Inherent impls. Try to print `Foo::bar` for an inherent
            // impl on `Foo`, but fallback to `<Foo>::bar` if self-type is
            // anything other than a simple path.
            match self_ty.kind {
                ty::Adt(..)
                | ty::Foreign(_)
                | ty::Bool
                | ty::Char
                | ty::Str
                | ty::Int(_)
                | ty::Uint(_)
                | ty::Float(_) => {
                    return self_ty.print(self);
                }

                _ => {}
            }
        }

        self.generic_delimiters(|mut cx| {
            define_scoped_cx!(cx);

            p!(print(self_ty));
            if let Some(trait_ref) = trait_ref {
                p!(write(" as "), print(trait_ref.print_only_trait_path()));
            }
            Ok(cx)
        })
    }

    fn pretty_path_append_impl(
        mut self,
        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
        self_ty: Ty<'tcx>,
        trait_ref: Option<ty::TraitRef<'tcx>>,
    ) -> Result<Self::Path, Self::Error> {
        self = print_prefix(self)?;

        self.generic_delimiters(|mut cx| {
            define_scoped_cx!(cx);

            p!(write("impl "));
            if let Some(trait_ref) = trait_ref {
                p!(print(trait_ref.print_only_trait_path()), write(" for "));
            }
            p!(print(self_ty));

            Ok(cx)
        })
    }

    fn pretty_print_type(mut self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
        define_scoped_cx!(self);

        match ty.kind {
            ty::Bool => p!(write("bool")),
            ty::Char => p!(write("char")),
            ty::Int(t) => p!(write("{}", t.name_str())),
            ty::Uint(t) => p!(write("{}", t.name_str())),
            ty::Float(t) => p!(write("{}", t.name_str())),
            ty::RawPtr(ref tm) => {
                p!(write(
                    "*{} ",
                    match tm.mutbl {
                        hir::Mutability::Mut => "mut",
                        hir::Mutability::Not => "const",
                    }
                ));
                p!(print(tm.ty))
            }
            ty::Ref(r, ty, mutbl) => {
                p!(write("&"));
                if self.region_should_not_be_omitted(r) {
                    p!(print(r), write(" "));
                }
                p!(print(ty::TypeAndMut { ty, mutbl }))
            }
            ty::Never => p!(write("!")),
            ty::Tuple(ref tys) => {
                p!(write("("), comma_sep(tys.iter()));
                if tys.len() == 1 {
                    p!(write(","));
                }
                p!(write(")"))
            }
            ty::FnDef(def_id, substs) => {
                let sig = self.tcx().fn_sig(def_id).subst(self.tcx(), substs);
                p!(print(sig), write(" {{"), print_value_path(def_id, substs), write("}}"));
            }
            ty::FnPtr(ref bare_fn) => p!(print(bare_fn)),
            ty::Infer(infer_ty) => {
                if let ty::TyVar(ty_vid) = infer_ty {
                    if let Some(name) = self.infer_ty_name(ty_vid) {
                        p!(write("{}", name))
                    } else {
                        p!(write("{}", infer_ty))
                    }
                } else {
                    p!(write("{}", infer_ty))
                }
            }
            ty::Error(_) => p!(write("[type error]")),
            ty::Param(ref param_ty) => p!(write("{}", param_ty)),
            ty::Bound(debruijn, bound_ty) => match bound_ty.kind {
                ty::BoundTyKind::Anon => self.pretty_print_bound_var(debruijn, bound_ty.var)?,
                ty::BoundTyKind::Param(p) => p!(write("{}", p)),
            },
            ty::Adt(def, substs) => {
                p!(print_def_path(def.did, substs));
            }
            ty::Dynamic(data, r) => {
                let print_r = self.region_should_not_be_omitted(r);
                if print_r {
                    p!(write("("));
                }
                p!(write("dyn "), print(data));
                if print_r {
                    p!(write(" + "), print(r), write(")"));
                }
            }
            ty::Foreign(def_id) => {
                p!(print_def_path(def_id, &[]));
            }
            ty::Projection(ref data) => p!(print(data)),
            ty::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
            ty::Opaque(def_id, substs) => {
                // FIXME(eddyb) print this with `print_def_path`.
                // We use verbose printing in 'NO_QUERIES' mode, to
                // avoid needing to call `predicates_of`. This should
                // only affect certain debug messages (e.g. messages printed
                // from `rustc_middle::ty` during the computation of `tcx.predicates_of`),
                // and should have no effect on any compiler output.
                if self.tcx().sess.verbose() || NO_QUERIES.with(|q| q.get()) {
                    p!(write("Opaque({:?}, {:?})", def_id, substs));
                    return Ok(self);
                }

                return Ok(with_no_queries(|| {
                    let def_key = self.tcx().def_key(def_id);
                    if let Some(name) = def_key.disambiguated_data.data.get_opt_name() {
                        p!(write("{}", name));
                        // FIXME(eddyb) print this with `print_def_path`.
                        if !substs.is_empty() {
                            p!(write("::"));
                            p!(generic_delimiters(|cx| cx.comma_sep(substs.iter())));
                        }
                        return Ok(self);
                    }
                    // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
                    // by looking up the projections associated with the def_id.
                    let bounds = self.tcx().predicates_of(def_id).instantiate(self.tcx(), substs);

                    let mut first = true;
                    let mut is_sized = false;
                    p!(write("impl"));
                    for predicate in bounds.predicates {
                        if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
                            // Don't print +Sized, but rather +?Sized if absent.
                            if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
                                is_sized = true;
                                continue;
                            }

                            p!(
                                write("{}", if first { " " } else { "+" }),
                                print(trait_ref.print_only_trait_path())
                            );
                            first = false;
                        }
                    }
                    if !is_sized {
                        p!(write("{}?Sized", if first { " " } else { "+" }));
                    } else if first {
                        p!(write(" Sized"));
                    }
                    Ok(self)
                })?);
            }
            ty::Str => p!(write("str")),
            ty::Generator(did, substs, movability) => {
                match movability {
                    hir::Movability::Movable => p!(write("[generator")),
                    hir::Movability::Static => p!(write("[static generator")),
                }

                // FIXME(eddyb) should use `def_span`.
                if let Some(did) = did.as_local() {
                    let hir_id = self.tcx().hir().as_local_hir_id(did);
                    let span = self.tcx().hir().span(hir_id);
                    p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));

                    if substs.as_generator().is_valid() {
                        let upvar_tys = substs.as_generator().upvar_tys();
                        let mut sep = " ";
                        for (&var_id, upvar_ty) in self
                            .tcx()
                            .upvars_mentioned(did)
                            .as_ref()
                            .iter()
                            .flat_map(|v| v.keys())
                            .zip(upvar_tys)
                        {
                            p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
                            sep = ", ";
                        }
                    }
                } else {
                    p!(write("@{}", self.tcx().def_path_str(did)));

                    if substs.as_generator().is_valid() {
                        let upvar_tys = substs.as_generator().upvar_tys();
                        let mut sep = " ";
                        for (index, upvar_ty) in upvar_tys.enumerate() {
                            p!(write("{}{}:", sep, index), print(upvar_ty));
                            sep = ", ";
                        }
                    }
                }

                if substs.as_generator().is_valid() {
                    p!(write(" "), print(substs.as_generator().witness()));
                }

                p!(write("]"))
            }
            ty::GeneratorWitness(types) => {
                p!(in_binder(&types));
            }
            ty::Closure(did, substs) => {
                p!(write("[closure"));

                // FIXME(eddyb) should use `def_span`.
                if let Some(did) = did.as_local() {
                    let hir_id = self.tcx().hir().as_local_hir_id(did);
                    if self.tcx().sess.opts.debugging_opts.span_free_formats {
                        p!(write("@"), print_def_path(did.to_def_id(), substs));
                    } else {
                        let span = self.tcx().hir().span(hir_id);
                        p!(write("@{}", self.tcx().sess.source_map().span_to_string(span)));
                    }

                    if substs.as_closure().is_valid() {
                        let upvar_tys = substs.as_closure().upvar_tys();
                        let mut sep = " ";
                        for (&var_id, upvar_ty) in self
                            .tcx()
                            .upvars_mentioned(did)
                            .as_ref()
                            .iter()
                            .flat_map(|v| v.keys())
                            .zip(upvar_tys)
                        {
                            p!(write("{}{}:", sep, self.tcx().hir().name(var_id)), print(upvar_ty));
                            sep = ", ";
                        }
                    }
                } else {
                    p!(write("@{}", self.tcx().def_path_str(did)));

                    if substs.as_closure().is_valid() {
                        let upvar_tys = substs.as_closure().upvar_tys();
                        let mut sep = " ";
                        for (index, upvar_ty) in upvar_tys.enumerate() {
                            p!(write("{}{}:", sep, index), print(upvar_ty));
                            sep = ", ";
                        }
                    }
                }

                if self.tcx().sess.verbose() && substs.as_closure().is_valid() {
                    p!(write(" closure_kind_ty="), print(substs.as_closure().kind_ty()));
                    p!(
                        write(" closure_sig_as_fn_ptr_ty="),
                        print(substs.as_closure().sig_as_fn_ptr_ty())
                    );
                }

                p!(write("]"))
            }
            ty::Array(ty, sz) => {
                p!(write("["), print(ty), write("; "));
                if self.tcx().sess.verbose() {
                    p!(write("{:?}", sz));
                } else if let ty::ConstKind::Unevaluated(..) = sz.val {
                    // Do not try to evaluate unevaluated constants. If we are const evaluating an
                    // array length anon const, rustc will (with debug assertions) print the
                    // constant's path. Which will end up here again.
                    p!(write("_"));
                } else if let Some(n) = sz.val.try_to_bits(self.tcx().data_layout.pointer_size) {
                    p!(write("{}", n));
                } else if let ty::ConstKind::Param(param) = sz.val {
                    p!(write("{}", param));
                } else {
                    p!(write("_"));
                }
                p!(write("]"))
            }
            ty::Slice(ty) => p!(write("["), print(ty), write("]")),
        }

        Ok(self)
    }

    fn pretty_print_bound_var(
        &mut self,
        debruijn: ty::DebruijnIndex,
        var: ty::BoundVar,
    ) -> Result<(), Self::Error> {
        if debruijn == ty::INNERMOST {
            write!(self, "^{}", var.index())
        } else {
            write!(self, "^{}_{}", debruijn.index(), var.index())
        }
    }

    fn infer_ty_name(&self, _: ty::TyVid) -> Option<String> {
        None
    }

    fn pretty_print_dyn_existential(
        mut self,
        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
    ) -> Result<Self::DynExistential, Self::Error> {
        define_scoped_cx!(self);

        // Generate the main trait ref, including associated types.
        let mut first = true;

        if let Some(principal) = predicates.principal() {
            p!(print_def_path(principal.def_id, &[]));

            let mut resugared = false;

            // Special-case `Fn(...) -> ...` and resugar it.
            let fn_trait_kind = self.tcx().fn_trait_kind_from_lang_item(principal.def_id);
            if !self.tcx().sess.verbose() && fn_trait_kind.is_some() {
                if let ty::Tuple(ref args) = principal.substs.type_at(0).kind {
                    let mut projections = predicates.projection_bounds();
                    if let (Some(proj), None) = (projections.next(), projections.next()) {
                        let tys: Vec<_> = args.iter().map(|k| k.expect_ty()).collect();
                        p!(pretty_fn_sig(&tys, false, proj.ty));
                        resugared = true;
                    }
                }
            }

            // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
            // in order to place the projections inside the `<...>`.
            if !resugared {
                // Use a type that can't appear in defaults of type parameters.
                let dummy_self = self.tcx().mk_ty_infer(ty::FreshTy(0));
                let principal = principal.with_self_ty(self.tcx(), dummy_self);

                let args = self.generic_args_to_print(
                    self.tcx().generics_of(principal.def_id),
                    principal.substs,
                );

                // Don't print `'_` if there's no unerased regions.
                let print_regions = args.iter().any(|arg| match arg.unpack() {
                    GenericArgKind::Lifetime(r) => *r != ty::ReErased,
                    _ => false,
                });
                let mut args = args.iter().cloned().filter(|arg| match arg.unpack() {
                    GenericArgKind::Lifetime(_) => print_regions,
                    _ => true,
                });
                let mut projections = predicates.projection_bounds();

                let arg0 = args.next();
                let projection0 = projections.next();
                if arg0.is_some() || projection0.is_some() {
                    let args = arg0.into_iter().chain(args);
                    let projections = projection0.into_iter().chain(projections);

                    p!(generic_delimiters(|mut cx| {
                        cx = cx.comma_sep(args)?;
                        if arg0.is_some() && projection0.is_some() {
                            write!(cx, ", ")?;
                        }
                        cx.comma_sep(projections)
                    }));
                }
            }
            first = false;
        }

        // Builtin bounds.
        // FIXME(eddyb) avoid printing twice (needed to ensure
        // that the auto traits are sorted *and* printed via cx).
        let mut auto_traits: Vec<_> =
            predicates.auto_traits().map(|did| (self.tcx().def_path_str(did), did)).collect();

        // The auto traits come ordered by `DefPathHash`. While
        // `DefPathHash` is *stable* in the sense that it depends on
        // neither the host nor the phase of the moon, it depends
        // "pseudorandomly" on the compiler version and the target.
        //
        // To avoid that causing instabilities in compiletest
        // output, sort the auto-traits alphabetically.
        auto_traits.sort();

        for (_, def_id) in auto_traits {
            if !first {
                p!(write(" + "));
            }
            first = false;

            p!(print_def_path(def_id, &[]));
        }

        Ok(self)
    }

    fn pretty_fn_sig(
        mut self,
        inputs: &[Ty<'tcx>],
        c_variadic: bool,
        output: Ty<'tcx>,
    ) -> Result<Self, Self::Error> {
        define_scoped_cx!(self);

        p!(write("("), comma_sep(inputs.iter().copied()));
        if c_variadic {
            if !inputs.is_empty() {
                p!(write(", "));
            }
            p!(write("..."));
        }
        p!(write(")"));
        if !output.is_unit() {
            p!(write(" -> "), print(output));
        }

        Ok(self)
    }

    fn pretty_print_const(
        mut self,
        ct: &'tcx ty::Const<'tcx>,
        print_ty: bool,
    ) -> Result<Self::Const, Self::Error> {
        define_scoped_cx!(self);

        if self.tcx().sess.verbose() {
            p!(write("Const({:?}: {:?})", ct.val, ct.ty));
            return Ok(self);
        }

        macro_rules! print_underscore {
            () => {{
                if print_ty {
                    self = self.typed_value(
                        |mut this| {
                            write!(this, "_")?;
                            Ok(this)
                        },
                        |this| this.print_type(ct.ty),
                        ": ",
                    )?;
                } else {
                    write!(self, "_")?;
                }
            }};
        }

        match ct.val {
            ty::ConstKind::Unevaluated(did, substs, promoted) => {
                if let Some(promoted) = promoted {
                    p!(print_value_path(did, substs));
                    p!(write("::{:?}", promoted));
                } else {
                    match self.tcx().def_kind(did) {
                        DefKind::Static | DefKind::Const | DefKind::AssocConst => {
                            p!(print_value_path(did, substs))
                        }
                        _ => {
                            if did.is_local() {
                                let span = self.tcx().def_span(did);
                                if let Ok(snip) = self.tcx().sess.source_map().span_to_snippet(span)
                                {
                                    p!(write("{}", snip))
                                } else {
                                    print_underscore!()
                                }
                            } else {
                                print_underscore!()
                            }
                        }
                    }
                }
            }
            ty::ConstKind::Infer(..) => print_underscore!(),
            ty::ConstKind::Param(ParamConst { name, .. }) => p!(write("{}", name)),
            ty::ConstKind::Value(value) => {
                return self.pretty_print_const_value(value, ct.ty, print_ty);
            }

            ty::ConstKind::Bound(debruijn, bound_var) => {
                self.pretty_print_bound_var(debruijn, bound_var)?
            }
            ty::ConstKind::Placeholder(placeholder) => p!(write("Placeholder({:?})", placeholder)),
            ty::ConstKind::Error(_) => p!(write("[const error]")),
        };
        Ok(self)
    }

    fn pretty_print_const_scalar(
        mut self,
        scalar: Scalar,
        ty: Ty<'tcx>,
        print_ty: bool,
    ) -> Result<Self::Const, Self::Error> {
        define_scoped_cx!(self);

        match (scalar, &ty.kind) {
            // Byte strings (&[u8; N])
            (
                Scalar::Ptr(ptr),
                ty::Ref(
                    _,
                    ty::TyS {
                        kind:
                            ty::Array(
                                ty::TyS { kind: ty::Uint(ast::UintTy::U8), .. },
                                ty::Const {
                                    val:
                                        ty::ConstKind::Value(ConstValue::Scalar(Scalar::Raw {
                                            data,
                                            ..
                                        })),
                                    ..
                                },
                            ),
                        ..
                    },
                    _,
                ),
            ) => match self.tcx().get_global_alloc(ptr.alloc_id) {
                Some(GlobalAlloc::Memory(alloc)) => {
                    if let Ok(byte_str) = alloc.get_bytes(&self.tcx(), ptr, Size::from_bytes(*data))
                    {
                        p!(pretty_print_byte_str(byte_str))
                    } else {
                        p!(write("<too short allocation>"))
                    }
                }
                // FIXME: for statics and functions, we could in principle print more detail.
                Some(GlobalAlloc::Static(def_id)) => p!(write("<static({:?})>", def_id)),
                Some(GlobalAlloc::Function(_)) => p!(write("<function>")),
                None => p!(write("<dangling pointer>")),
            },
            // Bool
            (Scalar::Raw { data: 0, .. }, ty::Bool) => p!(write("false")),
            (Scalar::Raw { data: 1, .. }, ty::Bool) => p!(write("true")),
            // Float
            (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F32)) => {
                p!(write("{}f32", Single::from_bits(data)))
            }
            (Scalar::Raw { data, .. }, ty::Float(ast::FloatTy::F64)) => {
                p!(write("{}f64", Double::from_bits(data)))
            }
            // Int
            (Scalar::Raw { data, .. }, ty::Uint(ui)) => {
                let size = Integer::from_attr(&self.tcx(), UnsignedInt(*ui)).size();
                let int = ConstInt::new(data, size, false, ty.is_ptr_sized_integral());
                if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
            }
            (Scalar::Raw { data, .. }, ty::Int(i)) => {
                let size = Integer::from_attr(&self.tcx(), SignedInt(*i)).size();
                let int = ConstInt::new(data, size, true, ty.is_ptr_sized_integral());
                if print_ty { p!(write("{:#?}", int)) } else { p!(write("{:?}", int)) }
            }
            // Char
            (Scalar::Raw { data, .. }, ty::Char) if char::from_u32(data as u32).is_some() => {
                p!(write("{:?}", char::from_u32(data as u32).unwrap()))
            }
            // Raw pointers
            (Scalar::Raw { data, .. }, ty::RawPtr(_)) => {
                self = self.typed_value(
                    |mut this| {
                        write!(this, "0x{:x}", data)?;
                        Ok(this)
                    },
                    |this| this.print_type(ty),
                    " as ",
                )?;
            }
            (Scalar::Ptr(ptr), ty::FnPtr(_)) => {
                // FIXME: this can ICE when the ptr is dangling or points to a non-function.
                // We should probably have a helper method to share code with the "Byte strings"
                // printing above (which also has to handle pointers to all sorts of things).
                let instance = self.tcx().global_alloc(ptr.alloc_id).unwrap_fn();
                self = self.typed_value(
                    |this| this.print_value_path(instance.def_id(), instance.substs),
                    |this| this.print_type(ty),
                    " as ",
                )?;
            }
            // For function type zsts just printing the path is enough
            (Scalar::Raw { size: 0, .. }, ty::FnDef(d, s)) => p!(print_value_path(*d, s)),
            // Nontrivial types with scalar bit representation
            (Scalar::Raw { data, size }, _) => {
                let print = |mut this: Self| {
                    if size == 0 {
                        write!(this, "transmute(())")?;
                    } else {
                        write!(this, "transmute(0x{:01$x})", data, size as usize * 2)?;
                    }
                    Ok(this)
                };
                self = if print_ty {
                    self.typed_value(print, |this| this.print_type(ty), ": ")?
                } else {
                    print(self)?
                };
            }
            // Any pointer values not covered by a branch above
            (Scalar::Ptr(p), _) => {
                self = self.pretty_print_const_pointer(p, ty, print_ty)?;
            }
        }
        Ok(self)
    }

    /// This is overridden for MIR printing because we only want to hide alloc ids from users, not
    /// from MIR where it is actually useful.
    fn pretty_print_const_pointer(
        mut self,
        _: Pointer,
        ty: Ty<'tcx>,
        print_ty: bool,
    ) -> Result<Self::Const, Self::Error> {
        if print_ty {
            self.typed_value(
                |mut this| {
                    this.write_str("&_")?;
                    Ok(this)
                },
                |this| this.print_type(ty),
                ": ",
            )
        } else {
            self.write_str("&_")?;
            Ok(self)
        }
    }

    fn pretty_print_byte_str(mut self, byte_str: &'tcx [u8]) -> Result<Self::Const, Self::Error> {
        define_scoped_cx!(self);
        p!(write("b\""));
        for &c in byte_str {
            for e in std::ascii::escape_default(c) {
                self.write_char(e as char)?;
            }
        }
        p!(write("\""));
        Ok(self)
    }

    fn pretty_print_const_value(
        mut self,
        ct: ConstValue<'tcx>,
        ty: Ty<'tcx>,
        print_ty: bool,
    ) -> Result<Self::Const, Self::Error> {
        define_scoped_cx!(self);

        if self.tcx().sess.verbose() {
            p!(write("ConstValue({:?}: ", ct), print(ty), write(")"));
            return Ok(self);
        }

        let u8_type = self.tcx().types.u8;

        match (ct, &ty.kind) {
            // Byte/string slices, printed as (byte) string literals.
            (
                ConstValue::Slice { data, start, end },
                ty::Ref(_, ty::TyS { kind: ty::Slice(t), .. }, _),
            ) if *t == u8_type => {
                // The `inspect` here is okay since we checked the bounds, and there are
                // no relocations (we have an active slice reference here). We don't use
                // this result to affect interpreter execution.
                let byte_str = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
                self.pretty_print_byte_str(byte_str)
            }
            (
                ConstValue::Slice { data, start, end },
                ty::Ref(_, ty::TyS { kind: ty::Str, .. }, _),
            ) => {
                // The `inspect` here is okay since we checked the bounds, and there are no
                // relocations (we have an active `str` reference here). We don't use this
                // result to affect interpreter execution.
                let slice = data.inspect_with_undef_and_ptr_outside_interpreter(start..end);
                let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
                p!(write("{:?}", s));
                Ok(self)
            }
            (ConstValue::ByRef { alloc, offset }, ty::Array(t, n)) if *t == u8_type => {
                let n = n.val.try_to_bits(self.tcx().data_layout.pointer_size).unwrap();
                // cast is ok because we already checked for pointer size (32 or 64 bit) above
                let n = Size::from_bytes(n);
                let ptr = Pointer::new(AllocId(0), offset);

                let byte_str = alloc.get_bytes(&self.tcx(), ptr, n).unwrap();
                p!(write("*"));
                p!(pretty_print_byte_str(byte_str));
                Ok(self)
            }

            // Aggregates, printed as array/tuple/struct/variant construction syntax.
            //
            // NB: the `has_param_types_or_consts` check ensures that we can use
            // the `destructure_const` query with an empty `ty::ParamEnv` without
            // introducing ICEs (e.g. via `layout_of`) from missing bounds.
            // E.g. `transmute([0usize; 2]): (u8, *mut T)` needs to know `T: Sized`
            // to be able to destructure the tuple into `(0u8, *mut T)
            //
            // FIXME(eddyb) for `--emit=mir`/`-Z dump-mir`, we should provide the
            // correct `ty::ParamEnv` to allow printing *all* constant values.
            (_, ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) if !ty.has_param_types_or_consts() => {
                let contents = self.tcx().destructure_const(
                    ty::ParamEnv::reveal_all()
                        .and(self.tcx().mk_const(ty::Const { val: ty::ConstKind::Value(ct), ty })),
                );
                let fields = contents.fields.iter().copied();

                match ty.kind {
                    ty::Array(..) => {
                        p!(write("["), comma_sep(fields), write("]"));
                    }
                    ty::Tuple(..) => {
                        p!(write("("), comma_sep(fields));
                        if contents.fields.len() == 1 {
                            p!(write(","));
                        }
                        p!(write(")"));
                    }
                    ty::Adt(def, substs) if def.variants.is_empty() => {
                        p!(print_value_path(def.did, substs));
                    }
                    ty::Adt(def, substs) => {
                        let variant_id =
                            contents.variant.expect("destructed const of adt without variant id");
                        let variant_def = &def.variants[variant_id];
                        p!(print_value_path(variant_def.def_id, substs));

                        match variant_def.ctor_kind {
                            CtorKind::Const => {}
                            CtorKind::Fn => {
                                p!(write("("), comma_sep(fields), write(")"));
                            }
                            CtorKind::Fictive => {
                                p!(write(" {{ "));
                                let mut first = true;
                                for (field_def, field) in variant_def.fields.iter().zip(fields) {
                                    if !first {
                                        p!(write(", "));
                                    }
                                    p!(write("{}: ", field_def.ident), print(field));
                                    first = false;
                                }
                                p!(write(" }}"));
                            }
                        }
                    }
                    _ => unreachable!(),
                }

                Ok(self)
            }

            (ConstValue::Scalar(scalar), _) => self.pretty_print_const_scalar(scalar, ty, print_ty),

            // FIXME(oli-obk): also pretty print arrays and other aggregate constants by reading
            // their fields instead of just dumping the memory.
            _ => {
                // fallback
                p!(write("{:?}", ct));
                if print_ty {
                    p!(write(": "), print(ty));
                }
                Ok(self)
            }
        }
    }
}

// HACK(eddyb) boxed to avoid moving around a large struct by-value.
pub struct FmtPrinter<'a, 'tcx, F>(Box<FmtPrinterData<'a, 'tcx, F>>);

pub struct FmtPrinterData<'a, 'tcx, F> {
    tcx: TyCtxt<'tcx>,
    fmt: F,

    empty_path: bool,
    in_value: bool,
    pub print_alloc_ids: bool,

    used_region_names: FxHashSet<Symbol>,
    region_index: usize,
    binder_depth: usize,

    pub region_highlight_mode: RegionHighlightMode,

    pub name_resolver: Option<Box<&'a dyn Fn(ty::sty::TyVid) -> Option<String>>>,
}

impl<F> Deref for FmtPrinter<'a, 'tcx, F> {
    type Target = FmtPrinterData<'a, 'tcx, F>;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<F> DerefMut for FmtPrinter<'_, '_, F> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.0
    }
}

impl<F> FmtPrinter<'a, 'tcx, F> {
    pub fn new(tcx: TyCtxt<'tcx>, fmt: F, ns: Namespace) -> Self {
        FmtPrinter(Box::new(FmtPrinterData {
            tcx,
            fmt,
            empty_path: false,
            in_value: ns == Namespace::ValueNS,
            print_alloc_ids: false,
            used_region_names: Default::default(),
            region_index: 0,
            binder_depth: 0,
            region_highlight_mode: RegionHighlightMode::default(),
            name_resolver: None,
        }))
    }
}

// HACK(eddyb) get rid of `def_path_str` and/or pass `Namespace` explicitly always
// (but also some things just print a `DefId` generally so maybe we need this?)
fn guess_def_namespace(tcx: TyCtxt<'_>, def_id: DefId) -> Namespace {
    match tcx.def_key(def_id).disambiguated_data.data {
        DefPathData::TypeNs(..) | DefPathData::CrateRoot | DefPathData::ImplTrait => {
            Namespace::TypeNS
        }

        DefPathData::ValueNs(..)
        | DefPathData::AnonConst
        | DefPathData::ClosureExpr
        | DefPathData::Ctor => Namespace::ValueNS,

        DefPathData::MacroNs(..) => Namespace::MacroNS,

        _ => Namespace::TypeNS,
    }
}

impl TyCtxt<'t> {
    /// Returns a string identifying this `DefId`. This string is
    /// suitable for user output.
    pub fn def_path_str(self, def_id: DefId) -> String {
        self.def_path_str_with_substs(def_id, &[])
    }

    pub fn def_path_str_with_substs(self, def_id: DefId, substs: &'t [GenericArg<'t>]) -> String {
        let ns = guess_def_namespace(self, def_id);
        debug!("def_path_str: def_id={:?}, ns={:?}", def_id, ns);
        let mut s = String::new();
        let _ = FmtPrinter::new(self, &mut s, ns).print_def_path(def_id, substs);
        s
    }
}

impl<F: fmt::Write> fmt::Write for FmtPrinter<'_, '_, F> {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.fmt.write_str(s)
    }
}

impl<F: fmt::Write> Printer<'tcx> for FmtPrinter<'_, 'tcx, F> {
    type Error = fmt::Error;

    type Path = Self;
    type Region = Self;
    type Type = Self;
    type DynExistential = Self;
    type Const = Self;

    fn tcx(&'a self) -> TyCtxt<'tcx> {
        self.tcx
    }

    fn print_def_path(
        mut self,
        def_id: DefId,
        substs: &'tcx [GenericArg<'tcx>],
    ) -> Result<Self::Path, Self::Error> {
        define_scoped_cx!(self);

        if substs.is_empty() {
            match self.try_print_visible_def_path(def_id)? {
                (cx, true) => return Ok(cx),
                (cx, false) => self = cx,
            }
        }

        let key = self.tcx.def_key(def_id);
        if let DefPathData::Impl = key.disambiguated_data.data {
            // Always use types for non-local impls, where types are always
            // available, and filename/line-number is mostly uninteresting.
            let use_types = !def_id.is_local() || {
                // Otherwise, use filename/line-number if forced.
                let force_no_types = FORCE_IMPL_FILENAME_LINE.with(|f| f.get());
                !force_no_types
            };

            if !use_types {
                // If no type info is available, fall back to
                // pretty printing some span information. This should
                // only occur very early in the compiler pipeline.
                let parent_def_id = DefId { index: key.parent.unwrap(), ..def_id };
                let span = self.tcx.def_span(def_id);

                self = self.print_def_path(parent_def_id, &[])?;

                // HACK(eddyb) copy of `path_append` to avoid
                // constructing a `DisambiguatedDefPathData`.
                if !self.empty_path {
                    write!(self, "::")?;
                }
                write!(self, "<impl at {}>", self.tcx.sess.source_map().span_to_string(span))?;
                self.empty_path = false;

                return Ok(self);
            }
        }

        self.default_print_def_path(def_id, substs)
    }

    fn print_region(self, region: ty::Region<'_>) -> Result<Self::Region, Self::Error> {
        self.pretty_print_region(region)
    }

    fn print_type(self, ty: Ty<'tcx>) -> Result<Self::Type, Self::Error> {
        self.pretty_print_type(ty)
    }

    fn print_dyn_existential(
        self,
        predicates: &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
    ) -> Result<Self::DynExistential, Self::Error> {
        self.pretty_print_dyn_existential(predicates)
    }

    fn print_const(self, ct: &'tcx ty::Const<'tcx>) -> Result<Self::Const, Self::Error> {
        self.pretty_print_const(ct, true)
    }

    fn path_crate(mut self, cnum: CrateNum) -> Result<Self::Path, Self::Error> {
        self.empty_path = true;
        if cnum == LOCAL_CRATE {
            if self.tcx.sess.rust_2018() {
                // We add the `crate::` keyword on Rust 2018, only when desired.
                if SHOULD_PREFIX_WITH_CRATE.with(|flag| flag.get()) {
                    write!(self, "{}", kw::Crate)?;
                    self.empty_path = false;
                }
            }
        } else {
            write!(self, "{}", self.tcx.crate_name(cnum))?;
            self.empty_path = false;
        }
        Ok(self)
    }

    fn path_qualified(
        mut self,
        self_ty: Ty<'tcx>,
        trait_ref: Option<ty::TraitRef<'tcx>>,
    ) -> Result<Self::Path, Self::Error> {
        self = self.pretty_path_qualified(self_ty, trait_ref)?;
        self.empty_path = false;
        Ok(self)
    }

    fn path_append_impl(
        mut self,
        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
        _disambiguated_data: &DisambiguatedDefPathData,
        self_ty: Ty<'tcx>,
        trait_ref: Option<ty::TraitRef<'tcx>>,
    ) -> Result<Self::Path, Self::Error> {
        self = self.pretty_path_append_impl(
            |mut cx| {
                cx = print_prefix(cx)?;
                if !cx.empty_path {
                    write!(cx, "::")?;
                }

                Ok(cx)
            },
            self_ty,
            trait_ref,
        )?;
        self.empty_path = false;
        Ok(self)
    }

    fn path_append(
        mut self,
        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
        disambiguated_data: &DisambiguatedDefPathData,
    ) -> Result<Self::Path, Self::Error> {
        self = print_prefix(self)?;

        // Skip `::{{constructor}}` on tuple/unit structs.
        if let DefPathData::Ctor = disambiguated_data.data {
            return Ok(self);
        }

        // FIXME(eddyb) `name` should never be empty, but it
        // currently is for `extern { ... }` "foreign modules".
        let name = disambiguated_data.data.as_symbol().as_str();
        if !name.is_empty() {
            if !self.empty_path {
                write!(self, "::")?;
            }
            if Ident::from_str(&name).is_raw_guess() {
                write!(self, "r#")?;
            }
            write!(self, "{}", name)?;

            // FIXME(eddyb) this will print e.g. `{{closure}}#3`, but it
            // might be nicer to use something else, e.g. `{closure#3}`.
            let dis = disambiguated_data.disambiguator;
            let print_dis = disambiguated_data.data.get_opt_name().is_none()
                || dis != 0 && self.tcx.sess.verbose();
            if print_dis {
                write!(self, "#{}", dis)?;
            }

            self.empty_path = false;
        }

        Ok(self)
    }

    fn path_generic_args(
        mut self,
        print_prefix: impl FnOnce(Self) -> Result<Self::Path, Self::Error>,
        args: &[GenericArg<'tcx>],
    ) -> Result<Self::Path, Self::Error> {
        self = print_prefix(self)?;

        // Don't print `'_` if there's no unerased regions.
        let print_regions = args.iter().any(|arg| match arg.unpack() {
            GenericArgKind::Lifetime(r) => *r != ty::ReErased,
            _ => false,
        });
        let args = args.iter().cloned().filter(|arg| match arg.unpack() {
            GenericArgKind::Lifetime(_) => print_regions,
            _ => true,
        });

        if args.clone().next().is_some() {
            if self.in_value {
                write!(self, "::")?;
            }
            self.generic_delimiters(|cx| cx.comma_sep(args))
        } else {
            Ok(self)
        }
    }
}

impl<F: fmt::Write> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx, F> {
    fn infer_ty_name(&self, id: ty::TyVid) -> Option<String> {
        self.0.name_resolver.as_ref().and_then(|func| func(id))
    }

    fn print_value_path(
        mut self,
        def_id: DefId,
        substs: &'tcx [GenericArg<'tcx>],
    ) -> Result<Self::Path, Self::Error> {
        let was_in_value = std::mem::replace(&mut self.in_value, true);
        self = self.print_def_path(def_id, substs)?;
        self.in_value = was_in_value;

        Ok(self)
    }

    fn in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, Self::Error>
    where
        T: Print<'tcx, Self, Output = Self, Error = Self::Error> + TypeFoldable<'tcx>,
    {
        self.pretty_in_binder(value)
    }

    fn typed_value(
        mut self,
        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
        t: impl FnOnce(Self) -> Result<Self, Self::Error>,
        conversion: &str,
    ) -> Result<Self::Const, Self::Error> {
        self.write_str("{")?;
        self = f(self)?;
        self.write_str(conversion)?;
        let was_in_value = std::mem::replace(&mut self.in_value, false);
        self = t(self)?;
        self.in_value = was_in_value;
        self.write_str("}")?;
        Ok(self)
    }

    fn generic_delimiters(
        mut self,
        f: impl FnOnce(Self) -> Result<Self, Self::Error>,
    ) -> Result<Self, Self::Error> {
        write!(self, "<")?;

        let was_in_value = std::mem::replace(&mut self.in_value, false);
        let mut inner = f(self)?;
        inner.in_value = was_in_value;

        write!(inner, ">")?;
        Ok(inner)
    }

    fn region_should_not_be_omitted(&self, region: ty::Region<'_>) -> bool {
        let highlight = self.region_highlight_mode;
        if highlight.region_highlighted(region).is_some() {
            return true;
        }

        if self.tcx.sess.verbose() {
            return true;
        }

        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;

        match *region {
            ty::ReEarlyBound(ref data) => {
                data.name != kw::Invalid && data.name != kw::UnderscoreLifetime
            }

            ty::ReLateBound(_, br)
            | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
            | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
                if let ty::BrNamed(_, name) = br {
                    if name != kw::Invalid && name != kw::UnderscoreLifetime {
                        return true;
                    }
                }

                if let Some((region, _)) = highlight.highlight_bound_region {
                    if br == region {
                        return true;
                    }
                }

                false
            }

            ty::ReVar(_) if identify_regions => true,

            ty::ReVar(_) | ty::ReErased => false,

            ty::ReStatic | ty::ReEmpty(_) => true,
        }
    }

    fn pretty_print_const_pointer(
        self,
        p: Pointer,
        ty: Ty<'tcx>,
        print_ty: bool,
    ) -> Result<Self::Const, Self::Error> {
        let print = |mut this: Self| {
            define_scoped_cx!(this);
            if this.print_alloc_ids {
                p!(write("{:?}", p));
            } else {
                p!(write("&_"));
            }
            Ok(this)
        };
        if print_ty {
            self.typed_value(print, |this| this.print_type(ty), ": ")
        } else {
            print(self)
        }
    }
}

// HACK(eddyb) limited to `FmtPrinter` because of `region_highlight_mode`.
impl<F: fmt::Write> FmtPrinter<'_, '_, F> {
    pub fn pretty_print_region(mut self, region: ty::Region<'_>) -> Result<Self, fmt::Error> {
        define_scoped_cx!(self);

        // Watch out for region highlights.
        let highlight = self.region_highlight_mode;
        if let Some(n) = highlight.region_highlighted(region) {
            p!(write("'{}", n));
            return Ok(self);
        }

        if self.tcx.sess.verbose() {
            p!(write("{:?}", region));
            return Ok(self);
        }

        let identify_regions = self.tcx.sess.opts.debugging_opts.identify_regions;

        // These printouts are concise.  They do not contain all the information
        // the user might want to diagnose an error, but there is basically no way
        // to fit that into a short string.  Hence the recommendation to use
        // `explain_region()` or `note_and_explain_region()`.
        match *region {
            ty::ReEarlyBound(ref data) => {
                if data.name != kw::Invalid {
                    p!(write("{}", data.name));
                    return Ok(self);
                }
            }
            ty::ReLateBound(_, br)
            | ty::ReFree(ty::FreeRegion { bound_region: br, .. })
            | ty::RePlaceholder(ty::Placeholder { name: br, .. }) => {
                if let ty::BrNamed(_, name) = br {
                    if name != kw::Invalid && name != kw::UnderscoreLifetime {
                        p!(write("{}", name));
                        return Ok(self);
                    }
                }

                if let Some((region, counter)) = highlight.highlight_bound_region {
                    if br == region {
                        p!(write("'{}", counter));
                        return Ok(self);
                    }
                }
            }
            ty::ReVar(region_vid) if identify_regions => {
                p!(write("{:?}", region_vid));
                return Ok(self);
            }
            ty::ReVar(_) => {}
            ty::ReErased => {}
            ty::ReStatic => {
                p!(write("'static"));
                return Ok(self);
            }
            ty::ReEmpty(ty::UniverseIndex::ROOT) => {
                p!(write("'<empty>"));
                return Ok(self);
            }
            ty::ReEmpty(ui) => {
                p!(write("'<empty:{:?}>", ui));
                return Ok(self);
            }
        }

        p!(write("'_"));

        Ok(self)
    }
}

// HACK(eddyb) limited to `FmtPrinter` because of `binder_depth`,
// `region_index` and `used_region_names`.
impl<F: fmt::Write> FmtPrinter<'_, 'tcx, F> {
    pub fn name_all_regions<T>(
        mut self,
        value: &ty::Binder<T>,
    ) -> Result<(Self, (T, BTreeMap<ty::BoundRegion, ty::Region<'tcx>>)), fmt::Error>
    where
        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
    {
        fn name_by_region_index(index: usize) -> Symbol {
            match index {
                0 => Symbol::intern("'r"),
                1 => Symbol::intern("'s"),
                i => Symbol::intern(&format!("'t{}", i - 2)),
            }
        }

        // Replace any anonymous late-bound regions with named
        // variants, using new unique identifiers, so that we can
        // clearly differentiate between named and unnamed regions in
        // the output. We'll probably want to tweak this over time to
        // decide just how much information to give.
        if self.binder_depth == 0 {
            self.prepare_late_bound_region_info(value);
        }

        let mut empty = true;
        let mut start_or_continue = |cx: &mut Self, start: &str, cont: &str| {
            write!(
                cx,
                "{}",
                if empty {
                    empty = false;
                    start
                } else {
                    cont
                }
            )
        };

        define_scoped_cx!(self);

        let mut region_index = self.region_index;
        let new_value = self.tcx.replace_late_bound_regions(value, |br| {
            let _ = start_or_continue(&mut self, "for<", ", ");
            let br = match br {
                ty::BrNamed(_, name) => {
                    let _ = write!(self, "{}", name);
                    br
                }
                ty::BrAnon(_) | ty::BrEnv => {
                    let name = loop {
                        let name = name_by_region_index(region_index);
                        region_index += 1;
                        if !self.used_region_names.contains(&name) {
                            break name;
                        }
                    };
                    let _ = write!(self, "{}", name);
                    ty::BrNamed(DefId::local(CRATE_DEF_INDEX), name)
                }
            };
            self.tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br))
        });
        start_or_continue(&mut self, "", "> ")?;

        self.binder_depth += 1;
        self.region_index = region_index;
        Ok((self, new_value))
    }

    pub fn pretty_in_binder<T>(self, value: &ty::Binder<T>) -> Result<Self, fmt::Error>
    where
        T: Print<'tcx, Self, Output = Self, Error = fmt::Error> + TypeFoldable<'tcx>,
    {
        let old_region_index = self.region_index;
        let (new, new_value) = self.name_all_regions(value)?;
        let mut inner = new_value.0.print(new)?;
        inner.region_index = old_region_index;
        inner.binder_depth -= 1;
        Ok(inner)
    }

    fn prepare_late_bound_region_info<T>(&mut self, value: &ty::Binder<T>)
    where
        T: TypeFoldable<'tcx>,
    {
        struct LateBoundRegionNameCollector<'a>(&'a mut FxHashSet<Symbol>);
        impl<'tcx> ty::fold::TypeVisitor<'tcx> for LateBoundRegionNameCollector<'_> {
            fn visit_region(&mut self, r: ty::Region<'tcx>) -> bool {
                if let ty::ReLateBound(_, ty::BrNamed(_, name)) = *r {
                    self.0.insert(name);
                }
                r.super_visit_with(self)
            }
        }

        self.used_region_names.clear();
        let mut collector = LateBoundRegionNameCollector(&mut self.used_region_names);
        value.visit_with(&mut collector);
        self.region_index = 0;
    }
}

impl<'tcx, T, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::Binder<T>
where
    T: Print<'tcx, P, Output = P, Error = P::Error> + TypeFoldable<'tcx>,
{
    type Output = P;
    type Error = P::Error;
    fn print(&self, cx: P) -> Result<Self::Output, Self::Error> {
        cx.in_binder(self)
    }
}

impl<'tcx, T, U, P: PrettyPrinter<'tcx>> Print<'tcx, P> for ty::OutlivesPredicate<T, U>
where
    T: Print<'tcx, P, Output = P, Error = P::Error>,
    U: Print<'tcx, P, Output = P, Error = P::Error>,
{
    type Output = P;
    type Error = P::Error;
    fn print(&self, mut cx: P) -> Result<Self::Output, Self::Error> {
        define_scoped_cx!(cx);
        p!(print(self.0), write(": "), print(self.1));
        Ok(cx)
    }
}

macro_rules! forward_display_to_print {
    ($($ty:ty),+) => {
        $(impl fmt::Display for $ty {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                ty::tls::with(|tcx| {
                    tcx.lift(self)
                        .expect("could not lift for printing")
                        .print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
                    Ok(())
                })
            }
        })+
    };
}

macro_rules! define_print_and_forward_display {
    (($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
        $(impl<'tcx, P: PrettyPrinter<'tcx>> Print<'tcx, P> for $ty {
            type Output = P;
            type Error = fmt::Error;
            fn print(&$self, $cx: P) -> Result<Self::Output, Self::Error> {
                #[allow(unused_mut)]
                let mut $cx = $cx;
                define_scoped_cx!($cx);
                let _: () = $print;
                #[allow(unreachable_code)]
                Ok($cx)
            }
        })+

        forward_display_to_print!($($ty),+);
    };
}

// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
impl fmt::Display for ty::RegionKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        ty::tls::with(|tcx| {
            self.print(FmtPrinter::new(tcx, f, Namespace::TypeNS))?;
            Ok(())
        })
    }
}

/// Wrapper type for `ty::TraitRef` which opts-in to pretty printing only
/// the trait path. That is, it will print `Trait<U>` instead of
/// `<T as Trait<U>>`.
#[derive(Copy, Clone, TypeFoldable, Lift)]
pub struct TraitRefPrintOnlyTraitPath<'tcx>(ty::TraitRef<'tcx>);

impl fmt::Debug for TraitRefPrintOnlyTraitPath<'tcx> {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        fmt::Display::fmt(self, f)
    }
}

impl ty::TraitRef<'tcx> {
    pub fn print_only_trait_path(self) -> TraitRefPrintOnlyTraitPath<'tcx> {
        TraitRefPrintOnlyTraitPath(self)
    }
}

impl ty::Binder<ty::TraitRef<'tcx>> {
    pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>> {
        self.map_bound(|tr| tr.print_only_trait_path())
    }
}

forward_display_to_print! {
    Ty<'tcx>,
    &'tcx ty::List<ty::ExistentialPredicate<'tcx>>,
    &'tcx ty::Const<'tcx>,

    // HACK(eddyb) these are exhaustive instead of generic,
    // because `for<'tcx>` isn't possible yet.
    ty::Binder<&'tcx ty::List<ty::ExistentialPredicate<'tcx>>>,
    ty::Binder<ty::TraitRef<'tcx>>,
    ty::Binder<TraitRefPrintOnlyTraitPath<'tcx>>,
    ty::Binder<ty::FnSig<'tcx>>,
    ty::Binder<ty::TraitPredicate<'tcx>>,
    ty::Binder<ty::SubtypePredicate<'tcx>>,
    ty::Binder<ty::ProjectionPredicate<'tcx>>,
    ty::Binder<ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>>,
    ty::Binder<ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>>,

    ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>,
    ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
}

define_print_and_forward_display! {
    (self, cx):

    &'tcx ty::List<Ty<'tcx>> {
        p!(write("{{"), comma_sep(self.iter()), write("}}"))
    }

    ty::TypeAndMut<'tcx> {
        p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
    }

    ty::ExistentialTraitRef<'tcx> {
        // Use a type that can't appear in defaults of type parameters.
        let dummy_self = cx.tcx().mk_ty_infer(ty::FreshTy(0));
        let trait_ref = self.with_self_ty(cx.tcx(), dummy_self);
        p!(print(trait_ref.print_only_trait_path()))
    }

    ty::ExistentialProjection<'tcx> {
        let name = cx.tcx().associated_item(self.item_def_id).ident;
        p!(write("{} = ", name), print(self.ty))
    }

    ty::ExistentialPredicate<'tcx> {
        match *self {
            ty::ExistentialPredicate::Trait(x) => p!(print(x)),
            ty::ExistentialPredicate::Projection(x) => p!(print(x)),
            ty::ExistentialPredicate::AutoTrait(def_id) => {
                p!(print_def_path(def_id, &[]));
            }
        }
    }

    ty::FnSig<'tcx> {
        p!(write("{}", self.unsafety.prefix_str()));

        if self.abi != Abi::Rust {
            p!(write("extern {} ", self.abi));
        }

        p!(write("fn"), pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
    }

    ty::InferTy {
        if cx.tcx().sess.verbose() {
            p!(write("{:?}", self));
            return Ok(cx);
        }
        match *self {
            ty::TyVar(_) => p!(write("_")),
            ty::IntVar(_) => p!(write("{}", "{integer}")),
            ty::FloatVar(_) => p!(write("{}", "{float}")),
            ty::FreshTy(v) => p!(write("FreshTy({})", v)),
            ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
            ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
        }
    }

    ty::TraitRef<'tcx> {
        p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
    }

    TraitRefPrintOnlyTraitPath<'tcx> {
        p!(print_def_path(self.0.def_id, self.0.substs));
    }

    ty::ParamTy {
        p!(write("{}", self.name))
    }

    ty::ParamConst {
        p!(write("{}", self.name))
    }

    ty::SubtypePredicate<'tcx> {
        p!(print(self.a), write(" <: "), print(self.b))
    }

    ty::TraitPredicate<'tcx> {
        p!(print(self.trait_ref.self_ty()), write(": "),
           print(self.trait_ref.print_only_trait_path()))
    }

    ty::ProjectionPredicate<'tcx> {
        p!(print(self.projection_ty), write(" == "), print(self.ty))
    }

    ty::ProjectionTy<'tcx> {
        p!(print_def_path(self.item_def_id, self.substs));
    }

    ty::ClosureKind {
        match *self {
            ty::ClosureKind::Fn => p!(write("Fn")),
            ty::ClosureKind::FnMut => p!(write("FnMut")),
            ty::ClosureKind::FnOnce => p!(write("FnOnce")),
        }
    }

    ty::Predicate<'tcx> {
        match self.kind() {
            &ty::PredicateKind::Trait(ref data, constness) => {
                if let hir::Constness::Const = constness {
                    p!(write("const "));
                }
                p!(print(data))
            }
            ty::PredicateKind::Subtype(predicate) => p!(print(predicate)),
            ty::PredicateKind::RegionOutlives(predicate) => p!(print(predicate)),
            ty::PredicateKind::TypeOutlives(predicate) => p!(print(predicate)),
            ty::PredicateKind::Projection(predicate) => p!(print(predicate)),
            ty::PredicateKind::WellFormed(arg) => p!(print(arg), write(" well-formed")),
            &ty::PredicateKind::ObjectSafe(trait_def_id) => {
                p!(write("the trait `"),
                   print_def_path(trait_def_id, &[]),
                   write("` is object-safe"))
            }
            &ty::PredicateKind::ClosureKind(closure_def_id, _closure_substs, kind) => {
                p!(write("the closure `"),
                   print_value_path(closure_def_id, &[]),
                   write("` implements the trait `{}`", kind))
            }
            &ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
                p!(write("the constant `"),
                   print_value_path(def_id, substs),
                   write("` can be evaluated"))
            }
            ty::PredicateKind::ConstEquate(c1, c2) => {
                p!(write("the constant `"),
                   print(c1),
                   write("` equals `"),
                   print(c2),
                   write("`"))
            }
        }
    }

    GenericArg<'tcx> {
        match self.unpack() {
            GenericArgKind::Lifetime(lt) => p!(print(lt)),
            GenericArgKind::Type(ty) => p!(print(ty)),
            GenericArgKind::Const(ct) => p!(print(ct)),
        }
    }
}
