Skip to content

Commit

Permalink
Auto merge of #73565 - matthewjasper:core-min-spec, r=nagisa
Browse files Browse the repository at this point in the history
Use min_specialization in libcore

Getting `TrustedRandomAccess` to work is the main interesting thing here.

- `get_unchecked` is now an unstable, hidden method on `Iterator`
- The contract for `TrustedRandomAccess` is made clearer in documentation
- Fixed a bug where `Debug` would create aliasing references when using the specialized zip impl
- Added tests for the side effects of `next_back` and `nth`.

closes #68536
  • Loading branch information
bors committed Aug 20, 2020
2 parents e15510c + dbad8c9 commit d9d4d39
Show file tree
Hide file tree
Showing 8 changed files with 487 additions and 200 deletions.
30 changes: 18 additions & 12 deletions library/core/src/iter/adapters/fuse.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::intrinsics;
use crate::iter::{
DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator, TrustedRandomAccess,
};
use crate::iter::adapters::zip::try_get_unchecked;
use crate::iter::TrustedRandomAccess;
use crate::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator, Iterator};
use crate::ops::Try;

/// An iterator that yields `None` forever after the underlying iterator
Expand Down Expand Up @@ -114,6 +114,19 @@ where
{
FuseImpl::find(self, predicate)
}

#[inline]
unsafe fn get_unchecked(&mut self, idx: usize) -> Self::Item
where
Self: TrustedRandomAccess,
{
match self.iter {
// SAFETY: the caller must uphold the contract for `Iterator::get_unchecked`.
Some(ref mut iter) => unsafe { try_get_unchecked(iter, idx) },
// SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
None => unsafe { intrinsics::unreachable() },
}
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -172,19 +185,12 @@ where
}
}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Fuse<I>
where
I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> I::Item {
match self.iter {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
Some(ref mut iter) => unsafe { iter.get_unchecked(i) },
// SAFETY: the caller asserts there is an item at `i`, so we're not exhausted.
None => unsafe { intrinsics::unreachable() },
}
}

fn may_have_side_effect() -> bool {
I::may_have_side_effect()
}
Expand Down
93 changes: 48 additions & 45 deletions library/core/src/iter/adapters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub use self::chain::Chain;
#[stable(feature = "rust1", since = "1.0.0")]
pub use self::flatten::{FlatMap, Flatten};
pub use self::fuse::Fuse;
use self::zip::try_get_unchecked;
pub(crate) use self::zip::TrustedRandomAccess;
pub use self::zip::Zip;

Expand Down Expand Up @@ -213,6 +214,15 @@ where
fn count(self) -> usize {
self.it.count()
}

unsafe fn get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
*unsafe { try_get_unchecked(&mut self.it, idx) }
}
}

#[stable(feature = "iter_copied", since = "1.36.0")]
Expand Down Expand Up @@ -266,16 +276,11 @@ where
}

#[doc(hidden)]
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied<I>
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Copied<I>
where
I: TrustedRandomAccess<Item = &'a T>,
T: Copy,
I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
unsafe { *self.it.get_unchecked(i) }
}

#[inline]
fn may_have_side_effect() -> bool {
I::may_have_side_effect()
Expand Down Expand Up @@ -344,6 +349,15 @@ where
{
self.it.map(T::clone).fold(init, f)
}

unsafe fn get_unchecked(&mut self, idx: usize) -> T
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
unsafe { try_get_unchecked(&mut self.it, idx).clone() }
}
}

#[stable(feature = "iter_cloned", since = "1.1.0")]
Expand Down Expand Up @@ -397,36 +411,14 @@ where
}

#[doc(hidden)]
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned<I>
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Cloned<I>
where
I: TrustedRandomAccess<Item = &'a T>,
T: Clone,
{
default unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
unsafe { self.it.get_unchecked(i) }.clone()
}

#[inline]
default fn may_have_side_effect() -> bool {
true
}
}

#[doc(hidden)]
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Cloned<I>
where
I: TrustedRandomAccess<Item = &'a T>,
T: Copy,
I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
unsafe { *self.it.get_unchecked(i) }
}

#[inline]
fn may_have_side_effect() -> bool {
I::may_have_side_effect()
true
}
}

Expand Down Expand Up @@ -872,6 +864,15 @@ where
{
self.iter.fold(init, map_fold(self.f, g))
}

unsafe fn get_unchecked(&mut self, idx: usize) -> B
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
unsafe { (self.f)(try_get_unchecked(&mut self.iter, idx)) }
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -927,15 +928,11 @@ where
}

#[doc(hidden)]
unsafe impl<B, I, F> TrustedRandomAccess for Map<I, F>
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I, F> TrustedRandomAccess for Map<I, F>
where
I: TrustedRandomAccess,
F: FnMut(I::Item) -> B,
{
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
(self.f)(unsafe { self.iter.get_unchecked(i) })
}
#[inline]
fn may_have_side_effect() -> bool {
true
Expand Down Expand Up @@ -1306,6 +1303,16 @@ where

self.iter.fold(init, enumerate(self.count, fold))
}

unsafe fn get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
where
Self: TrustedRandomAccess,
{
// SAFETY: the caller must uphold the contract for
// `Iterator::get_unchecked`.
let value = unsafe { try_get_unchecked(&mut self.iter, idx) };
(Add::add(self.count, idx), value)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
Expand Down Expand Up @@ -1391,15 +1398,11 @@ where
}

#[doc(hidden)]
#[unstable(feature = "trusted_random_access", issue = "none")]
unsafe impl<I> TrustedRandomAccess for Enumerate<I>
where
I: TrustedRandomAccess,
{
unsafe fn get_unchecked(&mut self, i: usize) -> (usize, I::Item) {
// SAFETY: the caller must uphold the contract for `TrustedRandomAccess::get_unchecked`.
(self.count + i, unsafe { self.iter.get_unchecked(i) })
}

fn may_have_side_effect() -> bool {
I::may_have_side_effect()
}
Expand Down
Loading

0 comments on commit d9d4d39

Please sign in to comment.