Skip to content
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
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ language_item_table! {

OwnedBox, sym::owned_box, owned_box, Target::Struct, GenericRequirement::Minimum(1);
GlobalAlloc, sym::global_alloc_ty, global_alloc_ty, Target::Struct, GenericRequirement::None;
NoaliasAllocator, sym::noalias_allocator, noalias_allocator_trait, Target::Trait, GenericRequirement::None;

PhantomData, sym::phantom_data, phantom_data, Target::Struct, GenericRequirement::Exact(1);

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1434,6 +1434,7 @@ symbols! {
no_sanitize,
no_stack_check,
no_std,
noalias_allocator,
nomem,
non_ascii_idents,
non_exhaustive,
Expand Down
10 changes: 10 additions & 0 deletions library/alloc/src/alloc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,19 @@ unsafe extern "Rust" {
#[unstable(feature = "allocator_api", issue = "32838")]
#[derive(Copy, Clone, Default, Debug)]
// the compiler needs to know when a Box uses the global allocator vs a custom one
// FIXME(nia-e): change everything to use the noalias_allocator lang item instead
#[lang = "global_alloc_ty"]
pub struct Global;

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl core::alloc::AllocatorClone for Global {}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl core::alloc::StaticAllocator for Global {}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl core::alloc::NoaliasAllocator for Global {}

/// Allocates memory with the global allocator.
///
/// This function forwards calls to the [`GlobalAlloc::alloc`] method
Expand Down
35 changes: 27 additions & 8 deletions library/alloc/src/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,12 @@ use core::task::{Context, Poll};

#[cfg(not(no_global_oom_handling))]
use crate::alloc::handle_alloc_error;
use crate::alloc::{AllocError, Allocator, Global, Layout};
use crate::alloc::{
AllocError, Allocator, AllocatorClone, AllocatorEq, Global, Layout, StaticAllocator,
};
use crate::raw_vec::RawVec;
#[cfg(not(no_global_oom_handling))]
use crate::str::from_boxed_utf8_unchecked;
use crate::str::from_boxed_utf8_unchecked_in;

/// Conversion related impls for `Box<_>` (`From`, `downcast`, etc)
mod convert;
Expand Down Expand Up @@ -712,7 +714,7 @@ impl<T, A: Allocator> Box<T, A> {
#[inline(always)]
pub fn pin_in(x: T, alloc: A) -> Pin<Self>
where
A: 'static + Allocator,
A: StaticAllocator,
{
Self::into_pin(Self::new_in(x, alloc))
}
Expand Down Expand Up @@ -1979,7 +1981,7 @@ impl<T: ?Sized, A: Allocator> Box<T, A> {
#[stable(feature = "box_into_pin", since = "1.63.0")]
pub fn into_pin(boxed: Self) -> Pin<Self>
where
A: 'static,
A: StaticAllocator,
{
// It's not possible to move or replace the insides of a `Pin<Box<T>>`
// when `T: !Unpin`, so it's safe to pin it directly without any
Expand Down Expand Up @@ -2153,11 +2155,10 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "box_slice_clone", since = "1.3.0")]
impl Clone for Box<str> {
impl<A: Allocator + Clone> Clone for Box<str, A> {
fn clone(&self) -> Self {
// this makes a copy of the data
let buf: Box<[u8]> = self.as_bytes().into();
unsafe { from_boxed_utf8_unchecked(buf) }
let buf = Box::clone_from_ref_in(self.as_bytes(), self.1.clone());
unsafe { from_boxed_utf8_unchecked_in(buf) }
}
}

Expand Down Expand Up @@ -2529,3 +2530,21 @@ unsafe impl<T: ?Sized + Allocator, A: Allocator> Allocator for Box<T, A> {
unsafe { (**self).shrink(ptr, old_layout, new_layout) }
}
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl<T, A> AllocatorClone for Box<T, A>
where
T: AllocatorClone,
Comment thread
nia-e marked this conversation as resolved.
// Otherwise, the clone impl *here* may unwind.
A: AllocatorClone,
Box<T, A>: Clone,
{
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl<T, A> AllocatorEq for Box<T, A>
where
T: AllocatorEq + ?Sized,
A: Allocator,
{
}
4 changes: 2 additions & 2 deletions library/alloc/src/boxed/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::fmt;
use core::mem;
use core::pin::Pin;

use crate::alloc::Allocator;
use crate::alloc::{Allocator, StaticAllocator};
#[cfg(not(no_global_oom_handling))]
use crate::borrow::Cow;
use crate::boxed::Box;
Expand Down Expand Up @@ -38,7 +38,7 @@ 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>>
where
A: 'static,
A: StaticAllocator,
{
/// Converts a `Box<T>` into a `Pin<Box<T>>`. If `T` does not implement [`Unpin`], then
/// `*boxed` will be pinned in memory and unable to be moved.
Expand Down
33 changes: 22 additions & 11 deletions library/alloc/src/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#![stable(feature = "rust1", since = "1.0.0")]

use core::alloc::AllocatorClone;
use core::cmp::Ordering;
use core::hash::{Hash, Hasher};
use core::iter::FusedIterator;
Expand Down Expand Up @@ -136,7 +137,6 @@ impl<T: fmt::Debug> fmt::Debug for IterMut<'_, T> {
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
///
/// [`into_iter`]: LinkedList::into_iter
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<
T,
Expand All @@ -145,6 +145,13 @@ pub struct IntoIter<
list: LinkedList<T, A>,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, A: Allocator + Clone> Clone for IntoIter<T, A> {
fn clone(&self) -> Self {
Self { list: self.list.clone() }
}
}

#[stable(feature = "collection_debug", since = "1.17.0")]
impl<T: fmt::Debug, A: Allocator> fmt::Debug for IntoIter<T, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Expand Down Expand Up @@ -340,7 +347,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
at: usize,
) -> Self
where
A: Clone,
A: AllocatorClone,
{
// The split node is the new head node of the second part
if let Some(mut split_node) = split_node {
Expand Down Expand Up @@ -383,7 +390,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
at: usize,
) -> Self
where
A: Clone,
A: AllocatorClone,
{
// The split node is the new tail node of the first part and owns
// the head of the second part.
Expand Down Expand Up @@ -994,7 +1001,7 @@ impl<T, A: Allocator> LinkedList<T, A> {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn split_off(&mut self, at: usize) -> LinkedList<T, A>
where
A: Clone,
A: AllocatorClone,
{
let len = self.len();
assert!(at <= len, "Cannot split off at a nonexistent index");
Expand Down Expand Up @@ -1748,7 +1755,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn remove_current_as_list(&mut self) -> Option<LinkedList<T, A>>
where
A: Clone,
A: AllocatorClone,
{
let mut unlinked_node = self.current?;
unsafe {
Expand Down Expand Up @@ -1776,7 +1783,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn split_after(&mut self) -> LinkedList<T, A>
where
A: Clone,
A: AllocatorClone,
{
let split_off_idx = if self.index == self.list.len { 0 } else { self.index + 1 };
if self.index == self.list.len {
Expand All @@ -1795,7 +1802,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> {
#[unstable(feature = "linked_list_cursors", issue = "58533")]
pub fn split_before(&mut self) -> LinkedList<T, A>
where
A: Clone,
A: AllocatorClone,
{
let split_off_idx = self.index;
self.index = 0;
Expand Down Expand Up @@ -2151,6 +2158,7 @@ impl<T: Ord, A: Allocator> Ord for LinkedList<T, A> {
}
}

// `AllocatorClone` bound is necessary due to the `split_off` in `clone_from`.
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
fn clone(&self) -> Self {
Expand All @@ -2167,12 +2175,15 @@ impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
/// resources of `self`'s elements as well.
fn clone_from(&mut self, source: &Self) {
let mut source_iter = source.iter();
if self.len() > source.len() {
self.split_off(source.len());
}
for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) {
for elem in self.iter_mut() {
let Some(source_elem) = source_iter.next() else {
break;
};
elem.clone_from(source_elem);
}
while self.len() > source.len() {
self.pop_back();
}
if !source_iter.is_empty() {
self.extend(source_iter.cloned());
}
Expand Down
27 changes: 15 additions & 12 deletions library/alloc/src/rc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ use core::{borrow, fmt, hint};

#[cfg(not(no_global_oom_handling))]
use crate::alloc::handle_alloc_error;
use crate::alloc::{AllocError, Allocator, Global, Layout};
use crate::alloc::{AllocError, Allocator, AllocatorClone, Global, Layout};
use crate::borrow::{Cow, ToOwned};
use crate::boxed::Box;
#[cfg(not(no_global_oom_handling))]
Expand Down Expand Up @@ -1771,7 +1771,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn downgrade(this: &Self) -> Weak<T, A>
where
A: Clone,
A: AllocatorClone,
{
this.inner().inc_weak();
// Make sure we do not create a dangling Weak
Expand Down Expand Up @@ -1852,7 +1852,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
#[unstable(feature = "allocator_api", issue = "32838")]
pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A)
where
A: Clone,
A: AllocatorClone,
{
// Retain Rc, but don't touch refcount by wrapping in ManuallyDrop
let rc = unsafe { mem::ManuallyDrop::new(Rc::<T, A>::from_raw_in(ptr, alloc)) };
Expand Down Expand Up @@ -2028,7 +2028,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
}

#[cfg(not(no_global_oom_handling))]
impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Rc<T, A> {
impl<T: ?Sized + CloneToUninit, A: AllocatorClone> Rc<T, A> {
/// Makes a mutable reference into the given `Rc`.
///
/// If there are other `Rc` pointers to the same allocation, then `make_mut` will
Expand Down Expand Up @@ -2309,7 +2309,7 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {

// Free the allocation without dropping its contents
let (bptr, alloc) = Box::into_raw_with_allocator(src);
let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop<T>, alloc.by_ref());
let src = Box::from_raw_in(bptr as *mut mem::ManuallyDrop<T>, &alloc);
drop(src);

Self::from_ptr_in(ptr, alloc)
Expand Down Expand Up @@ -2498,7 +2498,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc<T, A> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
impl<T: ?Sized, A: AllocatorClone> Clone for Rc<T, A> {
/// Makes a clone of the `Rc` pointer.
///
/// This creates another pointer to the same allocation, increasing the
Expand All @@ -2523,10 +2523,10 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Rc<T, A> {
}

#[unstable(feature = "ergonomic_clones", issue = "132290")]
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Rc<T, A> {}
impl<T: ?Sized, A: AllocatorClone> UseCloned for Rc<T, A> {}

#[unstable(feature = "share_trait", issue = "156756")]
impl<T: ?Sized, A: Allocator + Clone> Share for Rc<T, A> {}
impl<T: ?Sized, A: AllocatorClone> Share for Rc<T, A> {}

#[cfg(not(no_global_oom_handling))]
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -3547,7 +3547,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
#[stable(feature = "rc_weak", since = "1.4.0")]
pub fn upgrade(&self) -> Option<Rc<T, A>>
where
A: Clone,
A: AllocatorClone,
{
let inner = self.inner()?;

Expand Down Expand Up @@ -3692,7 +3692,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak<T, A> {
}

#[stable(feature = "rc_weak", since = "1.4.0")]
impl<T: ?Sized, A: Allocator + Clone> Clone for Weak<T, A> {
impl<T: ?Sized, A: AllocatorClone> Clone for Weak<T, A> {
/// Makes a clone of the `Weak` pointer that points to the same allocation.
///
/// # Examples
Expand All @@ -3714,7 +3714,7 @@ impl<T: ?Sized, A: Allocator + Clone> Clone for Weak<T, A> {
}

#[unstable(feature = "ergonomic_clones", issue = "132290")]
impl<T: ?Sized, A: Allocator + Clone> UseCloned for Weak<T, A> {}
impl<T: ?Sized, A: AllocatorClone> UseCloned for Weak<T, A> {}

#[stable(feature = "rc_weak", since = "1.4.0")]
impl<T: ?Sized, A: Allocator> fmt::Debug for Weak<T, A> {
Expand Down Expand Up @@ -4414,7 +4414,7 @@ impl<T: ?Sized, A: Allocator> UniqueRc<T, A> {
}
}

impl<T: ?Sized, A: Allocator + Clone> UniqueRc<T, A> {
impl<T: ?Sized, A: AllocatorClone> UniqueRc<T, A> {
/// Creates a new weak reference to the `UniqueRc`.
///
/// Attempting to upgrade this weak reference will fail before the `UniqueRc` has been converted
Expand Down Expand Up @@ -4603,3 +4603,6 @@ unsafe impl<T: ?Sized + Allocator, A: Allocator> Allocator for Rc<T, A> {
unsafe { (**self).shrink(ptr, old_layout, new_layout) }
}
}

#[unstable(feature = "allocator_api", issue = "32838")]
unsafe impl<T: Allocator + ?Sized, A: AllocatorClone> AllocatorClone for Rc<T, A> {}
16 changes: 16 additions & 0 deletions library/alloc/src/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,22 @@ pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
unsafe { Box::from_raw(Box::into_raw(v) as *mut str) }
}

/// Converts a boxed slice of bytes to a boxed string slice without checking
/// that the string contains valid UTF-8 generically over the box's allocator.
///
/// # Safety
///
/// * The provided bytes must contain a valid UTF-8 sequence.
#[unstable(feature = "allocator_api", issue = "32838")]
#[must_use]
#[inline]
pub unsafe fn from_boxed_utf8_unchecked_in<A: crate::alloc::Allocator>(
v: Box<[u8], A>,
) -> Box<str, A> {
let (ptr, alloc) = Box::into_raw_with_allocator(v);
unsafe { Box::from_raw_in(ptr as *mut str, alloc) }
}

/// Converts leading ascii bytes in `s` by calling the `convert` function.
///
/// For better average performance, this happens in chunks of `2*size_of::<usize>()`.
Expand Down
Loading
Loading