@@ -9,6 +9,7 @@ use crate::ty::subst::{Kind, Subst, SubstsRef, UnpackedKind};
9
9
use crate :: mir:: interpret:: ConstValue ;
10
10
use syntax:: symbol:: { keywords, Symbol } ;
11
11
12
+ use rustc_target:: spec:: abi:: Abi ;
12
13
use syntax:: symbol:: InternedString ;
13
14
14
15
use std:: cell:: Cell ;
@@ -1357,3 +1358,302 @@ impl<T, P: PrettyPrinter> Print<'tcx, P> for ty::Binder<T>
1357
1358
cx. in_binder ( self )
1358
1359
}
1359
1360
}
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