Skip to content

Commit d2b52c5

Browse files
committed
Auto merge of rust-lang#137795 - Jarcho:idx_opt, r=davidtwco
Allow bounds checks when enumerating `IndexSlice` to be elided Without this hint, each loop iteration has to separately bounds check the index. See https://godbolt.org/z/zrfPY4Ten for an example. This is technically a behaviour change, but only in cases where the compiler is going to crash anyways.
2 parents c625102 + da0fbc1 commit d2b52c5

File tree

2 files changed

+10
-0
lines changed

2 files changed

+10
-0
lines changed

compiler/rustc_index/src/slice.rs

+6
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,17 @@ impl<I: Idx, T> IndexSlice<I, T> {
6565

6666
#[inline]
6767
pub fn iter_enumerated(&self) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator {
68+
// Allow the optimizer to elide the bounds checking when creating each index.
69+
let _ = I::new(self.len());
6870
self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t))
6971
}
7072

7173
#[inline]
7274
pub fn indices(
7375
&self,
7476
) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + Clone + 'static {
77+
// Allow the optimizer to elide the bounds checking when creating each index.
78+
let _ = I::new(self.len());
7579
(0..self.len()).map(|n| I::new(n))
7680
}
7781

@@ -84,6 +88,8 @@ impl<I: Idx, T> IndexSlice<I, T> {
8488
pub fn iter_enumerated_mut(
8589
&mut self,
8690
) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator {
91+
// Allow the optimizer to elide the bounds checking when creating each index.
92+
let _ = I::new(self.len());
8793
self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t))
8894
}
8995

compiler/rustc_index/src/vec.rs

+4
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ impl<I: Idx, T> IndexVec<I, T> {
9393
/// be allocated only once, with a capacity of at least `n`.)
9494
#[inline]
9595
pub fn from_fn_n(func: impl FnMut(I) -> T, n: usize) -> Self {
96+
// Allow the optimizer to elide the bounds checking when creating each index.
97+
let _ = I::new(n);
9698
IndexVec::from_raw((0..n).map(I::new).map(func).collect())
9799
}
98100

@@ -128,6 +130,8 @@ impl<I: Idx, T> IndexVec<I, T> {
128130
pub fn into_iter_enumerated(
129131
self,
130132
) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator {
133+
// Allow the optimizer to elide the bounds checking when creating each index.
134+
let _ = I::new(self.len());
131135
self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t))
132136
}
133137

0 commit comments

Comments
 (0)