about summary refs log tree commit diff
path: root/src/libsyntax
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 /src/libsyntax
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.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ext/expand.rs26
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs7
2 files changed, 28 insertions, 5 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()`,