Skip to content

Commit 2a87b39

Browse files
authoredMar 7, 2020
Rollup merge of rust-lang#69706 - cuviper:subslice-methods, r=Centril
Use subslice patterns in slice methods For all of the methods that pick off the first or last element, we can use subslice patterns to implement them directly, rather than relying on deeper indexing function calls. At a minimum, this means the generated code will rely less on inlining for performance, but in some cases it also optimizes better.
2 parents 4f87d9f + 53be0cc commit 2a87b39

File tree

1 file changed

+8
-22
lines changed

1 file changed

+8
-22
lines changed
 

‎src/libcore/slice/mod.rs

+8-22
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ impl<T> [T] {
103103
#[stable(feature = "rust1", since = "1.0.0")]
104104
#[inline]
105105
pub fn first(&self) -> Option<&T> {
106-
self.get(0)
106+
if let [first, ..] = self { Some(first) } else { None }
107107
}
108108

109109
/// Returns a mutable pointer to the first element of the slice, or `None` if it is empty.
@@ -121,7 +121,7 @@ impl<T> [T] {
121121
#[stable(feature = "rust1", since = "1.0.0")]
122122
#[inline]
123123
pub fn first_mut(&mut self) -> Option<&mut T> {
124-
self.get_mut(0)
124+
if let [first, ..] = self { Some(first) } else { None }
125125
}
126126

127127
/// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -139,7 +139,7 @@ impl<T> [T] {
139139
#[stable(feature = "slice_splits", since = "1.5.0")]
140140
#[inline]
141141
pub fn split_first(&self) -> Option<(&T, &[T])> {
142-
if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
142+
if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
143143
}
144144

145145
/// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -159,12 +159,7 @@ impl<T> [T] {
159159
#[stable(feature = "slice_splits", since = "1.5.0")]
160160
#[inline]
161161
pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
162-
if self.is_empty() {
163-
None
164-
} else {
165-
let split = self.split_at_mut(1);
166-
Some((&mut split.0[0], split.1))
167-
}
162+
if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
168163
}
169164

170165
/// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -182,8 +177,7 @@ impl<T> [T] {
182177
#[stable(feature = "slice_splits", since = "1.5.0")]
183178
#[inline]
184179
pub fn split_last(&self) -> Option<(&T, &[T])> {
185-
let len = self.len();
186-
if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
180+
if let [init @ .., last] = self { Some((last, init)) } else { None }
187181
}
188182

189183
/// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -203,13 +197,7 @@ impl<T> [T] {
203197
#[stable(feature = "slice_splits", since = "1.5.0")]
204198
#[inline]
205199
pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
206-
let len = self.len();
207-
if len == 0 {
208-
None
209-
} else {
210-
let split = self.split_at_mut(len - 1);
211-
Some((&mut split.1[0], split.0))
212-
}
200+
if let [init @ .., last] = self { Some((last, init)) } else { None }
213201
}
214202

215203
/// Returns the last element of the slice, or `None` if it is empty.
@@ -226,8 +214,7 @@ impl<T> [T] {
226214
#[stable(feature = "rust1", since = "1.0.0")]
227215
#[inline]
228216
pub fn last(&self) -> Option<&T> {
229-
let last_idx = self.len().checked_sub(1)?;
230-
self.get(last_idx)
217+
if let [.., last] = self { Some(last) } else { None }
231218
}
232219

233220
/// Returns a mutable pointer to the last item in the slice.
@@ -245,8 +232,7 @@ impl<T> [T] {
245232
#[stable(feature = "rust1", since = "1.0.0")]
246233
#[inline]
247234
pub fn last_mut(&mut self) -> Option<&mut T> {
248-
let last_idx = self.len().checked_sub(1)?;
249-
self.get_mut(last_idx)
235+
if let [.., last] = self { Some(last) } else { None }
250236
}
251237

252238
/// Returns a reference to an element or subslice depending on the type of

0 commit comments

Comments
 (0)