Op::Repeat { subtree, separator, kind }
}
tt::TokenTree::Leaf(leaf) => match leaf {
- tt::Leaf::Punct(_) => {
- return Err(ExpandError::UnexpectedToken);
+ tt::Leaf::Punct(punct) => {
+ 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) => {
let name = &ident.text;
return;
}
- result.push(if k.is_punct() && k != UNDERSCORE {
+ result.push(if k.is_punct() {
assert_eq!(range.len(), TextSize::of('.'));
let delim = match k {
T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
let leaf: tt::Leaf = match k {
T![true] | T![false] => make_leaf!(Ident),
IDENT => make_leaf!(Ident),
- UNDERSCORE => make_leaf!(Ident),
k if k.is_keyword() => make_leaf!(Ident),
k if k.is_literal() => make_leaf!(Literal),
LIFETIME_IDENT => {
.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]
fn test_vertical_bar_with_pat() {
parse_macro(
Avoid @mentioning people in commit messages and pull request descriptions(they are added to commit message by bors).
Such messages create a lot of duplicate notification traffic during rebases.
+If possible, write commit messages from user's perspective:
+
+```
+# Good
+Goto definition works inside macros
+
+# Not as good
+Use original span for FileId
+```
+
+This makes it easier to prepare a changelog.
+
## Clippy
We don't enforce Clippy.