mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
rustc: streamline the Print/fmt::Display impls in ppaux and move them to ty::print::pretty.
This commit is contained in:
parent
030cdc9729
commit
1a0f3a2856
@ -135,7 +135,6 @@ pub mod ty;
|
||||
pub mod util {
|
||||
pub mod captures;
|
||||
pub mod common;
|
||||
mod ppaux;
|
||||
pub mod nodemap;
|
||||
pub mod profiling;
|
||||
pub mod bug;
|
||||
|
@ -13,11 +13,8 @@ use std::ops::Deref;
|
||||
mod pretty;
|
||||
pub use self::pretty::*;
|
||||
|
||||
// FIXME(eddyb) this module uses `pub(crate)` for things used only
|
||||
// from `ppaux` - when that is removed, they can be re-privatized.
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct PrintConfig {
|
||||
struct PrintConfig {
|
||||
used_region_names: Option<FxHashSet<InternedString>>,
|
||||
region_index: usize,
|
||||
binder_depth: usize,
|
||||
@ -26,7 +23,7 @@ pub(crate) struct PrintConfig {
|
||||
pub struct PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
pub printer: P,
|
||||
pub(crate) config: &'a mut PrintConfig,
|
||||
config: &'a mut PrintConfig,
|
||||
}
|
||||
|
||||
// HACK(eddyb) this is solely for `self: PrintCx<Self>`, e.g. to
|
||||
@ -51,7 +48,7 @@ impl<'a, 'gcx, 'tcx, P> PrintCx<'a, 'gcx, 'tcx, P> {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
|
||||
pub fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
|
||||
ty::tls::with(|tcx| PrintCx::with(tcx, printer, f))
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind};
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use syntax::symbol::{keywords, Symbol};
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
use syntax::symbol::InternedString;
|
||||
|
||||
use std::cell::Cell;
|
||||
@ -1357,3 +1358,302 @@ impl<T, P: PrettyPrinter> Print<'tcx, P> for ty::Binder<T>
|
||||
cx.in_binder(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait LiftAndPrintToFmt<'tcx> {
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result;
|
||||
}
|
||||
|
||||
impl<T> LiftAndPrintToFmt<'tcx> for T
|
||||
where T: ty::Lift<'tcx>,
|
||||
for<'a, 'b> <T as ty::Lift<'tcx>>::Lifted:
|
||||
Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error>
|
||||
{
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
|
||||
cx.tcx.lift(self).expect("could not lift for printing").print(cx)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
|
||||
impl LiftAndPrintToFmt<'tcx> for ty::RegionKind {
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
|
||||
self.print(cx)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! forward_display_to_print {
|
||||
(<$($T:ident),*> $ty:ty) => {
|
||||
impl<$($T),*> fmt::Display for $ty
|
||||
where Self: for<'a> LiftAndPrintToFmt<'a>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($ty:ty) => {
|
||||
forward_display_to_print!(<> $ty);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! define_print_and_forward_display {
|
||||
(($self:ident, $cx:ident): <$($T:ident),*> $ty:ty $print:block) => {
|
||||
impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $ty
|
||||
where $($T: Print<'tcx, P, Output = P, Error = P::Error>),*
|
||||
{
|
||||
type Output = P;
|
||||
type Error = fmt::Error;
|
||||
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
#[allow(unused_mut)]
|
||||
let mut $cx = $cx;
|
||||
define_scoped_cx!($cx);
|
||||
let _: () = $print;
|
||||
#[allow(unreachable_code)]
|
||||
Ok($cx.printer)
|
||||
}
|
||||
}
|
||||
|
||||
forward_display_to_print!(<$($T),*> $ty);
|
||||
};
|
||||
|
||||
(($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
|
||||
$(define_print_and_forward_display!(($self, $cx): <> $ty $print);)+
|
||||
};
|
||||
}
|
||||
|
||||
forward_display_to_print!(ty::RegionKind);
|
||||
forward_display_to_print!(Ty<'tcx>);
|
||||
forward_display_to_print!(<T> ty::Binder<T>);
|
||||
|
||||
define_print_and_forward_display! {
|
||||
(self, cx):
|
||||
|
||||
<T, U> ty::OutlivesPredicate<T, U> {
|
||||
p!(print(self.0), write(" : "), print(self.1))
|
||||
}
|
||||
}
|
||||
|
||||
define_print_and_forward_display! {
|
||||
(self, cx):
|
||||
|
||||
&'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
|
||||
// Generate the main trait ref, including associated types.
|
||||
let mut first = true;
|
||||
|
||||
if let Some(principal) = self.principal() {
|
||||
let mut resugared_principal = false;
|
||||
|
||||
// Special-case `Fn(...) -> ...` and resugar it.
|
||||
let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
|
||||
if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() {
|
||||
if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
|
||||
let mut projections = self.projection_bounds();
|
||||
if let (Some(proj), None) = (projections.next(), projections.next()) {
|
||||
nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty()));
|
||||
nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty));
|
||||
resugared_principal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !resugared_principal {
|
||||
// Use a type that can't appear in defaults of type parameters.
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
let principal = principal.with_self_ty(cx.tcx, dummy_self);
|
||||
nest!(|cx| cx.print_def_path(
|
||||
principal.def_id,
|
||||
Some(principal.substs),
|
||||
self.projection_bounds(),
|
||||
));
|
||||
}
|
||||
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<_> = self.auto_traits().map(|did| {
|
||||
(cx.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;
|
||||
|
||||
nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
|
||||
}
|
||||
}
|
||||
|
||||
&'tcx ty::List<Ty<'tcx>> {
|
||||
p!(write("{{"));
|
||||
let mut tys = self.iter();
|
||||
if let Some(&ty) = tys.next() {
|
||||
p!(print(ty));
|
||||
for &ty in tys {
|
||||
p!(write(", "), print(ty));
|
||||
}
|
||||
}
|
||||
p!(write("}}"))
|
||||
}
|
||||
|
||||
ty::TypeAndMut<'tcx> {
|
||||
p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
|
||||
print(self.ty))
|
||||
}
|
||||
|
||||
ty::ExistentialTraitRef<'tcx> {
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
|
||||
let trait_ref = *ty::Binder::bind(*self)
|
||||
.with_self_ty(cx.tcx, dummy_self)
|
||||
.skip_binder();
|
||||
p!(print(trait_ref))
|
||||
}
|
||||
|
||||
ty::FnSig<'tcx> {
|
||||
if self.unsafety == hir::Unsafety::Unsafe {
|
||||
p!(write("unsafe "));
|
||||
}
|
||||
|
||||
if self.abi != Abi::Rust {
|
||||
p!(write("extern {} ", self.abi));
|
||||
}
|
||||
|
||||
p!(write("fn"));
|
||||
nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
|
||||
ty::InferTy {
|
||||
if cx.tcx.sess.verbose() {
|
||||
p!(write("{:?}", self));
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
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> {
|
||||
nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty()));
|
||||
}
|
||||
|
||||
ConstValue<'tcx> {
|
||||
match self {
|
||||
ConstValue::Infer(..) => p!(write("_")),
|
||||
ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
|
||||
_ => p!(write("{:?}", self)),
|
||||
}
|
||||
}
|
||||
|
||||
ty::Const<'tcx> {
|
||||
p!(write("{} : {}", self.val, self.ty))
|
||||
}
|
||||
|
||||
ty::LazyConst<'tcx> {
|
||||
match self {
|
||||
// FIXME(const_generics) this should print at least the type.
|
||||
ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
|
||||
ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
ty::ProjectionPredicate<'tcx> {
|
||||
p!(print(self.projection_ty), write(" == "), print(self.ty))
|
||||
}
|
||||
|
||||
ty::ProjectionTy<'tcx> {
|
||||
nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty()));
|
||||
}
|
||||
|
||||
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 {
|
||||
ty::Predicate::Trait(ref data) => p!(print(data)),
|
||||
ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
p!(write("the trait `"));
|
||||
nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty()));
|
||||
p!(write("` is object-safe"))
|
||||
}
|
||||
ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
|
||||
p!(write("the closure `"));
|
||||
nest!(|cx| cx.print_value_path(closure_def_id, None));
|
||||
p!(write("` implements the trait `{}`", kind))
|
||||
}
|
||||
ty::Predicate::ConstEvaluatable(def_id, substs) => {
|
||||
p!(write("the constant `"));
|
||||
nest!(|cx| cx.print_value_path(def_id, Some(substs)));
|
||||
p!(write("` can be evaluated"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kind<'tcx> {
|
||||
match self.unpack() {
|
||||
UnpackedKind::Lifetime(lt) => p!(print(lt)),
|
||||
UnpackedKind::Type(ty) => p!(print(ty)),
|
||||
UnpackedKind::Const(ct) => p!(print(ct)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,418 +0,0 @@
|
||||
use crate::hir;
|
||||
use crate::hir::def::Namespace;
|
||||
use crate::ty::subst::{Kind, UnpackedKind};
|
||||
use crate::ty::{self, ParamConst, Ty, TyCtxt};
|
||||
use crate::ty::print::{FmtPrinter, PrettyPrinter, PrintCx, Print};
|
||||
use crate::mir::interpret::ConstValue;
|
||||
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
pub trait LiftAndPrintToFmt<'tcx> {
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result;
|
||||
}
|
||||
|
||||
impl<T> LiftAndPrintToFmt<'tcx> for T
|
||||
where T: ty::Lift<'tcx>,
|
||||
for<'a, 'b> <T as ty::Lift<'tcx>>::Lifted:
|
||||
Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error>
|
||||
{
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
|
||||
cx.tcx.lift(self).expect("could not lift for printing").print(cx)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
|
||||
impl LiftAndPrintToFmt<'tcx> for ty::RegionKind {
|
||||
fn lift_and_print_to_fmt(
|
||||
&self,
|
||||
tcx: TyCtxt<'_, '_, 'tcx>,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
) -> fmt::Result {
|
||||
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
|
||||
self.print(cx)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! define_print {
|
||||
(<$($T:ident),*> $target:ty) => {
|
||||
impl<$($T),*> fmt::Display for $target
|
||||
where Self: for<'a> LiftAndPrintToFmt<'a>
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(<$($T:ident),*> $target:ty, ($self:ident, $cx:ident) { display $disp:block }) => {
|
||||
impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $target
|
||||
where $($T: Print<'tcx, P, Output = P, Error = P::Error>),*
|
||||
{
|
||||
type Output = P;
|
||||
type Error = fmt::Error;
|
||||
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
|
||||
#[allow(unused_mut)]
|
||||
let mut $cx = $cx;
|
||||
define_scoped_cx!($cx);
|
||||
let _: () = $disp;
|
||||
#[allow(unreachable_code)]
|
||||
Ok($cx.printer)
|
||||
}
|
||||
}
|
||||
|
||||
define_print!(<$($T),*> $target);
|
||||
};
|
||||
|
||||
($target:ty) => {
|
||||
define_print!(<> $target);
|
||||
};
|
||||
|
||||
($target:ty, ($self:ident, $cx:ident) { display $disp:block }) => {
|
||||
define_print!(<> $target, ($self, $cx) { display $disp });
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! nest {
|
||||
($closure:expr) => {
|
||||
scoped_cx!() = scoped_cx!().nest($closure)?
|
||||
}
|
||||
}
|
||||
macro_rules! print_inner {
|
||||
(write ($($data:expr),+)) => {
|
||||
write!(scoped_cx!().printer, $($data),+)?
|
||||
};
|
||||
($kind:ident ($data:expr)) => {
|
||||
nest!(|cx| $data.$kind(cx))
|
||||
};
|
||||
}
|
||||
macro_rules! p {
|
||||
($($kind:ident $data:tt),+) => {
|
||||
{
|
||||
$(print_inner!($kind $data));+
|
||||
}
|
||||
};
|
||||
}
|
||||
macro_rules! define_scoped_cx {
|
||||
($cx:ident) => {
|
||||
#[allow(unused_macros)]
|
||||
macro_rules! scoped_cx {
|
||||
() => ($cx)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
define_print! {
|
||||
&'tcx ty::List<ty::ExistentialPredicate<'tcx>>, (self, cx) {
|
||||
display {
|
||||
// Generate the main trait ref, including associated types.
|
||||
let mut first = true;
|
||||
|
||||
if let Some(principal) = self.principal() {
|
||||
let mut resugared_principal = false;
|
||||
|
||||
// Special-case `Fn(...) -> ...` and resugar it.
|
||||
let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
|
||||
if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() {
|
||||
if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
|
||||
let mut projections = self.projection_bounds();
|
||||
if let (Some(proj), None) = (projections.next(), projections.next()) {
|
||||
nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty()));
|
||||
nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty));
|
||||
resugared_principal = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !resugared_principal {
|
||||
// Use a type that can't appear in defaults of type parameters.
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
let principal = principal.with_self_ty(cx.tcx, dummy_self);
|
||||
nest!(|cx| cx.print_def_path(
|
||||
principal.def_id,
|
||||
Some(principal.substs),
|
||||
self.projection_bounds(),
|
||||
));
|
||||
}
|
||||
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<_> = self.auto_traits().map(|did| {
|
||||
(cx.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;
|
||||
|
||||
nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
&'tcx ty::List<Ty<'tcx>>, (self, cx) {
|
||||
display {
|
||||
p!(write("{{"));
|
||||
let mut tys = self.iter();
|
||||
if let Some(&ty) = tys.next() {
|
||||
p!(print(ty));
|
||||
for &ty in tys {
|
||||
p!(write(", "), print(ty));
|
||||
}
|
||||
}
|
||||
p!(write("}}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::TypeAndMut<'tcx>, (self, cx) {
|
||||
display {
|
||||
p!(
|
||||
write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
|
||||
print(self.ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ExistentialTraitRef<'tcx>, (self, cx) {
|
||||
display {
|
||||
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
|
||||
|
||||
let trait_ref = *ty::Binder::bind(*self)
|
||||
.with_self_ty(cx.tcx, dummy_self)
|
||||
.skip_binder();
|
||||
p!(print(trait_ref))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::RegionKind
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::FnSig<'tcx>, (self, cx) {
|
||||
display {
|
||||
if self.unsafety == hir::Unsafety::Unsafe {
|
||||
p!(write("unsafe "));
|
||||
}
|
||||
|
||||
if self.abi != Abi::Rust {
|
||||
p!(write("extern {} ", self.abi));
|
||||
}
|
||||
|
||||
p!(write("fn"));
|
||||
nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::InferTy, (self, cx) {
|
||||
display {
|
||||
if cx.tcx.sess.verbose() {
|
||||
p!(write("{:?}", self));
|
||||
return Ok(cx.printer);
|
||||
}
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
<T> ty::Binder<T>
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::TraitRef<'tcx>, (self, cx) {
|
||||
display {
|
||||
nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
Ty<'tcx>
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ConstValue<'tcx>, (self, cx) {
|
||||
display {
|
||||
match self {
|
||||
ConstValue::Infer(..) => p!(write("_")),
|
||||
ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
|
||||
_ => p!(write("{:?}", self)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::Const<'tcx>, (self, cx) {
|
||||
display {
|
||||
p!(write("{} : {}", self.val, self.ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::LazyConst<'tcx>, (self, cx) {
|
||||
display {
|
||||
match self {
|
||||
// FIXME(const_generics) this should print at least the type.
|
||||
ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
|
||||
ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ParamTy, (self, cx) {
|
||||
display {
|
||||
p!(write("{}", self.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ParamConst, (self, cx) {
|
||||
display {
|
||||
p!(write("{}", self.name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
<T, U> ty::OutlivesPredicate<T, U>, (self, cx) {
|
||||
display {
|
||||
p!(print(self.0), write(" : "), print(self.1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::SubtypePredicate<'tcx>, (self, cx) {
|
||||
display {
|
||||
p!(print(self.a), write(" <: "), print(self.b))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::TraitPredicate<'tcx>, (self, cx) {
|
||||
display {
|
||||
p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ProjectionPredicate<'tcx>, (self, cx) {
|
||||
display {
|
||||
p!(print(self.projection_ty), write(" == "), print(self.ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ProjectionTy<'tcx>, (self, cx) {
|
||||
display {
|
||||
nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::ClosureKind, (self, cx) {
|
||||
display {
|
||||
match *self {
|
||||
ty::ClosureKind::Fn => p!(write("Fn")),
|
||||
ty::ClosureKind::FnMut => p!(write("FnMut")),
|
||||
ty::ClosureKind::FnOnce => p!(write("FnOnce")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
ty::Predicate<'tcx>, (self, cx) {
|
||||
display {
|
||||
match *self {
|
||||
ty::Predicate::Trait(ref data) => p!(print(data)),
|
||||
ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
|
||||
ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
|
||||
ty::Predicate::ObjectSafe(trait_def_id) => {
|
||||
p!(write("the trait `"));
|
||||
nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty()));
|
||||
p!(write("` is object-safe"))
|
||||
}
|
||||
ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
|
||||
p!(write("the closure `"));
|
||||
nest!(|cx| cx.print_value_path(closure_def_id, None));
|
||||
p!(write("` implements the trait `{}`", kind))
|
||||
}
|
||||
ty::Predicate::ConstEvaluatable(def_id, substs) => {
|
||||
p!(write("the constant `"));
|
||||
nest!(|cx| cx.print_value_path(def_id, Some(substs)));
|
||||
p!(write("` can be evaluated"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_print! {
|
||||
Kind<'tcx>, (self, cx) {
|
||||
display {
|
||||
match self.unpack() {
|
||||
UnpackedKind::Lifetime(lt) => p!(print(lt)),
|
||||
UnpackedKind::Type(ty) => p!(print(ty)),
|
||||
UnpackedKind::Const(ct) => p!(print(ct)),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user