Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2e7ca73
Don't emit an error on private doc tests when they're ignored
GuillaumeGomez Sep 12, 2020
15d25a8
Add test for ignored private doc test
GuillaumeGomez Sep 12, 2020
58310ce
Use intra-doc links in `core::mem`
camelid Sep 14, 2020
f7f9a6c
Add a comment why `extern crate` is necessary for rustdoc
jyn514 Sep 15, 2020
7d5db23
This commit introduces the following changes:
hameerabbasi Sep 14, 2020
5f0b775
Remove redundant `&format!`.
hameerabbasi Sep 15, 2020
b93a831
Add a comment why rustdoc loads crates from the sysroot
jyn514 Sep 15, 2020
5f3145f
Avoid printing dry run timings
Mark-Simulacrum Sep 15, 2020
2a5a6b4
Add missing code examples in libcore
GuillaumeGomez Sep 15, 2020
73d4171
fix a couple of stylistic clippy warnings
matthiaskrgr Sep 15, 2020
fafb2e9
[fuchsia] Propagate the userspace UTC clock
Sep 15, 2020
143e4e9
Fix stabilization marker for future_readiness_fns
yoshuawuyts Sep 15, 2020
fd9be8f
don't lazily evaulate some trivial values for Option::None replacemen…
matthiaskrgr Sep 15, 2020
e0c1621
Update books
ehuss Sep 15, 2020
c910e03
Strip a single leading tab when rendering dataflow diffs
ecstatic-morse Sep 16, 2020
1dc4f85
Simplify iter fuse struct doc
pickfire Sep 16, 2020
d04ca00
Remove unnecessary `clone()`s in bootstrap
jyn514 Sep 15, 2020
f240abc
Add array window fn
JulianKnodt Aug 13, 2020
5c29332
Make graphviz font configurable
richkadel Sep 16, 2020
3875abe
Added RUSTC_GRAPHVIZ_FONT environment variable
richkadel Sep 16, 2020
23a6777
Rollup merge of #75026 - JulianKnodt:array_windows, r=Amanieu
tmandry Sep 16, 2020
ece688b
Rollup merge of #76642 - GuillaumeGomez:ignored-private-doc-test, r=j…
tmandry Sep 16, 2020
a63f8c1
Rollup merge of #76719 - hameerabbasi:min-const-generics-ty, r=lcnr
tmandry Sep 16, 2020
153fb91
Rollup merge of #76721 - camelid:intra-doc-links-for-core-mem, r=jyn514
tmandry Sep 16, 2020
6e57eec
Rollup merge of #76728 - jyn514:rustdoc-extern-crate, r=ehuss
tmandry Sep 16, 2020
2e0dbf1
Rollup merge of #76735 - jyn514:no-clone, r=Mark-Simulacrum
tmandry Sep 16, 2020
2339374
Rollup merge of #76741 - Mark-Simulacrum:no-dry-run-timing, r=alexcri…
tmandry Sep 16, 2020
ab78ca9
Rollup merge of #76747 - GuillaumeGomez:more-missing-libcore-code-exa…
tmandry Sep 16, 2020
a6c4d30
Rollup merge of #76756 - matthiaskrgr:cl123ppy, r=Dylan-DPC
tmandry Sep 16, 2020
ab20774
Rollup merge of #76758 - adamlesinski:clone_clock, r=tmandry
tmandry Sep 16, 2020
273267c
Rollup merge of #76759 - yoshuawuyts:fix-future-pending-ready-stabili…
tmandry Sep 16, 2020
6e0131c
Rollup merge of #76760 - matthiaskrgr:clippy_lazy_eval, r=varkor
tmandry Sep 16, 2020
5d8bc90
Rollup merge of #76764 - ehuss:update-books, r=ehuss
tmandry Sep 16, 2020
cd766c9
Rollup merge of #76775 - ecstatic-morse:dataflow-extra-tab-diff, r=Ma…
tmandry Sep 16, 2020
d3c6321
Rollup merge of #76778 - pickfire:patch-7, r=jonas-schievink
tmandry Sep 16, 2020
3bf66ae
Rollup merge of #76794 - richkadel:graphviz-font, r=ecstatic-morse
tmandry Sep 16, 2020
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
Prev Previous commit
Next Next commit
Add array window fn
Updated issue to #75027

Update to rm oob access

And hopefully fix docs as well

Fixed naming conflict in test

Fix test which used 1-indexing

Nth starts from 0, woops

Fix a bunch of off by 1 errors

See https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=757b311987e3fae1ca47122969acda5a

Add even more off by 1 errors

And also write `next` and `next_back` in terms of `nth` and `nth_back`.

Run fmt

Fix forgetting to change fn name in test

add nth_back test & document unsafe

Remove as_ref().unwrap()
Documented occurrences of unsafe, noting what invariants are maintained
  • Loading branch information
