Rollup merge of #137043 - Sky9x:unsafe-pinned-pt1-libs, r=tgross35,RalfJung,WaffleLapkin
Initial `UnsafePinned` implementation [Part 1: Libs] Initial libs changes necessary to unblock further work on [RFC 3467](https://rust-lang.github.io/rfcs/3467-unsafe-pinned.html). Tracking issue: #125735 This PR is split off from #136964, and includes just the libs changes: - `UnsafePinned` struct - private `UnsafeUnpin` structural auto trait - Lang items for both - Compiler changes necessary to block niches on `UnsafePinned` This PR does not change codegen, miri, the existing `!Unpin` hack, or anything else. That work is to be split into later PRs. --- cc ``@RalfJung`` ``@Noratrieb`` ``@rustbot`` label F-unsafe_pinned T-libs-api
This commit is contained in:
commit
d04df1cba9
11 changed files with 290 additions and 8 deletions
|
@ -315,7 +315,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||
repr: &ReprOptions,
|
||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||
is_enum: bool,
|
||||
is_unsafe_cell: bool,
|
||||
is_special_no_niche: bool,
|
||||
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
||||
discr_range_of_repr: impl Fn(i128, i128) -> (Integer, bool),
|
||||
discriminants: impl Iterator<Item = (VariantIdx, i128)>,
|
||||
|
@ -348,7 +348,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||
repr,
|
||||
variants,
|
||||
is_enum,
|
||||
is_unsafe_cell,
|
||||
is_special_no_niche,
|
||||
scalar_valid_range,
|
||||
always_sized,
|
||||
present_first,
|
||||
|
@ -505,7 +505,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||
repr: &ReprOptions,
|
||||
variants: &IndexSlice<VariantIdx, IndexVec<FieldIdx, F>>,
|
||||
is_enum: bool,
|
||||
is_unsafe_cell: bool,
|
||||
is_special_no_niche: bool,
|
||||
scalar_valid_range: (Bound<u128>, Bound<u128>),
|
||||
always_sized: bool,
|
||||
present_first: VariantIdx,
|
||||
|
@ -524,7 +524,7 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
|
|||
let mut st = self.univariant(&variants[v], repr, kind)?;
|
||||
st.variants = Variants::Single { index: v };
|
||||
|
||||
if is_unsafe_cell {
|
||||
if is_special_no_niche {
|
||||
let hide_niches = |scalar: &mut _| match scalar {
|
||||
Scalar::Initialized { value, valid_range } => {
|
||||
*valid_range = WrappingRange::full(value.size(dl))
|
||||
|
|
|
@ -182,6 +182,7 @@ language_item_table! {
|
|||
DynMetadata, sym::dyn_metadata, dyn_metadata, Target::Struct, GenericRequirement::None;
|
||||
|
||||
Freeze, sym::freeze, freeze_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
UnsafeUnpin, sym::unsafe_unpin, unsafe_unpin_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
||||
FnPtrTrait, sym::fn_ptr_trait, fn_ptr_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
FnPtrAddr, sym::fn_ptr_addr, fn_ptr_addr, Target::Method(MethodKind::Trait { body: false }), GenericRequirement::None;
|
||||
|
@ -235,6 +236,8 @@ language_item_table! {
|
|||
IndexMut, sym::index_mut, index_mut_trait, Target::Trait, GenericRequirement::Exact(1);
|
||||
|
||||
UnsafeCell, sym::unsafe_cell, unsafe_cell_type, Target::Struct, GenericRequirement::None;
|
||||
UnsafePinned, sym::unsafe_pinned, unsafe_pinned_type, Target::Struct, GenericRequirement::None;
|
||||
|
||||
VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None;
|
||||
|
||||
Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0);
|
||||
|
|
|
@ -864,8 +864,8 @@ fn ty_is_known_nonnull<'tcx>(
|
|||
return true;
|
||||
}
|
||||
|
||||
// `UnsafeCell` has its niche hidden.
|
||||
if def.is_unsafe_cell() {
|
||||
// `UnsafeCell` and `UnsafePinned` have their niche hidden.
|
||||
if def.is_unsafe_cell() || def.is_unsafe_pinned() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ bitflags::bitflags! {
|
|||
const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8;
|
||||
/// Indicates whether the type is `UnsafeCell`.
|
||||
const IS_UNSAFE_CELL = 1 << 9;
|
||||
/// Indicates whether the type is `UnsafePinned`.
|
||||
const IS_UNSAFE_PINNED = 1 << 10;
|
||||
/// Indicates whether the type is anonymous.
|
||||
const IS_ANONYMOUS = 1 << 11;
|
||||
}
|
||||
}
|
||||
rustc_data_structures::external_bitflags_debug! { AdtFlags }
|
||||
|
@ -302,6 +306,9 @@ impl AdtDefData {
|
|||
if tcx.is_lang_item(did, LangItem::UnsafeCell) {
|
||||
flags |= AdtFlags::IS_UNSAFE_CELL;
|
||||
}
|
||||
if tcx.is_lang_item(did, LangItem::UnsafePinned) {
|
||||
flags |= AdtFlags::IS_UNSAFE_PINNED;
|
||||
}
|
||||
|
||||
AdtDefData { did, variants, flags, repr }
|
||||
}
|
||||
|
@ -405,6 +412,12 @@ impl<'tcx> AdtDef<'tcx> {
|
|||
self.flags().contains(AdtFlags::IS_UNSAFE_CELL)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is `UnsafePinned<T>`.
|
||||
#[inline]
|
||||
pub fn is_unsafe_pinned(self) -> bool {
|
||||
self.flags().contains(AdtFlags::IS_UNSAFE_PINNED)
|
||||
}
|
||||
|
||||
/// Returns `true` if this is `ManuallyDrop<T>`.
|
||||
#[inline]
|
||||
pub fn is_manually_drop(self) -> bool {
|
||||
|
|
|
@ -2215,6 +2215,8 @@ symbols! {
|
|||
unsafe_fields,
|
||||
unsafe_no_drop_flag,
|
||||
unsafe_pin_internals,
|
||||
unsafe_pinned,
|
||||
unsafe_unpin,
|
||||
unsize,
|
||||
unsized_const_param_ty,
|
||||
unsized_const_params,
|
||||
|
|
|
@ -514,6 +514,9 @@ fn layout_of_uncached<'tcx>(
|
|||
return map_layout(cx.calc.layout_of_union(&def.repr(), &variants));
|
||||
}
|
||||
|
||||
// UnsafeCell and UnsafePinned both disable niche optimizations
|
||||
let is_special_no_niche = def.is_unsafe_cell() || def.is_unsafe_pinned();
|
||||
|
||||
let get_discriminant_type =
|
||||
|min, max| abi::Integer::repr_discr(tcx, ty, &def.repr(), min, max);
|
||||
|
||||
|
@ -542,7 +545,7 @@ fn layout_of_uncached<'tcx>(
|
|||
&def.repr(),
|
||||
&variants,
|
||||
def.is_enum(),
|
||||
def.is_unsafe_cell(),
|
||||
is_special_no_niche,
|
||||
tcx.layout_scalar_valid_range(def.did()),
|
||||
get_discriminant_type,
|
||||
discriminants_iter(),
|
||||
|
@ -568,7 +571,7 @@ fn layout_of_uncached<'tcx>(
|
|||
&def.repr(),
|
||||
&variants,
|
||||
def.is_enum(),
|
||||
def.is_unsafe_cell(),
|
||||
is_special_no_niche,
|
||||
tcx.layout_scalar_valid_range(def.did()),
|
||||
get_discriminant_type,
|
||||
discriminants_iter(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue