@@ -9,6 +9,7 @@ use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind};
99use crate :: mir:: interpret:: ConstValue ;
1010use syntax:: symbol:: { keywords, Symbol } ;
1111
12+ use rustc_target:: spec:: abi:: Abi ;
1213use syntax:: symbol:: InternedString ;
1314
1415use 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