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 8 pull requests #83358

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
cce258b
Make NonNull::as_ref (and friends) return refs with unbound lifetimes
thomcc Jan 7, 2021
c89e643
Fix invalid slice access in String::retain
SkiFire13 Feb 26, 2021
7539626
Move `std::sys::unix::platform` to `std::sys::unix::ext`
CDirkx Mar 1, 2021
5176f67
slice: Stabilize IterMut::as_slice.
emilio Mar 4, 2021
93fda34
stabilize feature(osstring_ascii)
fogti Mar 5, 2021
8dc0ae2
Remove Option::{unwrap_none, expect_none}.
m-ou-se Mar 14, 2021
4002171
Download a more recent LLVM version if `src/version` is modified
jyn514 Mar 21, 2021
0acdada
Bump osstring_ascii stabilization version to 1.53.0.
m-ou-se Mar 21, 2021
236c0cf
implement TrustedLen and TrustedRandomAccess for VecDeque iterators
the8472 Jan 31, 2021
1438207
use BITS constant
the8472 Jan 31, 2021
895d7a9
implement TrustedRandomAccess for Ranges over int types
the8472 Jan 31, 2021
08a1dd2
implement TrustedRandomAccess for array::IntoIter
the8472 Jan 31, 2021
2bd7c1b
Bump slice_iter_mut_as_slice stable version.
m-ou-se Mar 21, 2021
ff39c34
Rollup merge of #80193 - zseri:stabilize-osstring-ascii, r=m-ou-se
Dylan-DPC Mar 21, 2021
86759bf
Rollup merge of #80771 - thomcc:nonnull-refmut, r=dtolnay
Dylan-DPC Mar 21, 2021
231b7c5
Rollup merge of #81607 - the8472:trustedrandomaccess-all-the-things, …
Dylan-DPC Mar 21, 2021
803c422
Rollup merge of #82554 - SkiFire13:fix-string-retain-unsoundness, r=m…
Dylan-DPC Mar 21, 2021
c19664d
Rollup merge of #82686 - CDirkx:unix-platform, r=m-ou-se
Dylan-DPC Mar 21, 2021
ca8d13d
Rollup merge of #82771 - emilio:iter-mut-as-slice, r=m-ou-se
Dylan-DPC Mar 21, 2021
4e456fc
Rollup merge of #83349 - m-ou-se:unwrap-none, r=dtolnay
Dylan-DPC Mar 21, 2021
60ea265
Rollup merge of #83350 - jyn514:llvm-version, r=Mark-Simulacrum
Dylan-DPC Mar 21, 2021
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
32 changes: 31 additions & 1 deletion library/alloc/src/collections/vec_deque/into_iter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt;
use core::iter::FusedIterator;
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};

use super::VecDeque;

