Skip to content

Commit

Permalink
Auto merge of #63319 - Centril:rollup-d89rmey, r=Centril
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Aug 6, 2019
2 parents 766b10a + c27405f commit 8996328
Show file tree
Hide file tree
Showing 62 changed files with 808 additions and 330 deletions.
117 changes: 117 additions & 0 deletions src/libcore/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,39 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
}
}

impl<I> StepBy<I> where I: ExactSizeIterator {
// The zero-based index starting from the end of the iterator of the
// last element. Used in the `DoubleEndedIterator` implementation.
fn next_back_index(&self) -> usize {
let rem = self.iter.len() % (self.step + 1);
if self.first_take {
if rem == 0 { self.step } else { rem - 1 }
} else {
rem
}
}
}

#[stable(feature = "double_ended_step_by_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for StepBy<I> where I: DoubleEndedIterator + ExactSizeIterator {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.nth_back(self.next_back_index())
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
// `self.iter.nth_back(usize::MAX)` does the right thing here when `n`
// is out of bounds because the length of `self.iter` does not exceed
// `usize::MAX` (because `I: ExactSizeIterator`) and `nth_back` is
// zero-indexed
let n = n
.saturating_mul(self.step + 1)
.saturating_add(self.next_back_index());
self.iter.nth_back(n)
}
}

// StepBy can only make the iterator shorter, so the len will still fit.
#[stable(feature = "iterator_step_by", since = "1.28.0")]
impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}
Expand Down Expand Up @@ -1158,6 +1191,45 @@ impl<I: Iterator> Iterator for Peekable<I> {
}
}

#[stable(feature = "double_ended_peek_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
self.iter.next_back().or_else(|| self.peeked.take().and_then(|x| x))
}

#[inline]
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
{
match self.peeked.take() {
Some(None) => return Try::from_ok(init),
Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() {
Ok(acc) => f(acc, v),
Err(e) => {
self.peeked = Some(Some(v));
Try::from_error(e)
}
},
None => self.iter.try_rfold(init, f),
}
}

#[inline]
fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc
where Fold: FnMut(Acc, Self::Item) -> Acc,
{
match self.peeked {
Some(None) => return init,
Some(Some(v)) => {
let acc = self.iter.rfold(init, &mut fold);
fold(acc, v)
}
None => self.iter.rfold(init, fold),
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}

Expand Down Expand Up @@ -1627,6 +1699,51 @@ impl<I> Iterator for Take<I> where I: Iterator{
}
}

#[stable(feature = "double_ended_take_iterator", since = "1.38.0")]
impl<I> DoubleEndedIterator for Take<I> where I: DoubleEndedIterator + ExactSizeIterator {
#[inline]
fn next_back(&mut self) -> Option<Self::Item> {
if self.n == 0 {
None
} else {
let n = self.n;
self.n -= 1;
self.iter.nth_back(self.iter.len().saturating_sub(n))
}
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
let len = self.iter.len();
if self.n > n {
let m = len.saturating_sub(self.n) + n;
self.n -= n + 1;
self.iter.nth_back(m)
} else {
if len > 0 {
self.iter.nth_back(len - 1);
}
None
}
}

#[inline]
fn try_rfold<Acc, Fold, R>(&mut self, init: Acc, fold: Fold) -> R where
Self: Sized, Fold: FnMut(Acc, Self::Item) -> R, R: Try<Ok = Acc>
{
if self.n == 0 {
Try::from_ok(init)
} else {
let len = self.iter.len();
if len > self.n && self.iter.nth_back(len - self.n - 1).is_none() {
Try::from_ok(init)
} else {
self.iter.try_rfold(init, fold)
}
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<I> ExactSizeIterator for Take<I> where I: ExactSizeIterator {}

Expand Down
12 changes: 8 additions & 4 deletions src/libcore/ptr/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,10 +1606,12 @@ impl<T: ?Sized> *const T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// used with the `add` method.
/// used with the `wrapping_add` method.
///
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
Expand Down Expand Up @@ -2407,10 +2409,12 @@ impl<T: ?Sized> *mut T {
/// `align`.
///
/// If it is not possible to align the pointer, the implementation returns
/// `usize::max_value()`.
/// `usize::max_value()`. It is permissible for the implementation to *always*
/// return `usize::max_value()`. Only your algorithm's performance can depend
/// on getting a usable offset here, not its correctness.
///
/// The offset is expressed in number of `T` elements, and not bytes. The value returned can be
/// used with the `add` method.
/// used with the `wrapping_add` method.
///
/// There are no guarantees whatsoever that offsetting the pointer will not overflow or go
/// beyond the allocation that the pointer points into. It is up to the caller to ensure that
Expand Down
14 changes: 8 additions & 6 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2308,9 +2308,10 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
/// length possible for a given type and input slice, but only your algorithm's performance
/// should depend on that, not its correctness. It is permissible for all of the input data to
/// be returned as the prefix or suffix slice.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.
Expand Down Expand Up @@ -2361,9 +2362,10 @@ impl<T> [T] {
/// maintained.
///
/// This method splits the slice into three distinct slices: prefix, correctly aligned middle
/// slice of a new type, and the suffix slice. The method does a best effort to make the
/// middle slice the greatest length possible for a given type and input slice, but only
/// your algorithm's performance should depend on that, not its correctness.
/// slice of a new type, and the suffix slice. The method may make the middle slice the greatest
/// length possible for a given type and input slice, but only your algorithm's performance
/// should depend on that, not its correctness. It is permissible for all of the input data to
/// be returned as the prefix or suffix slice.
///
/// This method has no purpose when either input element `T` or output element `U` are
/// zero-sized and will return the original slice without splitting anything.
Expand Down
Loading

0 comments on commit 8996328

Please sign in to comment.