@@ -227,12 +227,6 @@ impl<'a> HasDataLayout for &'a TargetDataLayout {
227
227
}
228
228
}
229
229
230
- impl < ' a , ' tcx > HasDataLayout for TyCtxt < ' a , ' tcx , ' tcx > {
231
- fn data_layout ( & self ) -> & TargetDataLayout {
232
- & self . data_layout
233
- }
234
- }
235
-
236
230
/// Endianness of the target, which must match cfg(target-endian).
237
231
#[ derive( Copy , Clone ) ]
238
232
pub enum Endian {
@@ -2089,80 +2083,85 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
2089
2083
}
2090
2084
}
2091
2085
2092
- /// A pair of a type and its layout. Implements various
2093
- /// type traversal APIs (e.g. recursing into fields).
2086
+ /// The details of the layout of a type, alongside the type itself.
2087
+ /// Provides various type traversal APIs (e.g. recursing into fields).
2088
+ ///
2089
+ /// Note that the details are NOT guaranteed to always be identical
2090
+ /// to those obtained from `layout_of(ty)`, as we need to produce
2091
+ /// layouts for which Rust types do not exist, such as enum variants
2092
+ /// or synthetic fields of enums (i.e. discriminants) and fat pointers.
2094
2093
#[ derive( Copy , Clone , Debug ) ]
2095
- pub struct TyLayout < ' tcx > {
2094
+ pub struct FullLayout < ' tcx > {
2096
2095
pub ty : Ty < ' tcx > ,
2097
- pub layout : & ' tcx Layout ,
2098
2096
pub variant_index : Option < usize > ,
2097
+ pub layout : & ' tcx Layout ,
2099
2098
}
2100
2099
2101
- impl < ' tcx > Deref for TyLayout < ' tcx > {
2100
+ impl < ' tcx > Deref for FullLayout < ' tcx > {
2102
2101
type Target = Layout ;
2103
2102
fn deref ( & self ) -> & Layout {
2104
2103
self . layout
2105
2104
}
2106
2105
}
2107
2106
2108
- pub trait LayoutTyper < ' tcx > : HasDataLayout {
2109
- type TyLayout ;
2110
-
2107
+ pub trait HasTyCtxt < ' tcx > : HasDataLayout {
2111
2108
fn tcx < ' a > ( & ' a self ) -> TyCtxt < ' a , ' tcx , ' tcx > ;
2112
- fn layout_of ( self , ty : Ty < ' tcx > ) -> Self :: TyLayout ;
2113
- fn normalize_projections ( self , ty : Ty < ' tcx > ) -> Ty < ' tcx > ;
2114
2109
}
2115
2110
2116
- /// Combines a tcx with the parameter environment so that you can
2117
- /// compute layout operations.
2118
- #[ derive( Copy , Clone ) ]
2119
- pub struct LayoutCx < ' a , ' tcx : ' a > {
2120
- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
2121
- param_env : ty:: ParamEnv < ' tcx > ,
2111
+ impl < ' a , ' gcx , ' tcx > HasDataLayout for TyCtxt < ' a , ' gcx , ' tcx > {
2112
+ fn data_layout ( & self ) -> & TargetDataLayout {
2113
+ & self . data_layout
2114
+ }
2122
2115
}
2123
2116
2124
- impl < ' a , ' tcx > LayoutCx < ' a , ' tcx > {
2125
- pub fn new ( tcx : TyCtxt < ' a , ' tcx , ' tcx > , param_env : ty :: ParamEnv < ' tcx > ) -> Self {
2126
- LayoutCx { tcx , param_env }
2117
+ impl < ' a , ' gcx , ' tcx > HasTyCtxt < ' gcx > for TyCtxt < ' a , ' gcx , ' tcx > {
2118
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
2119
+ self . global_tcx ( )
2127
2120
}
2128
2121
}
2129
2122
2130
- impl < ' a , ' tcx > HasDataLayout for LayoutCx < ' a , ' tcx > {
2123
+ impl < ' a , ' gcx , ' tcx , T : Copy > HasDataLayout for ( TyCtxt < ' a , ' gcx , ' tcx > , T ) {
2131
2124
fn data_layout ( & self ) -> & TargetDataLayout {
2132
- & self . tcx . data_layout
2125
+ self . 0 . data_layout ( )
2133
2126
}
2134
2127
}
2135
2128
2136
- impl < ' a , ' tcx > LayoutTyper < ' tcx > for LayoutCx < ' a , ' tcx > {
2137
- type TyLayout = Result < TyLayout < ' tcx > , LayoutError < ' tcx > > ;
2138
-
2139
- fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' tcx , ' tcx > {
2140
- self . tcx
2129
+ impl < ' a , ' gcx , ' tcx , T : Copy > HasTyCtxt < ' gcx > for ( TyCtxt < ' a , ' gcx , ' tcx > , T ) {
2130
+ fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' gcx > {
2131
+ self . 0 . tcx ( )
2141
2132
}
2133
+ }
2134
+
2135
+ pub trait LayoutOf < T > {
2136
+ type FullLayout ;
2137
+
2138
+ fn layout_of ( self , ty : T ) -> Self :: FullLayout ;
2139
+ }
2140
+
2141
+ impl < ' a , ' tcx > LayoutOf < Ty < ' tcx > > for ( TyCtxt < ' a , ' tcx , ' tcx > , ty:: ParamEnv < ' tcx > ) {
2142
+ type FullLayout = Result < FullLayout < ' tcx > , LayoutError < ' tcx > > ;
2142
2143
2143
- fn layout_of ( self , ty : Ty < ' tcx > ) -> Self :: TyLayout {
2144
- let ty = self . normalize_projections ( ty ) ;
2144
+ fn layout_of ( self , ty : Ty < ' tcx > ) -> Self :: FullLayout {
2145
+ let ( tcx , param_env ) = self ;
2145
2146
2146
- Ok ( TyLayout {
2147
+ let ty = tcx. normalize_associated_type_in_env ( & ty, param_env) ;
2148
+
2149
+ Ok ( FullLayout {
2147
2150
ty,
2148
- layout : ty . layout ( self . tcx , self . param_env ) ? ,
2149
- variant_index : None
2151
+ variant_index : None ,
2152
+ layout : ty . layout ( tcx , param_env ) ? ,
2150
2153
} )
2151
2154
}
2152
-
2153
- fn normalize_projections ( self , ty : Ty < ' tcx > ) -> Ty < ' tcx > {
2154
- self . tcx . normalize_associated_type_in_env ( & ty, self . param_env )
2155
- }
2156
2155
}
2157
2156
2158
- impl < ' a , ' tcx > TyLayout < ' tcx > {
2157
+ impl < ' a , ' tcx > FullLayout < ' tcx > {
2159
2158
pub fn for_variant ( & self , variant_index : usize ) -> Self {
2160
2159
let is_enum = match self . ty . sty {
2161
2160
ty:: TyAdt ( def, _) => def. is_enum ( ) ,
2162
2161
_ => false
2163
2162
} ;
2164
2163
assert ! ( is_enum) ;
2165
- TyLayout {
2164
+ FullLayout {
2166
2165
variant_index : Some ( variant_index) ,
2167
2166
..* self
2168
2167
}
@@ -2199,7 +2198,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
2199
2198
2200
2199
match * self . layout {
2201
2200
Scalar { .. } => {
2202
- bug ! ( "TyLayout ::field_count({:?}): not applicable" , self )
2201
+ bug ! ( "FullLayout ::field_count({:?}): not applicable" , self )
2203
2202
}
2204
2203
2205
2204
// Handled above (the TyAdt case).
@@ -2222,9 +2221,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
2222
2221
}
2223
2222
}
2224
2223
2225
- fn field_type_unnormalized < C : LayoutTyper < ' tcx > > ( & self , cx : C , i : usize ) -> Ty < ' tcx > {
2226
- let tcx = cx. tcx ( ) ;
2227
-
2224
+ fn field_type_unnormalized ( & self , tcx : TyCtxt < ' a , ' tcx , ' tcx > , i : usize ) -> Ty < ' tcx > {
2228
2225
let ptr_field_type = |pointee : Ty < ' tcx > | {
2229
2226
assert ! ( i < 2 ) ;
2230
2227
let slice = |element : Ty < ' tcx > | {
@@ -2238,7 +2235,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
2238
2235
ty:: TySlice ( element) => slice ( element) ,
2239
2236
ty:: TyStr => slice ( tcx. types . u8 ) ,
2240
2237
ty:: TyDynamic ( ..) => tcx. mk_mut_ptr ( tcx. mk_nil ( ) ) ,
2241
- _ => bug ! ( "TyLayout ::field_type({:?}): not applicable" , self )
2238
+ _ => bug ! ( "FullLayout ::field_type({:?}): not applicable" , self )
2242
2239
}
2243
2240
} ;
2244
2241
@@ -2253,7 +2250,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
2253
2250
ty:: TyFnDef ( ..) |
2254
2251
ty:: TyDynamic ( ..) |
2255
2252
ty:: TyForeign ( ..) => {
2256
- bug ! ( "TyLayout ::field_type({:?}): not applicable" , self )
2253
+ bug ! ( "FullLayout ::field_type({:?}): not applicable" , self )
2257
2254
}
2258
2255
2259
2256
// Potentially-fat pointers.
@@ -2311,20 +2308,16 @@ impl<'a, 'tcx> TyLayout<'tcx> {
2311
2308
2312
2309
ty:: TyProjection ( _) | ty:: TyAnon ( ..) | ty:: TyParam ( _) |
2313
2310
ty:: TyInfer ( _) | ty:: TyError => {
2314
- bug ! ( "TyLayout ::field_type: unexpected type `{}`" , self . ty)
2311
+ bug ! ( "FullLayout ::field_type: unexpected type `{}`" , self . ty)
2315
2312
}
2316
2313
}
2317
2314
}
2318
2315
2319
- pub fn field_type < C : LayoutTyper < ' tcx > > ( & self , cx : C , i : usize ) -> Ty < ' tcx > {
2320
- cx. normalize_projections ( self . field_type_unnormalized ( cx, i) )
2321
- }
2322
-
2323
- pub fn field < C : LayoutTyper < ' tcx > > ( & self ,
2324
- cx : C ,
2325
- i : usize )
2326
- -> C :: TyLayout {
2327
- cx. layout_of ( self . field_type ( cx, i) )
2316
+ pub fn field < C : LayoutOf < Ty < ' tcx > > + HasTyCtxt < ' tcx > > ( & self ,
2317
+ cx : C ,
2318
+ i : usize )
2319
+ -> C :: FullLayout {
2320
+ cx. layout_of ( self . field_type_unnormalized ( cx. tcx ( ) , i) )
2328
2321
}
2329
2322
}
2330
2323
0 commit comments