Skip to content

Commit 8996328

Browse files
committed
Auto merge of #63319 - Centril:rollup-d89rmey, r=Centril
Rollup of 14 pull requests Successful merges: - #61457 (Implement DoubleEndedIterator for iter::{StepBy, Peekable, Take}) - #63017 (Remove special code-path for handing unknown tokens) - #63184 (Explaining the reason why validation is performed in to_str of path.rs) - #63230 (Make use of possibly uninitialized data [E0381] a hard error) - #63260 (fix UB in a test) - #63264 (Revert "Rollup merge of #62696 - chocol4te:fix_#62194, r=estebank") - #63272 (Some more libsyntax::attr cleanup) - #63285 (Remove leftover AwaitOrigin) - #63287 (Don't store &Span) - #63293 (Clarify align_to's requirements and obligations) - #63295 (improve align_offset docs) - #63299 (Make qualify consts in_projection use PlaceRef) - #63312 (doc: fix broken sentence) - #63315 (Fix #63313) Failed merges: r? @ghost
2 parents 766b10a + c27405f commit 8996328

File tree

62 files changed

+808
-330
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+808
-330
lines changed

src/libcore/iter/adapters/mod.rs

+117
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
485485
}
486486
}
487487

488+
impl<I> StepBy<I> where I: ExactSizeIterator {
489+
// The zero-based index starting from the end of the iterator of the
490+
// last element. Used in the `DoubleEndedIterator` implementation.
491+
fn next_back_index(&self) -> usize {
492+
let rem = self.iter.len() % (self.step + 1);
493+
if self.first_take {
494+
if rem == 0 { self.step } else { rem - 1 }
495+
} else {
496+
rem
497+
}
498+
}
499+
}
500+
501+
#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
502+
impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSizeIterator {
503+
#[inline]
504+
fn next_back(&mut self) -> Option<Self::Item> {
505+
self.iter.nth_back(self.next_back_index())
506+
}
507+
508+
#[inline]
509+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
510+
// `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
511+
// is out of bounds because the length of `self.iter` does not exceed
512+
// `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
513+
// zero-indexed
514+
let n = n
515+
.saturating_mul(self.step + 1)
516+
.saturating_add(self.next_back_index());
517+
self.iter.nth_back(n)
518+
}
519+
}
520+
488521
// StepBy can only make the iterator shorter, so the len will still fit.
489522
#[stable(feature = "iterator_step_by", since = "1.28.0")]
490523
impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
@@ -1158,6 +1191,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
11581191
}
11591192
}
11601193

1194+
#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
1195+
impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
1196+
#[inline]
1197+
fn next_back(&mut self) -> Option<Self::Item> {
1198+
self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x))
1199+
}
1200+
1201+
#[inline]
1202+
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
1203+
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
1204+
{
1205+
match self.peeked.take() {
1206+
Some(None) => return Try::from_ok(init),
1207+
Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
1208+
Ok(acc) => f(acc, v),
1209+
Err(e) => {
1210+
self.peeked = Some(Some(v));
1211+
Try::from_error(e)
1212+
}
1213+
},
1214+
None => self.iter.try_rfold(init, f),
1215+
}
1216+
}
1217+
1218+
#[inline]
1219+
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
1220+
where Fold: FnMut(Acc, Self::Item) -> Acc,
1221+
{
1222+
match self.peeked {
1223+
Some(None) => return init,
1224+
Some(Some(v)) => {
1225+
let acc = self.iter.rfold(init, &mut fold);
1226+
fold(acc, v)
1227+
}
1228+
None => self.iter.rfold(init, fold),
1229+
}
1230+
}
1231+
}
1232+
11611233
#[stable(feature = "rust1", since = "1.0.0")]
11621234
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
11631235

@@ -1627,6 +1699,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
16271699
}
16281700
}
16291701

