mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 01:17:27 +00:00
Fix TokenStream::from_str for input consisting of a single Group
TokenStream holds a `tt::Subtree` but assumes its `delimiter` is always `None`. In particular, the iterator implementation iterates over the inner `token_trees` and ignores the `delimiter`. However, `TokenStream::from_str` violated this assumption when the input consists of a single Group by producing a Subtree with an outer delimiter, which was ignored as seen by a procedural macro. In this case, wrap an extra level of Subtree around it. Fixes #7810 Fixes #7875
This commit is contained in:
parent
750d3cb846
commit
632fa8ef4a
1 changed files with 34 additions and 2 deletions
|
@ -34,7 +34,16 @@ impl TokenStream {
|
|||
}
|
||||
|
||||
pub fn with_subtree(subtree: tt::Subtree) -> Self {
|
||||
TokenStream { subtree }
|
||||
if subtree.delimiter.is_some() {
|
||||
TokenStream {
|
||||
subtree: tt::Subtree {
|
||||
token_trees: vec![TokenTree::Subtree(subtree)],
|
||||
delimiter: None,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
TokenStream { subtree }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
|
@ -185,7 +194,7 @@ pub mod token_stream {
|
|||
mbe::parse_to_token_tree(src).ok_or("Failed to parse from mbe")?;
|
||||
|
||||
let subtree = subtree_replace_token_ids_with_unspecified(subtree);
|
||||
Ok(TokenStream { subtree })
|
||||
Ok(TokenStream::with_subtree(subtree))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,4 +788,27 @@ mod tests {
|
|||
|
||||
assert_eq!(s.to_string(), "struct T {}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_rustc_server_from_str() {
|
||||
use std::str::FromStr;
|
||||
let subtree_paren_a = tt::TokenTree::Subtree(tt::Subtree {
|
||||
delimiter: Some(tt::Delimiter {
|
||||
id: tt::TokenId::unspecified(),
|
||||
kind: tt::DelimiterKind::Parenthesis,
|
||||
}),
|
||||
token_trees: vec![tt::TokenTree::Leaf(tt::Leaf::Ident(tt::Ident {
|
||||
text: "a".into(),
|
||||
id: tt::TokenId::unspecified(),
|
||||
}))],
|
||||
});
|
||||
|
||||
let t1 = TokenStream::from_str("(a)").unwrap();
|
||||
assert_eq!(t1.subtree.token_trees.len(), 1);
|
||||
assert_eq!(t1.subtree.token_trees[0], subtree_paren_a);
|
||||
|
||||
let t2 = TokenStream::from_str("(a);").unwrap();
|
||||
assert_eq!(t2.subtree.token_trees.len(), 2);
|
||||
assert_eq!(t2.subtree.token_trees[0], subtree_paren_a);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue