about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2019-08-08 18:24:00 -0700
committerEsteban Küber <esteban@kuber.com.ar>2019-08-09 08:20:13 -0700
commit7c96d90c2081f3ca84b3786a125cf2c415335e40 (patch)
tree7b9bc7f69a5a318efb6388ebd41eff8ae03fa1a9
parent813a3a5d4b2be4e2101faa73a067da02a704a598 (diff)
downloadrust-7c96d90c2081f3ca84b3786a125cf2c415335e40.tar.gz
rust-7c96d90c2081f3ca84b3786a125cf2c415335e40.zip
More explicit diagnostic when using a `vec![]` in a pattern
```
error: unexpected `(` after qualified path
  --> $DIR/vec-macro-in-pattern.rs:3:14
   |
LL |         Some(vec![x]) => (),
   |              ^^^^^^^
   |              |
   |              unexpected `(` after qualified path
   |              in this macro invocation
   |              use a slice pattern here instead
   |
   = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
```
-rw-r--r--src/libsyntax/ext/expand.rs28
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs23
-rw-r--r--src/test/ui/proc-macro/lifetimes.stderr2
-rw-r--r--src/test/ui/suggestions/vec-macro-in-pattern.rs6
-rw-r--r--src/test/ui/suggestions/vec-macro-in-pattern.stderr15
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr1
6 files changed, 68 insertions, 7 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 964c81dd466..36f059531d3 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -686,12 +686,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         );
     }
 
-    fn parse_ast_fragment(&mut self,
-                          toks: TokenStream,
-                          kind: AstFragmentKind,
-                          path: &Path,
-                          span: Span)
-                          -> AstFragment {
+    fn parse_ast_fragment(
+        &mut self,
+        toks: TokenStream,
+        kind: AstFragmentKind,
+        path: &Path,
+        span: Span,
+    ) -> AstFragment {
         let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
         match parser.parse_ast_fragment(kind, false) {
             Ok(fragment) => {
@@ -700,6 +701,21 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             }
             Err(mut err) => {
                 err.set_span(span);
+                match kind {
+                    AstFragmentKind::Ty => {
+                        err.span_label(
+                            span,
+                            "this macro call doesn't expand to a type",
+                        );
+                    }
+                    AstFragmentKind::Pat => {
+                        err.span_label(
+                            span,
+                            "this macro call doesn't expand to a pattern",
+                        );
+                    }
+                    _ => {}
+                };
                 err.emit();
                 self.cx.trace_macros_diag();
                 kind.dummy(span)
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 7401f256412..a9d0b739d6a 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -70,6 +70,29 @@ impl<'a> ParserAnyMacro<'a> {
             } else if !parser.sess.source_map().span_to_filename(parser.token.span).is_real() {
                 e.span_label(site_span, "in this macro invocation");
             }
+            match kind {
+                AstFragmentKind::Ty => {
+                    e.span_label(
+                        site_span,
+                        "this macro call doesn't expand to a type",
+                    );
+                }
+                AstFragmentKind::Pat if macro_ident.name == sym::vec => {
+                    e.span_label(
+                        site_span,
+                        "use a slice pattern here instead",
+                    );
+                    e.help("for more information, see https://doc.rust-lang.org/edition-guide/\
+                              rust-2018/slice-patterns.html");
+                }
+                AstFragmentKind::Pat => {
+                    e.span_label(
+                        site_span,
+                        "this macro call doesn't expand to a pattern",
+                    );
+                }
+                _ => {}
+            };
             e
         }));
 
diff --git a/src/test/ui/proc-macro/lifetimes.stderr b/src/test/ui/proc-macro/lifetimes.stderr
index 2356a119530..6e91201405c 100644
--- a/src/test/ui/proc-macro/lifetimes.stderr
+++ b/src/test/ui/proc-macro/lifetimes.stderr
@@ -2,7 +2,7 @@ error: expected type, found `'`
   --> $DIR/lifetimes.rs:9:10
    |
 LL | type A = single_quote_alone!();
-   |          ^^^^^^^^^^^^^^^^^^^^^
+   |          ^^^^^^^^^^^^^^^^^^^^^ this macro call doesn't expand to a type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.rs b/src/test/ui/suggestions/vec-macro-in-pattern.rs
new file mode 100644
index 00000000000..5c42a6bdbd4
--- /dev/null
+++ b/src/test/ui/suggestions/vec-macro-in-pattern.rs
@@ -0,0 +1,6 @@
+fn main() {
+    match Some(vec![3]) {
+        Some(vec![x]) => (), //~ ERROR unexpected `(` after qualified path
+        _ => (),
+    }
+}
diff --git a/src/test/ui/suggestions/vec-macro-in-pattern.stderr b/src/test/ui/suggestions/vec-macro-in-pattern.stderr
new file mode 100644
index 00000000000..f94cb93a520
--- /dev/null
+++ b/src/test/ui/suggestions/vec-macro-in-pattern.stderr
@@ -0,0 +1,15 @@
+error: unexpected `(` after qualified path
+  --> $DIR/vec-macro-in-pattern.rs:3:14
+   |
+LL |         Some(vec![x]) => (),
+   |              ^^^^^^^
+   |              |
+   |              unexpected `(` after qualified path
+   |              in this macro invocation
+   |              use a slice pattern here instead
+   |
+   = help: for more information, see https://doc.rust-lang.org/edition-guide/rust-2018/slice-patterns.html
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index 965bbe5ea41..2f052341fae 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -6,6 +6,7 @@ LL |     let _ = Option:Some(vec![0, 1]);
    |                   |     |
    |                   |     expected type
    |                   |     in this macro invocation
+   |                   |     this macro call doesn't expand to a type
    |                   help: maybe write a path separator here: `::`
    |
    = note: `#![feature(type_ascription)]` lets you annotate an expression with a type: `<expr>: <type>`