layout_of: T: Thin
implies sizeof(&T) == sizeof(usize)
This commit is contained in:
parent
c7572670a1
commit
b25da9ce6d
2 changed files with 39 additions and 8 deletions
|
@ -155,17 +155,37 @@ fn layout_of_uncached<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
|
let unsized_part = tcx.struct_tail_erasing_lifetimes(pointee, param_env);
|
||||||
let metadata = match unsized_part.kind() {
|
|
||||||
ty::Foreign(..) => {
|
let metadata = if let Some(metadata_def_id) = tcx.lang_items().metadata_type() {
|
||||||
|
let metadata_ty = tcx.normalize_erasing_regions(
|
||||||
|
param_env,
|
||||||
|
tcx.mk_projection(metadata_def_id, [pointee]),
|
||||||
|
);
|
||||||
|
let metadata_layout = cx.layout_of(metadata_ty)?;
|
||||||
|
// If the metadata is a 1-zst, then the pointer is thin.
|
||||||
|
if metadata_layout.is_zst() && metadata_layout.align.abi.bytes() == 1 {
|
||||||
return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
|
return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
|
||||||
}
|
}
|
||||||
ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
|
|
||||||
ty::Dynamic(..) => {
|
let Abi::Scalar(metadata) = metadata_layout.abi else {
|
||||||
let mut vtable = scalar_unit(Pointer);
|
return Err(LayoutError::Unknown(unsized_part));
|
||||||
vtable.valid_range_mut().start = 1;
|
};
|
||||||
vtable
|
metadata
|
||||||
|
} else {
|
||||||
|
match unsized_part.kind() {
|
||||||
|
ty::Foreign(..) => {
|
||||||
|
return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr)));
|
||||||
|
}
|
||||||
|
ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)),
|
||||||
|
ty::Dynamic(..) => {
|
||||||
|
let mut vtable = scalar_unit(Pointer);
|
||||||
|
vtable.valid_range_mut().start = 1;
|
||||||
|
vtable
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(LayoutError::Unknown(unsized_part));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(LayoutError::Unknown(unsized_part)),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Effectively a (ptr, meta) tuple.
|
// Effectively a (ptr, meta) tuple.
|
||||||
|
|
11
src/test/ui/layout/thin-meta-implies-thin-ptr.rs
Normal file
11
src/test/ui/layout/thin-meta-implies-thin-ptr.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// check-pass
|
||||||
|
|
||||||
|
#![feature(ptr_metadata)]
|
||||||
|
|
||||||
|
use std::ptr::Thin;
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
||||||
|
fn foo<T: ?Sized + Thin>(t: *const T) -> *const () {
|
||||||
|
unsafe { std::mem::transmute(t) }
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue