@@ -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