about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-10-23 10:07:11 -0700
committerEsteban Küber <esteban@kuber.com.ar>2018-10-23 10:07:11 -0700
commit8544db0faa9e0f7a70323ad5f3e75358bba6820d (patch)
treeb4c546213efb548d9bc6cbb71b63ccd66aa2ae30
parenta66dc8a1489d2818b5e63f18e1464be79da1f137 (diff)
downloadrust-8544db0faa9e0f7a70323ad5f3e75358bba6820d.tar.gz
rust-8544db0faa9e0f7a70323ad5f3e75358bba6820d.zip
Add macro call span when lacking any other span in diagnostic
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs7
-rw-r--r--src/libsyntax_pos/lib.rs11
-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
4 files changed, 32 insertions, 1 deletions
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 87ade278c68..b70a7989275 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/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
+