about summary refs log tree commit diff
diff options
context:
space:
mode:
authordylni <46035563+dylni@users.noreply.github.com>2020-09-18 12:17:51 -0400
committerdylni <46035563+dylni@users.noreply.github.com>2020-09-18 12:17:51 -0400
commit1ff7da6551a7cdf6ace2a9d00e92bbab550334ee (patch)
tree83dfb35cedd5a32e6044bfb12c03d38a907b5b00
parent2c69266c0697b0c0b34abea62cba1a1d3c59c90c (diff)
downloadrust-1ff7da6551a7cdf6ace2a9d00e92bbab550334ee.tar.gz
rust-1ff7da6551a7cdf6ace2a9d00e92bbab550334ee.zip
Move `slice::check_range` to `RangeBounds`
-rw-r--r--library/alloc/src/collections/vec_deque.rs2
-rw-r--r--library/alloc/src/lib.rs2
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/string.rs5
-rw-r--r--library/alloc/src/vec.rs2
-rw-r--r--library/core/src/ops/range.rs82
-rw-r--r--library/core/src/slice/index.rs83
-rw-r--r--library/core/src/slice/mod.rs7
-rw-r--r--src/doc/unstable-book/src/library-features/range-bounds-for-length.md10
-rw-r--r--src/doc/unstable-book/src/library-features/slice-check-range.md10
10 files changed, 104 insertions, 101 deletions
diff --git a/library/alloc/src/collections/vec_deque.rs b/library/alloc/src/collections/vec_deque.rs
index 65cfe9a9b49..0cb8d7a891a 100644
--- a/library/alloc/src/collections/vec_deque.rs
+++ b/library/alloc/src/collections/vec_deque.rs
@@ -1089,7 +1089,7 @@ impl<T> VecDeque<T> {
     where
         R: RangeBounds<usize>,
     {
-        let Range { start, end } = slice::check_range(self.len(), range);
+        let Range { start, end } = range.for_length(self.len());
         let tail = self.wrap_add(self.tail, start);
         let head = self.wrap_add(self.tail, end);
         (tail, head)
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 7881c101f9f..002c7702779 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -116,11 +116,11 @@
 #![feature(or_patterns)]
 #![feature(pattern)]
 #![feature(ptr_internals)]
+#![feature(range_bounds_for_length)]
 #![feature(raw_ref_op)]
 #![feature(rustc_attrs)]
 #![feature(receiver_trait)]
 #![feature(min_specialization)]
-#![feature(slice_check_range)]
 #![feature(slice_ptr_get)]
 #![feature(slice_ptr_len)]
 #![feature(staged_api)]
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 79403cf8687..93501ef4085 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -91,8 +91,6 @@ use crate::borrow::ToOwned;
 use crate::boxed::Box;
 use crate::vec::Vec;
 
-#[unstable(feature = "slice_check_range", issue = "76393")]
-pub use core::slice::check_range;
 #[unstable(feature = "array_chunks", issue = "74985")]
 pub use core::slice::ArrayChunks;
 #[unstable(feature = "array_chunks", issue = "74985")]
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 2b0ce5ede56..26124e30111 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -49,7 +49,6 @@ use core::iter::{FromIterator, FusedIterator};
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds};
 use core::ptr;
-use core::slice;
 use core::str::{lossy, pattern::Pattern};
 
 use crate::borrow::{Cow, ToOwned};
@@ -1507,14 +1506,14 @@ impl String {
         // of the vector version. The data is just plain bytes.
         // Because the range removal happens in Drop, if the Drain iterator is leaked,
         // the removal will not happen.
-        let Range { start, end } = slice::check_range(self.len(), range);
+        let Range { start, end } = range.for_length(self.len());
         assert!(self.is_char_boundary(start));
         assert!(self.is_char_boundary(end));
 
         // Take out two simultaneous borrows. The &mut String won't be accessed
         // until iteration is over, in Drop.
         let self_ptr = self as *mut _;
-        // SAFETY: `check_range` and `is_char_boundary` do the appropriate bounds checks.
+        // SAFETY: `for_length` and `is_char_boundary` do the appropriate bounds checks.
         let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
 
         Drain { start, end, iter: chars_iter, string: self_ptr }
diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs
index 9dbea0dc9e6..e668b17c46c 100644
--- a/library/alloc/src/vec.rs
+++ b/library/alloc/src/vec.rs
@@ -1312,7 +1312,7 @@ impl<T> Vec<T> {
         // the hole, and the vector length is restored to the new length.
         //
         let len = self.len();
-        let Range { start, end } = slice::check_range(len, range);
+        let Range { start, end } = range.for_length(len);
 
         unsafe {
             // set self.vec length's to start, to be safe in case Drain is leaked
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index 2eaf7601e54..6ad55786176 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -1,5 +1,9 @@
 use crate::fmt;
 use crate::hash::Hash;
+use crate::slice::index::{
+    slice_end_index_len_fail, slice_end_index_overflow_fail, slice_index_order_fail,
+    slice_start_index_overflow_fail,
+};
 
 /// An unbounded range (`..`).
 ///
@@ -729,6 +733,84 @@ pub trait RangeBounds<T: ?Sized> {
             Unbounded => true,
         })
     }
+
+    /// Performs bounds-checking of this range.
+    ///
+    /// The returned [`Range`] is safe to pass to [`slice::get_unchecked`] and
+    /// [`slice::get_unchecked_mut`] for slices of the given length.
+    ///
+    /// [`slice::get_unchecked`]: crate::slice::get_unchecked
+    /// [`slice::get_unchecked_mut`]: crate::slice::get_unchecked_mut
+    ///
+    /// # Panics
+    ///
+    /// Panics if the range would be out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(range_bounds_for_length)]
+    ///
+    /// let v = [10, 40, 30];
+    /// assert_eq!(1..2, (1..2).for_length(v.len()));
+    /// assert_eq!(0..2, (..2).for_length(v.len()));
+    /// assert_eq!(1..3, (1..).for_length(v.len()));
+    /// ```
+    ///
+    /// Panics when [`Index::index`] would panic:
+    ///
+    /// ```should_panic
+    /// #![feature(range_bounds_for_length)]
+    ///
+    /// (2..1).for_length(3);
+    /// ```
+    ///
+    /// ```should_panic
+    /// #![feature(range_bounds_for_length)]
+    ///
+    /// (1..4).for_length(3);
+    /// ```
+    ///
+    /// ```should_panic
+    /// #![feature(range_bounds_for_length)]
+    ///
+    /// (1..=usize::MAX).for_length(3);
+    /// ```
+    ///
+    /// [`Index::index`]: crate::ops::Index::index
+    #[track_caller]
+    #[unstable(feature = "range_bounds_for_length", issue = "76393")]
+    fn for_length(self, len: usize) -> Range<usize>
+    where
+        Self: RangeBounds<usize>,
+    {
+        let start: Bound<&usize> = self.start_bound();
+        let start = match start {
+            Bound::Included(&start) => start,
+            Bound::Excluded(start) => {
+                start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
+            }
+            Bound::Unbounded => 0,
+        };
+
+        let end: Bound<&usize> = self.end_bound();
+        let end = match end {
+            Bound::Included(end) => {
+                end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
+            }
+            Bound::Excluded(&end) => end,
+            Bound::Unbounded => len,
+        };
+
+        if start > end {
+            slice_index_order_fail(start, end);
+        }
+        if end > len {
+            slice_end_index_len_fail(end, len);
+        }
+
+        Range { start, end }
+    }
 }
 
 use self::Bound::{Excluded, Included, Unbounded};
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index 16fcb6231dc..f1f21c1d24b 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -1,6 +1,6 @@
 //! Indexing implementations for `[T]`.
 
-use crate::ops::{self, Bound, Range, RangeBounds};
+use crate::ops;
 use crate::ptr;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -37,104 +37,31 @@ fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
 #[inline(never)]
 #[cold]
 #[track_caller]
-pub(super) fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
+pub(crate) fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
     panic!("range end index {} out of range for slice of length {}", index, len);
 }
 
 #[inline(never)]
 #[cold]
 #[track_caller]
