]> git.lizzy.rs Git - rust.git/commitdiff
Merge #7060
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Mon, 28 Dec 2020 12:34:19 +0000 (12:34 +0000)
committerGitHub <noreply@github.com>
Mon, 28 Dec 2020 12:34:19 +0000 (12:34 +0000)
7060: Fix mbe fail to pass expr with attr r=edwin0cheng a=edwin0cheng

bors r+

Fixes #5896

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
crates/mbe/src/parser.rs
crates/mbe/src/syntax_bridge.rs
crates/mbe/src/tests.rs
docs/dev/style.md

index c3fdd40404894e5009e4fd33c70fb39a41060482..d681905f5728f1b093c0ca88763edc2edfb1353c 100644 (file)
@@ -101,8 +101,15 @@ fn next_op<'a>(
                     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;
index 2bec7fd495b27673363c558d85bc3ffe06e6cca9..265c0d63d85c6dbd67b13fc240c4142f94567468 100644 (file)
@@ -313,7 +313,7 @@ fn collect_leaf(&mut self, result: &mut Vec<tt::TokenTree>) {
             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![')'])),
@@ -378,7 +378,6 @@ macro_rules! make_leaf {
             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 => {
index 0147506c79f2b550e3c971f538a5d2998cdb2722..1d9afb4fb8a1b236190380801377dc3ae647ce0c 100644 (file)
@@ -1031,6 +1031,42 @@ macro_rules! foo {
     .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(
index 13c6a2a167bab6f9d71e79f1cb224e54a011f6c8..58b30937988331d830883713154026143e461e4f 100644 (file)
@@ -63,6 +63,18 @@ After you are happy with the state of the code, please use [interactive rebase](
 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.