|
1 |
| -diff --git a/library/alloc/src/collections/vec_deque.rs b/library/alloc/src/collections/vec_deque.rs |
2 |
| -index 253a3e9f2be..65cfe9a9b49 100644 |
3 |
| ---- a/library/alloc/src/collections/vec_deque.rs |
4 |
| -+++ b/library/alloc/src/collections/vec_deque.rs |
5 |
| -@@ -1089,11 +1089,7 @@ impl<T> VecDeque<T> { |
6 |
| - where |
7 |
| - R: RangeBounds<usize>, |
8 |
| - { |
9 |
| -- // SAFETY: This buffer is only used to check the range. It might be partially |
10 |
| -- // uninitialized, but `check_range` needs a contiguous slice. |
11 |
| -- // https://github.com/rust-lang/rust/pull/75207#discussion_r471193682 |
12 |
| -- let buffer = unsafe { slice::from_raw_parts(self.ptr(), self.len()) }; |
13 |
| -- let Range { start, end } = buffer.check_range(range); |
14 |
| -+ let Range { start, end } = slice::check_range(self.len(), range); |
15 |
| - let tail = self.wrap_add(self.tail, start); |
16 |
| - let head = self.wrap_add(self.tail, end); |
17 |
| - (tail, head) |
18 |
| -diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs |
19 |
| -index 677bfdd2349..55afdd94f44 100644 |
20 |
| ---- a/library/alloc/src/slice.rs |
21 |
| -+++ b/library/alloc/src/slice.rs |
22 |
| -@@ -91,6 +91,8 @@ use crate::borrow::ToOwned; |
23 |
| - use crate::boxed::Box; |
24 |
| - use crate::vec::Vec; |
25 |
| - |
26 |
| -+#[unstable(feature = "slice_check_range", issue = "76393")] |
27 |
| -+pub use core::slice::check_range; |
28 |
| - #[unstable(feature = "array_chunks", issue = "74985")] |
29 |
| - pub use core::slice::ArrayChunks; |
30 |
| - #[unstable(feature = "array_chunks", issue = "74985")] |
31 |
| -diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs |
32 |
| -index e1724bf3c9a..2b0ce5ede56 100644 |
33 |
| ---- a/library/alloc/src/string.rs |
34 |
| -+++ b/library/alloc/src/string.rs |
35 |
| -@@ -49,6 +49,7 @@ use core::iter::{FromIterator, FusedIterator}; |
36 |
| - use core::ops::Bound::{Excluded, Included, Unbounded}; |
37 |
| - use core::ops::{self, Add, AddAssign, Index, IndexMut, Range, RangeBounds}; |
38 |
| - use core::ptr; |
39 |
| -+use core::slice; |
40 |
| - use core::str::{lossy, pattern::Pattern}; |
41 |
| - |
42 |
| - use crate::borrow::{Cow, ToOwned}; |
43 |
| -@@ -1506,7 +1507,7 @@ impl String { |
44 |
| - // of the vector version. The data is just plain bytes. |
45 |
| - // Because the range removal happens in Drop, if the Drain iterator is leaked, |
46 |
| - // the removal will not happen. |
47 |
| -- let Range { start, end } = self.as_bytes().check_range(range); |
48 |
| -+ let Range { start, end } = slice::check_range(self.len(), range); |
49 |
| - assert!(self.is_char_boundary(start)); |
50 |
| - assert!(self.is_char_boundary(end)); |
51 |
| - |
52 |
| -diff --git a/library/alloc/src/vec.rs b/library/alloc/src/vec.rs |
53 |
| -index baa6c0919de..3d48a06fd24 100644 |
54 |
| ---- a/library/alloc/src/vec.rs |
55 |
| -+++ b/library/alloc/src/vec.rs |
56 |
| -@@ -1310,7 +1310,7 @@ impl<T> Vec<T> { |
57 |
| - // the hole, and the vector length is restored to the new length. |
58 |
| - // |
59 |
| - let len = self.len(); |
60 |
| -- let Range { start, end } = self.check_range(range); |
61 |
| -+ let Range { start, end } = slice::check_range(len, range); |
62 |
| - |
63 |
| - unsafe { |
64 |
| - // set self.vec length's to start, to be safe in case Drain is leaked |
65 |
| -diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs |
66 |
| -index 53b0d0a2718..f3e6eb62926 100644 |
67 |
| ---- a/library/alloc/tests/vec.rs |
68 |
| -+++ b/library/alloc/tests/vec.rs |
69 |
| -@@ -880,7 +880,7 @@ fn test_from_iter_partially_drained_in_place_specialization() { |
70 |
| - #[test] |
71 |
| - fn test_from_iter_specialization_with_iterator_adapters() { |
72 |
| - fn assert_in_place_trait<T: InPlaceIterable>(_: &T) {}; |
73 |
| -- let src: Vec<usize> = vec![0usize; 65535]; |
74 |
| -+ let src: Vec<usize> = vec![0usize; if cfg!(miri) { 256 } else { 65535 }]; |
75 |
| - let srcptr = src.as_ptr(); |
76 |
| - let iter = src |
77 |
| - .into_iter() |
78 |
| -diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs |
79 |
| -index 4c027b23584..b4531f2d18c 100644 |
80 |
| ---- a/library/core/src/slice/mod.rs |
81 |
| -+++ b/library/core/src/slice/mod.rs |
82 |
| -@@ -354,79 +354,6 @@ impl<T> [T] { |
83 |
| - unsafe { &mut *index.get_unchecked_mut(self) } |
84 |
| - } |
85 |
| - |
86 |
| -- /// Converts a range over this slice to [`Range`]. |
87 |
| -- /// |
88 |
| -- /// The returned range is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]. |
89 |
| -- /// |
90 |
| -- /// [`get_unchecked`]: #method.get_unchecked |
91 |
| -- /// [`get_unchecked_mut`]: #method.get_unchecked_mut |
92 |
| -- /// |
93 |
| -- /// # Panics |
94 |
| -- /// |
95 |
| -- /// Panics if the range is out of bounds. |
96 |
| -- /// |
97 |
| -- /// # Examples |
98 |
| -- /// |
99 |
| -- /// ``` |
100 |
| -- /// #![feature(slice_check_range)] |
101 |
| -- /// |
102 |
| -- /// let v = [10, 40, 30]; |
103 |
| -- /// assert_eq!(1..2, v.check_range(1..2)); |
104 |
| -- /// assert_eq!(0..2, v.check_range(..2)); |
105 |
| -- /// assert_eq!(1..3, v.check_range(1..)); |
106 |
| -- /// ``` |
107 |
| -- /// |
108 |
| -- /// Panics when [`Index::index`] would panic: |
109 |
| -- /// |
110 |
| -- /// ```should_panic |
111 |
| -- /// #![feature(slice_check_range)] |
112 |
| -- /// |
113 |
| -- /// [10, 40, 30].check_range(2..1); |
114 |
| -- /// ``` |
115 |
| -- /// |
116 |
| -- /// ```should_panic |
117 |
| -- /// #![feature(slice_check_range)] |
118 |
| -- /// |
119 |
| -- /// [10, 40, 30].check_range(1..4); |
120 |
| -- /// ``` |
121 |
| -- /// |
122 |
| -- /// ```should_panic |
123 |
| -- /// #![feature(slice_check_range)] |
124 |
| -- /// |
125 |
| -- /// [10, 40, 30].check_range(1..=usize::MAX); |
126 |
| -- /// ``` |
127 |
| -- /// |
128 |
| -- /// [`Index::index`]: ops::Index::index |
129 |
| -- #[track_caller] |
130 |
| -- #[unstable(feature = "slice_check_range", issue = "76393")] |
131 |
| -- pub fn check_range<R: RangeBounds<usize>>(&self, range: R) -> Range<usize> { |
132 |
| -- let start = match range.start_bound() { |
133 |
| -- Bound::Included(&start) => start, |
134 |
| -- Bound::Excluded(start) => { |
135 |
| -- start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail()) |
136 |
| -- } |
137 |
| -- Bound::Unbounded => 0, |
138 |
| -- }; |
139 |
| -- |
140 |
| -- let len = self.len(); |
141 |
| -- let end = match range.end_bound() { |
142 |
| -- Bound::Included(end) => { |
143 |
| -- end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail()) |
144 |
| -- } |
145 |
| -- Bound::Excluded(&end) => end, |
146 |
| -- Bound::Unbounded => len, |
147 |
| -- }; |
148 |
| -- |
149 |
| -- if start > end { |
150 |
| -- slice_index_order_fail(start, end); |
151 |
| -- } |
152 |
| -- if end > len { |
153 |
| -- slice_end_index_len_fail(end, len); |
154 |
| -- } |
155 |
| -- |
156 |
| -- Range { start, end } |
157 |
| -- } |
158 |
| -- |
159 |
| - /// Returns a raw pointer to the slice's buffer. |
160 |
| - /// |
161 |
| - /// The caller must ensure that the slice outlives the pointer this |
162 |
| -@@ -2770,7 +2697,7 @@ impl<T> [T] { |
163 |
| - where |
164 |
| - T: Copy, |
165 |
| - { |
166 |
| -- let Range { start: src_start, end: src_end } = self.check_range(src); |
167 |
| -+ let Range { start: src_start, end: src_end } = check_range(self.len(), src); |
168 |
| - let count = src_end - src_start; |
169 |
| - assert!(dest <= self.len() - count, "dest is out of bounds"); |
170 |
| - // SAFETY: the conditions for `ptr::copy` have all been checked above, |
171 |
| -@@ -6660,6 +6587,79 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExactMut<'a, T> { |
172 |
| - // Free functions |
173 |
| - // |
174 |
| - |
175 |
| -+/// Converts a range over this slice to [`Range`]. |
176 |
| -+/// |
177 |
| -+/// The returned range is safe to pass to [`get_unchecked`] and [`get_unchecked_mut`]. |
178 |
| -+/// |
179 |
| -+/// [`get_unchecked`]: #method.get_unchecked |
180 |
| -+/// [`get_unchecked_mut`]: #method.get_unchecked_mut |
181 |
| -+/// |
182 |
| -+/// # Panics |
183 |
| -+/// |
184 |
| -+/// Panics if the range is out of bounds. |
185 |
| -+/// |
186 |
| -+/// # Examples |
187 |
| -+/// |
188 |
| -+/// ``` |
189 |
| -+/// #![feature(slice_check_range)] |
190 |
| -+/// use std::slice; |
191 |
| -+/// |
192 |
| -+/// let v = [10, 40, 30]; |
193 |
| -+/// assert_eq!(1..2, slice::check_range(v.len(), 1..2)); |
194 |
| -+/// assert_eq!(0..2, slice::check_range(v.len(), ..2)); |
195 |
| -+/// assert_eq!(1..3, slice::check_range(v.len(), 1..)); |
196 |
| -+/// ``` |
197 |
| -+/// |
198 |
| -+/// Panics when [`Index::index`] would panic: |
199 |
| -+/// |
200 |
| -+/// ```should_panic |
201 |
| -+/// #![feature(slice_check_range)] |
202 |
| -+/// |
203 |
| -+/// std::slice::check_range(3, 2..1); |
204 |
| -+/// ``` |
205 |
| -+/// |
206 |
| -+/// ```should_panic |
207 |
| -+/// #![feature(slice_check_range)] |
208 |
| -+/// |
209 |
| -+/// std::slice::check_range(3, 1..4); |
210 |
| -+/// ``` |
211 |
| -+/// |
212 |
| -+/// ```should_panic |
213 |
| -+/// #![feature(slice_check_range)] |
214 |
| -+/// |
215 |
| -+/// std::slice::check_range(3, 1..=usize::MAX); |
216 |
| -+/// ``` |
217 |
| -+/// |
218 |
| -+/// [`Index::index`]: ops::Index::index |
219 |
| -+#[track_caller] |
220 |
| -+#[unstable(feature = "slice_check_range", issue = "76393")] |
221 |
| -+pub fn check_range<R: RangeBounds<usize>>(len: usize, range: R) -> Range<usize> { |
222 |
| -+ let start = match range.start_bound() { |
223 |
| -+ Bound::Included(&start) => start, |
224 |
| -+ Bound::Excluded(start) => { |
225 |
| -+ start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail()) |
226 |
| -+ } |
227 |
| -+ Bound::Unbounded => 0, |
228 |
| -+ }; |
229 |
| -+ |
230 |
| -+ let end = match range.end_bound() { |
231 |
| -+ Bound::Included(end) => { |
232 |
| -+ end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail()) |
233 |
| -+ } |
234 |
| -+ Bound::Excluded(&end) => end, |
235 |
| -+ Bound::Unbounded => len, |
236 |
| -+ }; |
237 |
| -+ |
238 |
| -+ if start > end { |
239 |
| -+ slice_index_order_fail(start, end); |
240 |
| -+ } |
241 |
| -+ if end > len { |
242 |
| -+ slice_end_index_len_fail(end, len); |
243 |
| -+ } |
244 |
| -+ |
245 |
| -+ Range { start, end } |
246 |
| -+} |
247 |
| -+ |
248 |
| - /// Forms a slice from a pointer and a length. |
249 |
| - /// |
250 |
| - /// The `len` argument is the number of **elements**, not the number of bytes. |
| 1 | + |
0 commit comments