Skip to content

Commit b25da9c

Browse files
layout_of: T: Thin implies sizeof(&T) == sizeof(usize)
1 parent c757267 commit b25da9c

File tree

2 files changed

+39
-8
lines changed

2 files changed

+39
-8
lines changed

compiler/rustc_ty_utils/src/layout.rs

+28-8
Original file line numberDiff line numberDiff line change
@@ -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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// check-pass
2+
3+
#![feature(ptr_metadata)]
4+
5+
use std::ptr::Thin;
6+
7+
fn main() {}
8+
9+
fn foo<T: ?Sized + Thin>(t: *const T) -> *const () {
10+
unsafe { std::mem::transmute(t) }
11+
}

0 commit comments

Comments
 (0)