Use ptr::Alignment
for extra coolness points
This commit is contained in:
parent
36f5918bf1
commit
014c6f208e
@ -1,10 +1,10 @@
|
|||||||
use std::mem;
|
use std::ptr::Alignment;
|
||||||
|
|
||||||
/// Returns the ABI-required minimum alignment of a type in bytes.
|
/// Returns the ABI-required minimum alignment of a type in bytes.
|
||||||
///
|
///
|
||||||
/// This is equivalent to [`mem::align_of`], but also works for some unsized
|
/// This is equivalent to [`mem::align_of`], but also works for some unsized
|
||||||
/// types (e.g. slices or rustc's `List`s).
|
/// types (e.g. slices or rustc's `List`s).
|
||||||
pub const fn align_of<T: ?Sized + Aligned>() -> usize {
|
pub const fn align_of<T: ?Sized + Aligned>() -> Alignment {
|
||||||
T::ALIGN
|
T::ALIGN
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,13 +19,13 @@ pub const fn align_of<T: ?Sized + Aligned>() -> usize {
|
|||||||
/// [`mem::align_of<Self>()`]: mem::align_of
|
/// [`mem::align_of<Self>()`]: mem::align_of
|
||||||
pub unsafe trait Aligned {
|
pub unsafe trait Aligned {
|
||||||
/// Alignment of `Self`.
|
/// Alignment of `Self`.
|
||||||
const ALIGN: usize;
|
const ALIGN: Alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T> Aligned for T {
|
unsafe impl<T> Aligned for T {
|
||||||
const ALIGN: usize = mem::align_of::<Self>();
|
const ALIGN: Alignment = Alignment::of::<Self>();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T> Aligned for [T] {
|
unsafe impl<T> Aligned for [T] {
|
||||||
const ALIGN: usize = mem::align_of::<T>();
|
const ALIGN: Alignment = Alignment::of::<T>();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#![feature(lint_reasons)]
|
#![feature(lint_reasons)]
|
||||||
#![feature(unwrap_infallible)]
|
#![feature(unwrap_infallible)]
|
||||||
#![feature(strict_provenance)]
|
#![feature(strict_provenance)]
|
||||||
|
#![feature(ptr_alignment_type)]
|
||||||
#![allow(rustc::default_hash_types)]
|
#![allow(rustc::default_hash_types)]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
#![deny(rustc::untranslatable_diagnostic)]
|
#![deny(rustc::untranslatable_diagnostic)]
|
||||||
|
@ -70,13 +70,13 @@ pub unsafe trait Pointer: Deref {
|
|||||||
/// # struct T;
|
/// # struct T;
|
||||||
/// # impl Deref for T { type Target = u8; fn deref(&self) -> &u8 { &0 } }
|
/// # impl Deref for T { type Target = u8; fn deref(&self) -> &u8 { &0 } }
|
||||||
/// # impl T {
|
/// # impl T {
|
||||||
/// const BITS: usize = bits_for::<<Self as Deref>::Target>();
|
/// const BITS: u32 = bits_for::<<Self as Deref>::Target>();
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`BITS`]: Pointer::BITS
|
/// [`BITS`]: Pointer::BITS
|
||||||
/// [`Self::Target`]: Deref::Target
|
/// [`Self::Target`]: Deref::Target
|
||||||
const BITS: usize;
|
const BITS: u32;
|
||||||
|
|
||||||
/// Turns this pointer into a raw, non-null pointer.
|
/// Turns this pointer into a raw, non-null pointer.
|
||||||
///
|
///
|
||||||
@ -118,7 +118,7 @@ pub unsafe trait Tag: Copy {
|
|||||||
/// value.
|
/// value.
|
||||||
///
|
///
|
||||||
/// [`into_usize`]: Tag::into_usize
|
/// [`into_usize`]: Tag::into_usize
|
||||||
const BITS: usize;
|
const BITS: u32;
|
||||||
|
|
||||||
/// Turns this tag into an integer.
|
/// Turns this tag into an integer.
|
||||||
///
|
///
|
||||||
@ -142,7 +142,7 @@ pub unsafe trait Tag: Copy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
|
unsafe impl<T: ?Sized + Aligned> Pointer for Box<T> {
|
||||||
const BITS: usize = bits_for::<Self::Target>();
|
const BITS: u32 = bits_for::<Self::Target>();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_ptr(self) -> NonNull<T> {
|
fn into_ptr(self) -> NonNull<T> {
|
||||||
@ -158,7 +158,7 @@ unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
|
unsafe impl<T: ?Sized + Aligned> Pointer for Rc<T> {
|
||||||
const BITS: usize = bits_for::<Self::Target>();
|
const BITS: u32 = bits_for::<Self::Target>();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_ptr(self) -> NonNull<T> {
|
fn into_ptr(self) -> NonNull<T> {
|
||||||
@ -174,7 +174,7 @@ unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
|
unsafe impl<T: ?Sized + Aligned> Pointer for Arc<T> {
|
||||||
const BITS: usize = bits_for::<Self::Target>();
|
const BITS: u32 = bits_for::<Self::Target>();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_ptr(self) -> NonNull<T> {
|
fn into_ptr(self) -> NonNull<T> {
|
||||||
@ -190,7 +190,7 @@ unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
|
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a T {
|
||||||
const BITS: usize = bits_for::<Self::Target>();
|
const BITS: u32 = bits_for::<Self::Target>();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_ptr(self) -> NonNull<T> {
|
fn into_ptr(self) -> NonNull<T> {
|
||||||
@ -206,7 +206,7 @@ unsafe fn from_ptr(ptr: NonNull<T>) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
|
unsafe impl<'a, T: 'a + ?Sized + Aligned> Pointer for &'a mut T {
|
||||||
const BITS: usize = bits_for::<Self::Target>();
|
const BITS: u32 = bits_for::<Self::Target>();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_ptr(self) -> NonNull<T> {
|
fn into_ptr(self) -> NonNull<T> {
|
||||||
@ -223,14 +223,8 @@ unsafe fn from_ptr(mut ptr: NonNull<T>) -> Self {
|
|||||||
|
|
||||||
/// Returns the number of bits available for use for tags in a pointer to `T`
|
/// Returns the number of bits available for use for tags in a pointer to `T`
|
||||||
/// (this is based on `T`'s alignment).
|
/// (this is based on `T`'s alignment).
|
||||||
pub const fn bits_for<T: ?Sized + Aligned>() -> usize {
|
pub const fn bits_for<T: ?Sized + Aligned>() -> u32 {
|
||||||
let bits = crate::aligned::align_of::<T>().trailing_zeros();
|
crate::aligned::align_of::<T>().as_nonzero().trailing_zeros()
|
||||||
|
|
||||||
// This is a replacement for `.try_into().unwrap()` unavailable in `const`
|
|
||||||
// (it's fine to make an assert here, since this is only called in compile time)
|
|
||||||
assert!((bits as u128) < usize::MAX as u128);
|
|
||||||
|
|
||||||
bits as usize
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
|
/// A tag type used in [`CopyTaggedPtr`] and [`TaggedPtr`] tests.
|
||||||
@ -245,7 +239,7 @@ enum Tag2 {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
unsafe impl Tag for Tag2 {
|
unsafe impl Tag for Tag2 {
|
||||||
const BITS: usize = 2;
|
const BITS: u32 = 2;
|
||||||
|
|
||||||
fn into_usize(self) -> usize {
|
fn into_usize(self) -> usize {
|
||||||
self as _
|
self as _
|
||||||
|
@ -116,7 +116,7 @@ pub fn set_tag(&mut self, tag: T) {
|
|||||||
self.packed = Self::pack(self.pointer_raw(), tag);
|
self.packed = Self::pack(self.pointer_raw(), tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
const TAG_BIT_SHIFT: usize = usize::BITS as usize - T::BITS;
|
const TAG_BIT_SHIFT: u32 = usize::BITS - T::BITS;
|
||||||
const ASSERTION: () = { assert!(T::BITS <= P::BITS) };
|
const ASSERTION: () = { assert!(T::BITS <= P::BITS) };
|
||||||
|
|
||||||
/// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`,
|
/// Pack pointer `ptr` that comes from [`P::into_ptr`] with a `tag`,
|
||||||
@ -298,7 +298,7 @@ unsafe impl<P, T, const CP: bool> Send for CopyTaggedPtr<P, T, CP>
|
|||||||
/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
|
/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
|
||||||
///
|
///
|
||||||
/// unsafe impl Tag for Tag2 {
|
/// unsafe impl Tag for Tag2 {
|
||||||
/// const BITS: usize = 2;
|
/// const BITS: u32 = 2;
|
||||||
///
|
///
|
||||||
/// fn into_usize(self) -> usize { todo!() }
|
/// fn into_usize(self) -> usize { todo!() }
|
||||||
/// unsafe fn from_usize(tag: usize) -> Self { todo!() }
|
/// unsafe fn from_usize(tag: usize) -> Self { todo!() }
|
||||||
|
@ -150,7 +150,7 @@ fn hash_stable(&self, hcx: &mut HCX, hasher: &mut StableHasher) {
|
|||||||
/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
|
/// enum Tag2 { B00 = 0b00, B01 = 0b01, B10 = 0b10, B11 = 0b11 };
|
||||||
///
|
///
|
||||||
/// unsafe impl Tag for Tag2 {
|
/// unsafe impl Tag for Tag2 {
|
||||||
/// const BITS: usize = 2;
|
/// const BITS: u32 = 2;
|
||||||
///
|
///
|
||||||
/// fn into_usize(self) -> usize { todo!() }
|
/// fn into_usize(self) -> usize { todo!() }
|
||||||
/// unsafe fn from_usize(tag: usize) -> Self { todo!() }
|
/// unsafe fn from_usize(tag: usize) -> Self { todo!() }
|
||||||
|
@ -59,6 +59,7 @@
|
|||||||
#![feature(result_option_inspect)]
|
#![feature(result_option_inspect)]
|
||||||
#![feature(const_option)]
|
#![feature(const_option)]
|
||||||
#![feature(trait_alias)]
|
#![feature(trait_alias)]
|
||||||
|
#![feature(ptr_alignment_type)]
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
#![allow(rustc::potential_query_instability)]
|
#![allow(rustc::potential_query_instability)]
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::arena::Arena;
|
use crate::arena::Arena;
|
||||||
use rustc_data_structures::aligned::Aligned;
|
use rustc_data_structures::aligned::{align_of, Aligned};
|
||||||
use rustc_serialize::{Encodable, Encoder};
|
use rustc_serialize::{Encodable, Encoder};
|
||||||
use std::alloc::Layout;
|
use std::alloc::Layout;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
@ -203,13 +203,13 @@ unsafe impl<T: Sync> Sync for List<T> {}
|
|||||||
// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail,
|
// Layouts of `Equivalent<T>` and `List<T>` are the same, modulo opaque tail,
|
||||||
// thus aligns of `Equivalent<T>` and `List<T>` must be the same.
|
// thus aligns of `Equivalent<T>` and `List<T>` must be the same.
|
||||||
unsafe impl<T> Aligned for List<T> {
|
unsafe impl<T> Aligned for List<T> {
|
||||||
const ALIGN: usize = {
|
const ALIGN: ptr::Alignment = {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct Equivalent<T> {
|
struct Equivalent<T> {
|
||||||
_len: usize,
|
_len: usize,
|
||||||
_data: [T; 0],
|
_data: [T; 0],
|
||||||
}
|
}
|
||||||
|
|
||||||
mem::align_of::<Equivalent<T>>()
|
align_of::<Equivalent<T>>()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1626,7 +1626,8 @@ struct ParamTag {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
|
unsafe impl rustc_data_structures::tagged_ptr::Tag for ParamTag {
|
||||||
const BITS: usize = 2;
|
const BITS: u32 = 2;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into_usize(self) -> usize {
|
fn into_usize(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
@ -1636,6 +1637,7 @@ fn into_usize(self) -> usize {
|
|||||||
Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3,
|
Self { reveal: traits::Reveal::All, constness: hir::Constness::Const } => 3,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn from_usize(ptr: usize) -> Self {
|
unsafe fn from_usize(ptr: usize) -> Self {
|
||||||
match ptr {
|
match ptr {
|
||||||
|
Loading…
Reference in New Issue
Block a user