From 535675e13c24092f6004908df153635b1c894818 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 25 Jul 2022 10:31:28 -0700 Subject: [PATCH] Remove Vec from API of fallback::TokenStream --- src/fallback.rs | 34 ++++++++++++++++++++++++++-------- src/parse.rs | 22 +++++++++++----------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/fallback.rs b/src/fallback.rs index 0929aec0..b0309594 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -109,14 +109,6 @@ impl TokenStream { } } -impl From> for TokenStream { - fn from(inner: Vec) -> Self { - TokenStream { - inner: Rc::new(inner), - } - } -} - // Nonrecursive to prevent stack overflow. impl Drop for TokenStream { fn drop(&mut self) { @@ -140,6 +132,32 @@ impl Drop for TokenStream { } } +pub(crate) struct TokenStreamBuilder { + inner: Vec, +} + +impl TokenStreamBuilder { + pub fn new() -> Self { + TokenStreamBuilder { inner: Vec::new() } + } + + pub fn with_capacity(cap: usize) -> Self { + TokenStreamBuilder { + inner: Vec::with_capacity(cap), + } + } + + pub fn push(&mut self, tt: TokenTree) { + self.inner.push(tt); + } + + pub fn build(self) -> TokenStream { + TokenStream { + inner: Rc::new(self.inner), + } + } +} + #[cfg(span_locations)] fn get_cursor(src: &str) -> Cursor { // Create a dummy file & add it to the source map diff --git a/src/parse.rs b/src/parse.rs index 27828c03..ca6ea5c8 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,5 +1,6 @@ use crate::fallback::{ is_ident_continue, is_ident_start, Group, LexError, Literal, Span, TokenStream, + TokenStreamBuilder, }; use crate::{Delimiter, Punct, Spacing, TokenTree}; use std::char; @@ -150,7 +151,7 @@ fn word_break(input: Cursor) -> Result { } pub(crate) fn token_stream(mut input: Cursor) -> Result { - let mut trees = Vec::new(); + let mut trees = TokenStreamBuilder::new(); let mut stack = Vec::new(); loop { @@ -167,7 +168,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result { let first = match input.bytes().next() { Some(first) => first, None => match stack.last() { - None => return Ok(TokenStream::from(trees)), + None => return Ok(trees.build()), #[cfg(span_locations)] Some((lo, _frame)) => { return Err(LexError { @@ -190,7 +191,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result { #[cfg(span_locations)] let frame = (lo, frame); stack.push(frame); - trees = Vec::new(); + trees = TokenStreamBuilder::new(); } else if let Some(close_delimiter) = match first { b')' => Some(Delimiter::Parenthesis), b']' => Some(Delimiter::Bracket), @@ -208,7 +209,7 @@ pub(crate) fn token_stream(mut input: Cursor) -> Result { return Err(lex_error(input)); } input = input.advance(1); - let mut g = Group::new(open_delimiter, TokenStream::from(trees)); + let mut g = Group::new(open_delimiter, trees.build()); g.set_span(Span { #[cfg(span_locations)] lo, @@ -785,7 +786,7 @@ fn punct_char(input: Cursor) -> PResult { } } -fn doc_comment<'a>(input: Cursor<'a>, trees: &mut Vec) -> PResult<'a, ()> { +fn doc_comment<'a>(input: Cursor<'a>, trees: &mut TokenStreamBuilder) -> PResult<'a, ()> { #[cfg(span_locations)] let lo = input.off; let (rest, (comment, inner)) = doc_comment_contents(input)?; @@ -820,12 +821,11 @@ fn doc_comment<'a>(input: Cursor<'a>, trees: &mut Vec) -> PResult<'a, equal.set_span(span); let mut literal = crate::Literal::string(comment); literal.set_span(span); - let bracketed = TokenStream::from(vec![ - TokenTree::Ident(doc_ident), - TokenTree::Punct(equal), - TokenTree::Literal(literal), - ]); - let group = Group::new(Delimiter::Bracket, bracketed); + let mut bracketed = TokenStreamBuilder::with_capacity(3); + bracketed.push(TokenTree::Ident(doc_ident)); + bracketed.push(TokenTree::Punct(equal)); + bracketed.push(TokenTree::Literal(literal)); + let group = Group::new(Delimiter::Bracket, bracketed.build()); let mut group = crate::Group::_new_stable(group); group.set_span(span); trees.push(TokenTree::Group(group));