JulianKnodt committed Sep 16, 2020
commit f240abc1dc9e59bfabfb5ea765fa9eae0aad3122
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
#![cfg_attr(test, feature(test))]
#![feature(allocator_api)]
#![feature(array_chunks)]
#![feature(array_windows)]
#![feature(allow_internal_unstable)]
#![feature(arbitrary_self_types)]
#![feature(box_patterns)]
Expand Down
2 changes: 2 additions & 0 deletions library/alloc/src/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ use crate::vec::Vec;
pub use core::slice::ArrayChunks;
#[unstable(feature = "array_chunks", issue = "74985")]
pub use core::slice::ArrayChunksMut;
#[unstable(feature = "array_windows", issue = "75027")]
pub use core::slice::ArrayWindows;
#[stable(feature = "slice_get_slice", since = "1.28.0")]
pub use core::slice::SliceIndex;
#[stable(feature = "from_ref", since = "1.28.0")]
Expand Down
100 changes: 100 additions & 0 deletions library/core/src/slice/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1687,6 +1687,106 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
}
}

/// A windowed iterator over a slice in overlapping chunks (`N` elements at a
/// time), starting at the beginning of the slice
///
/// This struct is created by the [`array_windows`] method on [slices].
///
/// [`array_windows`]: ../../std/primitive.slice.html#method.array_windows
/// [slices]: ../../std/primitive.slice.html
#[derive(Debug, Clone, Copy)]
#[unstable(feature = "array_windows", issue = "75027")]
pub struct ArrayWindows<'a, T: 'a, const N: usize> {
pub(crate) slice_head: *const T,
pub(crate) num: usize,
pub(crate) marker: marker::PhantomData<&'a [T; N]>,
}

#[unstable(feature = "array_windows", issue = "75027")]
impl<'a, T, const N: usize> Iterator for ArrayWindows<'a, T, N> {
type Item = &'a [T; N];

#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.num == 0 {
return None;
}
// SAFETY:
// This is safe because it's indexing into a slice guaranteed to be length > N.
let ret = unsafe { &*self.slice_head.cast::<[T; N]>() };
// SAFETY: Guaranteed that there are at least 1 item remaining otherwise
// earlier branch would've been hit
self.slice_head = unsafe { self.slice_head.add(1) };

self.num -= 1;
Some(ret)
}

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.num, Some(self.num))
}

#[inline]
fn count(self) -> usize {
self.num
}

#[inline]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if self.num <= n {
self.num = 0;
return None;
}
// SAFETY:
// This is safe because it's indexing into a slice guaranteed to be length > N.
let ret = unsafe { &*self.slice_head.add(n).cast::<[T; N]>() };
// SAFETY: Guaranteed that there are at least n items remaining
self.slice_head = unsafe { self.slice_head.add(n + 1) };

self.num -= n + 1;
Some(ret)
}

#[inline]
fn last(mut self) -> Option<Self::Item> {
self.nth(self.num.checked_sub(1)?)
}
}

#[unstable(feature = "array_windows", issue = "75027")]
impl<'a, T, const N: usize> DoubleEndedIterator for ArrayWindows<'a, T, N> {
#[inline]
fn next_back(&mut self) -> Option<&'a [T; N]> {
if self.num == 0 {
return None;
}
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
let ret = unsafe { &*self.slice_head.add(self.num - 1).cast::<[T; N]>() };
self.num -= 1;
Some(ret)
}

#[inline]
fn nth_back(&mut self, n: usize) -> Option<&'a [T; N]> {
if self.num <= n {
self.num = 0;
return None;
}
// SAFETY: Guaranteed that there are n items remaining, n-1 for 0-indexing.
let ret = unsafe { &*self.slice_head.add(self.num - (n + 1)).cast::<[T; N]>() };
self.num -= n + 1;
Some(ret)
}
}

#[unstable(feature = "array_windows", issue = "75027")]
impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
fn is_empty(&self) -> bool {
self.num == 0
}
}

/// An iterator over a slice in (non-overlapping) chunks (`N` elements at a
/// time), starting at the beginning of the slice.
///
Expand Down
37 changes: 37 additions & 0 deletions library/core/src/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ pub use iter::{RChunks, RChunksExact, RChunksExactMut, RChunksMut};
#[unstable(feature = "array_chunks", issue = "74985")]
pub use iter::{ArrayChunks, ArrayChunksMut};

#[unstable(feature = "array_windows", issue = "75027")]
pub use iter::ArrayWindows;

#[unstable(feature = "split_inclusive", issue = "72360")]
pub use iter::{SplitInclusive, SplitInclusiveMut};

Expand Down Expand Up @@ -1099,6 +1102,40 @@ impl<T> [T] {
}
}

