@@ -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?;
@@ -1452,7 +1476,9 @@ impl<'a, 'gcx, 'tcx> Layout {
1452
1476
}
1453
1477
}
1454
1478
1455
- pub fn size ( & self , dl : & TargetDataLayout ) -> Size {
1479
+ pub fn size < C : HasDataLayout > ( & self , cx : C ) -> Size {
1480
+ let dl = cx. data_layout ( ) ;
1481
+
1456
1482
match * self {
1457
1483
Scalar { value, .. } | RawNullablePointer { value, .. } => {
1458
1484
value. size ( dl)
@@ -1494,7 +1520,9 @@ impl<'a, 'gcx, 'tcx> Layout {
1494
1520
}
1495
1521
}
1496
1522
1497
- pub fn align ( & self , dl : & TargetDataLayout ) -> Align {
1523
+ pub fn align < C : HasDataLayout > ( & self , cx : C ) -> Align {
1524
+ let dl = cx. data_layout ( ) ;
1525
+
1498
1526
match * self {
1499
1527
Scalar { value, .. } | RawNullablePointer { value, .. } => {
1500
1528
value. align ( dl)
@@ -1534,11 +1562,13 @@ impl<'a, 'gcx, 'tcx> Layout {
1534
1562
}
1535
1563
}
1536
1564
1537
- pub fn field_offset ( & self ,
1538
- dl : & TargetDataLayout ,
1539
- i : usize ,
1540
- variant_index : Option < usize > )
1541
- -> Size {
1565
+ pub fn field_offset < C : HasDataLayout > ( & self ,
1566
+ cx : C ,
1567
+ i : usize ,
1568
+ variant_index : Option < usize > )
1569
+ -> Size {
1570
+ let dl = cx. data_layout ( ) ;
1571
+
1542
1572
match * self {
1543
1573
Scalar { .. } |
1544
1574
CEnum { .. } |
@@ -1617,7 +1647,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
1617
1647
// First try computing a static layout.
1618
1648
let err = match ty. layout ( infcx) {
1619
1649
Ok ( layout) => {
1620
- return Ok ( SizeSkeleton :: Known ( layout. size ( & tcx. data_layout ) ) ) ;
1650
+ return Ok ( SizeSkeleton :: Known ( layout. size ( tcx) ) ) ;
1621
1651
}
1622
1652
Err ( err) => err
1623
1653
} ;
@@ -1748,27 +1778,64 @@ impl<'tcx> Deref for TyLayout<'tcx> {
1748
1778
}
1749
1779
}
1750
1780
1751
- impl < ' a , ' gcx , ' tcx > TyLayout < ' gcx > {
1752
- pub fn of ( infcx : & InferCtxt < ' a , ' gcx , ' tcx > , ty : Ty < ' gcx > )
1753
- -> Result < Self , LayoutError < ' gcx > > {
1754
- let ty = normalize_associated_type ( infcx, ty) ;
1781
+ pub trait HasTyCtxt < ' tcx > : HasDataLayout {
1782
+ fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
1783
+ }
1784
+
1785
+ impl < ' a , ' gcx , ' tcx > HasDataLayout for TyCtxt < ' a , ' gcx , ' tcx > {
1786
+ fn data_layout ( & self ) -> & TargetDataLayout {
1787
+ & self . data_layout
1788
+ }
1789
+ }
1790
+
1791
+ impl < ' a , ' gcx , ' tcx > HasTyCtxt < ' gcx > for TyCtxt < ' a , ' gcx , ' tcx > {
1792
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
1793
+ self . global_tcx ( )
1794
+ }
1795
+ }
1796
+
1797
+ impl < ' a , ' gcx , ' tcx > HasDataLayout for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1798
+ fn data_layout ( & self ) -> & TargetDataLayout {
1799
+ & self . tcx . data_layout
1800
+ }
1801
+ }
1802
+
1803
+ impl < ' a , ' gcx , ' tcx > HasTyCtxt < ' gcx > for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1804
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
1805
+ self . tcx . global_tcx ( )
1806
+ }
1807
+ }
1808
+
1809
+ pub trait LayoutTyper < ' tcx > : HasTyCtxt < ' tcx > {
1810
+ type TyLayout ;
1811
+
1812
+ fn layout_of ( self , ty : Ty < ' tcx > ) -> Self :: TyLayout ;
1813
+ }
1814
+
1815
+ impl < ' a , ' gcx , ' tcx > LayoutTyper < ' gcx > for & ' a InferCtxt < ' a , ' gcx , ' tcx > {
1816
+ type TyLayout = Result < TyLayout < ' gcx > , LayoutError < ' gcx > > ;
1817
+
1818
+ fn layout_of ( self , ty : Ty < ' gcx > ) -> Self :: TyLayout {
1819
+ let ty = normalize_associated_type ( self , ty) ;
1755
1820
1756
1821
Ok ( TyLayout {
1757
1822
ty : ty,
1758
- layout : ty. layout ( infcx ) ?,
1823
+ layout : ty. layout ( self ) ?,
1759
1824
variant_index : None
1760
1825
} )
1761
1826
}
1827
+ }
1762
1828
1829
+ impl < ' a , ' tcx > TyLayout < ' tcx > {
1763
1830
pub fn for_variant ( & self , variant_index : usize ) -> Self {
1764
1831
TyLayout {
1765
1832
variant_index : Some ( variant_index) ,
1766
1833
..* self
1767
1834
}
1768
1835
}
1769
1836
1770
- pub fn field_offset ( & self , dl : & TargetDataLayout , i : usize ) -> Size {
1771
- self . layout . field_offset ( dl , i, self . variant_index )
1837
+ pub fn field_offset < C : HasDataLayout > ( & self , cx : C , i : usize ) -> Size {
1838
+ self . layout . field_offset ( cx , i, self . variant_index )
1772
1839
}
1773
1840
1774
1841
pub fn field_count ( & self ) -> usize {
@@ -1808,9 +1875,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
1808
1875
}
1809
1876
}
1810
1877
1811
- pub fn field_type ( & self , tcx : TyCtxt < ' a , ' gcx , ' gcx > , i : usize ) -> Ty < ' gcx > {
1812
- let ptr_field_type = |pointee : Ty < ' gcx > | {
1813
- let slice = |element : Ty < ' gcx > | {
1878
+ pub fn field_type < C : HasTyCtxt < ' tcx > > ( & self , cx : C , i : usize ) -> Ty < ' tcx > {
1879
+ let tcx = cx. tcx ( ) ;
1880
+
1881
+ let ptr_field_type = |pointee : Ty < ' tcx > | {
1882
+ let slice = |element : Ty < ' tcx > | {
1814
1883
assert ! ( i < 2 ) ;
1815
1884
if i == 0 {
1816
1885
tcx. mk_mut_ptr ( element)
@@ -1877,8 +1946,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
1877
1946
}
1878
1947
}
1879
1948
1880
- pub fn field ( & self , infcx : & InferCtxt < ' a , ' gcx , ' tcx > , i : usize )
1881
- -> Result < Self , LayoutError < ' gcx > > {
1882
- TyLayout :: of ( infcx, self . field_type ( infcx. tcx . global_tcx ( ) , i) )
1949
+ pub fn field < C : LayoutTyper < ' tcx > > ( & self , cx : C , i : usize ) -> C :: TyLayout {
1950
+ cx. layout_of ( self . field_type ( cx, i) )
1883
1951
}
1884
1952
}
0 commit comments