@@ -19,7 +19,7 @@ use std::cmp;
19
19
use std:: fmt;
20
20
use std:: i128;
21
21
use std:: mem;
22
- use std:: ops:: { Deref , RangeInclusive } ;
22
+ use std:: ops:: RangeInclusive ;
23
23
24
24
use ich:: StableHashingContext ;
25
25
use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher ,
@@ -801,9 +801,9 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
801
801
802
802
if let Some ( i) = dataful_variant {
803
803
let count = ( niche_variants. end - niche_variants. start + 1 ) as u128 ;
804
- for ( field_index, field) in variants[ i] . iter ( ) . enumerate ( ) {
804
+ for ( field_index, & field) in variants[ i] . iter ( ) . enumerate ( ) {
805
805
let ( offset, niche, niche_start) =
806
- match field . find_niche ( self , count) ? {
806
+ match self . find_niche ( field , count) ? {
807
807
Some ( niche) => niche,
808
808
None => continue
809
809
} ;
@@ -1300,26 +1300,6 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
1300
1300
}
1301
1301
}
1302
1302
1303
- /// The details of the layout of a type, alongside the type itself.
1304
- /// Provides various type traversal APIs (e.g. recursing into fields).
1305
- ///
1306
- /// Note that the details are NOT guaranteed to always be identical
1307
- /// to those obtained from `layout_of(ty)`, as we need to produce
1308
- /// layouts for which Rust types do not exist, such as enum variants
1309
- /// or synthetic fields of enums (i.e. discriminants) and fat pointers.
1310
- #[ derive( Copy , Clone , Debug ) ]
1311
- pub struct TyLayout < ' tcx > {
1312
- pub ty : Ty < ' tcx > ,
1313
- details : & ' tcx LayoutDetails
1314
- }
1315
-
1316
- impl < ' tcx > Deref for TyLayout < ' tcx > {
1317
- type Target = & ' tcx LayoutDetails ;
1318
- fn deref ( & self ) -> & & ' tcx LayoutDetails {
1319
- & self . details
1320
- }
1321
- }
1322
-
1323
1303
pub trait HasTyCtxt < ' tcx > : HasDataLayout {
1324
1304
fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
1325
1305
}
@@ -1371,6 +1351,8 @@ impl<T, E> MaybeResult<T> for Result<T, E> {
1371
1351
}
1372
1352
}
1373
1353
1354
+ pub type TyLayout < ' tcx > = :: rustc_target:: abi:: TyLayout < ' tcx , Ty < ' tcx > > ;
1355
+
1374
1356
impl < ' a , ' tcx > LayoutOf for LayoutCx < ' tcx , TyCtxt < ' a , ' tcx , ' tcx > > {
1375
1357
type Ty = Ty < ' tcx > ;
1376
1358
type TyLayout = Result < TyLayout < ' tcx > , LayoutError < ' tcx > > ;
@@ -1458,22 +1440,22 @@ impl<'a, 'tcx> ty::maps::TyCtxtAt<'a, 'tcx, 'tcx> {
1458
1440
}
1459
1441
}
1460
1442
1461
- impl < ' a , ' tcx > TyLayout < ' tcx > {
1462
- pub fn for_variant < C > ( & self , cx : C , variant_index : usize ) -> Self
1463
- where C : LayoutOf < Ty = Ty < ' tcx > > + HasTyCtxt < ' tcx > ,
1464
- C :: TyLayout : MaybeResult < TyLayout < ' tcx > >
1465
- {
1466
- let details = match self . variants {
1467
- Variants :: Single { index } if index == variant_index => self . details ,
1443
+ impl < ' a , ' tcx , C > TyLayoutMethods < ' tcx , C > for Ty < ' tcx >
1444
+ where C : LayoutOf < Ty = Ty < ' tcx > > + HasTyCtxt < ' tcx > ,
1445
+ C :: TyLayout : MaybeResult < TyLayout < ' tcx > >
1446
+ {
1447
+ fn for_variant ( this : TyLayout < ' tcx > , cx : C , variant_index : usize ) -> TyLayout < ' tcx > {
1448
+ let details = match this . variants {
1449
+ Variants :: Single { index } if index == variant_index => this . details ,
1468
1450
1469
1451
Variants :: Single { index } => {
1470
1452
// Deny calling for_variant more than once for non-Single enums.
1471
- cx. layout_of ( self . ty ) . map_same ( |layout| {
1453
+ cx. layout_of ( this . ty ) . map_same ( |layout| {
1472
1454
assert_eq ! ( layout. variants, Variants :: Single { index } ) ;
1473
1455
layout
1474
1456
} ) ;
1475
1457
1476
- let fields = match self . ty . sty {
1458
+ let fields = match this . ty . sty {
1477
1459
ty:: TyAdt ( def, _) => def. variants [ variant_index] . fields . len ( ) ,
1478
1460
_ => bug ! ( )
1479
1461
} ;
@@ -1491,17 +1473,14 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1491
1473
assert_eq ! ( details. variants, Variants :: Single { index: variant_index } ) ;
1492
1474
1493
1475
TyLayout {
1494
- ty : self . ty ,
1476
+ ty : this . ty ,
1495
1477
details
1496
1478
}
1497
1479
}
1498
1480
1499
- pub fn field < C > ( & self , cx : C , i : usize ) -> C :: TyLayout
1500
- where C : LayoutOf < Ty = Ty < ' tcx > > + HasTyCtxt < ' tcx > ,
1501
- C :: TyLayout : MaybeResult < TyLayout < ' tcx > >
1502
- {
1481
+ fn field ( this : TyLayout < ' tcx > , cx : C , i : usize ) -> C :: TyLayout {
1503
1482
let tcx = cx. tcx ( ) ;
1504
- cx. layout_of ( match self . ty . sty {
1483
+ cx. layout_of ( match this . ty . sty {
1505
1484
ty:: TyBool |
1506
1485
ty:: TyChar |
1507
1486
ty:: TyInt ( _) |
@@ -1513,7 +1492,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1513
1492
ty:: TyGeneratorWitness ( ..) |
1514
1493
ty:: TyForeign ( ..) |
1515
1494
ty:: TyDynamic ( ..) => {
1516
- bug ! ( "TyLayout::field_type({:?}): not applicable" , self )
1495
+ bug ! ( "TyLayout::field_type({:?}): not applicable" , this )
1517
1496
}
1518
1497
1519
1498
// Potentially-fat pointers.
@@ -1527,13 +1506,13 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1527
1506
// as the `Abi` or `FieldPlacement` is checked by users.
1528
1507
if i == 0 {
1529
1508
let nil = tcx. mk_nil ( ) ;
1530
- let ptr_ty = if self . ty . is_unsafe_ptr ( ) {
1509
+ let ptr_ty = if this . ty . is_unsafe_ptr ( ) {
1531
1510
tcx. mk_mut_ptr ( nil)
1532
1511
} else {
1533
1512
tcx. mk_mut_ref ( tcx. types . re_static , nil)
1534
1513
} ;
1535
1514
return cx. layout_of ( ptr_ty) . map_same ( |mut ptr_layout| {
1536
- ptr_layout. ty = self . ty ;
1515
+ ptr_layout. ty = this . ty ;
1537
1516
ptr_layout
1538
1517
} ) ;
1539
1518
}
@@ -1546,7 +1525,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1546
1525
// the correct number of vtables slots.
1547
1526
tcx. mk_imm_ref ( tcx. types . re_static , tcx. mk_nil ( ) )
1548
1527
}
1549
- _ => bug ! ( "TyLayout::field_type({:?}): not applicable" , self )
1528
+ _ => bug ! ( "TyLayout::field_type({:?}): not applicable" , this )
1550
1529
}
1551
1530
}
1552
1531
@@ -1568,12 +1547,12 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1568
1547
1569
1548
// SIMD vector types.
1570
1549
ty:: TyAdt ( def, ..) if def. repr . simd ( ) => {
1571
- self . ty . simd_type ( tcx)
1550
+ this . ty . simd_type ( tcx)
1572
1551
}
1573
1552
1574
1553
// ADTs.
1575
1554
ty:: TyAdt ( def, substs) => {
1576
- match self . variants {
1555
+ match this . variants {
1577
1556
Variants :: Single { index } => {
1578
1557
def. variants [ index] . fields [ i] . ty ( tcx, substs)
1579
1558
}
@@ -1593,45 +1572,25 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1593
1572
1594
1573
ty:: TyProjection ( _) | ty:: TyAnon ( ..) | ty:: TyParam ( _) |
1595
1574
ty:: TyInfer ( _) | ty:: TyError => {
1596
- bug ! ( "TyLayout::field_type: unexpected type `{}`" , self . ty)
1575
+ bug ! ( "TyLayout::field_type: unexpected type `{}`" , this . ty)
1597
1576
}
1598
1577
} )
1599
1578
}
1579
+ }
1600
1580
1601
- /// Returns true if the layout corresponds to an unsized type.
1602
- pub fn is_unsized ( & self ) -> bool {
1603
- self . abi . is_unsized ( )
1604
- }
1605
-
1606
- /// Returns true if the type is a ZST and not unsized.
1607
- pub fn is_zst ( & self ) -> bool {
1608
- match self . abi {
1609
- Abi :: Uninhabited => true ,
1610
- Abi :: Scalar ( _) |
1611
- Abi :: ScalarPair ( ..) |
1612
- Abi :: Vector { .. } => false ,
1613
- Abi :: Aggregate { sized } => sized && self . size . bytes ( ) == 0
1614
- }
1615
- }
1616
-
1617
- pub fn size_and_align ( & self ) -> ( Size , Align ) {
1618
- ( self . size , self . align )
1619
- }
1620
-
1581
+ impl < ' a , ' tcx > LayoutCx < ' tcx , TyCtxt < ' a , ' tcx , ' tcx > > {
1621
1582
/// Find the offset of a niche leaf field, starting from
1622
1583
/// the given type and recursing through aggregates, which
1623
1584
/// has at least `count` consecutive invalid values.
1624
1585
/// The tuple is `(offset, scalar, niche_value)`.
1625
1586
// FIXME(eddyb) traverse already optimized enums.
1626
- fn find_niche < C > ( & self , cx : C , count : u128 )
1587
+ fn find_niche ( self , layout : TyLayout < ' tcx > , count : u128 )
1627
1588
-> Result < Option < ( Size , Scalar , u128 ) > , LayoutError < ' tcx > >
1628
- where C : LayoutOf < Ty = Ty < ' tcx > , TyLayout = Result < Self , LayoutError < ' tcx > > > +
1629
- HasTyCtxt < ' tcx >
1630
1589
{
1631
1590
let scalar_component = |scalar : & Scalar , offset| {
1632
1591
let Scalar { value, valid_range : ref v } = * scalar;
1633
1592
1634
- let bits = value. size ( cx ) . bits ( ) ;
1593
+ let bits = value. size ( self ) . bits ( ) ;
1635
1594
assert ! ( bits <= 128 ) ;
1636
1595
let max_value = !0u128 >> ( 128 - bits) ;
1637
1596
@@ -1658,17 +1617,17 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1658
1617
// Locals variables which live across yields are stored
1659
1618
// in the generator type as fields. These may be uninitialized
1660
1619
// so we don't look for niches there.
1661
- if let ty:: TyGenerator ( ..) = self . ty . sty {
1620
+ if let ty:: TyGenerator ( ..) = layout . ty . sty {
1662
1621
return Ok ( None ) ;
1663
1622
}
1664
1623
1665
- match self . abi {
1624
+ match layout . abi {
1666
1625
Abi :: Scalar ( ref scalar) => {
1667
1626
return Ok ( scalar_component ( scalar, Size :: from_bytes ( 0 ) ) ) ;
1668
1627
}
1669
1628
Abi :: ScalarPair ( ref a, ref b) => {
1670
1629
return Ok ( scalar_component ( a, Size :: from_bytes ( 0 ) ) . or_else ( || {
1671
- scalar_component ( b, a. value . size ( cx ) . abi_align ( b. value . align ( cx ) ) )
1630
+ scalar_component ( b, a. value . size ( self ) . abi_align ( b. value . align ( self ) ) )
1672
1631
} ) ) ;
1673
1632
}
1674
1633
Abi :: Vector { ref element, .. } => {
@@ -1678,22 +1637,22 @@ impl<'a, 'tcx> TyLayout<'tcx> {
1678
1637
}
1679
1638
1680
1639
// Perhaps one of the fields is non-zero, let's recurse and find out.
1681
- if let FieldPlacement :: Union ( _) = self . fields {
1640
+ if let FieldPlacement :: Union ( _) = layout . fields {
1682
1641
// Only Rust enums have safe-to-inspect fields
1683
1642
// (a discriminant), other unions are unsafe.
1684
- if let Variants :: Single { .. } = self . variants {
1643
+ if let Variants :: Single { .. } = layout . variants {
1685
1644
return Ok ( None ) ;
1686
1645
}
1687
1646
}
1688
- if let FieldPlacement :: Array { .. } = self . fields {
1689
- if self . fields . count ( ) > 0 {
1690
- return self . field ( cx , 0 ) ?. find_niche ( cx , count) ;
1647
+ if let FieldPlacement :: Array { .. } = layout . fields {
1648
+ if layout . fields . count ( ) > 0 {
1649
+ return self . find_niche ( layout . field ( self , 0 ) ?, count) ;
1691
1650
}
1692
1651
}
1693
- for i in 0 ..self . fields . count ( ) {
1694
- let r = self . field ( cx , i) ?. find_niche ( cx , count) ?;
1652
+ for i in 0 ..layout . fields . count ( ) {
1653
+ let r = self . find_niche ( layout . field ( self , i) ?, count) ?;
1695
1654
if let Some ( ( offset, scalar, niche_value) ) = r {
1696
- let offset = self . fields . offset ( i) + offset;
1655
+ let offset = layout . fields . offset ( i) + offset;
1697
1656
return Ok ( Some ( ( offset, scalar, niche_value) ) ) ;
1698
1657
}
1699
1658
}
0 commit comments