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
36 changes: 20 additions & 16 deletions library/alloc/src/raw_vec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

use core::marker::{Destruct, PhantomData};
use core::mem::{Alignment, ManuallyDrop, MaybeUninit, SizedTypeProperties};
use core::ptr::{self, NonNull, Unique};
use core::panic::UnwindSafe;
use core::ptr::{self, NonNull};
use core::{cmp, hint};

#[cfg(not(no_global_oom_handling))]
Expand Down Expand Up @@ -54,14 +55,16 @@ const unsafe fn new_cap<T>(cap: usize) -> Cap {
/// involved. This type is excellent for building your own data structures like Vec and VecDeque.
/// In particular:
///
/// * Produces `Unique::dangling()` on zero-sized types.
/// * Produces `Unique::dangling()` on zero-length allocations.
/// * Avoids freeing `Unique::dangling()`.
/// * Produces `NonNull::dangling()` on zero-sized types.
/// * Produces `NonNull::dangling()` on zero-length allocations.
/// * Avoids freeing `NonNull::dangling()`.
/// * Catches all overflows in capacity computations (promotes them to "capacity overflow" panics).
/// * Guards against 32-bit systems allocating more than `isize::MAX` bytes.
/// * Provides niches for capacities greater than `isize::MAX`.
/// * Guards against overflowing your length.
/// * Calls `handle_alloc_error` for fallible allocations.
/// * Contains a `ptr::Unique` and thus endows the user with all related benefits.
/// * Implements `Send`, `Sync` and `UnwindSafe` iff `(T, A)` does.
/// * Carries `PhantomData<T>` for auto trait and `may_dangle` correctness.
/// * Uses the excess returned from the allocator to use the largest available capacity.
///
/// This type does not in anyway inspect the memory that it manages. When dropped it *will*
Expand All @@ -85,7 +88,7 @@ pub(crate) struct RawVec<T, A: Allocator = Global> {
/// as most operations don't need the actual type, just its layout.
#[allow(missing_debug_implementations)]
struct RawVecInner<A: Allocator = Global> {
ptr: Unique<u8>,
ptr: NonNull<u8>,
/// Never used for ZSTs; it's `capacity()`'s responsibility to return usize::MAX in that case.
///
/// # Safety
Expand All @@ -94,6 +97,9 @@ struct RawVecInner<A: Allocator = Global> {
cap: Cap,
alloc: A,
}
unsafe impl<A: Allocator + Send> Send for RawVecInner<A> {}
unsafe impl<A: Allocator + Sync> Sync for RawVecInner<A> {}
impl<A: Allocator + UnwindSafe> UnwindSafe for RawVecInner<A> {}

impl<T> RawVec<T, Global> {
/// Creates the biggest possible `RawVec` (on the system heap)
Expand Down Expand Up @@ -298,7 +304,7 @@ impl<T, A: Allocator> RawVec<T, A> {
}

/// Gets a raw pointer to the start of the allocation. Note that this is
/// `Unique::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
/// `NonNull::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
/// be careful.
#[inline]
pub(crate) const fn ptr(&self) -> *mut T {
Expand Down Expand Up @@ -487,7 +493,7 @@ const impl<A: [const] Allocator + [const] Destruct> RawVecInner<A> {
// matches the size requested. If that ever changes, the capacity
// here should change to `ptr.len() / size_of::<T>()`.
Ok(Self {
ptr: Unique::from(ptr.cast()),
ptr: ptr.cast(),
// SAFETY: We return early if `T` is a ZST, and if `capacity` would
// overflow an isize layout creation would have returned early as well.
cap: unsafe { Cap::new_unchecked(capacity) },
Expand Down Expand Up @@ -582,7 +588,7 @@ const impl<A: [const] Allocator + [const] Destruct> RawVecInner<A> {
impl<A: Allocator> RawVecInner<A> {
#[inline]
const fn new_in(alloc: A, align: Alignment) -> Self {
let ptr = Unique::from_non_null(NonNull::without_provenance(align.as_nonzero_usize()));
let ptr = NonNull::without_provenance(align.as_nonzero_usize());
// `cap: 0` means "unallocated". zero-sized types are ignored.
Self { ptr, cap: ZERO_CAP, alloc }
}
Expand All @@ -608,13 +614,13 @@ impl<A: Allocator> RawVecInner<A> {
#[inline]
const unsafe fn from_raw_parts_in(ptr: *mut u8, cap: Cap, alloc: A) -> Self {
// SAFETY: Upheld by caller.
Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc }
Self { ptr: unsafe { NonNull::new_unchecked(ptr) }, cap, alloc }
}

#[inline]
#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
const unsafe fn from_nonnull_in(ptr: NonNull<u8>, cap: Cap, alloc: A) -> Self {
Self { ptr: Unique::from(ptr), cap, alloc }
Self { ptr, cap, alloc }
}

#[inline]
Expand All @@ -624,7 +630,7 @@ impl<A: Allocator> RawVecInner<A> {

#[inline]
const fn non_null<T>(&self) -> NonNull<T> {
self.ptr.cast().as_non_null_ptr()
self.ptr.cast()
}

#[inline]
Expand Down Expand Up @@ -793,7 +799,7 @@ impl<A: Allocator> RawVecInner<A> {
// Allocators currently return a `NonNull<[u8]>` whose length matches
// the size requested. If that ever changes, the capacity here should
// change to `ptr.len() / size_of::<T>()`.
self.ptr = Unique::from(ptr.cast());
self.ptr = ptr.cast();
// SAFETY: Upheld by caller.
self.cap = unsafe { Cap::new_unchecked(cap) };
}
Expand Down Expand Up @@ -865,9 +871,7 @@ impl<A: Allocator> RawVecInner<A> {
// SAFETY: T isn't a ZST if we're here and `ptr` is our pointer that `current_memory`
// ensures was allocated with `layout`.
unsafe { self.alloc.deallocate(ptr, layout) };
self.ptr =
// SAFETY: Alignment is guaranteed to be nonzero.
unsafe { Unique::new_unchecked(ptr::without_provenance_mut(elem_layout.align())) };
self.ptr = NonNull::without_provenance(elem_layout.alignment().as_nonzero_usize());
self.cap = ZERO_CAP;
} else {
// SAFETY: `cap` is less than the previous capacity, which must have fit in an
Expand Down
2 changes: 1 addition & 1 deletion library/alloc/src/raw_vec/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ struct ZST;
// A `RawVec` holding zero-sized elements should always look like this.
fn zst_sanity<T>(v: &RawVec<T>) {
assert_eq!(v.capacity(), usize::MAX);
assert_eq!(v.ptr(), core::ptr::Unique::<T>::dangling().as_ptr());
assert_eq!(v.ptr(), core::ptr::dangling_mut::<T>());
assert_eq!(unsafe { v.inner.current_memory(T::LAYOUT) }, None);
}

Expand Down
1 change: 0 additions & 1 deletion library/alloctests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
#![feature(maybe_uninit_uninit_array_transpose)]
#![feature(ptr_alignment_type)]
#![feature(ptr_cast_slice)]
#![feature(ptr_internals)]
#![feature(rev_into_inner)]
#![feature(sized_type_properties)]
#![feature(slice_iter_mut_as_mut_slice)]
Expand Down
12 changes: 6 additions & 6 deletions src/etc/natvis/liballoc.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<Item Name="[capacity]" ExcludeView="simple">buf.inner.cap.__0</Item>
<ArrayItems>
<Size>len</Size>
<ValuePointer>($T1*)buf.inner.ptr.pointer.pointer</ValuePointer>
<ValuePointer>($T1*)buf.inner.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Type>
Expand All @@ -23,7 +23,7 @@
<If Condition="i == len">
<Break/>
</If>
<Item>(($T1*)buf.inner.ptr.pointer.pointer)[(i + head.__0) % buf.inner.cap.__0]</Item>
<Item>(($T1*)buf.inner.ptr.pointer)[(i + head.__0) % buf.inner.cap.__0]</Item>
<Exec>i = i + 1</Exec>
</Loop>
</CustomListItems>
Expand All @@ -41,17 +41,17 @@
</Expand>
</Type>
<Type Name="alloc::string::String">
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
<StringView>(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8</StringView>
<DisplayString>{(char*)vec.buf.inner.ptr.pointer,[vec.len]s8}</DisplayString>
<StringView>(char*)vec.buf.inner.ptr.pointer,[vec.len]s8</StringView>
<Expand>
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
<Item Name="[capacity]" ExcludeView="simple">vec.buf.inner.cap.__0</Item>
<Synthetic Name="[chars]">
<DisplayString>{(char*)vec.buf.inner.ptr.pointer.pointer,[vec.len]s8}</DisplayString>
<DisplayString>{(char*)vec.buf.inner.ptr.pointer,[vec.len]s8}</DisplayString>
<Expand>
<ArrayItems>
<Size>vec.len</Size>
<ValuePointer>(char*)vec.buf.inner.ptr.pointer.pointer</ValuePointer>
<ValuePointer>(char*)vec.buf.inner.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
Expand Down
6 changes: 3 additions & 3 deletions src/etc/natvis/libstd.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,14 @@
</Type>

<Type Name="std::ffi::os_str::OsString">
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer,[inner.inner.bytes.len]}</DisplayString>
<Expand>
<Synthetic Name="[chars]">
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer,[inner.inner.bytes.len]}</DisplayString>
<DisplayString>{(char*)inner.inner.bytes.buf.inner.ptr.pointer,[inner.inner.bytes.len]}</DisplayString>
<Expand>
<ArrayItems>
<Size>inner.inner.bytes.len</Size>
<ValuePointer>(char*)inner.inner.bytes.buf.inner.ptr.pointer.pointer</ValuePointer>
<ValuePointer>(char*)inner.inner.bytes.buf.inner.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
Expand Down
2 changes: 1 addition & 1 deletion tests/debuginfo/strings-and-strs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//@ gdb-command:run

//@ gdb-command:print plain_string
//@ gdb-check:$1 = alloc::string::String {vec: alloc::vec::Vec<u8, alloc::alloc::Global> {buf: alloc::raw_vec::RawVec<u8, alloc::alloc::Global> {inner: alloc::raw_vec::RawVecInner<alloc::alloc::Global> {ptr: core::ptr::unique::Unique<u8> {pointer: core::ptr::non_null::NonNull<u8> {pointer: 0x[...]}, _marker: core::marker::PhantomData<u8>}, cap: core::num::niche_types::UsizeNoHighBit (5), alloc: alloc::alloc::Global}, _marker: core::marker::PhantomData<u8>}, len: 5}}
//@ gdb-check:$1 = alloc::string::String {vec: alloc::vec::Vec<u8, alloc::alloc::Global> {buf: alloc::raw_vec::RawVec<u8, alloc::alloc::Global> {inner: alloc::raw_vec::RawVecInner<alloc::alloc::Global> {ptr: core::ptr::non_null::NonNull<u8> {pointer: 0x[...]}, cap: core::num::niche_types::UsizeNoHighBit (5), alloc: alloc::alloc::Global}, _marker: core::marker::PhantomData<u8>}, len: 5}}

//@ gdb-command:print plain_str
//@ gdb-check:$2 = "Hello"
Expand Down
28 changes: 12 additions & 16 deletions tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,26 @@
+ scope 6 (inlined alloc::raw_vec::RawVecInner::ptr::<A>) {
+ scope 7 (inlined alloc::raw_vec::RawVecInner::non_null::<A>) {
+ let mut _12: std::ptr::NonNull<u8>;
+ scope 8 (inlined std::ptr::Unique::<u8>::cast::<A>) {
+ scope 9 (inlined NonNull::<u8>::cast::<A>) {
+ scope 10 (inlined NonNull::<u8>::as_ptr) {
+ }
+ scope 8 (inlined NonNull::<u8>::cast::<A>) {
+ scope 9 (inlined NonNull::<u8>::as_ptr) {
+ }
+ }
+ scope 11 (inlined std::ptr::Unique::<A>::as_non_null_ptr) {
+ }
+ }
+ scope 12 (inlined NonNull::<A>::as_ptr) {
+ scope 10 (inlined NonNull::<A>::as_ptr) {
+ }
+ }
+ }
+ }
+ scope 13 (inlined std::ptr::mut_ptr::<impl *mut A>::cast_slice) {
+ scope 14 (inlined slice_from_raw_parts_mut::<A>) {
+ scope 15 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
+ scope 11 (inlined std::ptr::mut_ptr::<impl *mut A>::cast_slice) {
+ scope 12 (inlined slice_from_raw_parts_mut::<A>) {
+ scope 13 (inlined std::ptr::from_raw_parts_mut::<[A], A>) {
+ }
+ }
+ }
+ scope 16 (inlined std::ptr::mut_ptr::<impl *mut [A]>::drop_in_place) {
+ scope 17 (inlined drop_in_place::<[A]>) {
+ scope 14 (inlined std::ptr::mut_ptr::<impl *mut [A]>::drop_in_place) {
+ scope 15 (inlined drop_in_place::<[A]>) {
+ let mut _13: &mut [A];
+ scope 18 (inlined std::ptr::drop_glue::<[A]> - shim(Some([A]))) {
+ scope 16 (inlined std::ptr::drop_glue::<[A]> - shim(Some([A]))) {
+ let mut _14: usize;
+ let mut _15: *mut A;
+ let mut _16: bool;
Expand All @@ -55,9 +51,9 @@
+ }
+ }
+ }
+ scope 19 (inlined drop_in_place::<Option<B>>) {
+ scope 17 (inlined drop_in_place::<Option<B>>) {
+ let mut _17: &mut std::option::Option<B>;
+ scope 20 (inlined std::ptr::drop_glue::<Option<B>> - shim(Some(Option<B>))) {
+ scope 18 (inlined std::ptr::drop_glue::<Option<B>> - shim(Some(Option<B>))) {
+ let mut _18: isize;
+ let mut _19: isize;
+ }
Expand All @@ -77,7 +73,7 @@
+ StorageLive(_9);
+ StorageLive(_10);
+ StorageLive(_12);
+ _12 = copy (((((*_7).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+ _12 = copy ((((*_7).0: alloc::raw_vec::RawVec<A>).0: alloc::raw_vec::RawVecInner).0: std::ptr::NonNull<u8>);
+ _10 = copy _12 as *mut A (Transmute);
+ StorageDead(_12);
+ _11 = copy ((*_7).1: usize);
Expand Down
Loading
Loading