about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2020-03-17 08:55:28 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2020-03-24 06:28:10 +0100
commit0a8db690a4cffc687bddcaabc762e3e8746adec6 (patch)
treee8b1363e160934b6356bf3822d63ba48cf7025bd
parent0f2d9686ccbb67ce23e6acf587c5d1395288dc00 (diff)
downloadrust-0a8db690a4cffc687bddcaabc762e3e8746adec6.tar.gz
rust-0a8db690a4cffc687bddcaabc762e3e8746adec6.zip
nix panictry! in ParserAnyMacro::make
-rw-r--r--src/librustc_expand/expand.rs2
-rw-r--r--src/librustc_expand/mbe/macro_rules.rs77
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.rs8
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr22
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.rs8
-rw-r--r--src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr22
-rw-r--r--src/test/ui/macros/macro-context.rs2
-rw-r--r--src/test/ui/macros/macro-context.stderr26
-rw-r--r--src/test/ui/type/ascription/issue-47666.rs2
-rw-r--r--src/test/ui/type/ascription/issue-47666.stderr32
10 files changed, 153 insertions, 48 deletions
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 4f568e5456c..58217d98986 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -204,7 +204,7 @@ ast_fragments! {
 }
 
 impl AstFragmentKind {
-    fn dummy(self, span: Span) -> AstFragment {
+    crate fn dummy(self, span: Span) -> AstFragment {
         self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
     }
 
diff --git a/src/librustc_expand/mbe/macro_rules.rs b/src/librustc_expand/mbe/macro_rules.rs
index b6b69400bad..3c619c62c2b 100644
--- a/src/librustc_expand/mbe/macro_rules.rs
+++ b/src/librustc_expand/mbe/macro_rules.rs
@@ -83,41 +83,56 @@ fn suggest_slice_pat(e: &mut DiagnosticBuilder<'_>, site_span: Span, parser: &Pa
     );
 }
 
+fn emit_frag_parse_err(
+    mut e: DiagnosticBuilder<'_>,
+    parser: &Parser<'_>,
+    site_span: Span,
+    macro_ident: ast::Ident,
+    arm_span: Span,
+    kind: AstFragmentKind,
+) {
+    if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
+        if !e.span.is_dummy() {
+            // early end of macro arm (#52866)
+            e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
+        }
+        let msg = &e.message[0];
+        e.message[0] = (
+            format!(
+                "macro expansion ends with an incomplete expression: {}",
+                msg.0.replace(", found `<eof>`", ""),
+            ),
+            msg.1,
+        );
+    }
+    if e.span.is_dummy() {
+        // Get around lack of span in error (#30128)
+        e.replace_span_with(site_span);
+        if !parser.sess.source_map().is_imported(arm_span) {
+            e.span_label(arm_span, "in this macro arm");
+        }
+    } else if parser.sess.source_map().is_imported(parser.token.span) {
+        e.span_label(site_span, "in this macro invocation");
+    }
+    match kind {
+        AstFragmentKind::Pat if macro_ident.name == sym::vec => {
+            suggest_slice_pat(&mut e, site_span, parser);
+        }
+        _ => annotate_err_with_kind(&mut e, kind, site_span),
+    };
+    e.emit();
+}
+
 impl<'a> ParserAnyMacro<'a> {
     crate fn make(mut self: Box<ParserAnyMacro<'a>>, kind: AstFragmentKind) -> AstFragment {
         let ParserAnyMacro { site_span, macro_ident, ref mut parser, arm_span } = *self;
-        let fragment = panictry!(parse_ast_fragment(parser, kind).map_err(|mut e| {
-            if parser.token == token::Eof && e.message().ends_with(", found `<eof>`") {
-                if !e.span.is_dummy() {
-                    // early end of macro arm (#52866)
-                    e.replace_span_with(parser.sess.source_map().next_point(parser.token.span));
-                }
-                let msg = &e.message[0];
-                e.message[0] = (
-                    format!(
-                        "macro expansion ends with an incomplete expression: {}",
-                        msg.0.replace(", found `<eof>`", ""),
-                    ),
-                    msg.1,
-                );
+        let fragment = match parse_ast_fragment(parser, kind) {
+            Ok(f) => f,
+            Err(err) => {
+                emit_frag_parse_err(err, parser, site_span, macro_ident, arm_span, kind);
+                return kind.dummy(site_span);
             }
-            if e.span.is_dummy() {
-                // Get around lack of span in error (#30128)
-                e.replace_span_with(site_span);
-                if !parser.sess.source_map().is_imported(arm_span) {
-                    e.span_label(arm_span, "in this macro arm");
-                }
-            } else if parser.sess.source_map().is_imported(parser.token.span) {
-                e.span_label(site_span, "in this macro invocation");
-            }
-            match kind {
-                AstFragmentKind::Pat if macro_ident.name == sym::vec => {
-                    suggest_slice_pat(&mut e, site_span, parser);
-                }
-                _ => annotate_err_with_kind(&mut e, kind, 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/test/ui/editions/edition-keywords-2018-2015-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
index dbc0465b08e..a7a10d0f677 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.rs
@@ -1,9 +1,15 @@
 // edition:2018
 // aux-build:edition-kw-macro-2015.rs
 
+fn main() {}
+
 #[macro_use]
 extern crate edition_kw_macro_2015;
 
+mod module {
+    pub fn r#async() {}
+}
+
 pub fn check_async() {
     let mut async = 1; //~ ERROR expected identifier, found keyword `async`
     let mut r#async = 1; // OK
@@ -13,7 +19,7 @@ pub fn check_async() {
     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
     r#async = consumes_async_raw!(r#async); // OK
 
-    if passes_ident!(async) == 1 {}
+    if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found keyword `async`
     module::r#async(); // OK
diff --git a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
index e12d1a48463..3c3b934b531 100644
--- a/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2015-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:8:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:14:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ^^^^^^^
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:18:13
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:24:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,13 +21,13 @@ LL |     module::r#async();
    |             ^^^^^^^
 
 error: no rules expected the token `r#async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:12:31
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:18:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
 
 error: no rules expected the token `async`
-  --> $DIR/edition-keywords-2018-2015-parsing.rs:13:35
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:19:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -38,10 +38,20 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    | 
-  ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8
+  ::: $DIR/edition-keywords-2018-2015-parsing.rs:22:8
    |
 LL |     if passes_ident!(async) == 1 {}
    |        -------------------- in this macro invocation
 
-error: aborting due to 5 previous errors
+error[E0658]: async closures are unstable
+  --> $DIR/edition-keywords-2018-2015-parsing.rs:22:22
+   |
+LL |     if passes_ident!(async) == 1 {}
+   |                      ^^^^^
+   |
+   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
+   = help: add `#![feature(async_closure)]` to the crate attributes to enable
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
index 5aca0839f0f..b12ad76a747 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.rs
@@ -1,9 +1,15 @@
 // edition:2018
 // aux-build:edition-kw-macro-2018.rs
 
+fn main() {}
+
 #[macro_use]
 extern crate edition_kw_macro_2018;
 
+mod module {
+    pub fn r#async() {}
+}
+
 pub fn check_async() {
     let mut async = 1; //~ ERROR expected identifier, found keyword `async`
     let mut r#async = 1; // OK
@@ -13,7 +19,7 @@ pub fn check_async() {
     r#async = consumes_async_raw!(async); //~ ERROR no rules expected the token `async`
     r#async = consumes_async_raw!(r#async); // OK
 
-    if passes_ident!(async) == 1 {}
+    if passes_ident!(async) == 1 {} //~ ERROR async closures are unstable
     if passes_ident!(r#async) == 1 {} // OK
     module::async(); //~ ERROR expected identifier, found keyword `async`
     module::r#async(); // OK
diff --git a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
index 110165fc077..a2b129d17e0 100644
--- a/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
+++ b/src/test/ui/editions/edition-keywords-2018-2018-parsing.stderr
@@ -1,5 +1,5 @@
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:8:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:14:13
    |
 LL |     let mut async = 1;
    |             ^^^^^ expected identifier, found keyword
@@ -10,7 +10,7 @@ LL |     let mut r#async = 1;
    |             ^^^^^^^
 
 error: expected identifier, found keyword `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:18:13
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:24:13
    |
 LL |     module::async();
    |             ^^^^^ expected identifier, found keyword
@@ -21,13 +21,13 @@ LL |     module::r#async();
    |             ^^^^^^^
 
 error: no rules expected the token `r#async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:12:31
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:18:31
    |
 LL |     r#async = consumes_async!(r#async);
    |                               ^^^^^^^ no rules expected this token in macro call
 
 error: no rules expected the token `async`
-  --> $DIR/edition-keywords-2018-2018-parsing.rs:13:35
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:19:35
    |
 LL |     r#async = consumes_async_raw!(async);
    |                                   ^^^^^ no rules expected this token in macro call
@@ -38,10 +38,20 @@ error: macro expansion ends with an incomplete expression: expected one of `move
 LL |     ($i: ident) => ($i)
    |                       ^ expected one of `move`, `|`, or `||`
    | 
-  ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8
+  ::: $DIR/edition-keywords-2018-2018-parsing.rs:22:8
    |
 LL |     if passes_ident!(async) == 1 {}
    |        -------------------- in this macro invocation
 
-error: aborting due to 5 previous errors
+error[E0658]: async closures are unstable
+  --> $DIR/edition-keywords-2018-2018-parsing.rs:22:22
+   |
+LL |     if passes_ident!(async) == 1 {}
+   |                      ^^^^^
+   |
+   = note: see issue #62290 <https://github.com/rust-lang/rust/issues/62290> for more information
+   = help: add `#![feature(async_closure)]` to the crate attributes to enable
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/macros/macro-context.rs b/src/test/ui/macros/macro-context.rs
index 9130c3d921c..13e179578ad 100644
--- a/src/test/ui/macros/macro-context.rs
+++ b/src/test/ui/macros/macro-context.rs
@@ -4,6 +4,8 @@ macro_rules! m {
                             //~| ERROR macro expansion ignores token `typeof`
                             //~| ERROR macro expansion ignores token `;`
                             //~| ERROR macro expansion ignores token `;`
+                            //~| ERROR cannot find type `i` in this scope
+                            //~| ERROR cannot find value `i` in this scope
 }
 
 fn main() {
diff --git a/src/test/ui/macros/macro-context.stderr b/src/test/ui/macros/macro-context.stderr
index 2e712110689..17c73898124 100644
--- a/src/test/ui/macros/macro-context.stderr
+++ b/src/test/ui/macros/macro-context.stderr
@@ -42,5 +42,29 @@ LL |     m!();
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error[E0412]: cannot find type `i` in this scope
+  --> $DIR/macro-context.rs:3:13
+   |
+LL |     () => ( i ; typeof );
+   |             ^ help: a builtin type with a similar name exists: `i8`
+...
+LL |     let a: m!();
+   |            ---- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0425]: cannot find value `i` in this scope
+  --> $DIR/macro-context.rs:3:13
+   |
+LL |     () => ( i ; typeof );
+   |             ^ help: a local variable with a similar name exists: `a`
+...
+LL |     let i = m!();
+   |             ---- in this macro invocation
+   |
+   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 6 previous errors
 
+Some errors have detailed explanations: E0412, E0425.
+For more information about an error, try `rustc --explain E0412`.
diff --git a/src/test/ui/type/ascription/issue-47666.rs b/src/test/ui/type/ascription/issue-47666.rs
index ceb1dd89dae..8035de4a48a 100644
--- a/src/test/ui/type/ascription/issue-47666.rs
+++ b/src/test/ui/type/ascription/issue-47666.rs
@@ -1,5 +1,7 @@
 fn main() {
     let _ = Option:Some(vec![0, 1]); //~ ERROR expected type, found
+    //~^ ERROR expected value, found enum `Option`
+    //~| ERROR expected type, found variant `Some`
 }
 
 // This case isn't currently being handled gracefully due to the macro invocation.
diff --git a/src/test/ui/type/ascription/issue-47666.stderr b/src/test/ui/type/ascription/issue-47666.stderr
index f4c9240ab53..3cd3be70aa7 100644
--- a/src/test/ui/type/ascription/issue-47666.stderr
+++ b/src/test/ui/type/ascription/issue-47666.stderr
@@ -13,5 +13,35 @@ LL |     let _ = Option:Some(vec![0, 1]);
    = note: see issue #23416 <https://github.com/rust-lang/rust/issues/23416> for more information
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to previous error
+error[E0423]: expected value, found enum `Option`
+  --> $DIR/issue-47666.rs:2:13
+   |
+LL |     let _ = Option:Some(vec![0, 1]);
+   |             ^^^^^^
+   |
+help: try using one of the enum's variants
+   |
+LL |     let _ = std::option::Option::None:Some(vec![0, 1]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _ = std::option::Option::Some:Some(vec![0, 1]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0573]: expected type, found variant `Some`
+  --> $DIR/issue-47666.rs:2:20
+   |
+LL |     let _ = Option:Some(vec![0, 1]);
+   |                    ^^^^^^^^^^^^^^^^ not a type
+   |
+help: try using the variant's enum
+   |
+LL |     let _ = Option:std::option::Option;
+   |                    ^^^^^^^^^^^^^^^^^^^
+help: maybe you meant to write a path separator here
+   |
+LL |     let _ = Option::Some(vec![0, 1]);
+   |                   ^^
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0423, E0573.
+For more information about an error, try `rustc --explain E0423`.