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