Skip to content

Commit a822d08

Browse files
committed
Remove TokenStreamBuilder.
It's now only used in one function. Also, the "should we glue the tokens?" check is only necessary when pushing a `TokenTree::Token`, not when pushing a `TokenTree::Delimited`. As part of this, we now do the "should we glue the tokens?" check immediately, which avoids having look back at the previous token. It also puts all the logic dealing with token gluing in a single place.
1 parent 8d0754d commit a822d08

File tree

1 file changed

+20
-37
lines changed

1 file changed

+20
-37
lines changed

compiler/rustc_parse/src/lexer/tokentrees.rs

+20-37
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ impl<'a> TokenTreesReader<'a> {
4747
// Parse a stream of tokens into a list of `TokenTree`s.
4848
fn parse_token_trees(&mut self, is_top_level: bool) -> PResult<'a, TokenStream> {
4949
self.token = self.string_reader.next_token().0;
50-
let mut buf = TokenStreamBuilder::default();
50+
let mut buf = Vec::new();
5151
loop {
5252
match self.token.kind {
5353
token::OpenDelim(delim) => buf.push(self.parse_token_tree_open_delim(delim)),
5454
token::CloseDelim(delim) => {
5555
return if !is_top_level {
56-
Ok(buf.into_token_stream())
56+
Ok(TokenStream::new(buf))
5757
} else {
5858
Err(self.close_delim_err(delim))
5959
};
@@ -62,21 +62,28 @@ impl<'a> TokenTreesReader<'a> {
6262
if !is_top_level {
6363
self.eof_err().emit();
6464
}
65-
return Ok(buf.into_token_stream());
65+
return Ok(TokenStream::new(buf));
6666
}
6767
_ => {
68-
// `this_spacing` for the returned token refers to whether the token is
69-
// immediately followed by another op token. It is determined by the
70-
// next token: its kind and its `preceded_by_whitespace` status.
71-
let (next_tok, is_next_tok_preceded_by_whitespace) =
72-
self.string_reader.next_token();
73-
let this_spacing = if is_next_tok_preceded_by_whitespace || !next_tok.is_op() {
74-
Spacing::Alone
75-
} else {
76-
Spacing::Joint
68+
// Get the next normal token. This might require getting multiple adjacent
69+
// single-char tokens and joining them together.
70+
let (this_spacing, next_tok) = loop {
71+
let (next_tok, is_next_tok_preceded_by_whitespace) =
72+
self.string_reader.next_token();
73+
if !is_next_tok_preceded_by_whitespace {
74+
if let Some(glued) = self.token.glue(&next_tok) {
75+
self.token = glued;
76+
} else {
77+
let this_spacing =
78+
if next_tok.is_op() { Spacing::Joint } else { Spacing::Alone };
79+
break (this_spacing, next_tok);
80+
}
81+
} else {
82+
break (Spacing::Alone, next_tok);
83+
}
7784
};
7885
let this_tok = std::mem::replace(&mut self.token, next_tok);
79-
buf.push(TokenTree::Token(this_tok, this_spacing))
86+
buf.push(TokenTree::Token(this_tok, this_spacing));
8087
}
8188
}
8289
}
@@ -249,27 +256,3 @@ impl<'a> TokenTreesReader<'a> {
249256
err
250257
}
251258
}
252-
253-
#[derive(Default)]
254-
struct TokenStreamBuilder {
255-
buf: Vec<TokenTree>,
256-
}
257-
258-
impl TokenStreamBuilder {
259-
#[inline(always)]
260-
fn push(&mut self, tree: TokenTree) {
261-
if let Some(TokenTree::Token(prev_token, Spacing::Joint)) = self.buf.last()
262-
&& let TokenTree::Token(token, joint) = &tree
263-
&& let Some(glued) = prev_token.glue(token)
264-
{
265-
self.buf.pop();
266-
self.buf.push(TokenTree::Token(glued, *joint));
267-
} else {
268-
self.buf.push(tree)
269-
}
270-
}
271-
272-
fn into_token_stream(self) -> TokenStream {
273-
TokenStream::new(self.buf)
274-
}
275-
}

0 commit comments

Comments
 (0)