/// Returns an iterator over overlapping windows of `N` elements of a slice,
/// starting at the beginning of the slice.
///
/// This is the const generic equivalent of [`windows`].
///
/// If `N` is smaller than the size of the array, it will return no windows.
///
/// # Panics
///
/// Panics if `N` is 0. This check will most probably get changed to a compile time
/// error before this method gets stabilized.
///
/// # Examples
///
/// ```
/// #![feature(array_windows)]
/// let slice = [0, 1, 2, 3];
/// let mut iter = slice.array_windows();
/// assert_eq!(iter.next().unwrap(), &[0, 1]);
/// assert_eq!(iter.next().unwrap(), &[1, 2]);
/// assert_eq!(iter.next().unwrap(), &[2, 3]);
/// assert!(iter.next().is_none());
/// ```
///
/// [`windows`]: #method.windows
#[unstable(feature = "array_windows", issue = "75027")]
#[inline]
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
assert_ne!(N, 0);

let num_windows = self.len().saturating_sub(N - 1);
ArrayWindows { slice_head: self.as_ptr(), num: num_windows, marker: marker::PhantomData }
}

/// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
/// of the slice.
///
Expand Down
1 change: 1 addition & 0 deletions library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(array_chunks)]
#![feature(array_methods)]
#![feature(array_map)]
#![feature(array_windows)]
#![feature(bool_to_option)]
#![feature(bound_cloned)]
#![feature(box_syntax)]
Expand Down
49 changes: 49 additions & 0 deletions library/core/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,55 @@ fn test_array_chunks_mut_zip() {
assert_eq!(v1, [13, 14, 19, 20, 4]);
}

#[test]
fn test_array_windows_infer() {
let v: &[i32] = &[0, 1, 0, 1];
assert_eq!(v.array_windows::<2>().count(), 3);
let c = v.array_windows();
for &[a, b] in c {
assert_eq!(a + b, 1);
}

let v2: &[i32] = &[0, 1, 2, 3, 4, 5, 6];
let total = v2.array_windows().map(|&[a, b, c]| a + b + c).sum::<i32>();
assert_eq!(total, 3 + 6 + 9 + 12 + 15);
}

#[test]
fn test_array_windows_count() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let c = v.array_windows::<3>();
assert_eq!(c.count(), 4);

let v2: &[i32] = &[0, 1, 2, 3, 4];
let c2 = v2.array_windows::<6>();
assert_eq!(c2.count(), 0);

let v3: &[i32] = &[];
let c3 = v3.array_windows::<2>();
assert_eq!(c3.count(), 0);
}

#[test]
fn test_array_windows_nth() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let snd = v.array_windows::<4>().nth(1);
assert_eq!(snd, Some(&[1, 2, 3, 4]));
let mut arr_windows = v.array_windows::<2>();
assert_ne!(arr_windows.nth(0), arr_windows.nth(0));
let last = v.array_windows::<3>().last();
assert_eq!(last, Some(&[3, 4, 5]));
}

#[test]
fn test_array_windows_nth_back() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
let snd = v.array_windows::<4>().nth_back(1);
assert_eq!(snd, Some(&[1, 2, 3, 4]));
let mut arr_windows = v.array_windows::<2>();
assert_ne!(arr_windows.nth_back(0), arr_windows.nth_back(0));
}

#[test]
fn test_rchunks_count() {
let v: &[i32] = &[0, 1, 2, 3, 4, 5];
Expand Down
12 changes: 6 additions & 6 deletions src/test/ui/const-generics/type-dependent/issue-61936.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
#![cfg_attr(min, feature(min_const_generics))]

trait SliceExt<T: Clone> {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N>;
fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N>;
}

impl <T: Clone> SliceExt<T> for [T] {
fn array_windows<'a, const N: usize>(&'a self) -> ArrayWindows<'a, T, N> {
ArrayWindows{ idx: 0, slice: &self }
fn array_windows_example<'a, const N: usize>(&'a self) -> ArrayWindowsExample<'a, T, N> {
ArrayWindowsExample{ idx: 0, slice: &self }
}
}

struct ArrayWindows<'a, T, const N: usize> {
struct ArrayWindowsExample<'a, T, const N: usize> {
slice: &'a [T],
idx: usize,
}

impl <'a, T: Clone, const N: usize> Iterator for ArrayWindows<'a, T, N> {
impl <'a, T: Clone, const N: usize> Iterator for ArrayWindowsExample<'a, T, N> {
type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> {
// Note: this is unsound for some `T` and not meant as an example
Expand All @@ -45,7 +45,7 @@ const FOUR: usize = 4;
fn main() {
let v: Vec<usize> = vec![0; 100];

for array in v.as_slice().array_windows::<FOUR>() {
for array in v.as_slice().array_windows_example::<FOUR>() {
assert_eq!(array, [0, 0, 0, 0])
}
}