Skip to content

Commit 7dee111

Browse files
Move IntervalSet to store I directly
This avoids trouble with I = usize on 64-bit systems, where previously we would either assert or truncate when converting to u32.
1 parent e540587 commit 7dee111

File tree

1 file changed

+24
-28
lines changed

1 file changed

+24
-28
lines changed

compiler/rustc_index/src/interval.rs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,31 @@ mod tests;
1515
#[derive(Debug, Clone, PartialEq, Eq, Hash, Encodable, Decodable)]
1616
pub struct IntervalSet<I> {
1717
// Start, end
18-
map: SmallVec<[(u32, u32); 4]>,
18+
map: SmallVec<[(I, I); 4]>,
1919
domain: usize,
2020
_data: PhantomData<I>,
2121
}
2222

2323
#[inline]
24-
fn inclusive_start<T: Idx>(range: impl RangeBounds<T>) -> u32 {
24+
fn inclusive_start<T: Idx>(range: impl RangeBounds<T>) -> T {
2525
match range.start_bound() {
26-
Bound::Included(start) => start.index() as u32,
27-
Bound::Excluded(start) => start.index() as u32 + 1,
28-
Bound::Unbounded => 0,
26+
Bound::Included(start) => *start,
27+
Bound::Excluded(start) => T::new(start.index() + 1),
28+
Bound::Unbounded => T::new(0),
2929
}
3030
}
3131

3232
#[inline]
33-
fn inclusive_end<T: Idx>(domain: usize, range: impl RangeBounds<T>) -> Option<u32> {
33+
fn inclusive_end<T: Idx>(domain: usize, range: impl RangeBounds<T>) -> Option<T> {
3434
let end = match range.end_bound() {
35-
Bound::Included(end) => end.index() as u32,
36-
Bound::Excluded(end) => end.index().checked_sub(1)? as u32,
37-
Bound::Unbounded => domain.checked_sub(1)? as u32,
35+
Bound::Included(end) => *end,
36+
Bound::Excluded(end) => T::new(end.index().checked_sub(1)?),
37+
Bound::Unbounded => T::new(domain.checked_sub(1)?),
3838
};
3939
Some(end)
4040
}
4141

42-
impl<I: Idx> IntervalSet<I> {
42+
impl<I: Ord + Idx> IntervalSet<I> {
4343
pub fn new(domain: usize) -> IntervalSet<I> {
4444
IntervalSet { map: SmallVec::new(), domain, _data: PhantomData }
4545
}
@@ -71,7 +71,7 @@ impl<I: Idx> IntervalSet<I> {
7171
where
7272
I: Step,
7373
{
74-
self.map.iter().map(|&(start, end)| I::new(start as usize)..I::new(end as usize + 1))
74+
self.map.iter().map(|&(start, end)| start..I::new(end.index() + 1))
7575
}
7676

7777
/// Returns true if we increased the number of elements present.
@@ -100,10 +100,10 @@ impl<I: Idx> IntervalSet<I> {
100100
// if r.0 == end + 1, then we're actually adjacent, so we want to
101101
// continue to the next range. We're looking here for the first
102102
// range which starts *non-adjacently* to our end.
103-
let next = self.map.partition_point(|r| r.0 <= end + 1);
103+
let next = self.map.partition_point(|r| r.0.index() <= end.index() + 1);
104104
if let Some(last) = next.checked_sub(1) {
105105
let (prev_start, prev_end) = &mut self.map[last];
106-
if *prev_end + 1 >= start {
106+
if prev_end.index() + 1 >= start.index() {
107107
// If the start for the inserted range is adjacent to the
108108
// end of the previous, we can extend the previous range.
109109
if start < *prev_start {
@@ -168,15 +168,11 @@ impl<I: Idx> IntervalSet<I> {
168168
let (prev_start, prev_end) = self.map.remove(idx);
169169
// The range we're looking at contains the range we're removing completely.
170170
assert!(prev_start <= start && end <= prev_end);
171-
self.insert_range(I::new(prev_start as usize)..I::new(start as usize));
172-
self.insert_range((
173-
Bound::Excluded(I::new(end as usize)),
174-
Bound::Included(I::new(prev_end as usize)),
175-
));
171+
self.insert_range(prev_start..start);
172+
self.insert_range((Bound::Excluded(end), Bound::Included(prev_end)));
176173
}
177174

178175
pub fn contains(&self, needle: I) -> bool {
179-
let needle = needle.index() as u32;
180176
let Some(last) = self.map.partition_point(|r| r.0 <= needle).checked_sub(1) else {
181177
// All ranges in the map start after the new range's end
182178
return false;
@@ -209,7 +205,7 @@ impl<I: Idx> IntervalSet<I> {
209205
return None;
210206
}
211207
let range = self.map.get(self.map.partition_point(|r| r.1 < start))?;
212-
if range.0 > end { None } else { Some(I::new(std::cmp::max(range.0, start) as usize)) }
208+
if range.0 > end { None } else { Some(std::cmp::max(range.0, start)) }
213209
}
214210

215211
/// Returns the minimum (first) element **not** present in the set from `range`.
@@ -223,13 +219,13 @@ impl<I: Idx> IntervalSet<I> {
223219
return None;
224220
}
225221
let Some(range) = self.map.get(self.map.partition_point(|r| r.1 < start)) else {
226-
return Some(I::new(start as usize));
222+
return Some(start);
227223
};
228224
if start < range.0 {
229-
return Some(I::new(start as usize));
230-
} else if range.1 as usize + 1 < self.domain {
231-
if range.1 + 1 <= end {
232-
return Some(I::new(range.1 as usize + 1));
225+
return Some(start);
226+
} else if range.1.index() + 1 < self.domain {
227+
if range.1.index() + 1 <= end.index() {
228+
return Some(I::new(range.1.index() + 1));
233229
}
234230
}
235231

@@ -251,12 +247,12 @@ impl<I: Idx> IntervalSet<I> {
251247
return None;
252248
};
253249
let (_, prev_end) = &self.map[last];
254-
if start <= *prev_end { Some(I::new(std::cmp::min(*prev_end, end) as usize)) } else { None }
250+
if start <= *prev_end { Some(std::cmp::min(*prev_end, end)) } else { None }
255251
}
256252

257253
pub fn insert_all(&mut self) {
258254
self.clear();
259-
self.map.push((0, self.domain.try_into().unwrap()));
255+
self.map.push((I::new(0), I::new(self.domain)));
260256
}
261257

262258
pub fn union(&mut self, other: &IntervalSet<I>) -> bool
@@ -287,7 +283,7 @@ where
287283
column_size: usize,
288284
}
289285

290-
impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
286+
impl<R: Idx, C: Ord + Step + Idx> SparseIntervalMatrix<R, C> {
291287
pub fn new(column_size: usize) -> SparseIntervalMatrix<R, C> {
292288
SparseIntervalMatrix { rows: IndexVec::new(), column_size }
293289
}

0 commit comments

Comments
 (0)