about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2019-03-16 14:56:39 +0800
committerkennytm <kennytm@gmail.com>2019-03-16 22:39:49 +0800
commit6fbd55385d588486ed992bfd07f2ff731d6af682 (patch)
tree3c4d54619de9b6613659bab409dbb98150eebd6c /src
parent0e57b7230d69a529b11d9deb423cb53ba028eba0 (diff)
parent5abd6d9492e8a5a4592bca4c18e1de6104b1ea51 (diff)
downloadrust-6fbd55385d588486ed992bfd07f2ff731d6af682.tar.gz
rust-6fbd55385d588486ed992bfd07f2ff731d6af682.zip
Rollup merge of #59079 - euclio:macro-semi, r=estebank
add suggestions to invalid macro item error

r? @estebank
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs45
-rw-r--r--src/test/ui/issues/issue-10536.rs2
-rw-r--r--src/test/ui/issues/issue-10536.stderr10
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.rs11
-rw-r--r--src/test/ui/parser/macros-no-semicolon-items.stderr41
5 files changed, 85 insertions, 24 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index fe31311094b..22af7d47fd0 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> {
 
                 let ident = self.parse_ident()?;
                 let (delim, tokens) = self.expect_delimited_token_tree()?;
-                if delim != MacDelimiter::Brace {
-                    if !self.eat(&token::Semi) {
-                        let msg = "macros that expand to items must either \
-                                   be surrounded with braces or followed by a semicolon";
-                        self.span_err(self.prev_span, msg);
-                    }
+                if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+                    self.report_invalid_macro_expansion_item();
                 }
 
                 (ident, ast::MacroDef { tokens: tokens, legacy: true })
@@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> {
                 // if it has a special ident, it's definitely an item
                 //
                 // Require a semicolon or braces.
-                if style != MacStmtStyle::Braces {
-                    if !self.eat(&token::Semi) {
-                        self.span_err(self.prev_span,
-                                      "macros that expand to items must \
-                                       either be surrounded with braces or \
-                                       followed by a semicolon");
-                    }
+                if style != MacStmtStyle::Braces && !self.eat(&token::Semi) {
+                    self.report_invalid_macro_expansion_item();
                 }
                 let span = lo.to(hi);
                 Stmt {
@@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> {
             };
             // eat a matched-delimiter token tree:
             let (delim, tts) = self.expect_delimited_token_tree()?;
-            if delim != MacDelimiter::Brace {
-                if !self.eat(&token::Semi) {
-                    self.span_err(self.prev_span,
-                                  "macros that expand to items must either \
-                                   be surrounded with braces or followed by \
-                                   a semicolon");
-                }
+            if delim != MacDelimiter::Brace && !self.eat(&token::Semi) {
+                self.report_invalid_macro_expansion_item();
             }
 
             let hi = self.prev_span;
@@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> {
             }
         }
     }
+
+    fn report_invalid_macro_expansion_item(&self) {
+        self.struct_span_err(
+            self.prev_span,
+            "macros that expand to items must be delimited with braces or followed by a semicolon",
+        ).multipart_suggestion(
+            "change the delimiters to curly braces",
+            vec![
+                (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")),
+                (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()),
+            ],
+            Applicability::MaybeIncorrect,
+        ).span_suggestion(
+            self.sess.source_map.next_point(self.prev_span),
+            "add a semicolon",
+            ';'.to_string(),
+            Applicability::MaybeIncorrect,
+        ).emit();
+    }
 }
 
 pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs
index 95c8c2b0585..ceb44ecf7f5 100644
--- a/src/test/ui/issues/issue-10536.rs
+++ b/src/test/ui/issues/issue-10536.rs
@@ -12,7 +12,7 @@ pub fn main() {
     foo!();
 
     assert!({one! two()});
-    //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a
+    //~^ ERROR macros that expand to items
     //~| ERROR cannot find macro `one!` in this scope
     //~| ERROR mismatched types
 
diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr
index d5caf777cd4..584cdf43a8f 100644
--- a/src/test/ui/issues/issue-10536.stderr
+++ b/src/test/ui/issues/issue-10536.stderr
@@ -1,8 +1,16 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
   --> $DIR/issue-10536.rs:14:22
    |
 LL |     assert!({one! two()});
    |                      ^^
+help: change the delimiters to curly braces
+   |
+LL |     assert!({one! two {}});
+   |                       ^^
+help: add a semicolon
+   |
+LL |     assert!({one! two();});
+   |                        ^
 
 error: expected `(` or `{`, found `}`
   --> $DIR/issue-10536.rs:21:22
diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs
index a727cafcab0..3afc275d61a 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.rs
+++ b/src/test/ui/parser/macros-no-semicolon-items.rs
@@ -1,4 +1,15 @@
 macro_rules! foo()  //~ ERROR semicolon
+                    //~| ERROR unexpected end of macro
+
+macro_rules! bar {
+    ($($tokens:tt)*) => {}
+}
+
+bar!( //~ ERROR semicolon
+    blah
+    blah
+    blah
+)
 
 fn main() {
 }
diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr
index a869a53c1ee..5276aa6f5e9 100644
--- a/src/test/ui/parser/macros-no-semicolon-items.stderr
+++ b/src/test/ui/parser/macros-no-semicolon-items.stderr
@@ -1,8 +1,45 @@
-error: macros that expand to items must either be surrounded with braces or followed by a semicolon
+error: macros that expand to items must be delimited with braces or followed by a semicolon
   --> $DIR/macros-no-semicolon-items.rs:1:17
    |
 LL | macro_rules! foo()
    |                 ^^
+help: change the delimiters to curly braces
+   |
+LL | macro_rules! foo {}
+   |                  ^^
+help: add a semicolon
+   |
+LL | macro_rules! foo();
+   |                   ^
+
+error: macros that expand to items must be delimited with braces or followed by a semicolon
+  --> $DIR/macros-no-semicolon-items.rs:8:5
+   |
+LL |   bar!(
+   |  _____^
+LL | |     blah
+LL | |     blah
+LL | |     blah
+LL | | )
+   | |_^
+help: change the delimiters to curly braces
+   |
+LL | bar! {
+LL |     blah
+LL |     blah
+LL |     blah
+LL | }
+   |
+help: add a semicolon
+   |
+LL | );
+   |  ^
+
+error: unexpected end of macro invocation
+  --> $DIR/macros-no-semicolon-items.rs:1:1
+   |
+LL | macro_rules! foo()
+   | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors