Skip to content

Commit 1a0f3a2

Browse files
committed
rustc: streamline the Print/fmt::Display impls in ppaux and move them to ty::print::pretty.
1 parent 030cdc9 commit 1a0f3a2

File tree

4 files changed

+303
-425
lines changed

4 files changed

+303
-425
lines changed

src/librustc/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ pub mod ty;
135135
pub mod util {
136136
pub mod captures;
137137
pub mod common;
138-
mod ppaux;
139138
pub mod nodemap;
140139
pub mod profiling;
141140
pub mod bug;

src/librustc/ty/print/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,8 @@ use std::ops::Deref;
1313
mod pretty;
1414
pub use self::pretty::*;
1515

16-
// FIXME(eddyb) this module uses `pub(crate)` for things used only
17-
// from `ppaux` - when that is removed, they can be re-privatized.
18-
1916
#[derive(Default)]
20-
pub(crate) struct PrintConfig {
17+
struct PrintConfig {
2118
used_region_names: Option<FxHashSet<InternedString>>,
2219
region_index: usize,
2320
binder_depth: usize,
@@ -26,7 +23,7 @@ pub(crate) struct PrintConfig {
2623
pub struct PrintCx<'a, 'gcx, 'tcx, P> {
2724
pub tcx: TyCtxt<'a, 'gcx, 'tcx>,
2825
pub printer: P,
29-
pub(crate) config: &'a mut PrintConfig,
26+
config: &'a mut PrintConfig,
3027
}
3128

3229
// 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> {
5148
})
5249
}
5350

54-
pub(crate) fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
51+
pub fn with_tls_tcx<R>(printer: P, f: impl FnOnce(PrintCx<'_, '_, '_, P>) -> R) -> R {
5552
ty::tls::with(|tcx| PrintCx::with(tcx, printer, f))
5653
}
5754
}

src/librustc/ty/print/pretty.rs

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind};
99
use crate::mir::interpret::ConstValue;
1010
use syntax::symbol::{keywords, Symbol};
1111

12+
use rustc_target::spec::abi::Abi;
1213
use syntax::symbol::InternedString;
1314

