Skip to content

Commit a5d7d65

Browse files
committed
Auto merge of rust-lang#83360 - Dylan-DPC:rollup-17xulpv, r=Dylan-DPC
Rollup of 9 pull requests Successful merges: - rust-lang#80193 (stabilize `feature(osstring_ascii)`) - rust-lang#80771 (Make NonNull::as_ref (and friends) return refs with unbound lifetimes) - rust-lang#81607 (Implement TrustedLen and TrustedRandomAccess for Range<integer>, array::IntoIter, VecDequeue's iterators) - rust-lang#82554 (Fix invalid slice access in String::retain) - rust-lang#82686 (Move `std::sys::unix::platform` to `std::sys::unix::ext`) - rust-lang#82771 (slice: Stabilize IterMut::as_slice.) - rust-lang#83329 (Cleanup LLVM debuginfo module docs) - rust-lang#83336 (Fix ICE with `use clippy::a::b;`) - rust-lang#83350 (Download a more recent LLVM version if `src/version` is modified) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 4769388 + 4211102 commit a5d7d65

File tree

15 files changed

+226
-79
lines changed

15 files changed

+226
-79
lines changed

alloc/src/collections/vec_deque/into_iter.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33

44
use super::VecDeque;
55

@@ -36,6 +36,22 @@ impl<T> Iterator for IntoIter<T> {
3636
let len = self.inner.len();
3737
(len, Some(len))
3838
}
39+
40+
#[inline]
41+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
42+
where
43+
Self: TrustedRandomAccess,
44+
{
45+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
46+
// that is in bounds.
47+
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
48+
// multiple repeated reads of the same index would be safe and the
49+
// values are !Drop, thus won't suffer from double drops.
50+
unsafe {
51+
let idx = self.inner.wrap_add(self.inner.tail, idx);
52+
self.inner.buffer_read(idx)
53+
}
54+
}
3955
}
4056

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

5672
#[stable(feature = "fused", since = "1.26.0")]
5773
impl<T> FusedIterator for IntoIter<T> {}
74+
75+
#[unstable(feature = "trusted_len", issue = "37572")]
76+
unsafe impl<T> TrustedLen for IntoIter<T> {}
77+
78+
#[doc(hidden)]
79+
#[unstable(feature = "trusted_random_access", issue = "none")]
80+
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
81+
// and thus we can't implement drop-handling
82+
unsafe impl<T> TrustedRandomAccess for IntoIter<T>
83+
where
84+
T: Copy,
85+
{
86+
const MAY_HAVE_SIDE_EFFECT: bool = false;
87+
}

alloc/src/collections/vec_deque/iter.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33
use core::ops::Try;
44

55
use super::{count, wrap_index, RingSlices};
@@ -101,6 +101,19 @@ impl<'a, T> Iterator for Iter<'a, T> {
101101
fn last(mut self) -> Option<&'a T> {
102102
self.next_back()
103103
}
104+
105+
#[inline]
106+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
107+
where
108+
Self: TrustedRandomAccess,
109+
{
110+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
111+
// that is in bounds.
112+
unsafe {
113+
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
114+
self.ring.get_unchecked(idx)
115+
}
116+
}
104117
}
105118

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

158171
#[stable(feature = "fused", since = "1.26.0")]
159172
impl<T> FusedIterator for Iter<'_, T> {}
173+
174+
#[unstable(feature = "trusted_len", issue = "37572")]
175+
unsafe impl<T> TrustedLen for Iter<'_, T> {}
176+
177+
#[doc(hidden)]
178+
#[unstable(feature = "trusted_random_access", issue = "none")]
179+
unsafe impl<T> TrustedRandomAccess for Iter<'_, T> {
180+
const MAY_HAVE_SIDE_EFFECT: bool = false;
181+
}

alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use core::fmt;
2-
use core::iter::FusedIterator;
2+
use core::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
33
use core::marker::PhantomData;
44

