@@ -1788,22 +1788,18 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
17881788 let field_info: Vec < _ > = flds
17891789 . iter ( )
17901790 . enumerate ( )
1791- . map ( |( i, & name) | match layout. field ( self , i) {
1792- Err ( err) => {
1793- bug ! ( "no layout found for field {}: `{:?}`" , name, err) ;
1791+ . map ( |( i, & name) | {
1792+ let field_layout = layout. field ( self , i) ;
1793+ let offset = layout. fields . offset ( i) ;
1794+ let field_end = offset + field_layout. size ;
1795+ if min_size < field_end {
1796+ min_size = field_end;
17941797 }
1795- Ok ( field_layout) => {
1796- let offset = layout. fields . offset ( i) ;
1797- let field_end = offset + field_layout. size ;
1798- if min_size < field_end {
1799- min_size = field_end;
1800- }
1801- FieldInfo {
1802- name : name. to_string ( ) ,
1803- offset : offset. bytes ( ) ,
1804- size : field_layout. size . bytes ( ) ,
1805- align : field_layout. align . abi . bytes ( ) ,
1806- }
1798+ FieldInfo {
1799+ name : name. to_string ( ) ,
1800+ offset : offset. bytes ( ) ,
1801+ size : field_layout. size . bytes ( ) ,
1802+ align : field_layout. align . abi . bytes ( ) ,
18071803 }
18081804 } )
18091805 . collect ( ) ;
@@ -2146,30 +2142,24 @@ where
21462142 TyAndLayout { ty : this. ty , layout }
21472143 }
21482144
2149- fn ty_and_layout_field ( this : TyAndLayout < ' tcx > , cx : & C , i : usize ) -> C :: TyAndLayout {
2150- enum TyMaybeWithLayout < ' tcx , C : LayoutOf < ' tcx > > {
2151- Ty ( C :: Ty ) ,
2152- TyAndLayout ( C :: TyAndLayout ) ,
2145+ fn ty_and_layout_field ( this : TyAndLayout < ' tcx > , cx : & C , i : usize ) -> TyAndLayout < ' tcx > {
2146+ enum TyMaybeWithLayout < ' tcx > {
2147+ Ty ( Ty < ' tcx > ) ,
2148+ TyAndLayout ( TyAndLayout < ' tcx > ) ,
21532149 }
21542150
2155- fn ty_and_layout_kind <
2156- C : LayoutOf < ' tcx , Ty = Ty < ' tcx > > + HasTyCtxt < ' tcx > + HasParamEnv < ' tcx > ,
2157- > (
2151+ fn field_ty_or_layout (
21582152 this : TyAndLayout < ' tcx > ,
2159- cx : & C ,
2153+ cx : & ( impl HasTyCtxt < ' tcx > + HasParamEnv < ' tcx > ) ,
21602154 i : usize ,
2161- ty : C :: Ty ,
2162- ) -> TyMaybeWithLayout < ' tcx , C > {
2155+ ) -> TyMaybeWithLayout < ' tcx > {
21632156 let tcx = cx. tcx ( ) ;
2164- let tag_layout = |tag : & Scalar | -> C :: TyAndLayout {
2157+ let tag_layout = |tag : & Scalar | -> TyAndLayout < ' tcx > {
21652158 let layout = Layout :: scalar ( cx, tag. clone ( ) ) ;
2166- MaybeResult :: from ( Ok ( TyAndLayout {
2167- layout : tcx. intern_layout ( layout) ,
2168- ty : tag. value . to_ty ( tcx) ,
2169- } ) )
2159+ TyAndLayout { layout : tcx. intern_layout ( layout) , ty : tag. value . to_ty ( tcx) }
21702160 } ;
21712161
2172- match * ty. kind ( ) {
2162+ match * this . ty . kind ( ) {
21732163 ty:: Bool
21742164 | ty:: Char
21752165 | ty:: Int ( _)
@@ -2180,7 +2170,7 @@ where
21802170 | ty:: FnDef ( ..)
21812171 | ty:: GeneratorWitness ( ..)
21822172 | ty:: Foreign ( ..)
2183- | ty:: Dynamic ( ..) => bug ! ( "TyAndLayout::field_type ({:?}): not applicable" , this) ,
2173+ | ty:: Dynamic ( ..) => bug ! ( "TyAndLayout::field ({:?}): not applicable" , this) ,
21842174
21852175 // Potentially-fat pointers.
21862176 ty:: Ref ( _, pointee, _) | ty:: RawPtr ( ty:: TypeAndMut { ty : pointee, .. } ) => {
@@ -2192,17 +2182,19 @@ where
21922182 // as the `Abi` or `FieldsShape` is checked by users.
21932183 if i == 0 {
21942184 let nil = tcx. mk_unit ( ) ;
2195- let ptr_ty = if ty. is_unsafe_ptr ( ) {
2185+ let unit_ptr_ty = if this . ty . is_unsafe_ptr ( ) {
21962186 tcx. mk_mut_ptr ( nil)
21972187 } else {
21982188 tcx. mk_mut_ref ( tcx. lifetimes . re_static , nil)
21992189 } ;
2200- return TyMaybeWithLayout :: TyAndLayout ( MaybeResult :: from (
2201- cx. layout_of ( ptr_ty) . to_result ( ) . map ( |mut ptr_layout| {
2202- ptr_layout. ty = ty;
2203- ptr_layout
2204- } ) ,
2205- ) ) ;
2190+
2191+ // NOTE(eddyb) using an empty `ParamEnv`, and `unwrap`-ing
2192+ // the `Result` should always work because the type is
2193+ // always either `*mut ()` or `&'static mut ()`.
2194+ return TyMaybeWithLayout :: TyAndLayout ( TyAndLayout {
2195+ ty : this. ty ,
2196+ ..tcx. layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( unit_ptr_ty) ) . unwrap ( )
2197+ } ) ;
22062198 }
22072199
22082200 match tcx. struct_tail_erasing_lifetimes ( pointee, cx. param_env ( ) ) . kind ( ) {
@@ -2226,7 +2218,7 @@ where
22262218 ])
22272219 */
22282220 }
2229- _ => bug ! ( "TyAndLayout::field_type ({:?}): not applicable" , this) ,
2221+ _ => bug ! ( "TyAndLayout::field ({:?}): not applicable" , this) ,
22302222 }
22312223 }
22322224
@@ -2235,9 +2227,11 @@ where
22352227 ty:: Str => TyMaybeWithLayout :: Ty ( tcx. types . u8 ) ,
22362228
22372229 // Tuples, generators and closures.
2238- ty:: Closure ( _, ref substs) => {
2239- ty_and_layout_kind ( this, cx, i, substs. as_closure ( ) . tupled_upvars_ty ( ) )
2240- }
2230+ ty:: Closure ( _, ref substs) => field_ty_or_layout (
2231+ TyAndLayout { ty : substs. as_closure ( ) . tupled_upvars_ty ( ) , ..this } ,
2232+ cx,
2233+ i,
2234+ ) ,
22412235
22422236 ty:: Generator ( def_id, ref substs, _) => match this. variants {
22432237 Variants :: Single { index } => TyMaybeWithLayout :: Ty (
@@ -2280,14 +2274,25 @@ where
22802274 | ty:: Opaque ( ..)
22812275 | ty:: Param ( _)
22822276 | ty:: Infer ( _)
2283- | ty:: Error ( _) => bug ! ( "TyAndLayout::field_type : unexpected type `{}`" , this. ty) ,
2277+ | ty:: Error ( _) => bug ! ( "TyAndLayout::field : unexpected type `{}`" , this. ty) ,
22842278 }
22852279 }
22862280
2287- cx. layout_of ( match ty_and_layout_kind ( this, cx, i, this. ty ) {
2288- TyMaybeWithLayout :: Ty ( result) => result,
2289- TyMaybeWithLayout :: TyAndLayout ( result) => return result,
2290- } )
2281+ match field_ty_or_layout ( this, cx, i) {
2282+ TyMaybeWithLayout :: Ty ( field_ty) => {
2283+ cx. tcx ( ) . layout_of ( cx. param_env ( ) . and ( field_ty) ) . unwrap_or_else ( |e| {
2284+ bug ! (
2285+ "failed to get layout for `{}`: {},\n \
2286+ despite it being a field (#{}) of an existing layout: {:#?}",
2287+ field_ty,
2288+ e,
2289+ i,
2290+ this
2291+ )
2292+ } )
2293+ }
2294+ TyMaybeWithLayout :: TyAndLayout ( field_layout) => field_layout,
2295+ }
22912296 }
22922297
22932298 fn ty_and_layout_pointee_info_at (
0 commit comments