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