@@ -155,17 +155,37 @@ fn layout_of_uncached<'tcx>(
155155 }
156156
157157 let unsized_part = tcx. struct_tail_erasing_lifetimes ( pointee, param_env) ;
158- let metadata = match unsized_part. kind ( ) {
159- ty:: Foreign ( ..) => {
158+
159+ let metadata = if let Some ( metadata_def_id) = tcx. lang_items ( ) . metadata_type ( ) {
160+ let metadata_ty = tcx. normalize_erasing_regions (
161+ param_env,
162+ tcx. mk_projection ( metadata_def_id, [ pointee] ) ,
163+ ) ;
164+ let metadata_layout = cx. layout_of ( metadata_ty) ?;
165+ // If the metadata is a 1-zst, then the pointer is thin.
166+ if metadata_layout. is_zst ( ) && metadata_layout. align . abi . bytes ( ) == 1 {
160167 return Ok ( tcx. intern_layout ( LayoutS :: scalar ( cx, data_ptr) ) ) ;
161168 }
162- ty:: Slice ( _) | ty:: Str => scalar_unit ( Int ( dl. ptr_sized_integer ( ) , false ) ) ,
163- ty:: Dynamic ( ..) => {
164- let mut vtable = scalar_unit ( Pointer ) ;
165- vtable. valid_range_mut ( ) . start = 1 ;
166- vtable
169+
170+ let Abi :: Scalar ( metadata) = metadata_layout. abi else {
171+ return Err ( LayoutError :: Unknown ( unsized_part) ) ;
172+ } ;
173+ metadata
174+ } else {
175+ match unsized_part. kind ( ) {
176+ ty:: Foreign ( ..) => {
177+ return Ok ( tcx. intern_layout ( LayoutS :: scalar ( cx, data_ptr) ) ) ;
178+ }
179+ ty:: Slice ( _) | ty:: Str => scalar_unit ( Int ( dl. ptr_sized_integer ( ) , false ) ) ,
180+ ty:: Dynamic ( ..) => {
181+ let mut vtable = scalar_unit ( Pointer ) ;
182+ vtable. valid_range_mut ( ) . start = 1 ;
183+ vtable
184+ }
185+ _ => {
186+ return Err ( LayoutError :: Unknown ( unsized_part) ) ;
187+ }
167188 }
168- _ => return Err ( LayoutError :: Unknown ( unsized_part) ) ,
169189 } ;
170190
171191 // Effectively a (ptr, meta) tuple.
0 commit comments