mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 16:54:01 +00:00
Auto merge of #123884 - jhpratt:rollup-1kwk0jz, r=jhpratt
Rollup of 4 pull requests Successful merges: - #123835 (Avoid more NonNull-raw-NonNull roundtrips in Vec) - #123868 (Stabilize (const_)slice_ptr_len and (const_)slice_ptr_is_empty_nonnull) - #123872 (Fix Pietro's entry in the mailmap) - #123873 (Merge cuviper in the mailmap) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
59c38c0604
5
.mailmap
5
.mailmap
@ -307,6 +307,8 @@ Joseph T. Lyons <JosephTLyons@gmail.com> <JosephTLyons@users.noreply.github.com>
|
||||
Josh Cotton <jcotton42@outlook.com>
|
||||
Josh Driver <keeperofdakeys@gmail.com>
|
||||
Josh Holmer <jholmer.in@gmail.com>
|
||||
Josh Stone <cuviper@gmail.com> <jistone@redhat.com>
|
||||
Josh Stone <cuviper@gmail.com> <jistone@fedoraproject.org>
|
||||
Julian Knodt <julianknodt@gmail.com>
|
||||
jumbatm <jumbatm@gmail.com> <30644300+jumbatm@users.noreply.github.com>
|
||||
Junyoung Cho <june0.cho@samsung.com>
|
||||
@ -474,7 +476,8 @@ Philipp Matthias Schäfer <philipp.matthias.schaefer@posteo.de>
|
||||
phosphorus <steepout@qq.com>
|
||||
Pierre Krieger <pierre.krieger1708@gmail.com>
|
||||
pierwill <pierwill@users.noreply.github.com> <19642016+pierwill@users.noreply.github.com>
|
||||
Pietro Albini <pietro@pietroalbini.org> <pietro@pietroalbini.io> <pietro.albini@ferrous-systems.com>
|
||||
Pietro Albini <pietro@pietroalbini.org> <pietro@pietroalbini.io>
|
||||
Pietro Albini <pietro@pietroalbini.org> <pietro.albini@ferrous-systems.com>
|
||||
Pradyumna Rahul <prkinformed@gmail.com>
|
||||
Przemysław Wesołek <jest@go.art.pl> Przemek Wesołek <jest@go.art.pl>
|
||||
r00ster <r00ster91@protonmail.com>
|
||||
|
@ -151,7 +151,6 @@
|
||||
#![feature(slice_from_ptr_range)]
|
||||
#![feature(slice_index_methods)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(slice_ptr_len)]
|
||||
#![feature(slice_range)]
|
||||
#![feature(std_internals)]
|
||||
#![feature(str_internals)]
|
||||
|
@ -259,6 +259,17 @@ impl<T, A: Allocator> RawVec<T, A> {
|
||||
Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc }
|
||||
}
|
||||
|
||||
/// A convenience method for hoisting the non-null precondition out of [`RawVec::from_raw_parts_in`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// See [`RawVec::from_raw_parts_in`].
|
||||
#[inline]
|
||||
pub(crate) unsafe fn from_nonnull_in(ptr: NonNull<T>, capacity: usize, alloc: A) -> Self {
|
||||
let cap = if T::IS_ZST { Cap::ZERO } else { unsafe { Cap(capacity) } };
|
||||
Self { ptr: Unique::from(ptr), cap, alloc }
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// be careful.
|
||||
|
@ -161,7 +161,7 @@ use core::iter::{InPlaceIterable, SourceIter, TrustedRandomAccessNoCoerce};
|
||||
use core::marker::PhantomData;
|
||||
use core::mem::{self, ManuallyDrop, SizedTypeProperties};
|
||||
use core::num::NonZero;
|
||||
use core::ptr::{self, NonNull};
|
||||
use core::ptr;
|
||||
|
||||
use super::{InPlaceDrop, InPlaceDstDataSrcBufDrop, SpecFromIter, SpecFromIterNested, Vec};
|
||||
|
||||
@ -254,28 +254,30 @@ where
|
||||
let (src_buf, src_ptr, src_cap, mut dst_buf, dst_end, dst_cap) = unsafe {
|
||||
let inner = iterator.as_inner().as_into_iter();
|
||||
(
|
||||
inner.buf.as_ptr(),
|
||||
inner.buf,
|
||||
inner.ptr,
|
||||
inner.cap,
|
||||
inner.buf.as_ptr() as *mut T,
|
||||
inner.buf.cast::<T>(),
|
||||
inner.end as *const T,
|
||||
inner.cap * mem::size_of::<I::Src>() / mem::size_of::<T>(),
|
||||
)
|
||||
};
|
||||
|
||||
// SAFETY: `dst_buf` and `dst_end` are the start and end of the buffer.
|
||||
let len = unsafe { SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf, dst_end) };
|
||||
let len = unsafe {
|
||||
SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf.as_ptr() as *mut T, dst_end)
|
||||
};
|
||||
|
||||
let src = unsafe { iterator.as_inner().as_into_iter() };
|
||||
// check if SourceIter contract was upheld
|
||||
// caveat: if they weren't we might not even make it to this point
|
||||
debug_assert_eq!(src_buf, src.buf.as_ptr());
|
||||
debug_assert_eq!(src_buf, src.buf);
|
||||
// check InPlaceIterable contract. This is only possible if the iterator advanced the
|
||||
// source pointer at all. If it uses unchecked access via TrustedRandomAccess
|
||||
// then the source pointer will stay in its initial position and we can't use it as reference
|
||||
if src.ptr != src_ptr {
|
||||
debug_assert!(
|
||||
unsafe { dst_buf.add(len) as *const _ } <= src.ptr.as_ptr(),
|
||||
unsafe { dst_buf.add(len).cast() } <= src.ptr,
|
||||
"InPlaceIterable contract violation, write pointer advanced beyond read pointer"
|
||||
);
|
||||
}
|
||||
@ -315,10 +317,9 @@ where
|
||||
let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);
|
||||
let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align);
|
||||
|
||||
let result =
|
||||
alloc.shrink(NonNull::new_unchecked(dst_buf as *mut u8), old_layout, new_layout);
|
||||
let result = alloc.shrink(dst_buf.cast(), old_layout, new_layout);
|
||||
let Ok(reallocated) = result else { handle_alloc_error(new_layout) };
|
||||
dst_buf = reallocated.as_ptr() as *mut T;
|
||||
dst_buf = reallocated.cast::<T>();
|
||||
}
|
||||
} else {
|
||||
debug_assert_eq!(src_cap * mem::size_of::<I::Src>(), dst_cap * mem::size_of::<T>());
|
||||
@ -326,7 +327,7 @@ where
|
||||
|
||||
mem::forget(dst_guard);
|
||||
|
||||
let vec = unsafe { Vec::from_raw_parts(dst_buf, len, dst_cap) };
|
||||
let vec = unsafe { Vec::from_nonnull(dst_buf, len, dst_cap) };
|
||||
|
||||
vec
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
use core::marker::PhantomData;
|
||||
use core::ptr::NonNull;
|
||||
use core::ptr::{self, drop_in_place};
|
||||
use core::slice::{self};
|
||||
|
||||
@ -31,7 +32,7 @@ impl<T> Drop for InPlaceDrop<T> {
|
||||
// the source allocation - i.e. before the reallocation happened - to avoid leaking them
|
||||
// if some other destructor panics.
|
||||
pub(super) struct InPlaceDstDataSrcBufDrop<Src, Dest> {
|
||||
pub(super) ptr: *mut Dest,
|
||||
pub(super) ptr: NonNull<Dest>,
|
||||
pub(super) len: usize,
|
||||
pub(super) src_cap: usize,
|
||||
pub(super) src: PhantomData<Src>,
|
||||
@ -42,8 +43,8 @@ impl<Src, Dest> Drop for InPlaceDstDataSrcBufDrop<Src, Dest> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let _drop_allocation =
|
||||
RawVec::<Src>::from_raw_parts_in(self.ptr.cast::<Src>(), self.src_cap, Global);
|
||||
drop_in_place(core::ptr::slice_from_raw_parts_mut::<Dest>(self.ptr, self.len));
|
||||
RawVec::<Src>::from_nonnull_in(self.ptr.cast::<Src>(), self.src_cap, Global);
|
||||
drop_in_place(core::ptr::slice_from_raw_parts_mut::<Dest>(self.ptr.as_ptr(), self.len));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter<T, A> {
|
||||
// `IntoIter::alloc` is not used anymore after this and will be dropped by RawVec
|
||||
let alloc = ManuallyDrop::take(&mut self.0.alloc);
|
||||
// RawVec handles deallocation
|
||||
let _ = RawVec::from_raw_parts_in(self.0.buf.as_ptr(), self.0.cap, alloc);
|
||||
let _ = RawVec::from_nonnull_in(self.0.buf, self.0.cap, alloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -603,6 +603,17 @@ impl<T> Vec<T> {
|
||||
pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self {
|
||||
unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) }
|
||||
}
|
||||
|
||||
/// A convenience method for hoisting the non-null precondition out of [`Vec::from_raw_parts`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// See [`Vec::from_raw_parts`].
|
||||
#[inline]
|
||||
#[cfg(not(no_global_oom_handling))] // required by tests/run-make/alloc-no-oom-handling
|
||||
pub(crate) unsafe fn from_nonnull(ptr: NonNull<T>, length: usize, capacity: usize) -> Self {
|
||||
unsafe { Self::from_nonnull_in(ptr, length, capacity, Global) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, A: Allocator> Vec<T, A> {
|
||||
@ -820,6 +831,22 @@ impl<T, A: Allocator> Vec<T, A> {
|
||||
unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } }
|
||||
}
|
||||
|
||||
/// A convenience method for hoisting the non-null precondition out of [`Vec::from_raw_parts_in`].
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// See [`Vec::from_raw_parts_in`].
|
||||
#[inline]
|
||||
#[cfg(not(no_global_oom_handling))] // required by tests/run-make/alloc-no-oom-handling
|
||||
pub(crate) unsafe fn from_nonnull_in(
|
||||
ptr: NonNull<T>,
|
||||
length: usize,
|
||||
capacity: usize,
|
||||
alloc: A,
|
||||
) -> Self {
|
||||
unsafe { Vec { buf: RawVec::from_nonnull_in(ptr, capacity, alloc), len: length } }
|
||||
}
|
||||
|
||||
/// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity)`.
|
||||
///
|
||||
/// Returns the raw pointer to the underlying data, the length of
|
||||
|
@ -51,7 +51,7 @@ impl<T> SpecFromIter<T, IntoIter<T>> for Vec<T> {
|
||||
if has_advanced {
|
||||
ptr::copy(it.ptr.as_ptr(), it.buf.as_ptr(), it.len());
|
||||
}
|
||||
return Vec::from_raw_parts(it.buf.as_ptr(), it.len(), it.cap);
|
||||
return Vec::from_nonnull(it.buf, it.len(), it.cap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,6 @@
|
||||
#![feature(const_slice_from_raw_parts_mut)]
|
||||
#![feature(const_slice_from_ref)]
|
||||
#![feature(const_slice_index)]
|
||||
#![feature(const_slice_ptr_len)]
|
||||
#![feature(const_slice_split_at_mut)]
|
||||
#![feature(const_str_from_utf8_unchecked_mut)]
|
||||
#![feature(const_strict_overflow_ops)]
|
||||
|
@ -1647,16 +1647,15 @@ impl<T> *const [T] {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_len)]
|
||||
///
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
|
||||
/// assert_eq!(slice.len(), 3);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
#[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_allow_const_fn_unstable(ptr_metadata)]
|
||||
pub const fn len(self) -> usize {
|
||||
metadata(self)
|
||||
}
|
||||
@ -1666,15 +1665,14 @@ impl<T> *const [T] {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(slice_ptr_len)]
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *const [i8] = ptr::slice_from_raw_parts(ptr::null(), 3);
|
||||
/// assert!(!slice.is_empty());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
#[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn is_empty(self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
@ -1804,7 +1802,7 @@ impl<T, const N: usize> *const [T; N] {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(array_ptr_get, slice_ptr_len)]
|
||||
/// #![feature(array_ptr_get)]
|
||||
///
|
||||
/// let arr: *const [i32; 3] = &[1, 2, 4] as *const [i32; 3];
|
||||
/// let slice: *const [i32] = arr.as_slice();
|
||||
|
@ -1909,15 +1909,15 @@ impl<T> *mut [T] {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_len)]
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
|
||||
/// assert_eq!(slice.len(), 3);
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
#[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_allow_const_fn_unstable(ptr_metadata)]
|
||||
pub const fn len(self) -> usize {
|
||||
metadata(self)
|
||||
}
|
||||
@ -1927,15 +1927,14 @@ impl<T> *mut [T] {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(slice_ptr_len)]
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// let slice: *mut [i8] = ptr::slice_from_raw_parts_mut(ptr::null_mut(), 3);
|
||||
/// assert!(!slice.is_empty());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "slice_ptr_len", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_len", issue = "71146")]
|
||||
#[stable(feature = "slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(feature = "const_slice_ptr_len", since = "CURRENT_RUSTC_VERSION")]
|
||||
pub const fn is_empty(self) -> bool {
|
||||
self.len() == 0
|
||||
}
|
||||
|
@ -1562,7 +1562,6 @@ impl<T> NonNull<[T]> {
|
||||
/// ```
|
||||
#[stable(feature = "slice_ptr_len_nonnull", since = "1.63.0")]
|
||||
#[rustc_const_stable(feature = "const_slice_ptr_len_nonnull", since = "1.63.0")]
|
||||
#[rustc_allow_const_fn_unstable(const_slice_ptr_len)]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn len(self) -> usize {
|
||||
@ -1574,14 +1573,16 @@ impl<T> NonNull<[T]> {
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(slice_ptr_is_empty_nonnull)]
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// let slice: NonNull<[i8]> = NonNull::slice_from_raw_parts(NonNull::dangling(), 3);
|
||||
/// assert!(!slice.is_empty());
|
||||
/// ```
|
||||
#[unstable(feature = "slice_ptr_is_empty_nonnull", issue = "71146")]
|
||||
#[rustc_const_unstable(feature = "const_slice_ptr_is_empty_nonnull", issue = "71146")]
|
||||
#[stable(feature = "slice_ptr_is_empty_nonnull", since = "CURRENT_RUSTC_VERSION")]
|
||||
#[rustc_const_stable(
|
||||
feature = "const_slice_ptr_is_empty_nonnull",
|
||||
since = "CURRENT_RUSTC_VERSION"
|
||||
)]
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub const fn is_empty(self) -> bool {
|
||||
|
@ -54,7 +54,6 @@
|
||||
#![feature(sort_internals)]
|
||||
#![feature(slice_take)]
|
||||
#![feature(slice_from_ptr_range)]
|
||||
#![feature(slice_ptr_len)]
|
||||
#![feature(slice_split_once)]
|
||||
#![feature(split_as_slice)]
|
||||
#![feature(maybe_uninit_fill)]
|
||||
|
@ -265,7 +265,6 @@
|
||||
feature(slice_index_methods, coerce_unsized, sgx_platform)
|
||||
)]
|
||||
#![cfg_attr(any(windows, target_os = "uefi"), feature(round_char_boundary))]
|
||||
#![cfg_attr(target_os = "xous", feature(slice_ptr_len))]
|
||||
#![cfg_attr(target_family = "wasm", feature(stdarch_wasm_atomic_wait))]
|
||||
#![cfg_attr(
|
||||
all(any(target_arch = "x86_64", target_arch = "x86"), target_os = "uefi"),
|
||||
|
@ -1,5 +1,4 @@
|
||||
//@ run-pass
|
||||
#![feature(slice_ptr_len)]
|
||||
|
||||
use std::ptr::NonNull;
|
||||
|
||||
|
@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<_, _>` consider using one of the foll
|
||||
Vec::<T>::with_capacity
|
||||
Vec::<T>::try_with_capacity
|
||||
Vec::<T>::from_raw_parts
|
||||
and 4 others
|
||||
and 6 others
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
help: the function `contains` is implemented on `[_]`
|
||||
|
|
||||
|
@ -9,7 +9,7 @@ note: if you're trying to build a new `Vec<Q>` consider using one of the followi
|
||||
Vec::<T>::with_capacity
|
||||
Vec::<T>::try_with_capacity
|
||||
Vec::<T>::from_raw_parts
|
||||
and 4 others
|
||||
and 6 others
|
||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||
help: there is an associated function `new` with a similar name
|
||||
|
|
||||
|
Loading…
Reference in New Issue
Block a user