Skip to content

Commit 2e0ad5a

Browse files
committed
Glued tokens can themselves be joint.
When gluing two tokens, the second of which is joint, the result should also be joint. This fixes an issue with joining three `Dot` tokens to make a `DotDotDot` - the intermediate `DotDot` would not be joint and therefore we would not attempt to glue the last `Dot` token, yielding `.. .` instead of `...`.
1 parent f62f774 commit 2e0ad5a

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

src/libsyntax/tokenstream.rs

+24-6
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,12 @@ impl TokenStream {
286286
TokenStream::concat(result)
287287
}
288288

289-
fn first_tree(&self) -> Option<TokenTree> {
289+
fn first_tree_and_joint(&self) -> Option<(TokenTree, bool)> {
290290
match self.kind {
291291
TokenStreamKind::Empty => None,
292-
TokenStreamKind::Tree(ref tree) |
293-
TokenStreamKind::JointTree(ref tree) => Some(tree.clone()),
294-
TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree(),
292+
TokenStreamKind::Tree(ref tree) => Some((tree.clone(), false)),
293+
TokenStreamKind::JointTree(ref tree) => Some((tree.clone(), true)),
294+
TokenStreamKind::Stream(ref stream) => stream.first().unwrap().first_tree_and_joint(),
295295
}
296296
}
297297

@@ -315,12 +315,18 @@ impl TokenStreamBuilder {
315315
let stream = stream.into();
316316
let last_tree_if_joint = self.0.last().and_then(TokenStream::last_tree_if_joint);
317317
if let Some(TokenTree::Token(last_span, last_tok)) = last_tree_if_joint {
318-
if let Some(TokenTree::Token(span, tok)) = stream.first_tree() {
318+
if let Some((TokenTree::Token(span, tok), is_joint)) = stream.first_tree_and_joint() {
319319
if let Some(glued_tok) = last_tok.glue(tok) {
320320
let last_stream = self.0.pop().unwrap();
321321
self.push_all_but_last_tree(&last_stream);
322322
let glued_span = last_span.to(span);
323-
self.0.push(TokenTree::Token(glued_span, glued_tok).into());
323+
let glued_tt = TokenTree::Token(glued_span, glued_tok);
324+
let glued_tokenstream = if is_joint {
325+
glued_tt.joint()
326+
} else {
327+
glued_tt.into()
328+
};
329+
self.0.push(glued_tokenstream);
324330
self.push_all_but_first_tree(&stream);
325331
return
326332
}
@@ -669,4 +675,16 @@ mod tests {
669675
assert_eq!(test1.is_empty(), false);
670676
assert_eq!(test2.is_empty(), false);
671677
}
678+
679+
#[test]
680+
fn test_dotdotdot() {
681+
let mut builder = TokenStreamBuilder::new();
682+
builder.push(TokenTree::Token(sp(0, 1), Token::Dot).joint());
683+
builder.push(TokenTree::Token(sp(1, 2), Token::Dot).joint());
684+
builder.push(TokenTree::Token(sp(2, 3), Token::Dot));
685+
let stream = builder.build();
686+
assert!(stream.eq_unspanned(&string_to_ts("...")));
687+
assert_eq!(stream.trees().count(), 1);
688+
}
689+
672690
}

0 commit comments

Comments
 (0)