1415
use std::cell::Cell;
@@ -1357,3 +1358,302 @@ impl<T, P: PrettyPrinter> Print<'tcx, P> for ty::Binder<T>
13571358
cx.in_binder(self)
13581359
}
13591360
}
1361+
1362+
pub trait LiftAndPrintToFmt<'tcx> {
1363+
fn lift_and_print_to_fmt(
1364+
&self,
1365+
tcx: TyCtxt<'_, '_, 'tcx>,
1366+
f: &mut fmt::Formatter<'_>,
1367+
) -> fmt::Result;
1368+
}
1369+
1370+
impl<T> LiftAndPrintToFmt<'tcx> for T
1371+
where T: ty::Lift<'tcx>,
1372+
for<'a, 'b> <T as ty::Lift<'tcx>>::Lifted:
1373+
Print<'tcx, FmtPrinter<&'a mut fmt::Formatter<'b>>, Error = fmt::Error>
1374+
{
1375+
fn lift_and_print_to_fmt(
1376+
&self,
1377+
tcx: TyCtxt<'_, '_, 'tcx>,
1378+
f: &mut fmt::Formatter<'_>,
1379+
) -> fmt::Result {
1380+
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
1381+
cx.tcx.lift(self).expect("could not lift for printing").print(cx)?;
1382+
Ok(())
1383+
})
1384+
}
1385+
}
1386+
1387+
// HACK(eddyb) this is separate because `ty::RegionKind` doesn't need lifting.
1388+
impl LiftAndPrintToFmt<'tcx> for ty::RegionKind {
1389+
fn lift_and_print_to_fmt(
1390+
&self,
1391+
tcx: TyCtxt<'_, '_, 'tcx>,
1392+
f: &mut fmt::Formatter<'_>,
1393+
) -> fmt::Result {
1394+
PrintCx::with(tcx, FmtPrinter::new(f, Namespace::TypeNS), |cx| {
1395+
self.print(cx)?;
1396+
Ok(())
1397+
})
1398+
}
1399+
}
1400+
1401+
macro_rules! forward_display_to_print {
1402+
(<$($T:ident),*> $ty:ty) => {
1403+
impl<$($T),*> fmt::Display for $ty
1404+
where Self: for<'a> LiftAndPrintToFmt<'a>
1405+
{
1406+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1407+
ty::tls::with(|tcx| self.lift_and_print_to_fmt(tcx, f))
1408+
}
1409+
}
1410+
};
1411+
1412+
($ty:ty) => {
1413+
forward_display_to_print!(<> $ty);
1414+
};
1415+
}
1416+
1417+
macro_rules! define_print_and_forward_display {
1418+
(($self:ident, $cx:ident): <$($T:ident),*> $ty:ty $print:block) => {
1419+
impl<$($T,)* P: PrettyPrinter> Print<'tcx, P> for $ty
1420+
where $($T: Print<'tcx, P, Output = P, Error = P::Error>),*
1421+
{
1422+
type Output = P;
1423+
type Error = fmt::Error;
1424+
fn print(&$self, $cx: PrintCx<'_, '_, 'tcx, P>) -> Result<Self::Output, Self::Error> {
1425+
#[allow(unused_mut)]
1426+
let mut $cx = $cx;
1427+
define_scoped_cx!($cx);
1428+
let _: () = $print;
1429+
#[allow(unreachable_code)]
1430+
Ok($cx.printer)
1431+
}
1432+
}
1433+
1434+
forward_display_to_print!(<$($T),*> $ty);
1435+
};
1436+
1437+
(($self:ident, $cx:ident): $($ty:ty $print:block)+) => {
1438+
$(define_print_and_forward_display!(($self, $cx): <> $ty $print);)+
1439+
};
1440+
}
1441+
1442+
forward_display_to_print!(ty::RegionKind);
1443+
forward_display_to_print!(Ty<'tcx>);
1444+
forward_display_to_print!(<T> ty::Binder<T>);
1445+
1446+
define_print_and_forward_display! {
1447+
(self, cx):
1448+
1449+
<T, U> ty::OutlivesPredicate<T, U> {
1450+
p!(print(self.0), write(" : "), print(self.1))
1451+
}
1452+
}
1453+
1454+
define_print_and_forward_display! {
1455+
(self, cx):
1456+
1457+
&'tcx ty::List<ty::ExistentialPredicate<'tcx>> {
1458+
// Generate the main trait ref, including associated types.
1459+
let mut first = true;
1460+
1461+
if let Some(principal) = self.principal() {
1462+
let mut resugared_principal = false;
1463+
1464+
// Special-case `Fn(...) -> ...` and resugar it.
1465+
let fn_trait_kind = cx.tcx.lang_items().fn_trait_kind(principal.def_id);
1466+
if !cx.tcx.sess.verbose() && fn_trait_kind.is_some() {
1467+
if let ty::Tuple(ref args) = principal.substs.type_at(0).sty {
1468+
let mut projections = self.projection_bounds();
1469+
if let (Some(proj), None) = (projections.next(), projections.next()) {
1470+
nest!(|cx| cx.print_def_path(principal.def_id, None, iter::empty()));
1471+
nest!(|cx| cx.pretty_fn_sig(args, false, proj.ty));
1472+
resugared_principal = true;
1473+
}
1474+
}
1475+
}
1476+
1477+
if !resugared_principal {
1478+
// Use a type that can't appear in defaults of type parameters.
1479+
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
1480+
let principal = principal.with_self_ty(cx.tcx, dummy_self);
1481+
nest!(|cx| cx.print_def_path(
1482+
principal.def_id,
1483+
Some(principal.substs),
1484+
self.projection_bounds(),
1485+
));
1486+
}
1487+
first = false;
1488+
}
1489+
1490+
// Builtin bounds.
1491+
// FIXME(eddyb) avoid printing twice (needed to ensure
1492+
// that the auto traits are sorted *and* printed via cx).
1493+
let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
1494+
(cx.tcx.def_path_str(did), did)
1495+
}).collect();
1496+
1497+
// The auto traits come ordered by `DefPathHash`. While
1498+
// `DefPathHash` is *stable* in the sense that it depends on
1499+
// neither the host nor the phase of the moon, it depends
1500+
// "pseudorandomly" on the compiler version and the target.
1501+
//
1502+
// To avoid that causing instabilities in compiletest
1503+
// output, sort the auto-traits alphabetically.
1504+
auto_traits.sort();
1505+
1506+
for (_, def_id) in auto_traits {
1507+
if !first {
1508+
p!(write(" + "));
1509+
}
1510+
first = false;
1511+
1512+
nest!(|cx| cx.print_def_path(def_id, None, iter::empty()));
1513+
}
1514+
}
1515+
1516+
&'tcx ty::List<Ty<'tcx>> {
1517+
p!(write("{{"));
1518+
let mut tys = self.iter();
1519+
if let Some(&ty) = tys.next() {
1520+
p!(print(ty));
1521+
for &ty in tys {
1522+
p!(write(", "), print(ty));
1523+
}
1524+
}
1525+
p!(write("}}"))
1526+
}
1527+
1528+
ty::TypeAndMut<'tcx> {
1529+
p!(write("{}", if self.mutbl == hir::MutMutable { "mut " } else { "" }),
1530+
print(self.ty))
1531+
}
1532+
1533+
ty::ExistentialTraitRef<'tcx> {
1534+
let dummy_self = cx.tcx.mk_infer(ty::FreshTy(0));
1535+
1536+
let trait_ref = *ty::Binder::bind(*self)
1537+
.with_self_ty(cx.tcx, dummy_self)
1538+
.skip_binder();
1539+
p!(print(trait_ref))
1540+
}
1541+
1542+
ty::FnSig<'tcx> {
1543+
if self.unsafety == hir::Unsafety::Unsafe {
1544+
p!(write("unsafe "));
1545+
}
1546+
1547+
if self.abi != Abi::Rust {
1548+
p!(write("extern {} ", self.abi));
1549+
}
1550+
1551+
p!(write("fn"));
1552+
nest!(|cx| cx.pretty_fn_sig(self.inputs(), self.c_variadic, self.output()));
1553+
}
1554+
1555+
ty::InferTy {
1556+
if cx.tcx.sess.verbose() {
1557+
p!(write("{:?}", self));
1558+
return Ok(cx.printer);
1559+
}
1560+
match *self {
1561+
ty::TyVar(_) => p!(write("_")),
1562+
ty::IntVar(_) => p!(write("{}", "{integer}")),
1563+
ty::FloatVar(_) => p!(write("{}", "{float}")),
1564+
ty::FreshTy(v) => p!(write("FreshTy({})", v)),
1565+
ty::FreshIntTy(v) => p!(write("FreshIntTy({})", v)),
1566+
ty::FreshFloatTy(v) => p!(write("FreshFloatTy({})", v))
1567+
}
1568+
}
1569+
1570+
ty::TraitRef<'tcx> {
1571+
nest!(|cx| cx.print_def_path(self.def_id, Some(self.substs), iter::empty()));
1572+
}
1573+
1574+
ConstValue<'tcx> {
1575+
match self {
1576+
ConstValue::Infer(..) => p!(write("_")),
1577+
ConstValue::Param(ParamConst { name, .. }) => p!(write("{}", name)),
1578+
_ => p!(write("{:?}", self)),
1579+
}
1580+
}
1581+
1582+
ty::Const<'tcx> {
1583+
p!(write("{} : {}", self.val, self.ty))
1584+
}
1585+
1586+
ty::LazyConst<'tcx> {
1587+
match self {
1588+
// FIXME(const_generics) this should print at least the type.
1589+
ty::LazyConst::Unevaluated(..) => p!(write("_ : _")),
1590+
ty::LazyConst::Evaluated(c) => p!(write("{}", c)),
1591+
}
1592+
}
1593+
1594+
ty::ParamTy {
1595+
p!(write("{}", self.name))
1596+
}
1597+
1598+
ty::ParamConst {
1599+
p!(write("{}", self.name))
1600+
}
1601+
1602+
ty::SubtypePredicate<'tcx> {
1603+
p!(print(self.a), write(" <: "), print(self.b))
1604+
}
1605+
1606+
ty::TraitPredicate<'tcx> {
1607+
p!(print(self.trait_ref.self_ty()), write(": "), print(self.trait_ref))
1608+
}
1609+
1610+
ty::ProjectionPredicate<'tcx> {
1611+
p!(print(self.projection_ty), write(" == "), print(self.ty))
1612+
}
1613+
1614+
ty::ProjectionTy<'tcx> {
1615+
nest!(|cx| cx.print_def_path(self.item_def_id, Some(self.substs), iter::empty()));
1616+
}
1617+
1618+
ty::ClosureKind {
1619+
match *self {
1620+
ty::ClosureKind::Fn => p!(write("Fn")),
1621+
ty::ClosureKind::FnMut => p!(write("FnMut")),
1622+
ty::ClosureKind::FnOnce => p!(write("FnOnce")),
1623+
}
1624+
}
1625+
1626+
ty::Predicate<'tcx> {
1627+
match *self {
1628+
ty::Predicate::Trait(ref data) => p!(print(data)),
1629+
ty::Predicate::Subtype(ref predicate) => p!(print(predicate)),
1630+
ty::Predicate::RegionOutlives(ref predicate) => p!(print(predicate)),
1631+
ty::Predicate::TypeOutlives(ref predicate) => p!(print(predicate)),
1632+
ty::Predicate::Projection(ref predicate) => p!(print(predicate)),
1633+
ty::Predicate::WellFormed(ty) => p!(print(ty), write(" well-formed")),
1634+
ty::Predicate::ObjectSafe(trait_def_id) => {
1635+
p!(write("the trait `"));
1636+
nest!(|cx| cx.print_def_path(trait_def_id, None, iter::empty()));
1637+
p!(write("` is object-safe"))
1638+
}
1639+
ty::Predicate::ClosureKind(closure_def_id, _closure_substs, kind) => {
1640+
p!(write("the closure `"));
1641+
nest!(|cx| cx.print_value_path(closure_def_id, None));
1642+
p!(write("` implements the trait `{}`", kind))
1643+
}
1644+
ty::Predicate::ConstEvaluatable(def_id, substs) => {
1645+
p!(write("the constant `"));
1646+
nest!(|cx| cx.print_value_path(def_id, Some(substs)));
1647+
p!(write("` can be evaluated"))
1648+
}
1649+
}
1650+
}
1651+
1652+
Kind<'tcx> {
1653+
match self.unpack() {
1654+
UnpackedKind::Lifetime(lt) => p!(print(lt)),
1655+
UnpackedKind::Type(ty) => p!(print(ty)),
1656+
UnpackedKind::Const(ct) => p!(print(ct)),
1657+
}
1658+
}
1659+
}

0 commit comments

Comments
 (0)