Skip to content

Commit b480366

Browse files
committed
Rollup merge of rust-lang#47343 - goffrie:master, r=jseyfried
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 `...`. r? @jseyfried
2 parents cf70a48 + 2e0ad5a commit b480366

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)