-pub(super) fn slice_index_order_fail(index: usize, end: usize) -> ! {
+pub(crate) fn slice_index_order_fail(index: usize, end: usize) -> ! {
     panic!("slice index starts at {} but ends at {}", index, end);
 }
 
 #[inline(never)]
 #[cold]
 #[track_caller]
-pub(super) fn slice_start_index_overflow_fail() -> ! {
+pub(crate) fn slice_start_index_overflow_fail() -> ! {
     panic!("attempted to index slice from after maximum usize");
 }
 
 #[inline(never)]
 #[cold]
 #[track_caller]
-pub(super) fn slice_end_index_overflow_fail() -> ! {
+pub(crate) fn slice_end_index_overflow_fail() -> ! {
     panic!("attempted to index slice up to maximum usize");
 }
 
-/// Performs bounds-checking of the given range.
-/// The returned [`Range`] is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]
-/// for slices of the given length.
-///
-/// [`get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
-/// [`get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
-///
-/// # Panics
-///
-/// Panics if the range is out of bounds.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(slice_check_range)]
-/// use std::slice;
-///
-/// let v = [10, 40, 30];
-/// assert_eq!(1..2, slice::check_range(v.len(), 1..2));
-/// assert_eq!(0..2, slice::check_range(v.len(), ..2));
-/// assert_eq!(1..3, slice::check_range(v.len(), 1..));
-/// ```
-///
-/// Panics when [`Index::index`] would panic:
-///
-/// ```should_panic
-/// #![feature(slice_check_range)]
-///
-/// std::slice::check_range(3, 2..1);
-/// ```
-///
-/// ```should_panic
-/// #![feature(slice_check_range)]
-///
-/// std::slice::check_range(3, 1..4);
-/// ```
-///
-/// ```should_panic
-/// #![feature(slice_check_range)]
-///
-/// std::slice::check_range(3, 1..=usize::MAX);
-/// ```
-///
-/// [`Index::index`]: ops::Index::index
-#[track_caller]
-#[unstable(feature = "slice_check_range", issue = "76393")]
-pub fn check_range<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> {
-    let start = match range.start_bound() {
-        Bound::Included(&start) => start,
-        Bound::Excluded(start) => {
-            start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail())
-        }
-        Bound::Unbounded => 0,
-    };
-
-    let end = match range.end_bound() {
-        Bound::Included(end) => {
-            end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail())
-        }
-        Bound::Excluded(&end) => end,
-        Bound::Unbounded => len,
-    };
-
-    if start > end {
-        slice_index_order_fail(start, end);
-    }
-    if end > len {
-        slice_end_index_len_fail(end, len);
-    }
-
-    Range { start, end }
-}
-
 mod private_slice_index {
     use super::ops;
     #[stable(feature = "slice_get_slice", since = "1.28.0")]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 8e9d1eb98a8..5ad57b23c4a 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -29,7 +29,7 @@ pub mod memchr;
 
 mod ascii;
 mod cmp;
-mod index;
+pub(crate) mod index;
 mod iter;
 mod raw;
 mod rotate;
@@ -75,9 +75,6 @@ pub use sort::heapsort;
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use index::SliceIndex;
 
-#[unstable(feature = "slice_check_range", issue = "76393")]
-pub use index::check_range;
-
 #[lang = "slice"]
 #[cfg(not(test))]
 impl<T> [T] {
@@ -2758,7 +2755,7 @@ impl<T> [T] {
     where
         T: Copy,
     {
-        let Range { start: src_start, end: src_end } = check_range(self.len(), src);
+        let Range { start: src_start, end: src_end } = src.for_length(self.len());
         let count = src_end - src_start;
         assert!(dest <= self.len() - count, "dest is out of bounds");
         // SAFETY: the conditions for `ptr::copy` have all been checked above,
diff --git a/src/doc/unstable-book/src/library-features/range-bounds-for-length.md b/src/doc/unstable-book/src/library-features/range-bounds-for-length.md
new file mode 100644
index 00000000000..47a1bd8dff1
--- /dev/null
+++ b/src/doc/unstable-book/src/library-features/range-bounds-for-length.md
@@ -0,0 +1,10 @@
+# `range_bounds_for_length`
+
+The tracking issue for this feature is: [#76393]
+
+------------------------
+
+This adds [`RangeBounds::for_length`].
+
+[#76393]: https://github.com/rust-lang/rust/issues/76393
+[`RangeBounds::for_length`]: https://doc.rust-lang.org/nightly/std/ops/trait.RangeBounds.html#method.for_length
diff --git a/src/doc/unstable-book/src/library-features/slice-check-range.md b/src/doc/unstable-book/src/library-features/slice-check-range.md
deleted file mode 100644
index 83e5738cf54..00000000000
--- a/src/doc/unstable-book/src/library-features/slice-check-range.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# `slice_check_range`
-
-The tracking issue for this feature is: [#76393]
-
-------------------------
-
-This adds [`slice::check_range`].
-
-[#76393]: https://github.com/rust-lang/rust/issues/76393
-[`slice::check_range`]: https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.check_range