Skip to content

Commit

Permalink
Merge pull request #490 from dtolnay/fastdrop
Browse files Browse the repository at this point in the history
Optimize TokenStream's Drop
  • Loading branch information
dtolnay authored Jan 11, 2025
2 parents acc7d36 + 029360d commit 87e04d2
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
37 changes: 24 additions & 13 deletions src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,21 +125,32 @@ fn push_token_from_proc_macro(mut vec: RcVecMut<TokenTree>, token: TokenTree) {
// Nonrecursive to prevent stack overflow.
impl Drop for TokenStream {
fn drop(&mut self) {
let mut inner = match self.inner.get_mut() {
Some(inner) => inner,
let mut stack = Vec::new();
let mut current = match self.inner.get_mut() {
Some(inner) => inner.take().into_iter(),
None => return,
};
while let Some(token) = inner.pop() {
let group = match token {
TokenTree::Group(group) => group.inner,
_ => continue,
};
#[cfg(wrap_proc_macro)]
let group = match group {
crate::imp::Group::Fallback(group) => group,
crate::imp::Group::Compiler(_) => continue,
};
inner.extend(group.stream.take_inner());
loop {
while let Some(token) = current.next() {
let group = match token {
TokenTree::Group(group) => group.inner,
_ => continue,
};
#[cfg(wrap_proc_macro)]
let group = match group {
crate::imp::Group::Fallback(group) => group,
crate::imp::Group::Compiler(_) => continue,
};
let mut group = group;
if let Some(inner) = group.stream.inner.get_mut() {
stack.push(current);
current = inner.take().into_iter();
}
}
match stack.pop() {
Some(next) => current = next,
None => return,
}
}
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/rcvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,14 @@ impl<'a, T> RcVecMut<'a, T> {
self.inner.extend(iter);
}

pub(crate) fn pop(&mut self) -> Option<T> {
self.inner.pop()
}

pub(crate) fn as_mut(&mut self) -> RcVecMut<T> {
RcVecMut { inner: self.inner }
}

pub(crate) fn take(self) -> RcVecBuilder<T> {
let vec = mem::take(self.inner);
RcVecBuilder { inner: vec }
}
}

impl<T> Clone for RcVec<T> {
Expand Down

0 comments on commit 87e04d2

Please sign in to comment.