Skip to content

Commit 05af66a

Browse files
committed
Improve design of assert_len
1 parent d4e3570 commit 05af66a

File tree

8 files changed

+38
-29
lines changed

8 files changed

+38
-29
lines changed

library/alloc/src/collections/vec_deque/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ impl<T> VecDeque<T> {
10631063
where
10641064
R: RangeBounds<usize>,
10651065
{
1066-
let Range { start, end } = range.assert_len(self.len());
1066+
let Range { start, end } = range.ensure_subset_of(..self.len());
10671067
let tail = self.wrap_add(self.tail, start);
10681068
let head = self.wrap_add(self.tail, end);
10691069
(tail, head)

library/alloc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
#![feature(or_patterns)]
113113
#![feature(pattern)]
114114
#![feature(ptr_internals)]
115-
#![feature(range_bounds_assert_len)]
115+
#![feature(range_bounds_ensure_subset_of)]
116116
#![feature(rustc_attrs)]
117117
#![feature(receiver_trait)]
118118
#![cfg_attr(bootstrap, feature(min_const_generics))]

library/alloc/src/string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,14 +1510,14 @@ impl String {
15101510
// of the vector version. The data is just plain bytes.
15111511
// Because the range removal happens in Drop, if the Drain iterator is leaked,
15121512
// the removal will not happen.
1513-
let Range { start, end } = range.assert_len(self.len());
1513+
let Range { start, end } = range.ensure_subset_of(..self.len());
15141514
assert!(self.is_char_boundary(start));
15151515
assert!(self.is_char_boundary(end));
15161516

15171517
// Take out two simultaneous borrows. The &mut String won't be accessed
15181518
// until iteration is over, in Drop.
15191519
let self_ptr = self as *mut _;
1520-
// SAFETY: `assert_len` and `is_char_boundary` do the appropriate bounds checks.
1520+
// SAFETY: `ensure_subset_of` and `is_char_boundary` do the appropriate bounds checks.
15211521
let chars_iter = unsafe { self.get_unchecked(start..end) }.chars();
15221522

15231523
Drain { start, end, iter: chars_iter, string: self_ptr }

library/alloc/src/vec/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1597,7 +1597,7 @@ impl<T, A: Allocator> Vec<T, A> {
15971597
// the hole, and the vector length is restored to the new length.
15981598
//
15991599
let len = self.len();
1600-
let Range { start, end } = range.assert_len(len);
1600+
let Range { start, end } = range.ensure_subset_of(..len);
16011601

16021602
unsafe {
16031603
// set self.vec length's to start, to be safe in case Drain is leaked

library/core/src/ops/range.rs

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -766,8 +766,15 @@ pub trait RangeBounds<T: ?Sized> {
766766

767767
/// Performs bounds-checking of this range.
768768
///
769+
/// This method is similar to [`Index::index`] for slices, but it returns a
770+
/// [`Range`] equivalent to this range. You can use this method to turn any
771+
/// range into `start` and `end` values.
772+
///
773+
/// The given range is the range of the slice to use for bounds-checking. It
774+
/// should be a [`RangeTo`] range that ends at the length of the slice.
775+
///
769776
/// The returned [`Range`] is safe to pass to [`slice::get_unchecked`] and
770-
/// [`slice::get_unchecked_mut`] for slices of the given length.
777+
/// [`slice::get_unchecked_mut`] for slices with the given range.
771778
///
772779
/// [`slice::get_unchecked`]: ../../std/primitive.slice.html#method.get_unchecked
773780
/// [`slice::get_unchecked_mut`]: ../../std/primitive.slice.html#method.get_unchecked_mut
@@ -779,49 +786,51 @@ pub trait RangeBounds<T: ?Sized> {
779786
/// # Examples
780787
///
781788
/// ```
782-
/// #![feature(range_bounds_assert_len)]
789+
/// #![feature(range_bounds_ensure_subset_of)]
783790
///
784791
/// use std::ops::RangeBounds;
785792
///
786793
/// let v = [10, 40, 30];
787-
/// assert_eq!(1..2, (1..2).assert_len(v.len()));
788-
/// assert_eq!(0..2, (..2).assert_len(v.len()));
789-
/// assert_eq!(1..3, (1..).assert_len(v.len()));
794+
/// assert_eq!(1..2, (1..2).ensure_subset_of(..v.len()));
795+
/// assert_eq!(0..2, (..2).ensure_subset_of(..v.len()));
796+
/// assert_eq!(1..3, (1..).ensure_subset_of(..v.len()));
790797
/// ```
791798
///
792799
/// Panics when [`Index::index`] would panic:
793800
///
794801
/// ```should_panic
795-
/// #![feature(range_bounds_assert_len)]
802+
/// #![feature(range_bounds_ensure_subset_of)]
796803
///
797804
/// use std::ops::RangeBounds;
798805
///
799-
/// (2..1).assert_len(3);
806+
/// (2..1).ensure_subset_of(..3);
800807
/// ```
801808
///
802809
/// ```should_panic
803-
/// #![feature(range_bounds_assert_len)]
810+
/// #![feature(range_bounds_ensure_subset_of)]
804811
///
805812
/// use std::ops::RangeBounds;
806813
///
807-
/// (1..4).assert_len(3);
814+
/// (1..4).ensure_subset_of(..3);
808815
/// ```
809816
///
810817
/// ```should_panic
811-
/// #![feature(range_bounds_assert_len)]
818+
/// #![feature(range_bounds_ensure_subset_of)]
812819
///
813820
/// use std::ops::RangeBounds;
814821
///
815-
/// (1..=usize::MAX).assert_len(3);
822+
/// (1..=usize::MAX).ensure_subset_of(..3);
816823
/// ```
817824
///
818825
/// [`Index::index`]: crate::ops::Index::index
819826
#[track_caller]
820-
#[unstable(feature = "range_bounds_assert_len", issue = "76393")]
821-
fn assert_len(self, len: usize) -> Range<usize>
827+
#[unstable(feature = "range_bounds_ensure_subset_of", issue = "76393")]
828+
fn ensure_subset_of(self, range: RangeTo<usize>) -> Range<usize>
822829
where
823830
Self: RangeBounds<usize>,
824831
{
832+
let len = range.end;
833+
825834
let start: Bound<&usize> = self.start_bound();
826835
let start = match start {
827836
Bound::Included(&start) => start,

library/core/src/slice/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3052,7 +3052,7 @@ impl<T> [T] {
30523052
where
30533053
T: Copy,
30543054
{
3055-
let Range { start: src_start, end: src_end } = src.assert_len(self.len());
3055+
let Range { start: src_start, end: src_end } = src.ensure_subset_of(..self.len());
30563056
let count = src_end - src_start;
30573057
assert!(dest <= self.len() - count, "dest is out of bounds");
30583058
// SAFETY: the conditions for `ptr::copy` have all been checked above,

src/doc/unstable-book/src/library-features/range-bounds-assert-len.md

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# `range_bounds_ensure_subset_of`
2+
3+
The tracking issue for this feature is: [#76393]
4+
5+
------------------------
6+
7+
This adds [`RangeBounds::ensure_subset_of`].
8+
9+
[#76393]: https://github.com/rust-lang/rust/issues/76393
10+
[`RangeBounds::ensure_subset_of`]: https://doc.rust-lang.org/nightly/std/ops/trait.RangeBounds.html#method.ensure_subset_of

0 commit comments

Comments
 (0)