55
use super::{count, wrap_index, RingSlices};
@@ -87,6 +87,19 @@ impl<'a, T> Iterator for IterMut<'a, T> {
8787
fn last(mut self) -> Option<&'a mut T> {
8888
self.next_back()
8989
}
90+
91+
#[inline]
92+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
93+
where
94+
Self: TrustedRandomAccess,
95+
{
96+
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
97+
// that is in bounds.
98+
unsafe {
99+
let idx = wrap_index(self.tail.wrapping_add(idx), self.ring.len());
100+
&mut *self.ring.get_unchecked_mut(idx)
101+
}
102+
}
90103
}
91104

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

127140
#[stable(feature = "fused", since = "1.26.0")]
128141
impl<T> FusedIterator for IterMut<'_, T> {}
142+
143+
#[unstable(feature = "trusted_len", issue = "37572")]
144+
unsafe impl<T> TrustedLen for IterMut<'_, T> {}
145+
146+
#[doc(hidden)]
147+
#[unstable(feature = "trusted_random_access", issue = "none")]
148+
unsafe impl<T> TrustedRandomAccess for IterMut<'_, T> {
149+
const MAY_HAVE_SIDE_EFFECT: bool = false;
150+
}

alloc/src/collections/vec_deque/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ mod tests;
5858
const INITIAL_CAPACITY: usize = 7; // 2^3 - 1
5959
const MINIMUM_CAPACITY: usize = 1; // 2 - 1
6060

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

6363
/// A double-ended queue implemented with a growable ring buffer.
6464
///

