@@ -202,6 +202,16 @@ impl TargetDataLayout {
202202 }
203203}
204204
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+
205215/// Endianness of the target, which must match cfg(target-endian).
206216#[ derive( Copy , Clone ) ]
207217pub enum Endian {
@@ -242,7 +252,9 @@ impl Size {
242252 Size :: from_bytes ( ( self . bytes ( ) + mask) & !mask)
243253 }
244254
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+
246258 // Each Size is less than dl.obj_size_bound(), so the sum is
247259 // also less than 1 << 62 (and therefore can't overflow).
248260 let bytes = self . bytes ( ) + offset. bytes ( ) ;
@@ -254,7 +266,9 @@ impl Size {
254266 }
255267 }
256268
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+
258272 // Each Size is less than dl.obj_size_bound(), so the sum is
259273 // also less than 1 << 62 (and therefore can't overflow).
260274 match self . bytes ( ) . checked_mul ( count) {
@@ -354,7 +368,9 @@ impl Integer {
354368 }
355369 }
356370
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+
358374 match * self {
359375 I1 => dl. i1_align ,
360376 I8 => dl. i8_align ,
@@ -408,7 +424,9 @@ impl Integer {
408424 }
409425
410426 /// 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+
412430 let wanted = align. abi ( ) ;
413431 for & candidate in & [ I8 , I16 , I32 , I64 ] {
414432 let ty = Int ( candidate) ;
@@ -420,7 +438,9 @@ impl Integer {
420438 }
421439
422440 /// 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+
424444 match ity {
425445 attr:: SignedInt ( IntTy :: I8 ) | attr:: UnsignedInt ( UintTy :: U8 ) => I8 ,
426446 attr:: SignedInt ( IntTy :: I16 ) | attr:: UnsignedInt ( UintTy :: U16 ) => I16 ,
@@ -450,7 +470,7 @@ impl Integer {
450470 let min_default = I8 ;
451471
452472 if let Some ( ity) = repr. int {
453- let discr = Integer :: from_attr ( & tcx. data_layout , ity) ;
473+ let discr = Integer :: from_attr ( tcx, ity) ;
454474 let fit = if ity. is_signed ( ) { signed_fit } else { unsigned_fit } ;
455475 if discr < fit {
456476 bug ! ( "Integer::repr_discr: `#[repr]` hint too small for \
@@ -491,7 +511,9 @@ pub enum Primitive {
491511}
492512
493513impl 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+
495517 match self {
496518 Int ( I1 ) | Int ( I8 ) => Size :: from_bits ( 8 ) ,
497519 Int ( I16 ) => Size :: from_bits ( 16 ) ,
@@ -502,7 +524,9 @@ impl Primitive {
502524 }
503525 }
504526
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+
506530 match self {
507531 Int ( I1 ) => dl. i1_align ,
508532 Int ( I8 ) => dl. i8_align ,
@@ -682,8 +706,8 @@ impl<'a, 'gcx, 'tcx> Struct {
682706 }
683707
684708 /// 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 > >
687711 where I : Iterator < Item =Result < & ' a Layout , LayoutError < ' gcx > > > {
688712 for field in fields {
689713 let field = field?;
@@ -831,7 +855,7 @@ pub struct Union {
831855}
832856
833857impl < ' a , ' gcx , ' tcx > Union {
834- pub fn new ( dl : & TargetDataLayout , packed : bool ) -> Union {
858+ fn new ( dl : & TargetDataLayout , packed : bool ) -> Union {
835859 Union {
836860 align : if packed { dl. i8_align } else { dl. aggregate_align } ,
837861 min_size : Size :: from_bytes ( 0 ) ,
@@ -840,10 +864,10 @@ impl<'a, 'gcx, 'tcx> Union {
840864 }
841865
842866 /// 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 > >
847871 where I : Iterator < Item =Result < & ' a Layout , LayoutError < ' gcx > > > {
848872 for ( index, field) in fields. enumerate ( ) {
849873 let field = field?;
@@ -1452,7 +1476,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14521476 }
14531477 }
14541478
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+
14561482 match * self {
14571483 Scalar { value, .. } | RawNullablePointer { value, .. } => {
14581484 value. size ( dl)
@@ -1494,7 +1520,9 @@ impl<'a, 'gcx, 'tcx> Layout {
14941520 }
14951521 }
14961522
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+
14981526 match * self {
14991527 Scalar { value, .. } | RawNullablePointer { value, .. } => {
15001528 value. align ( dl)
@@ -1534,11 +1562,13 @@ impl<'a, 'gcx, 'tcx> Layout {
15341562 }
15351563 }
15361564
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+
15421572 match * self {
15431573 Scalar { .. } |
15441574 CEnum { .. } |
@@ -1617,7 +1647,7 @@ impl<'a, 'gcx, 'tcx> SizeSkeleton<'gcx> {
16171647 // First try computing a static layout.
16181648 let err = match ty. layout ( infcx) {
16191649 Ok ( layout) => {
1620- return Ok ( SizeSkeleton :: Known ( layout. size ( & tcx. data_layout ) ) ) ;
1650+ return Ok ( SizeSkeleton :: Known ( layout. size ( tcx) ) ) ;
16211651 }
16221652 Err ( err) => err
16231653 } ;
@@ -1748,27 +1778,64 @@ impl<'tcx> Deref for TyLayout<'tcx> {
17481778 }
17491779}
17501780
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) ;
17551820
17561821 Ok ( TyLayout {
17571822 ty : ty,
1758- layout : ty. layout ( infcx ) ?,
1823+ layout : ty. layout ( self ) ?,
17591824 variant_index : None
17601825 } )
17611826 }
1827+ }
17621828
1829+ impl < ' a , ' tcx > TyLayout < ' tcx > {
17631830 pub fn for_variant ( & self , variant_index : usize ) -> Self {
17641831 TyLayout {
17651832 variant_index : Some ( variant_index) ,
17661833 ..* self
17671834 }
17681835 }
17691836
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 )
17721839 }
17731840
17741841 pub fn field_count ( & self ) -> usize {
@@ -1808,9 +1875,11 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
18081875 }
18091876 }
18101877
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 > | {
18141883 assert ! ( i < 2 ) ;
18151884 if i == 0 {
18161885 tcx. mk_mut_ptr ( element)
@@ -1877,8 +1946,7 @@ impl<'a, 'gcx, 'tcx> TyLayout<'gcx> {
18771946 }
18781947 }
18791948
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) )
18831951 }
18841952}
0 commit comments