mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-01 19:23:50 +00:00
Fix #3436
This commit is contained in:
parent
e76dddd610
commit
028595548b
@ -181,13 +181,9 @@ pub(crate) fn parse_macro(
|
|||||||
err,
|
err,
|
||||||
node.value
|
node.value
|
||||||
);
|
);
|
||||||
|
let mut parent = loc.kind.file_id().call_node(db);
|
||||||
let mut parent = loc.kind.file_id().call_node(db);
|
|
||||||
while let Some(node) = parent.clone() {
|
while let Some(node) = parent.clone() {
|
||||||
log::warn!(
|
log::warn!("parent: macro_call: {:#})", node.value);
|
||||||
"parent: macro_call: {:#})",
|
|
||||||
node.value
|
|
||||||
);
|
|
||||||
parent = node.file_id.call_node(db);
|
parent = node.file_id.call_node(db);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,6 +155,60 @@ impl<'a> TtIter<'a> {
|
|||||||
ok
|
ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn expect_tt(&mut self) -> Result<tt::TokenTree, ()> {
|
||||||
|
let tt = self.next().ok_or_else(|| ())?.clone();
|
||||||
|
let punct = match tt {
|
||||||
|
tt::TokenTree::Leaf(tt::Leaf::Punct(punct)) if punct.spacing == tt::Spacing::Joint => {
|
||||||
|
punct
|
||||||
|
}
|
||||||
|
_ => return Ok(tt),
|
||||||
|
};
|
||||||
|
|
||||||
|
let (second, third) = match (self.peek_n(0), self.peek_n(1)) {
|
||||||
|
(
|
||||||
|
Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p2))),
|
||||||
|
Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p3))),
|
||||||
|
) if p2.spacing == tt::Spacing::Joint => (p2.char, Some(p3.char)),
|
||||||
|
(Some(tt::TokenTree::Leaf(tt::Leaf::Punct(p2))), _) => (p2.char, None),
|
||||||
|
_ => return Ok(tt),
|
||||||
|
};
|
||||||
|
|
||||||
|
match (punct.char, second, third) {
|
||||||
|
('.', '.', Some('.'))
|
||||||
|
| ('.', '.', Some('='))
|
||||||
|
| ('<', '<', Some('='))
|
||||||
|
| ('>', '>', Some('=')) => {
|
||||||
|
let tt2 = self.next().unwrap().clone();
|
||||||
|
let tt3 = self.next().unwrap().clone();
|
||||||
|
Ok(tt::Subtree { delimiter: None, token_trees: vec![tt, tt2, tt3] }.into())
|
||||||
|
}
|
||||||
|
('-', '=', None)
|
||||||
|
| ('-', '>', None)
|
||||||
|
| (':', ':', None)
|
||||||
|
| ('!', '=', None)
|
||||||
|
| ('.', '.', None)
|
||||||
|
| ('*', '=', None)
|
||||||
|
| ('/', '=', None)
|
||||||
|
| ('&', '&', None)
|
||||||
|
| ('&', '=', None)
|
||||||
|
| ('%', '=', None)
|
||||||
|
| ('^', '=', None)
|
||||||
|
| ('+', '=', None)
|
||||||
|
| ('<', '<', None)
|
||||||
|
| ('<', '=', None)
|
||||||
|
| ('=', '=', None)
|
||||||
|
| ('=', '>', None)
|
||||||
|
| ('>', '=', None)
|
||||||
|
| ('>', '>', None)
|
||||||
|
| ('|', '=', None)
|
||||||
|
| ('|', '|', None) => {
|
||||||
|
let tt2 = self.next().unwrap().clone();
|
||||||
|
Ok(tt::Subtree { delimiter: None, token_trees: vec![tt.clone(), tt2] }.into())
|
||||||
|
}
|
||||||
|
_ => Ok(tt),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn expect_lifetime(&mut self) -> Result<&tt::Ident, ()> {
|
pub(crate) fn expect_lifetime(&mut self) -> Result<&tt::Ident, ()> {
|
||||||
let ident = self.expect_ident()?;
|
let ident = self.expect_ident()?;
|
||||||
// check if it start from "`"
|
// check if it start from "`"
|
||||||
@ -302,7 +356,7 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> Result<Option<Fragment>, Ex
|
|||||||
let ident = input.expect_ident().map_err(|()| err!("expected ident"))?.clone();
|
let ident = input.expect_ident().map_err(|()| err!("expected ident"))?.clone();
|
||||||
tt::Leaf::from(ident).into()
|
tt::Leaf::from(ident).into()
|
||||||
}
|
}
|
||||||
"tt" => input.next().ok_or_else(|| err!())?.clone(),
|
"tt" => input.expect_tt().map_err(|()| err!())?.clone(),
|
||||||
"lifetime" => {
|
"lifetime" => {
|
||||||
let ident = input.expect_lifetime().map_err(|()| err!())?;
|
let ident = input.expect_lifetime().map_err(|()| err!())?;
|
||||||
tt::Leaf::Ident(ident.clone()).into()
|
tt::Leaf::Ident(ident.clone()).into()
|
||||||
|
@ -825,6 +825,19 @@ fn test_tt_group() {
|
|||||||
)
|
)
|
||||||
.assert_expand_items(r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#);
|
.assert_expand_items(r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tt_composite() {
|
||||||
|
parse_macro(
|
||||||
|
r#"
|
||||||
|
macro_rules! foo {
|
||||||
|
($i:tt) => { 0 }
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.assert_expand_items(r#"foo! { => }"#, r#"0"#);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_lifetime() {
|
fn test_lifetime() {
|
||||||
parse_macro(
|
parse_macro(
|
||||||
|
@ -53,6 +53,10 @@ impl<'a> TtIter<'a> {
|
|||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn peek_n(&self, n: usize) -> Option<&tt::TokenTree> {
|
||||||
|
self.inner.as_slice().get(n)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for TtIter<'a> {
|
impl<'a> Iterator for TtIter<'a> {
|
||||||
|
Loading…
Reference in New Issue
Block a user