Skip to content

Commit

Permalink
Auto merge of #97870 - eggyal:inplace_fold_spec, r=wesleywiser
Browse files Browse the repository at this point in the history
Use liballoc's specialised in-place vec collection

liballoc already specialises in-place vector collection, so manually
reimplementing it in `IdFunctor::try_map_id` was superfluous.
  • Loading branch information
bors committed Nov 19, 2022
2 parents ff0ffda + 9208c08 commit becc24a
Showing 1 changed file with 2 additions and 34 deletions.
36 changes: 2 additions & 34 deletions compiler/rustc_data_structures/src/functor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,11 @@ impl<T> IdFunctor for Vec<T> {
type Inner = T;

#[inline]
fn try_map_id<F, E>(self, mut f: F) -> Result<Self, E>
fn try_map_id<F, E>(self, f: F) -> Result<Self, E>
where
F: FnMut(Self::Inner) -> Result<Self::Inner, E>,
{
struct HoleVec<T> {
vec: Vec<mem::ManuallyDrop<T>>,
hole: Option<usize>,
}

impl<T> Drop for HoleVec<T> {
fn drop(&mut self) {
unsafe {
for (index, slot) in self.vec.iter_mut().enumerate() {
if self.hole != Some(index) {
mem::ManuallyDrop::drop(slot);
}
}
}
}
}

unsafe {
let (ptr, length, capacity) = self.into_raw_parts();
let vec = Vec::from_raw_parts(ptr.cast(), length, capacity);
let mut hole_vec = HoleVec { vec, hole: None };

for (index, slot) in hole_vec.vec.iter_mut().enumerate() {
hole_vec.hole = Some(index);
let original = mem::ManuallyDrop::take(slot);
let mapped = f(original)?;
*slot = mem::ManuallyDrop::new(mapped);
hole_vec.hole = None;
}

mem::forget(hole_vec);
Ok(Vec::from_raw_parts(ptr, length, capacity))
}
self.into_iter().map(f).collect()
}
}

Expand Down

0 comments on commit becc24a

Please sign in to comment.