about summary refs log tree commit diff
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2018-10-26 18:25:03 +0800
committerkennytm <kennytm@gmail.com>2018-10-26 23:06:28 +0800
commitc6cd57dd860efbe0cb7506dfad93462bcb520d74 (patch)
tree3f744ab35258bbdd04afe712247a31e20cd6b521
parent9111fab74df4e0f6f2b8bfb5936f3772ba59a960 (diff)
parentf8818cbf8fc30ac626b2a0a306736c1293257209 (diff)
downloadrust-c6cd57dd860efbe0cb7506dfad93462bcb520d74.tar.gz
rust-c6cd57dd860efbe0cb7506dfad93462bcb520d74.zip
Rollup merge of #55292 - estebank:macro-eof, r=pnkfelix
Macro diagnostics tweaks

Fix #30128, fix #10951 by adding an appropriate span to the diagnostic.
Fix #26288 by suggesting adding semicolon to macro call.
-rw-r--r--src/libsyntax/ext/expand.rs26
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs7
-rw-r--r--src/libsyntax_pos/lib.rs11
-rw-r--r--src/test/ui/issues/issue-30007.stderr9
-rw-r--r--src/test/ui/macros/macro-context.stderr27
-rw-r--r--src/test/ui/macros/macro-in-expression-context-2.rs7
-rw-r--r--src/test/ui/macros/macro-in-expression-context-2.stderr8
-rw-r--r--src/test/ui/macros/macro-in-expression-context.fixed15
-rw-r--r--src/test/ui/macros/macro-in-expression-context.rs15
-rw-r--r--src/test/ui/macros/macro-in-expression-context.stderr15
-rw-r--r--src/test/ui/parser/macro/macro-incomplete-parse.stderr18
11 files changed, 123 insertions, 35 deletions
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 9e06384f5a8..4deeb4a43d9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1036,10 +1036,28 @@ impl<'a> Parser<'a> {
             // Avoid emitting backtrace info twice.
             let def_site_span = self.span.with_ctxt(SyntaxContext::empty());
             let mut err = self.diagnostic().struct_span_err(def_site_span, &msg);
-            let msg = format!("caused by the macro expansion here; the usage \
-                               of `{}!` is likely invalid in {} context",
-                               macro_path, kind_name);
-            err.span_note(span, &msg).emit();
+            err.span_label(span, "caused by the macro expansion here");
+            let msg = format!(
+                "the usage of `{}!` is likely invalid in {} context",
+                macro_path,
+                kind_name,
+            );
+            err.note(&msg);
+            let semi_span = self.sess.source_map().next_point(span);
+
+            let semi_full_span = semi_span.to(self.sess.source_map().next_point(semi_span));
+            match self.sess.source_map().span_to_snippet(semi_full_span) {
+                Ok(ref snippet) if &snippet[..] != ";" && kind_name == "expression" => {
+                    err.span_suggestion_with_applicability(
+                        semi_span,
+                        "you might be missing a semicolon here",
+                        ";".to_owned(),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
+                _ => {}
+            }
+            err.emit();
         }
     }
 }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 805aa9bef22..5e53b8b99c7 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -50,7 +50,12 @@ pub struct ParserAnyMacro<'a> {
 impl<'a> ParserAnyMacro<'a> {
     pub fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser } = *self;
-        let fragment = panictry!(parser.parse_ast_fragment(kind, true));
+        let fragment = panictry!(parser.parse_ast_fragment(kind, true).map_err(|mut e| {
+            if e.span.is_dummy() {  // Get around lack of span in error (#30128)
+                e.set_span(site_span);
+            }
+            e
+        }));
 
         // We allow semicolons at the end of expressions -- e.g. the semicolon in
         // `macro_rules! m { () => { panic!(); } }` isn't parsed by `.parse_expr()`,
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index 45eaf1d3190..639155636ed 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -612,6 +612,17 @@ impl MultiSpan {
         &self.primary_spans
     }
 
