Skip to content
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

Rollup of 4 pull requests #123884

Merged
merged 8 commits into from
Apr 13, 2024
5 changes: 4 additions & 1 deletion .mailmap
Original file line number Diff line number Diff line change
@@ -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>
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
11 changes: 11 additions & 0 deletions library/alloc/src/raw_vec.rs
Original file line number Diff line number Diff line change
@@ -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.
21 changes: 11 additions & 10 deletions library/alloc/src/vec/in_place_collect.rs
Original file line number Diff line number Diff line change
@@ -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,18 +317,17 @@ 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>());
}

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
}
7 changes: 4 additions & 3 deletions library/alloc/src/vec/in_place_drop.rs
Original file line number Diff line number Diff line change
@@ -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));
};
}
}
2 changes: 1 addition & 1 deletion library/alloc/src/vec/into_iter.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
27 changes: 27 additions & 0 deletions library/alloc/src/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion library/alloc/src/vec/spec_from_iter.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}

1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
14 changes: 6 additions & 8 deletions library/core/src/ptr/const_ptr.rs
Original file line number Diff line number Diff line change
@@ -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();
11 changes: 5 additions & 6 deletions library/core/src/ptr/mut_ptr.rs
Original file line number Diff line number Diff line change
@@ -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
}
9 changes: 5 additions & 4 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
@@ -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 {
1 change: 0 additions & 1 deletion library/core/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -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)]
1 change: 0 additions & 1 deletion library/std/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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 change: 0 additions & 1 deletion tests/ui/consts/const_fn_unsize.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
//@ run-pass
#![feature(slice_ptr_len)]

use std::ptr::NonNull;

2 changes: 1 addition & 1 deletion tests/ui/suggestions/deref-path-method.stderr
Original file line number Diff line number Diff line change
@@ -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 `[_]`
|
2 changes: 1 addition & 1 deletion tests/ui/ufcs/bad-builder.stderr
Original file line number Diff line number Diff line change
@@ -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
|