From 172907a8554f6947e7b7e14a262c7e2914f31016 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 10 Jan 2025 17:41:46 -0800 Subject: [PATCH] Non-recursively drop TokenStream relocating only streams, not tokens --- src/fallback.rs | 37 ++++++++++++++++++++++++------------- src/rcvec.rs | 13 +++++++++---- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/src/fallback.rs b/src/fallback.rs index 92b342f..202e175 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -125,21 +125,32 @@ fn push_token_from_proc_macro(mut vec: RcVecMut, 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(), 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.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, + }; + let mut group = group; + if let Some(inner) = group.stream.inner.get_mut() { + stack.push(current); + current = inner.take(); + } + } + match stack.pop() { + Some(next) => current = next, + None => return, + } } } } diff --git a/src/rcvec.rs b/src/rcvec.rs index cde9f25..1c77b7a 100644 --- a/src/rcvec.rs +++ b/src/rcvec.rs @@ -80,6 +80,10 @@ impl RcVecBuilder { self.inner.extend(iter); } + pub(crate) fn pop(&mut self) -> Option { + self.inner.pop() + } + pub(crate) fn as_mut(&mut self) -> RcVecMut { RcVecMut { inner: &mut self.inner, @@ -102,13 +106,14 @@ impl<'a, T> RcVecMut<'a, T> { self.inner.extend(iter); } - pub(crate) fn pop(&mut self) -> Option { - self.inner.pop() - } - pub(crate) fn as_mut(&mut self) -> RcVecMut { RcVecMut { inner: self.inner } } + + pub(crate) fn take(self) -> RcVecBuilder { + let vec = mem::take(self.inner); + RcVecBuilder { inner: vec } + } } impl Clone for RcVec {