Expand Down Expand Up @@ -36,6 +36,22 @@ impl<T> Iterator for IntoIter<T> {
let len = self.inner.len();
(len, Some(len))
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
// multiple repeated reads of the same index would be safe and the
// values are !Drop, thus won't suffer from double drops.
unsafe {
let idx = self.inner.wrap_add(self.inner.tail, idx);
self.inner.buffer_read(idx)
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -55,3 +71,17 @@ impl<T> ExactSizeIterator for IntoIter<T> {

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for IntoIter<T> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for IntoIter<T> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
// and thus we can't implement drop-handling
unsafe impl<T> TrustedRandomAccess for IntoIter<T>
where
T: Copy,
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
24 changes: 23 additions & 1 deletion library/alloc/src/collections/vec_deque/iter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt;
use core::iter::FusedIterator;
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
use core::ops::Try;

use super::{count, wrap_index, RingSlices};
Expand Down Expand Up @@ -101,6 +101,19 @@ impl<'a, T> Iterator for Iter<'a, T> {
fn last(mut self) -> Option<&'a T> {
self.next_back()
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
unsafe {
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
self.ring.get_unchecked(idx)
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -157,3 +170,12 @@ impl<T> ExactSizeIterator for Iter<'_, T> {

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for Iter<'_, T> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for Iter<'_, T> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
24 changes: 23 additions & 1 deletion library/alloc/src/collections/vec_deque/iter_mut.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use core::fmt;
use core::iter::FusedIterator;
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
use core::marker::PhantomData;

use super::{count, wrap_index, RingSlices};
Expand Down Expand Up @@ -87,6 +87,19 @@ impl<'a, T> Iterator for IterMut<'a, T> {
fn last(mut self) -> Option<&'a mut T> {
self.next_back()
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
unsafe {
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
&mut *self.ring.get_unchecked_mut(idx)
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -126,3 +139,12 @@ impl<T> ExactSizeIterator for IterMut<'_, T> {

#[stable(feature = "fused", since = "1.26.0")]
impl<T> FusedIterator for IterMut<'_, T> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<T> TrustedLen for IterMut<'_, T> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
2 changes: 1 addition & 1 deletion library/alloc/src/collections/vec_deque/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ mod tests;
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
const MINIMUM_CAPACITY: usize = 1; // 2 - 1

const MAXIMUM_ZST_CAPACITY: usize = 1 << (core::mem::size_of::<usize>() * 8 - 1); // Largest possible power of two
const MAXIMUM_ZST_CAPACITY: usize = 1 << (usize::BITS - 1); // Largest possible power of two

/// A double-ended queue implemented with a growable ring buffer.
///
Expand Down
37 changes: 22 additions & 15 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1289,37 +1289,44 @@ impl String {
where
F: FnMut(char) -> bool,
{
let len = self.len();
let mut del_bytes = 0;
let mut idx = 0;
struct SetLenOnDrop<'a> {
s: &'a mut String,
idx: usize,
del_bytes: usize,
}

unsafe {
self.vec.set_len(0);
impl<'a> Drop for SetLenOnDrop<'a> {
fn drop(&mut self) {
let new_len = self.idx - self.del_bytes;
debug_assert!(new_len <= self.s.len());
unsafe { self.s.vec.set_len(new_len) };
}
}

while idx < len {
let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() };
let len = self.len();
let mut guard = SetLenOnDrop { s: self, idx: 0, del_bytes: 0 };

while guard.idx < len {
let ch = unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap() };
let ch_len = ch.len_utf8();

if !f(ch) {
del_bytes += ch_len;
} else if del_bytes > 0 {
guard.del_bytes += ch_len;
} else if guard.del_bytes > 0 {
unsafe {
ptr::copy(
self.vec.as_ptr().add(idx),
self.vec.as_mut_ptr().add(idx - del_bytes),
guard.s.vec.as_ptr().add(guard.idx),
guard.s.vec.as_mut_ptr().add(guard.idx - guard.del_bytes),
ch_len,
);
}
}

// Point idx to the next char
idx += ch_len;
guard.idx += ch_len;
}

unsafe {
self.vec.set_len(len - del_bytes);
}
drop(guard);
}

/// Inserts a character into this `String` at a byte position.
Expand Down
25 changes: 24 additions & 1 deletion library/core/src/array/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
fmt,
iter::{ExactSizeIterator, FusedIterator, TrustedLen},
iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
mem::{self, MaybeUninit},
ops::Range,
ptr,
Expand Down Expand Up @@ -130,6 +130,18 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
fn last(mut self) -> Option<Self::Item> {
self.next_back()
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// SAFETY: Callers are only allowed to pass an index that is in bounds
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
// multiple repeated reads of the same index would be safe and the
// values aree !Drop, thus won't suffer from double drops.
unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
}
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
Expand Down Expand Up @@ -184,6 +196,17 @@ impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
unsafe impl<T, const N: usize> TrustedLen for IntoIter<T, N> {}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
// and thus we can't implement drop-handling
unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
where
T: Copy,
{
const MAY_HAVE_SIDE_EFFECT: bool = false;
}

#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
fn clone(&self) -> Self {
Expand Down
43 changes: 42 additions & 1 deletion library/core/src/iter/range.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::convert::TryFrom;
use crate::mem;
use crate::ops::{self, Try};

use super::{FusedIterator, TrustedLen};
use super::{FusedIterator, TrustedLen, TrustedRandomAccess};

/// Objects that have a notion of *successor* and *predecessor* operations.
///
Expand Down Expand Up @@ -493,6 +493,18 @@ macro_rules! range_exact_iter_impl {
)*)
}

/// Safety: This macro must only be used on types that are `Copy` and result in ranges
/// which have an exact `size_hint()` where the upper bound must not be `None`.
macro_rules! unsafe_range_trusted_random_access_impl {
($($t:ty)*) => ($(
#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl TrustedRandomAccess for ops::Range<$t> {
const MAY_HAVE_SIDE_EFFECT: bool = false;
}
)*)
}

macro_rules! range_incl_exact_iter_impl {
($($t:ty)*) => ($(
#[stable(feature = "inclusive_range", since = "1.26.0")]
Expand Down Expand Up @@ -553,6 +565,18 @@ impl<A: Step> Iterator for ops::Range<A> {
fn max(mut self) -> Option<A> {
self.next_back()
}

#[inline]
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
// SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
// that is in bounds.
// Additionally Self: TrustedRandomAccess is only implemented for Copy types
// which means even repeated reads of the same index would be safe.
unsafe { Step::forward_unchecked(self.start.clone(), idx) }
}
}

// These macros generate `ExactSizeIterator` impls for various range types.
Expand All @@ -574,6 +598,23 @@ range_exact_iter_impl! {
u32
i32
}

unsafe_range_trusted_random_access_impl! {
usize u8 u16
isize i8 i16
}

#[cfg(target_pointer_width = "32")]
unsafe_range_trusted_random_access_impl! {
u32 i32
}

#[cfg(target_pointer_width = "64")]
unsafe_range_trusted_random_access_impl! {
u32 i32
u64 i64
}

range_incl_exact_iter_impl! {
u8
i8
Expand Down
Loading