1702+
#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
1703+
impl<I> DoubleEndedIterator for Take<I> where I: DoubleEndedIterator + ExactSizeIterator {
1704+
#[inline]
1705+
fn next_back(&mut self) -> Option<Self::Item> {
1706+
if self.n == 0 {
1707+
None
1708+
} else {
1709+
let n = self.n;
1710+
self.n -= 1;
1711+
self.iter.nth_back(self.iter.len().saturating_sub(n))
1712+
}
1713+
}
1714+
1715+
#[inline]
1716+
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1717+
let len = self.iter.len();
1718+
if self.n > n {
1719+
let m = len.saturating_sub(self.n) + n;
1720+
self.n -= n + 1;
1721+
self.iter.nth_back(m)
1722+
} else {
1723+
if len > 0 {
1724+
self.iter.nth_back(len - 1);
1725+
}
1726+
None
1727+
}
1728+
}
1729+
1730+
#[inline]
1731+
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
1732+
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>
1733+
{
1734+
if self.n == 0 {
1735+
Try::from_ok(init)
1736+
} else {
1737+
let len = self.iter.len();
1738+
if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
1739+
Try::from_ok(init)
1740+
} else {
1741+
self.iter.try_rfold(init, fold)
1742+
}
1743+
}
1744+
}
1745+
}
1746+
16301747
#[stable(feature = "rust1", since = "1.0.0")]
16311748
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}
16321749

src/libcore/ptr/mod.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -1606,10 +1606,12 @@ impl<T: ?Sized> *const T {
16061606
/// `align`.
16071607
///
16081608
/// If it is not possible to align the pointer, the implementation returns
1609-
/// `usize::max_value()`.
1609+
/// `usize::max_value()`. It is permissible for the implementation to *always*
1610+
/// return `usize::max_value()`. Only your algorithm's performance can depend
1611+
/// on getting a usable offset here, not its correctness.
16101612
///
16111613
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
1612-
/// used with the `add` method.
1614+
/// used with the `wrapping_add` method.
16131615
///
16141616
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
16151617
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
@@ -2407,10 +2409,12 @@ impl<T: ?Sized> *mut T {
24072409
/// `align`.
24082410
///
24092411
/// If it is not possible to align the pointer, the implementation returns
2410-
/// `usize::max_value()`.
2412+
/// `usize::max_value()`. It is permissible for the implementation to *always*
2413+
/// return `usize::max_value()`. Only your algorithm's performance can depend
2414+
/// on getting a usable offset here, not its correctness.
24112415
///
24122416
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
2413-
/// used with the `add` method.
2417+
/// used with the `wrapping_add` method.
24142418
///
24152419
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
24162420
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that

src/libcore/slice/mod.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -2308,9 +2308,10 @@ impl<T> [T] {
23082308
/// maintained.
23092309
///
23102310
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
2311-
/// slice of a new type, and the suffix slice. The method does a best effort to make the
2312-
/// middle slice the greatest length possible for a given type and input slice, but only
2313-
/// your algorithm's performance should depend on that, not its correctness.
2311+
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
2312+
/// length possible for a given type and input slice, but only your algorithm's performance
2313+
/// should depend on that, not its correctness. It is permissible for all of the input data to
2314+
/// be returned as the prefix or suffix slice.
23142315
///
23152316
/// This method has no purpose when either input element `T` or output element `U` are
23162317
/// zero-sized and will return the original slice without splitting anything.
@@ -2361,9 +2362,10 @@ impl<T> [T] {
23612362
/// maintained.
23622363
///
23632364
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
2364-
/// slice of a new type, and the suffix slice. The method does a best effort to make the
2365-
/// middle slice the greatest length possible for a given type and input slice, but only
2366-
/// your algorithm's performance should depend on that, not its correctness.
2365+
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
2366+
/// length possible for a given type and input slice, but only your algorithm's performance
2367+
/// should depend on that, not its correctness. It is permissible for all of the input data to
2368+
/// be returned as the prefix or suffix slice.
23672369
///
23682370
/// This method has no purpose when either input element `T` or output element `U` are
23692371
/// zero-sized and will return the original slice without splitting anything.

0 commit comments

Comments
 (0)