Skip to content

Constify conversion traits #144289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions library/alloc/src/borrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@ use crate::fmt;
use crate::string::String;

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B>
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<'a, B: ?Sized> const Borrow<B> for Cow<'a, B>
where
B: ToOwned,
B::Owned: ~const Borrow<B>,
{
fn borrow(&self) -> &B {
&**self
Expand Down Expand Up @@ -326,9 +328,10 @@ impl<B: ?Sized + ToOwned> Cow<'_, B> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<B: ?Sized + ToOwned> Deref for Cow<'_, B>
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<B: ?Sized + ToOwned> const Deref for Cow<'_, B>
where
B::Owned: Borrow<B>,
B::Owned: ~const Borrow<B>,
{
type Target = B;

Expand Down Expand Up @@ -439,7 +442,11 @@ where
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized + ToOwned> AsRef<T> for Cow<'_, T> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized + ToOwned> const AsRef<T> for Cow<'_, T>
where
T::Owned: ~const Borrow<T>,
{
fn as_ref(&self) -> &T {
self
}
Expand Down
40 changes: 28 additions & 12 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,8 @@ impl<T, A: Allocator> Box<T, A> {
///
/// This conversion does not allocate on the heap and happens in place.
#[unstable(feature = "box_into_boxed_slice", issue = "71582")]
pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
#[rustc_const_unstable(feature = "const_convert_methods", issue = "144288")]
pub const fn into_boxed_slice(boxed: Self) -> Box<[T], A> {
let (raw, alloc) = Box::into_raw_with_allocator(boxed);
unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) }
}
Expand Down Expand Up @@ -1268,7 +1269,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// [memory layout]: self#memory-layout
#[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
#[rustc_const_unstable(feature = "allocator_api", issue = "32838")]
pub const unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self {
Box(unsafe { Unique::new_unchecked(raw) }, alloc)
}

Expand Down Expand Up @@ -1375,7 +1377,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
#[must_use = "losing the pointer will leak memory"]
#[unstable(feature = "allocator_api", issue = "32838")]
#[inline]
pub fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
#[rustc_const_unstable(feature = "allocator_api", issue = "32838")]
pub const fn into_raw_with_allocator(b: Self) -> (*mut T, A) {
let mut b = mem::ManuallyDrop::new(b);
// We carefully get the raw pointer out in a way that Miri's aliasing model understands what
// is happening: using the primitive "deref" of `Box`. In case `A` is *not* `Global`, we
Expand Down Expand Up @@ -1436,7 +1439,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
#[unstable(feature = "allocator_api", issue = "32838")]
// #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
#[inline]
pub fn into_non_null_with_allocator(b: Self) -> (NonNull<T>, A) {
#[rustc_const_unstable(feature = "allocator_api", issue = "32838")]
pub const fn into_non_null_with_allocator(b: Self) -> (NonNull<T>, A) {
let (ptr, alloc) = Box::into_raw_with_allocator(b);
// SAFETY: `Box` is guaranteed to be non-null.
unsafe { (NonNull::new_unchecked(ptr), alloc) }
Expand All @@ -1449,7 +1453,12 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
)]
#[inline]
#[doc(hidden)]
pub fn into_unique(b: Self) -> (Unique<T>, A) {
#[rustc_const_unstable(
feature = "ptr_internals",
issue = "none",
reason = "use `Box::leak(b).into()` or `Unique::from(Box::leak(b))` instead"
)]
pub const fn into_unique(b: Self) -> (Unique<T>, A) {
let (ptr, alloc) = Box::into_raw_with_allocator(b);
unsafe { (Unique::from(&mut *ptr), alloc) }
}
Expand Down Expand Up @@ -1641,7 +1650,8 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
/// let bar = Pin::from(foo);
/// ```
#[stable(feature = "box_into_pin", since = "1.63.0")]
pub fn into_pin(boxed: Self) -> Pin<Self>
#[rustc_const_unstable(feature = "const_convert_methods", issue = "144288")]
pub const fn into_pin(boxed: Self) -> Pin<Self>
where
A: 'static,
{
Expand Down Expand Up @@ -1942,7 +1952,8 @@ impl<T: ?Sized, A: Allocator> fmt::Pointer for Box<T, A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const Deref for Box<T, A> {
type Target = T;

fn deref(&self) -> &T {
Expand All @@ -1951,7 +1962,8 @@ impl<T: ?Sized, A: Allocator> Deref for Box<T, A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, A: Allocator> DerefMut for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const DerefMut for Box<T, A> {
fn deref_mut(&mut self) -> &mut T {
&mut **self
}
Expand Down Expand Up @@ -2028,28 +2040,32 @@ unsafe impl<T: ?Sized, A: Allocator> PinCoerceUnsized for Box<T, A> {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T, Global> {}

#[stable(feature = "box_borrow", since = "1.1.0")]
impl<T: ?Sized, A: Allocator> Borrow<T> for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const Borrow<T> for Box<T, A> {
fn borrow(&self) -> &T {
&**self
}
}

#[stable(feature = "box_borrow", since = "1.1.0")]
impl<T: ?Sized, A: Allocator> BorrowMut<T> for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const BorrowMut<T> for Box<T, A> {
fn borrow_mut(&mut self) -> &mut T {
&mut **self
}
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized, A: Allocator> AsRef<T> for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const AsRef<T> for Box<T, A> {
fn as_ref(&self) -> &T {
&**self
}
}

#[stable(since = "1.5.0", feature = "smart_ptr_as_ref")]
impl<T: ?Sized, A: Allocator> AsMut<T> for Box<T, A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const AsMut<T> for Box<T, A> {
fn as_mut(&mut self) -> &mut T {
&mut **self
}
Expand Down
15 changes: 9 additions & 6 deletions library/alloc/src/boxed/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ impl<T> From<T> for Box<T> {
}

#[stable(feature = "pin", since = "1.33.0")]
impl<T: ?Sized, A: Allocator> From<Box<T, A>> for Pin<Box<T, A>>
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized, A: Allocator> const From<Box<T, A>> for Pin<Box<T, A>>
where
A: 'static,
{
Expand Down Expand Up @@ -228,7 +229,8 @@ impl From<Cow<'_, str>> for Box<str> {
}

#[stable(feature = "boxed_str_conv", since = "1.19.0")]
impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<A: Allocator> const From<Box<str, A>> for Box<[u8], A> {
/// Converts a `Box<str>` into a `Box<[u8]>`
///
/// This conversion does not allocate on the heap and happens in place.
Expand All @@ -247,8 +249,7 @@ impl<A: Allocator> From<Box<str, A>> for Box<[u8], A> {
/// ```
#[inline]
fn from(s: Box<str, A>) -> Self {
let (raw, alloc) = Box::into_raw_with_allocator(s);
unsafe { Box::from_raw_in(raw as *mut [u8], alloc) }
s.into_boxed_bytes()
}
}

Expand All @@ -275,10 +276,11 @@ impl<T, const N: usize> From<[T; N]> for Box<[T]> {
/// # Safety
///
/// `boxed_slice.len()` must be exactly `N`.
unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
boxed_slice: Box<[T], A>,
) -> Box<[T; N], A> {
debug_assert_eq!(boxed_slice.len(), N);
debug_assert!(boxed_slice.len() == N);

let (ptr, alloc) = Box::into_raw_with_allocator(boxed_slice);
// SAFETY: Pointer and allocator came from an existing box,
Expand All @@ -287,6 +289,7 @@ unsafe fn boxed_slice_as_array_unchecked<T, A: Allocator, const N: usize>(
}

#[stable(feature = "boxed_slice_try_from", since = "1.43.0")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T, const N: usize> TryFrom<Box<[T]>> for Box<[T; N]> {
type Error = Box<[T]>;

Expand Down
28 changes: 21 additions & 7 deletions library/alloc/src/boxed/thin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use core::error::Error;
use core::fmt::{self, Debug, Display, Formatter};
use core::intrinsics::const_eval_select;
#[cfg(not(no_global_oom_handling))]
use core::intrinsics::{const_allocate, const_make_global};
use core::marker::PhantomData;
Expand Down Expand Up @@ -138,7 +139,8 @@ impl<T: ?Sized + Display> Display for ThinBox<T> {
}

#[unstable(feature = "thin_box", issue = "92791")]
impl<T: ?Sized> Deref for ThinBox<T> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized> const Deref for ThinBox<T> {
type Target = T;

fn deref(&self) -> &T {
Expand All @@ -150,6 +152,7 @@ impl<T: ?Sized> Deref for ThinBox<T> {
}

#[unstable(feature = "thin_box", issue = "92791")]
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
impl<T: ?Sized> DerefMut for ThinBox<T> {
fn deref_mut(&mut self) -> &mut T {
let value = self.data();
Expand All @@ -172,17 +175,20 @@ impl<T: ?Sized> Drop for ThinBox<T> {

#[unstable(feature = "thin_box", issue = "92791")]
impl<T: ?Sized> ThinBox<T> {
fn meta(&self) -> <T as Pointee>::Metadata {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const fn meta(&self) -> <T as Pointee>::Metadata {
// Safety:
// - NonNull and valid.
unsafe { *self.with_header().header() }
}

fn data(&self) -> *mut u8 {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const fn data(&self) -> *mut u8 {
self.with_header().value()
}

fn with_header(&self) -> &WithHeader<<T as Pointee>::Metadata> {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const fn with_header(&self) -> &WithHeader<<T as Pointee>::Metadata> {
// SAFETY: both types are transparent to `NonNull<u8>`
unsafe { &*((&raw const self.ptr) as *const WithHeader<_>) }
}
Expand Down Expand Up @@ -398,7 +404,8 @@ impl<H> WithHeader<H> {
}
}

fn header(&self) -> *mut H {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const fn header(&self) -> *mut H {
// Safety:
// - At least `size_of::<H>()` bytes are allocated ahead of the pointer.
// - We know that H will be aligned because the middle pointer is aligned to the greater
Expand All @@ -407,11 +414,18 @@ impl<H> WithHeader<H> {
// will always result in an aligned header pointer, it just may not point to the
// beginning of the allocation.
let hp = unsafe { self.0.as_ptr().sub(Self::header_size()) as *mut H };
debug_assert!(hp.is_aligned());

const fn ignore_alignment_const<H>(_hp: *mut H) {}
fn check_alignment_rt<H>(hp: *mut H) {
debug_assert!(hp.is_aligned());
}
const_eval_select((hp,), ignore_alignment_const, check_alignment_rt);

hp
}

fn value(&self) -> *mut u8 {
#[rustc_const_unstable(feature = "const_convert", issue = "143773")]
const fn value(&self) -> *mut u8 {
self.0.as_ptr()
}

Expand Down
Loading
Loading