+    /// Returns `true` if this contains only a dummy primary span with any hygienic context.
+    pub fn is_dummy(&self) -> bool {
+        let mut is_dummy = true;
+        for span in &self.primary_spans {
+            if !span.is_dummy() {
+                is_dummy = false;
+            }
+        }
+        is_dummy
+    }
+
     /// Replaces all occurrences of one Span with another. Used to move Spans in areas that don't
     /// display well (like std macros). Returns true if replacements occurred.
     pub fn replace(&mut self, before: Span, after: Span) -> bool {
diff --git a/src/test/ui/issues/issue-30007.stderr b/src/test/ui/issues/issue-30007.stderr
index a467ff6dd0a..028ed048d65 100644
--- a/src/test/ui/issues/issue-30007.stderr
+++ b/src/test/ui/issues/issue-30007.stderr
@@ -3,12 +3,11 @@ error: macro expansion ignores token `;` and any following
    |
 LL |     () => ( String ; );     //~ ERROR macro expansion ignores token `;`
    |                    ^
-   |
-note: caused by the macro expansion here; the usage of `t!` is likely invalid in type context
-  --> $DIR/issue-30007.rs:16:16
-   |
+...
 LL |     let i: Vec<t!()>;
-   |                ^^^^
+   |                ---- caused by the macro expansion here
+   |
+   = note: the usage of `t!` is likely invalid in type context
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index b3e67fb2607..005e1d1c8e7 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -3,36 +3,33 @@ error: macro expansion ignores token `;` and any following
    |
 LL |     () => ( i ; typeof );   //~ ERROR expected expression, found reserved keyword `typeof`
    |               ^
-   |
-note: caused by the macro expansion here; the usage of `m!` is likely invalid in type context
-  --> $DIR/macro-context.rs:20:12
-   |
+...
 LL |     let a: m!();
-   |            ^^^^
+   |            ---- caused by the macro expansion here
+   |
+   = note: the usage of `m!` is likely invalid in type context
 
 error: macro expansion ignores token `typeof` and any following
   --> $DIR/macro-context.rs:13:17
    |
 LL |     () => ( i ; typeof );   //~ ERROR expected expression, found reserved keyword `typeof`
    |                 ^^^^^^
-   |
-note: caused by the macro expansion here; the usage of `m!` is likely invalid in expression context
-  --> $DIR/macro-context.rs:21:13
-   |
+...
 LL |     let i = m!();
-   |             ^^^^
+   |             ---- caused by the macro expansion here
+   |
+   = note: the usage of `m!` is likely invalid in expression context
 
 error: macro expansion ignores token `;` and any following
   --> $DIR/macro-context.rs:13:15
    |
 LL |     () => ( i ; typeof );   //~ ERROR expected expression, found reserved keyword `typeof`
    |               ^
-   |
-note: caused by the macro expansion here; the usage of `m!` is likely invalid in pattern context
-  --> $DIR/macro-context.rs:23:9
-   |
+...
 LL |         m!() => {}
-   |         ^^^^
+   |         ---- caused by the macro expansion here
+   |
+   = note: the usage of `m!` is likely invalid in pattern context
 
 error: expected expression, found reserved keyword `typeof`
   --> $DIR/macro-context.rs:13:17
diff --git a/src/test/ui/macros/macro-in-expression-context-2.rs b/src/test/ui/macros/macro-in-expression-context-2.rs
new file mode 100644
index 00000000000..cf8572aefa2
--- /dev/null
+++ b/src/test/ui/macros/macro-in-expression-context-2.rs
@@ -0,0 +1,7 @@
+macro_rules! empty { () => () }
+
+fn main() {
+    match 42 {
+        _ => { empty!() }
+    };
+}
diff --git a/src/test/ui/macros/macro-in-expression-context-2.stderr b/src/test/ui/macros/macro-in-expression-context-2.stderr
new file mode 100644
index 00000000000..80d5dbd66cc
--- /dev/null
+++ b/src/test/ui/macros/macro-in-expression-context-2.stderr
@@ -0,0 +1,8 @@
+error: expected expression, found `<eof>`
+  --> $DIR/macro-in-expression-context-2.rs:5:16
+   |
+LL |         _ => { empty!() }
+   |                ^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/macros/macro-in-expression-context.fixed b/src/test/ui/macros/macro-in-expression-context.fixed
new file mode 100644
index 00000000000..df36db0f49e
--- /dev/null
+++ b/src/test/ui/macros/macro-in-expression-context.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+macro_rules! foo {
+    () => {
+        assert_eq!("A", "A");
+        assert_eq!("B", "B");
+    }
+    //~^^ ERROR macro expansion ignores token `assert_eq` and any following
+    //~| NOTE the usage of `foo!` is likely invalid in expression context
+}
+
+fn main() {
+    foo!();
+    //~^ NOTE caused by the macro expansion here
+}
diff --git a/src/test/ui/macros/macro-in-expression-context.rs b/src/test/ui/macros/macro-in-expression-context.rs
new file mode 100644
index 00000000000..b3f5e568967
--- /dev/null
+++ b/src/test/ui/macros/macro-in-expression-context.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+
+macro_rules! foo {
+    () => {
+        assert_eq!("A", "A");
+        assert_eq!("B", "B");
+    }
+    //~^^ ERROR macro expansion ignores token `assert_eq` and any following
+    //~| NOTE the usage of `foo!` is likely invalid in expression context
+}
+
+fn main() {
+    foo!()
+    //~^ NOTE caused by the macro expansion here
+}
diff --git a/src/test/ui/macros/macro-in-expression-context.stderr b/src/test/ui/macros/macro-in-expression-context.stderr
new file mode 100644
index 00000000000..d27d6fbaef7
--- /dev/null
+++ b/src/test/ui/macros/macro-in-expression-context.stderr
@@ -0,0 +1,15 @@
+error: macro expansion ignores token `assert_eq` and any following
+  --> $DIR/macro-in-expression-context.rs:6:9
+   |
+LL |         assert_eq!("B", "B");
+   |         ^^^^^^^^^
+...
+LL |     foo!()
+   |     ------- help: you might be missing a semicolon here: `;`
+   |     |
+   |     caused by the macro expansion here
+   |
+   = note: the usage of `foo!` is likely invalid in expression context
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/parser/macro/macro-incomplete-parse.stderr b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
index 198730dc07a..806aca511d0 100644
--- a/src/test/ui/parser/macro/macro-incomplete-parse.stderr
+++ b/src/test/ui/parser/macro/macro-incomplete-parse.stderr
@@ -3,12 +3,11 @@ error: macro expansion ignores token `,` and any following
    |
 LL |         , //~ ERROR macro expansion ignores token `,`
    |         ^
-   |
-note: caused by the macro expansion here; the usage of `ignored_item!` is likely invalid in item context
-  --> $DIR/macro-incomplete-parse.rs:31:1
-   |
+...
 LL | ignored_item!();
-   | ^^^^^^^^^^^^^^^^
+   | ---------------- caused by the macro expansion here
+   |
+   = note: the usage of `ignored_item!` is likely invalid in item context
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `,`
   --> $DIR/macro-incomplete-parse.rs:22:14
@@ -24,12 +23,11 @@ error: macro expansion ignores token `,` and any following
    |
 LL |     () => ( 1, 2 ) //~ ERROR macro expansion ignores token `,`
    |              ^
-   |
-note: caused by the macro expansion here; the usage of `ignored_pat!` is likely invalid in pattern context
-  --> $DIR/macro-incomplete-parse.rs:36:9
-   |
+...
 LL |         ignored_pat!() => (),
-   |         ^^^^^^^^^^^^^^
+   |         -------------- caused by the macro expansion here
+   |
+   = note: the usage of `ignored_pat!` is likely invalid in pattern context
 
 error: aborting due to 3 previous errors