Skip to content

Commit

Permalink
Auto merge of #47308 - frewsxcv:rollup, r=frewsxcv
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

- Successful merges: #46762, #46777, #47262, #47285, #47301
- Failed merges:
  • Loading branch information
bors committed Jan 10, 2018
2 parents 107e65e + 8fbfd2c commit 92c32d2
Show file tree
Hide file tree
Showing 13 changed files with 501 additions and 278 deletions.
489 changes: 266 additions & 223 deletions src/doc/rust.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/liballoc/benches/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ macro_rules! rotate {
fn $name(b: &mut Bencher) {
let size = mem::size_of_val(&$gen(1)[0]);
let mut v = $gen($len * 8 / size);
b.iter(|| black_box(&mut v).rotate(($mid*8+size-1)/size));
b.iter(|| black_box(&mut v).rotate_left(($mid*8+size-1)/size));
b.bytes = (v.len() * size) as u64;
}
}
Expand Down
99 changes: 64 additions & 35 deletions src/liballoc/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1360,24 +1360,61 @@ impl<T> [T] {
core_slice::SliceExt::sort_unstable_by_key(self, f);
}

/// Permutes the slice in-place such that `self[mid..]` moves to the
/// beginning of the slice while `self[..mid]` moves to the end of the
/// slice. Equivalently, rotates the slice `mid` places to the left
/// or `k = self.len() - mid` places to the right.
/// Rotates the slice in-place such that the first `mid` elements of the
/// slice move to the end while the last `self.len() - mid` elements move to
/// the front. After calling `rotate_left`, the element previously at index
/// `mid` will become the first element in the slice.
///
/// This is a "k-rotation", a permutation in which item `i` moves to
/// position `i + k`, modulo the length of the slice. See _Elements
/// of Programming_ [§10.4][eop].
/// # Panics
///
/// This function will panic if `mid` is greater than the length of the
/// slice. Note that `mid == self.len()` does _not_ panic and is a no-op
/// rotation.
///
/// # Complexity
///
/// Takes linear (in `self.len()`) time.
///
/// # Examples
///
/// Rotation by `mid` and rotation by `k` are inverse operations.
/// ```
/// #![feature(slice_rotate)]
///
/// [eop]: https://books.google.com/books?id=CO9ULZGINlsC&pg=PA178&q=k-rotation
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a.rotate_left(2);
/// assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
/// ```
///
/// Rotating a subslice:
///
/// ```
/// #![feature(slice_rotate)]
///
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a[1..5].rotate_left(1);
/// assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
/// ```
#[unstable(feature = "slice_rotate", issue = "41891")]
pub fn rotate_left(&mut self, mid: usize) {
core_slice::SliceExt::rotate_left(self, mid);
}

#[unstable(feature = "slice_rotate", issue = "41891")]
#[rustc_deprecated(since = "", reason = "renamed to `rotate_left`")]
pub fn rotate(&mut self, mid: usize) {
core_slice::SliceExt::rotate_left(self, mid);
}

