@@ -202,6 +202,16 @@ impl TargetDataLayout {
202
202
}
203
203
}
204
204
205
+ pub trait HasDataLayout : Copy {
206
+ fn data_layout ( & self ) -> & TargetDataLayout ;
207
+ }
208
+
209
+ impl < ' a > HasDataLayout for & ' a TargetDataLayout {
210
+ fn data_layout ( & self ) -> & TargetDataLayout {
211
+ self
212
+ }
213
+ }
214
+
205
215
/// Endianness of the target, which must match cfg(target-endian).
206
216
#[ derive( Copy , Clone ) ]
207
217
pub enum Endian {
@@ -242,7 +252,9 @@ impl Size {
242
252
Size :: from_bytes ( ( self . bytes ( ) + mask) & !mask)
243
253
}
244
254
245
- pub fn checked_add ( self , offset : Size , dl : & TargetDataLayout ) -> Option < Size > {
255
+ pub fn checked_add < C : HasDataLayout > ( self , offset : Size , cx : C ) -> Option < Size > {
256
+ let dl = cx. data_layout ( ) ;
257
+
246
258
// Each Size is less than dl.obj_size_bound(), so the sum is
247
259
// also less than 1 << 62 (and therefore can't overflow).
248
260
let bytes = self . bytes ( ) + offset. bytes ( ) ;
@@ -254,7 +266,9 @@ impl Size {
254
266
}
255
267
}
256
268
257
- pub fn checked_mul ( self , count : u64 , dl : & TargetDataLayout ) -> Option < Size > {
269
+ pub fn checked_mul < C : HasDataLayout > ( self , count : u64 , cx : C ) -> Option < Size > {
270
+ let dl = cx. data_layout ( ) ;
271
+
258
272
// Each Size is less than dl.obj_size_bound(), so the sum is
259
273
// also less than 1 << 62 (and therefore can't overflow).
260
274
match self . bytes ( ) . checked_mul ( count) {
@@ -354,7 +368,9 @@ impl Integer {
354
368
}
355
369
}
356
370
357
- pub fn align ( & self , dl : & TargetDataLayout ) -> Align {
371
+ pub fn align < C : HasDataLayout > ( & self , cx : C ) -> Align {
372
+ let dl = cx. data_layout ( ) ;
373
+
358
374
match * self {
359
375
I1 => dl. i1_align ,
360
376
I8 => dl. i8_align ,
@@ -408,7 +424,9 @@ impl Integer {
408
424
}
409
425
410
426
/// Find the smallest integer with the given alignment.
411
- pub fn for_abi_align ( dl : & TargetDataLayout , align : Align ) -> Option < Integer > {
427
+ pub fn for_abi_align < C : HasDataLayout > ( cx : C , align : Align ) -> Option < Integer > {
428
+ let dl = cx. data_layout ( ) ;
429
+
412
430
let wanted = align. abi ( ) ;
413
431
for & candidate in & [ I8 , I16 , I32 , I64 ] {
414
432
let ty = Int ( candidate) ;
@@ -420,7 +438,9 @@ impl Integer {
420
438
}
421
439
422
440
/// Get the Integer type from an attr::IntType.
423
- pub fn from_attr ( dl : & TargetDataLayout , ity : attr:: IntType ) -> Integer {
441
+ pub fn from_attr < C : HasDataLayout > ( cx : C , ity : attr:: IntType ) -> Integer {
442
+ let dl = cx. data_layout ( ) ;
443
+
424
444
match ity {
425
445
attr:: SignedInt ( IntTy :: I8 ) | attr:: UnsignedInt ( UintTy :: U8 ) => I8 ,
426
446
attr:: SignedInt ( IntTy :: I16 ) | attr:: UnsignedInt ( UintTy :: U16 ) => I16 ,
@@ -450,7 +470,7 @@ impl Integer {
450
470
let min_default = I8 ;
451
471
452
472
if let Some ( ity) = repr. int {
453
- let discr = Integer :: from_attr ( & tcx. data_layout , ity) ;
473
+ let discr = Integer :: from_attr ( tcx, ity) ;
454
474
let fit = if ity. is_signed ( ) { signed_fit } else { unsigned_fit } ;
455
475
if discr < fit {
456
476
bug ! ( "Integer::repr_discr: `#[repr]` hint too small for \
@@ -491,7 +511,9 @@ pub enum Primitive {
491
511
}
492
512
493
513
impl Primitive {
494
- pub fn size ( self , dl : & TargetDataLayout ) -> Size {
514
+ pub fn size < C : HasDataLayout > ( self , cx : C ) -> Size {
515
+ let dl = cx. data_layout ( ) ;
516
+
495
517
match self {
496
518
Int ( I1 ) | Int ( I8 ) => Size :: from_bits ( 8 ) ,
497
519
Int ( I16 ) => Size :: from_bits ( 16 ) ,
@@ -502,7 +524,9 @@ impl Primitive {
502
524
}
503
525
}
504
526
505
- pub fn align ( self , dl : & TargetDataLayout ) -> Align {
527
+ pub fn align < C : HasDataLayout > ( self , cx : C ) -> Align {
528
+ let dl = cx. data_layout ( ) ;
529
+
506
530
match self {
507
531
Int ( I1 ) => dl. i1_align ,
508
532
Int ( I8 ) => dl. i8_align ,
@@ -682,8 +706,8 @@ impl<'a, 'gcx, 'tcx> Struct {
682
706
}
683
707
684
708
/// Determine whether a structure would be zero-sized, given its fields.
685
- pub fn would_be_zero_sized < I > ( dl : & TargetDataLayout , fields : I )
686
- -> Result < bool , LayoutError < ' gcx > >
709
+ fn would_be_zero_sized < I > ( dl : & TargetDataLayout , fields : I )
710
+ -> Result < bool , LayoutError < ' gcx > >
687
711
where I : Iterator < Item =Result < & ' a Layout , LayoutError < ' gcx > > > {
688
712
for field in fields {
689
713
let field = field?;
@@ -831,7 +855,7 @@ pub struct Union {
831
855
}
832
856
833
857
impl < ' a , ' gcx , ' tcx > Union {
834
- pub fn new ( dl : & TargetDataLayout , packed : bool ) -> Union {
858
+ fn new ( dl : & TargetDataLayout , packed : bool ) -> Union {
835
859
Union {
836
860
align : if packed { dl. i8_align } else { dl. aggregate_align } ,
837
861
min_size : Size :: from_bytes ( 0 ) ,
@@ -840,10 +864,10 @@ impl<'a, 'gcx, 'tcx> Union {
840
864
}
841
865
842
866
/// Extend the Struct with more fields.
843
- pub fn extend < I > ( & mut self , dl : & TargetDataLayout ,
844
- fields : I ,
845
- scapegoat : Ty < ' gcx > )
846
- -> Result < ( ) , LayoutError < ' gcx > >
867
+ fn extend < I > ( & mut self , dl : & TargetDataLayout ,
868
+ fields : I ,
869
+ scapegoat : Ty < ' gcx > )
870
+ -> Result < ( ) , LayoutError < ' gcx > >
847
871
where I : Iterator < Item =Result < & ' a Layout , LayoutError < ' gcx > > > {
848
872
for ( index, field) in fields. enumerate ( ) {
849
873
let field = field?;
@@ -1450,7 +1474,9 @@ impl<'a, 'gcx, 'tcx> Layout {
1450
1474
}
1451
1475
}
1452
1476
1453
- pub fn size ( & self , dl : & TargetDataLayout ) -> Size {
1477
+ pub fn size < C : HasDataLayout > ( & self , cx : C ) -> Size {
1478
+ let dl = cx. data_layout ( ) ;
1479
+
1454
1480
match * self {
1455
1481
Scalar { value, .. } | RawNullablePointer { value, .. } => {
1456
1482
value. size ( dl)
@@ -1492,7 +1518,9 @@ impl<'a, 'gcx, 'tcx> Layout {
1492
1518
}
1493
1519
}
1494
1520
1495
- pub fn align ( & self , dl : & TargetDataLayout ) -> Align {
1521
+ pub fn align < C : HasDataLayout > ( & self , cx : C ) -> Align {
1522
+ let dl = cx. data_layout ( ) ;
1523
+
1496
1524
match * self {
1497
1525
Scalar { value, .. } | RawNullablePointer { value, .. } => {
1498
1526
value. align ( dl)
@@ -1532,11 +1560,13 @@ impl<'a, 'gcx, 'tcx> Layout {
1532
1560
}
1533
1561
}
1534
1562
1535
- pub fn field_offset ( & self ,
1536
- dl : & TargetDataLayout ,
1537
- i : usize ,
1538
- variant_index : Option < usize > )
1539
- -> Size {
1563
+ pub fn field_offset < C : HasDataLayout > ( & self ,
1564
+ cx : C ,
1565
+ i : usize ,
1566
+ variant_index : Option < usize > )
1567
+ -> Size {
1568
+ let dl = cx. data_layout ( ) ;
1569
+
1540
1570
match * self {
1541
1571
Scalar { .. } |
1542
1572
CEnum { .. } |
@@ -1615,7 +1645,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
1615
1645
// First try computing a static layout.
1616
1646
let err = match ty. layout ( infcx) {
1617
1647
Ok ( layout) => {
1618
- return Ok ( SizeSkeleton :: Known ( layout. size ( & tcx. data_layout ) ) ) ;
1648
+ return Ok ( SizeSkeleton :: Known ( layout. size ( tcx) ) ) ;
1619
1649
}
1620
1650
Err ( err) => err
1621
1651
} ;
@@ -1746,30 +1776,69 @@ impl<'tcx> Deref for TyLayout<'tcx> {
1746
1776
}
1747
1777
}
1748
1778
1749
- impl < ' a , ' gcx , ' tcx > TyLayout < ' gcx > {
1750
- pub fn of ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > , ty : Ty < ' gcx > )
1751
- -> Result < Self , LayoutError < ' gcx > > {
1752
- let ty = normalize_associated_type ( infcx, ty) ;
1779
+ pub trait HasTyCtxt < ' tcx > : HasDataLayout {
1780
+ fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
1781
+ }
1782
+
1783
+ impl < ' a , ' gcx , ' tcx > HasDataLayout for TyCtxt < ' a , ' gcx , ' tcx > {
1784
+ fn data_layout ( & self ) -> & TargetDataLayout {
1785
+ & self . data_layout
1786
+ }
1787
+ }
1788
+
1789
+ impl < ' a , ' gcx , ' tcx > HasTyCtxt < ' gcx > for TyCtxt < ' a , ' gcx , ' tcx > {
1790
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
1791
+ self . global_tcx ( )
1792
+ }
1793
+ }
1794
+
1795
+ impl < ' a , ' gcx , ' tcx > HasDataLayout for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1796
+ fn data_layout ( & self ) -> & TargetDataLayout {
1797
+ & self . tcx . data_layout
1798
+ }
1799
+ }
1800
+
1801
+ impl < ' a , ' gcx , ' tcx > HasTyCtxt < ' gcx > for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1802
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
1803
+ self . tcx . global_tcx ( )
1804
+ }
1805
+ }
1806
+
1807
+ pub trait LayoutTyper < ' tcx > : HasTyCtxt < ' tcx > {
1808
+ type TyLayout ;
1809
+
1810
+ fn layout_of ( self , ty : Ty < ' tcx > ) -> Self :: TyLayout ;
1811
+ }
1812
+
1813
+ impl < ' a , ' gcx , ' tcx > LayoutTyper < ' gcx > for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1814
+ type TyLayout = Result < TyLayout < ' gcx > , LayoutError < ' gcx > > ;
1815
+
1816
+ fn layout_of ( self , ty : Ty < ' gcx > ) -> Self :: TyLayout {
1817
+ let ty = normalize_associated_type ( self , ty) ;
1753
1818
1754
1819
Ok ( TyLayout {
1755
1820
ty : ty,
1756
- layout : ty. layout ( infcx ) ?,
1821
+ layout : ty. layout ( self ) ?,
1757
1822
variant_index : None
1758
1823
} )
1759
1824
}
1825
+ }
1760
1826
1827
+ impl < ' a , ' tcx > TyLayout < ' tcx > {
1761
1828
pub fn for_variant ( & self , variant_index : usize ) -> Self {
1762
1829
TyLayout {
1763
1830
variant_index : Some ( variant_index) ,
1764
1831
..* self
1765
1832
}
1766
1833
}
1767
1834
1768
- pub fn field_offset ( & self , dl : & TargetDataLayout , i : usize ) -> Size {
1769
- self . layout . field_offset ( dl , i, self . variant_index )
1835
+ pub fn field_offset < C : HasDataLayout > ( & self , cx : C , i : usize ) -> Size {
1836
+ self . layout . field_offset ( cx , i, self . variant_index )
1770
1837
}
1771
1838
1772
- pub fn field_count ( & self , tcx : TyCtxt < ' a , ' gcx , ' gcx > ) -> usize {
1839
+ pub fn field_count < C : HasTyCtxt < ' tcx > > ( & self , cx : C ) -> usize {
1840
+ let tcx = cx. tcx ( ) ;
1841
+
1773
1842
let ptr_field_count = || {
1774
1843
if let FatPointer { .. } = * self . layout {
1775
1844
2
@@ -1831,9 +1900,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
1831
1900
}
1832
1901
}
1833
1902
1834
- pub fn field_type ( & self , tcx : TyCtxt < ' a , ' gcx , ' gcx > , i : usize ) -> Ty < ' gcx > {
1835
- let ptr_field_type = |pointee : Ty < ' gcx > | {
1836
- let slice = |element : Ty < ' gcx > | {
1903
+ pub fn field_type < C : HasTyCtxt < ' tcx > > ( & self , cx : C , i : usize ) -> Ty < ' tcx > {
1904
+ let tcx = cx. tcx ( ) ;
1905
+
1906
+ let ptr_field_type = |pointee : Ty < ' tcx > | {
1907
+ let slice = |element : Ty < ' tcx > | {
1837
1908
assert ! ( i < 2 ) ;
1838
1909
if i == 0 {
1839
1910
tcx. mk_mut_ptr ( element)
@@ -1907,8 +1978,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
1907
1978
}
1908
1979
}
1909
1980
1910
- pub fn field ( & self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > , i : usize )
1911
- -> Result < Self , LayoutError < ' gcx > > {
1912
- TyLayout :: of ( infcx, self . field_type ( infcx. tcx . global_tcx ( ) , i) )
1981
+ pub fn field < C : LayoutTyper < ' tcx > > ( & self , cx : C , i : usize ) -> C :: TyLayout {
1982
+ cx. layout_of ( self . field_type ( cx, i) )
1913
1983
}
1914
1984
}
0 commit comments