@@ -155,17 +155,37 @@ fn layout_of_uncached<'tcx>(
155
155
}
156
156
157
157
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 {
160
167
return Ok ( tcx. intern_layout ( LayoutS :: scalar ( cx, data_ptr) ) ) ;
161
168
}
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
+ }
167
188
}
168
- _ => return Err ( LayoutError :: Unknown ( unsized_part) ) ,
169
189
} ;
170
190
171
191
// Effectively a (ptr, meta) tuple.
0 commit comments