/// Rotates the slice in-place such that the first `self.len() - k`
/// elements of the slice move to the end while the last `k` elements move
/// to the front. After calling `rotate_right`, the element previously at
/// index `self.len() - k` will become the first element in the slice.
///
/// # Panics
///
/// This function will panic if `mid` is greater than the length of the
/// slice. (Note that `mid == self.len()` does _not_ panic; it's a nop
/// rotation with `k == 0`, the inverse of a rotation with `mid == 0`.)
/// This function will panic if `k` is greater than the length of the
/// slice. Note that `k == self.len()` does _not_ panic and is a no-op
/// rotation.
///
/// # Complexity
///
Expand All @@ -1388,31 +1425,23 @@ impl<T> [T] {
/// ```
/// #![feature(slice_rotate)]
///
/// let mut a = [1, 2, 3, 4, 5, 6, 7];
/// let mid = 2;
/// a.rotate(mid);
/// assert_eq!(&a, &[3, 4, 5, 6, 7, 1, 2]);
/// let k = a.len() - mid;
/// a.rotate(k);
/// assert_eq!(&a, &[1, 2, 3, 4, 5, 6, 7]);
///
/// use std::ops::Range;
/// fn slide<T>(slice: &mut [T], range: Range<usize>, to: usize) {
/// if to < range.start {
/// slice[to..range.end].rotate(range.start-to);
/// } else if to > range.end {
/// slice[range.start..to].rotate(range.end-range.start);
/// }
/// }
/// let mut v: Vec<_> = (0..10).collect();
/// slide(&mut v, 1..4, 7);
/// assert_eq!(&v, &[0, 4, 5, 6, 1, 2, 3, 7, 8, 9]);
/// slide(&mut v, 6..8, 1);
/// assert_eq!(&v, &[0, 3, 7, 4, 5, 6, 1, 2, 8, 9]);
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a.rotate_right(2);
/// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
/// ```
///
/// Rotate a subslice:
///
/// ```
/// #![feature(slice_rotate)]
///
/// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
/// a[1..5].rotate_right(1);
/// assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
/// ```
#[unstable(feature = "slice_rotate", issue = "41891")]
pub fn rotate(&mut self, mid: usize) {
core_slice::SliceExt::rotate(self, mid);
pub fn rotate_right(&mut self, k: usize) {
core_slice::SliceExt::rotate_right(self, k);
}

/// Copies the elements from `src` into `self`.
Expand Down
51 changes: 43 additions & 8 deletions src/liballoc/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -494,37 +494,72 @@ fn test_sort_stability() {
}

#[test]
fn test_rotate() {
fn test_rotate_left() {
let expected: Vec<_> = (0..13).collect();
let mut v = Vec::new();

// no-ops
v.clone_from(&expected);
v.rotate(0);
v.rotate_left(0);
assert_eq!(v, expected);
v.rotate(expected.len());
v.rotate_left(expected.len());
assert_eq!(v, expected);
let mut zst_array = [(), (), ()];
zst_array.rotate(2);
zst_array.rotate_left(2);

// happy path
v = (5..13).chain(0..5).collect();
v.rotate(8);
v.rotate_left(8);
assert_eq!(v, expected);

let expected: Vec<_> = (0..1000).collect();

// small rotations in large slice, uses ptr::copy
v = (2..1000).chain(0..2).collect();
v.rotate(998);
v.rotate_left(998);
assert_eq!(v, expected);
v = (998..1000).chain(0..998).collect();
v.rotate(2);
v.rotate_left(2);
assert_eq!(v, expected);

// non-small prime rotation, has a few rounds of swapping
v = (389..1000).chain(0..389).collect();
v.rotate(1000-389);
v.rotate_left(1000-389);
assert_eq!(v, expected);
}

#[test]
fn test_rotate_right() {
let expected: Vec<_> = (0..13).collect();
let mut v = Vec::new();

// no-ops
v.clone_from(&expected);
v.rotate_right(0);
assert_eq!(v, expected);
v.rotate_right(expected.len());
assert_eq!(v, expected);
let mut zst_array = [(), (), ()];
zst_array.rotate_right(2);

// happy path
v = (5..13).chain(0..5).collect();
v.rotate_right(5);
assert_eq!(v, expected);

let expected: Vec<_> = (0..1000).collect();

// small rotations in large slice, uses ptr::copy
v = (2..1000).chain(0..2).collect();
v.rotate_right(2);
assert_eq!(v, expected);
v = (998..1000).chain(0..998).collect();
v.rotate_right(998);
assert_eq!(v, expected);

// non-small prime rotation, has a few rounds of swapping
v = (389..1000).chain(0..389).collect();
v.rotate_right(389);
assert_eq!(v, expected);
}

Expand Down
17 changes: 15 additions & 2 deletions src/libcore/slice/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,10 @@ pub trait SliceExt {
fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;

#[unstable(feature = "slice_rotate", issue = "41891")]
fn rotate(&mut self, mid: usize);
fn rotate_left(&mut self, mid: usize);

#[unstable(feature = "slice_rotate", issue = "41891")]
fn rotate_right(&mut self, k: usize);

#[stable(feature = "clone_from_slice", since = "1.7.0")]
fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
Expand Down Expand Up @@ -645,7 +648,7 @@ impl<T> SliceExt for [T] {
self.binary_search_by(|p| p.cmp(x))
}

fn rotate(&mut self, mid: usize) {
fn rotate_left(&mut self, mid: usize) {
assert!(mid <= self.len());
let k = self.len() - mid;

Expand All @@ -655,6 +658,16 @@ impl<T> SliceExt for [T] {
}
}

fn rotate_right(&mut self, k: usize) {
assert!(k <= self.len());
let mid = self.len() - k;

unsafe {
let p = self.as_mut_ptr();
rotate::ptr_rotate(mid, p.offset(mid as isize), k);
}
}

#[inline]
fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
assert!(self.len() == src.len(),
Expand Down
21 changes: 18 additions & 3 deletions src/libcore/tests/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,17 +329,32 @@ fn test_iter_folds() {
}

#[test]
fn test_rotate() {
fn test_rotate_left() {
const N: usize = 600;
let a: &mut [_] = &mut [0; N];
for i in 0..N {
a[i] = i;
}

a.rotate(42);
a.rotate_left(42);
let k = N - 42;

for i in 0..N {
assert_eq!(a[(i+k)%N], i);
assert_eq!(a[(i + k) % N], i);
}
}

#[test]
fn test_rotate_right() {
const N: usize = 600;
let a: &mut [_] = &mut [0; N];
for i in 0..N {
a[i] = i;
}

a.rotate_right(42);

for i in 0..N {
assert_eq!(a[(i + 42) % N], i);
}
}
7 changes: 6 additions & 1 deletion src/librustc_lint/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1214,8 +1214,13 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for InvalidNoMangleItems {
// don't have anything to attach a symbol to
let msg = "const items should never be #[no_mangle]";
let mut err = cx.struct_span_lint(NO_MANGLE_CONST_ITEMS, it.span, msg);

// account for "pub const" (#45562)
let start = cx.tcx.sess.codemap().span_to_snippet(it.span)
.map(|snippet| snippet.find("const").unwrap_or(0))
.unwrap_or(0) as u32;
// `const` is 5 chars
let const_span = it.span.with_hi(BytePos(it.span.lo().0 + 5));
let const_span = it.span.with_hi(BytePos(it.span.lo().0 + start + 5));
err.span_suggestion(const_span,
"try a static value",
"pub static".to_owned());
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ pub mod builtin {
/// Unconditionally causes compilation to fail with the given error message when encountered.
///
/// This macro should be used when a crate uses a conditional compilation strategy to provide
/// better error messages for errornous conditions.
/// better error messages for erroneous conditions.
///
/// # Examples
///
Expand Down
3 changes: 1 addition & 2 deletions src/libstd/panicking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,6 @@ impl<'a> Location<'a> {
/// # Examples
///
/// ```should_panic
/// #![feature(panic_col)]
/// use std::panic;
///
/// panic::set_hook(Box::new(|panic_info| {
Expand All @@ -329,7 +328,7 @@ impl<'a> Location<'a> {
///
/// panic!("Normal panic");
/// ```
#[unstable(feature = "panic_col", reason = "recently added", issue = "42939")]
#[stable(feature = "panic_col", since = "1.25")]
pub fn column(&self) -> u32 {
self.col
}
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/suggestions/issue-45562.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[no_mangle] pub const RAH: usize = 5;
//~^ ERROR const items should never be #[no_mangle]

fn main() {}
12 changes: 12 additions & 0 deletions src/test/ui/suggestions/issue-45562.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
error: const items should never be #[no_mangle]
--> $DIR/issue-45562.rs:11:14
|
11 | #[no_mangle] pub const RAH: usize = 5;
| ---------^^^^^^^^^^^^^^^^
| |
| help: try a static value: `pub static`
|
= note: #[deny(no_mangle_const_items)] on by default

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2867,7 +2867,7 @@ fn read2_abbreviated(mut child: Child) -> io::Result<Output> {
*skipped += data.len();
if data.len() <= TAIL_LEN {
tail[..data.len()].copy_from_slice(data);
tail.rotate(data.len());
tail.rotate_left(data.len());
} else {
tail.copy_from_slice(&data[(data.len() - TAIL_LEN)..]);
}
Expand Down
Loading

0 comments on commit 92c32d2

Please sign in to comment.