alloc/src/string.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,37 +1289,44 @@ impl String {
12891289
where
12901290
F: FnMut(char) -> bool,
12911291
{
1292-
let len = self.len();
1293-
let mut del_bytes = 0;
1294-
let mut idx = 0;
1292+
struct SetLenOnDrop<'a> {
1293+
s: &'a mut String,
1294+
idx: usize,
1295+
del_bytes: usize,
1296+
}
12951297

1296-
unsafe {
1297-
self.vec.set_len(0);
1298+
impl<'a> Drop for SetLenOnDrop<'a> {
1299+
fn drop(&mut self) {
1300+
let new_len = self.idx - self.del_bytes;
1301+
debug_assert!(new_len <= self.s.len());
1302+
unsafe { self.s.vec.set_len(new_len) };
1303+
}
12981304
}
12991305

1300-
while idx < len {
1301-
let ch = unsafe { self.get_unchecked(idx..len).chars().next().unwrap() };
1306+
let len = self.len();
1307+
let mut guard = SetLenOnDrop { s: self, idx: 0, del_bytes: 0 };
1308+
1309+
while guard.idx < len {
1310+
let ch = unsafe { guard.s.get_unchecked(guard.idx..len).chars().next().unwrap() };
13021311
let ch_len = ch.len_utf8();
13031312

13041313
if !f(ch) {
1305-
del_bytes += ch_len;
1306-
} else if del_bytes > 0 {
1314+
guard.del_bytes += ch_len;
1315+
} else if guard.del_bytes > 0 {
13071316
unsafe {
13081317
ptr::copy(
1309-
self.vec.as_ptr().add(idx),
1310-
self.vec.as_mut_ptr().add(idx - del_bytes),
1318+
guard.s.vec.as_ptr().add(guard.idx),
1319+
guard.s.vec.as_mut_ptr().add(guard.idx - guard.del_bytes),
13111320
ch_len,
13121321
);
13131322
}
13141323
}
13151324

13161325
// Point idx to the next char
1317-
idx += ch_len;
1326+
guard.idx += ch_len;
13181327
}
13191328

1320-
unsafe {
1321-
self.vec.set_len(len - del_bytes);
1322-
}
1329+
drop(guard);
13231330
}
13241331

13251332
/// Inserts a character into this `String` at a byte position.

core/src/array/iter.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use crate::{
44
fmt,
5-
iter::{ExactSizeIterator, FusedIterator, TrustedLen},
5+
iter::{ExactSizeIterator, FusedIterator, TrustedLen, TrustedRandomAccess},
66
mem::{self, MaybeUninit},
77
ops::Range,
88
ptr,
@@ -130,6 +130,18 @@ impl<T, const N: usize> Iterator for IntoIter<T, N> {
130130
fn last(mut self) -> Option<Self::Item> {
131131
self.next_back()
132132
}
133+
134+
#[inline]
135+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
136+
where
137+
Self: TrustedRandomAccess,
138+
{
139+
// SAFETY: Callers are only allowed to pass an index that is in bounds
140+
// Additionally Self: TrustedRandomAccess is only implemented for T: Copy which means even
141+
// multiple repeated reads of the same index would be safe and the
142+
// values aree !Drop, thus won't suffer from double drops.
143+
unsafe { self.data.get_unchecked(self.alive.start + idx).assume_init_read() }
144+
}
133145
}
134146

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

199+
#[doc(hidden)]
200+
#[unstable(feature = "trusted_random_access", issue = "none")]
201+
// T: Copy as approximation for !Drop since get_unchecked does not update the pointers
202+
// and thus we can't implement drop-handling
203+
unsafe impl<T, const N: usize> TrustedRandomAccess for IntoIter<T, N>
204+
where
205+
T: Copy,
206+
{
207+
const MAY_HAVE_SIDE_EFFECT: bool = false;
208+
}
209+
187210
#[stable(feature = "array_value_iter_impls", since = "1.40.0")]
188211
impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
189212
fn clone(&self) -> Self {

core/src/iter/range.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::convert::TryFrom;
33
use crate::mem;
44
use crate::ops::{self, Try};
55

6-
use super::{FusedIterator, TrustedLen};
6+
use super::{FusedIterator, TrustedLen, TrustedRandomAccess};
77

88
/// Objects that have a notion of *successor* and *predecessor* operations.
99
///
@@ -493,6 +493,18 @@ macro_rules! range_exact_iter_impl {
493493
)*)
494494
}
495495

496+
/// Safety: This macro must only be used on types that are `Copy` and result in ranges
497+
/// which have an exact `size_hint()` where the upper bound must not be `None`.
498+
macro_rules! unsafe_range_trusted_random_access_impl {
499+
($($t:ty)*) => ($(
500+
#[doc(hidden)]
501+
#[unstable(feature = "trusted_random_access", issue = "none")]
502+
unsafe impl TrustedRandomAccess for ops::Range<$t> {
503+
const MAY_HAVE_SIDE_EFFECT: bool = false;
504+
}
505+
)*)
506+
}
507+
496508
macro_rules! range_incl_exact_iter_impl {
497509
($($t:ty)*) => ($(
498510
#[stable(feature = "inclusive_range", since = "1.26.0")]
@@ -553,6 +565,18 @@ impl<A: Step> Iterator for ops::Range<A> {
553565
fn max(mut self) -> Option<A> {
554566
self.next_back()
555567
}
568+
569+
#[inline]
570+
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
571+
where
572+
Self: TrustedRandomAccess,
573+
{
574+
// SAFETY: The TrustedRandomAccess contract requires that callers only pass an index
575+
// that is in bounds.
576+
// Additionally Self: TrustedRandomAccess is only implemented for Copy types
577+
// which means even repeated reads of the same index would be safe.
578+
unsafe { Step::forward_unchecked(self.start.clone(), idx) }
579+
}
556580
}
557581

558582
// These macros generate `ExactSizeIterator` impls for various range types.
@@ -574,6 +598,23 @@ range_exact_iter_impl! {
574598
u32
575599
i32
576600
}
601+
602+
unsafe_range_trusted_random_access_impl! {
603+
usize u8 u16
604+
isize i8 i16
605+
}
606+
607+
#[cfg(target_pointer_width = "32")]
608+
unsafe_range_trusted_random_access_impl! {
609+
u32 i32
610+
}
611+
612+
#[cfg(target_pointer_width = "64")]
613+
unsafe_range_trusted_random_access_impl! {
614+
u32 i32
615+
u64 i64
616+
}
617+
577618
range_incl_exact_iter_impl! {
578619
u8
579620
i8

core/src/ptr/non_null.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<T: Sized> NonNull<T> {
110110
/// [the module documentation]: crate::ptr#safety
111111
#[inline]
112112
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
113-
pub unsafe fn as_uninit_ref(&self) -> &MaybeUninit<T> {
113+
pub unsafe fn as_uninit_ref<'a>(&self) -> &'a MaybeUninit<T> {
114114
// SAFETY: the caller must guarantee that `self` meets all the
115115
// requirements for a reference.
116116
unsafe { &*self.cast().as_ptr() }
@@ -142,7 +142,7 @@ impl<T: Sized> NonNull<T> {
142142
/// [the module documentation]: crate::ptr#safety
143143
#[inline]
144144
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
145-
pub unsafe fn as_uninit_mut(&mut self) -> &mut MaybeUninit<T> {
145+
pub unsafe fn as_uninit_mut<'a>(&mut self) -> &'a mut MaybeUninit<T> {
146146
// SAFETY: the caller must guarantee that `self` meets all the
147147
// requirements for a reference.
148148
unsafe { &mut *self.cast().as_ptr() }
@@ -244,7 +244,7 @@ impl<T: ?Sized> NonNull<T> {
244244
/// [the module documentation]: crate::ptr#safety
245245
#[stable(feature = "nonnull", since = "1.25.0")]
246246
#[inline]
247-
pub unsafe fn as_ref(&self) -> &T {
247+
pub unsafe fn as_ref<'a>(&self) -> &'a T {
248248
// SAFETY: the caller must guarantee that `self` meets all the
249249
// requirements for a reference.
250250
unsafe { &*self.as_ptr() }
@@ -280,7 +280,7 @@ impl<T: ?Sized> NonNull<T> {
280280
/// [the module documentation]: crate::ptr#safety
281281
#[stable(feature = "nonnull", since = "1.25.0")]
282282
#[inline]
283-
pub unsafe fn as_mut(&mut self) -> &mut T {
283+
pub unsafe fn as_mut<'a>(&mut self) -> &'a mut T {
284284
// SAFETY: the caller must guarantee that `self` meets all the
285285
// requirements for a mutable reference.
286286
unsafe { &mut *self.as_ptr() }
@@ -427,7 +427,7 @@ impl<T> NonNull<[T]> {
427427
/// [valid]: crate::ptr#safety
428428
#[inline]
429429
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
430-
pub unsafe fn as_uninit_slice(&self) -> &[MaybeUninit<T>] {
430+
pub unsafe fn as_uninit_slice<'a>(&self) -> &'a [MaybeUninit<T>] {
431431
// SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
432432
unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) }
433433
}
@@ -488,7 +488,7 @@ impl<T> NonNull<[T]> {
488488
/// ```
489489
#[inline]
490490
#[unstable(feature = "ptr_as_uninit", issue = "75402")]
491-
pub unsafe fn as_uninit_slice_mut(&self) -> &mut [MaybeUninit<T>] {
491+
pub unsafe fn as_uninit_slice_mut<'a>(&self) -> &'a mut [MaybeUninit<T>] {
492492
// SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
493493
unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) }
494494
}

core/src/slice/iter.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ impl<'a, T> IterMut<'a, T> {
286286
/// Basic usage:
287287
///
288288
/// ```
289-
/// # #![feature(slice_iter_mut_as_slice)]
290289
/// let mut slice: &mut [usize] = &mut [1, 2, 3];
291290
///
292291
/// // First, we get the iterator:
@@ -299,12 +298,19 @@ impl<'a, T> IterMut<'a, T> {
299298
/// // Now `as_slice` returns "[2, 3]":
300299
/// assert_eq!(iter.as_slice(), &[2, 3]);
301300
/// ```
302-
#[unstable(feature = "slice_iter_mut_as_slice", reason = "recently added", issue = "58957")]
301+
#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
303302
pub fn as_slice(&self) -> &[T] {
304303
self.make_slice()
305304
}
306305
}
307306

307+
#[stable(feature = "slice_iter_mut_as_slice", since = "1.53.0")]
308+
impl<T> AsRef<[T]> for IterMut<'_, T> {
309+
fn as_ref(&self) -> &[T] {
310+
self.as_slice()
311+
}
312+
}
313+
308314
iterator! {struct IterMut -> *mut T, &'a mut T, mut, {mut}, {}}
309315

310316
/// An internal abstraction over the splitting iterators, so that

0 commit comments

Comments
 (0)