Merge #7059
7059: Special case $_ in meta var instead of treat it as ident in mbe r=lnicola a=edwin0cheng In #6929, we treat '_' as an ident but rustc is only allow it in some special places (e.g. meta var in mbe , type, pat etc). This PR rollback that and we only make '$_' works in meta var matching. Fixes #7056 Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
99ec2f623d
@ -101,8 +101,15 @@ fn next_op<'a>(
|
|||||||
Op::Repeat { subtree, separator, kind }
|
Op::Repeat { subtree, separator, kind }
|
||||||
}
|
}
|
||||||
tt::TokenTree::Leaf(leaf) => match leaf {
|
tt::TokenTree::Leaf(leaf) => match leaf {
|
||||||
tt::Leaf::Punct(_) => {
|
tt::Leaf::Punct(punct) => {
|
||||||
return Err(ExpandError::UnexpectedToken);
|
static UNDERSCORE: SmolStr = SmolStr::new_inline("_");
|
||||||
|
|
||||||
|
if punct.char != '_' {
|
||||||
|
return Err(ExpandError::UnexpectedToken);
|
||||||
|
}
|
||||||
|
let name = &UNDERSCORE;
|
||||||
|
let kind = eat_fragment_kind(src, mode)?;
|
||||||
|
Op::Var { name, kind }
|
||||||
}
|
}
|
||||||
tt::Leaf::Ident(ident) => {
|
tt::Leaf::Ident(ident) => {
|
||||||
let name = &ident.text;
|
let name = &ident.text;
|
||||||
|
@ -313,7 +313,7 @@ fn collect_leaf(&mut self, result: &mut Vec<tt::TokenTree>) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.push(if k.is_punct() && k != UNDERSCORE {
|
result.push(if k.is_punct() {
|
||||||
assert_eq!(range.len(), TextSize::of('.'));
|
assert_eq!(range.len(), TextSize::of('.'));
|
||||||
let delim = match k {
|
let delim = match k {
|
||||||
T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
|
T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
|
||||||
@ -378,7 +378,6 @@ macro_rules! make_leaf {
|
|||||||
let leaf: tt::Leaf = match k {
|
let leaf: tt::Leaf = match k {
|
||||||
T![true] | T![false] => make_leaf!(Ident),
|
T![true] | T![false] => make_leaf!(Ident),
|
||||||
IDENT => make_leaf!(Ident),
|
IDENT => make_leaf!(Ident),
|
||||||
UNDERSCORE => make_leaf!(Ident),
|
|
||||||
k if k.is_keyword() => make_leaf!(Ident),
|
k if k.is_keyword() => make_leaf!(Ident),
|
||||||
k if k.is_literal() => make_leaf!(Literal),
|
k if k.is_literal() => make_leaf!(Literal),
|
||||||
LIFETIME_IDENT => {
|
LIFETIME_IDENT => {
|
||||||
|
@ -1019,6 +1019,42 @@ macro_rules! foo {
|
|||||||
.assert_expand_items(r#"foo! { => }"#, r#"0"#);
|
.assert_expand_items(r#"foo! { => }"#, r#"0"#);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_underscore_not_greedily() {
|
||||||
|
parse_macro(
|
||||||
|
r#"
|
||||||
|
macro_rules! q {
|
||||||
|
($($a:ident)* _) => {0};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
// `_` overlaps with `$a:ident` but rustc matches it under the `_` token
|
||||||
|
.assert_expand_items(r#"q![a b c d _]"#, r#"0"#);
|
||||||
|
|
||||||
|
parse_macro(
|
||||||
|
r#"
|
||||||
|
macro_rules! q {
|
||||||
|
($($a:expr => $b:ident)* _ => $c:expr) => {0};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
// `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr`
|
||||||
|
.assert_expand_items(r#"q![a => b c => d _ => ou]"#, r#"0"#);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_underscore_as_type() {
|
||||||
|
parse_macro(
|
||||||
|
r#"
|
||||||
|
macro_rules! q {
|
||||||
|
($a:ty) => {0};
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
// Underscore is a type
|
||||||
|
.assert_expand_items(r#"q![_]"#, r#"0"#);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_vertical_bar_with_pat() {
|
fn test_vertical_bar_with_pat() {
|
||||||
parse_macro(
|
parse_macro(
|
||||||
|
Loading…
Reference in New Issue
Block a user