about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_expand/base.rs18
-rw-r--r--src/librustc_expand/expand.rs5
-rw-r--r--src/librustc_expand/proc_macro.rs23
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-1.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-2.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-3.rs2
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.rs9
-rw-r--r--src/test/ui/proc-macro/invalid-punct-ident-4.stderr16
8 files changed, 52 insertions, 25 deletions
diff --git a/src/librustc_expand/base.rs b/src/librustc_expand/base.rs
index b615b34634f..20e1895270a 100644
--- a/src/librustc_expand/base.rs
+++ b/src/librustc_expand/base.rs
@@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
 use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::{self, Lrc};
-use rustc_errors::{DiagnosticBuilder, DiagnosticId};
+use rustc_errors::{DiagnosticBuilder, DiagnosticId, ErrorReported};
 use rustc_parse::{self, parser, MACRO_ARGUMENTS};
 use rustc_session::parse::ParseSess;
 use rustc_span::edition::Edition;
@@ -296,16 +296,26 @@ where
 }
 
 pub trait ProcMacro {
-    fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt<'_>, span: Span, ts: TokenStream) -> TokenStream;
+    fn expand<'cx>(
+        &self,
+        ecx: &'cx mut ExtCtxt<'_>,
+        span: Span,
+        ts: TokenStream,
+    ) -> Result<TokenStream, ErrorReported>;
 }
 
 impl<F> ProcMacro for F
 where
     F: Fn(TokenStream) -> TokenStream,
 {
-    fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream {
+    fn expand<'cx>(
+        &self,
+        _ecx: &'cx mut ExtCtxt<'_>,
+        _span: Span,
+        ts: TokenStream,
+    ) -> Result<TokenStream, ErrorReported> {
         // FIXME setup implicit context in TLS before calling self.
-        (*self)(ts)
+        Ok((*self)(ts))
     }
 }
 
diff --git a/src/librustc_expand/expand.rs b/src/librustc_expand/expand.rs
index 58217d98986..57314824d5a 100644
--- a/src/librustc_expand/expand.rs
+++ b/src/librustc_expand/expand.rs
@@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             InvocationKind::Bang { mac, .. } => match ext {
                 SyntaxExtensionKind::Bang(expander) => {
                     self.gate_proc_macro_expansion_kind(span, fragment_kind);
-                    let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
+                    let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
+                        Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
+                        Ok(ts) => ts,
+                    };
                     self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
                 }
                 SyntaxExtensionKind::LegacyBang(expander) => {
diff --git a/src/librustc_expand/proc_macro.rs b/src/librustc_expand/proc_macro.rs
index cb9afa4cd4f..404f29f1fcf 100644
--- a/src/librustc_expand/proc_macro.rs
+++ b/src/librustc_expand/proc_macro.rs
@@ -5,7 +5,7 @@ use rustc_ast::ast::{self, ItemKind, MetaItemKind, NestedMetaItem};
 use rustc_ast::token;
 use rustc_ast::tokenstream::{self, TokenStream};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{Applicability, FatalError};
+use rustc_errors::{Applicability, ErrorReported, FatalError};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, DUMMY_SP};
 
@@ -21,21 +21,16 @@ impl base::ProcMacro for BangProcMacro {
         ecx: &'cx mut ExtCtxt<'_>,
         span: Span,
         input: TokenStream,
-    ) -> TokenStream {
+    ) -> Result<TokenStream, ErrorReported> {
         let server = proc_macro_server::Rustc::new(ecx);
-        match self.client.run(&EXEC_STRATEGY, server, input) {
-            Ok(stream) => stream,
-            Err(e) => {
-                let msg = "proc macro panicked";
-                let mut err = ecx.struct_span_fatal(span, msg);
-                if let Some(s) = e.as_str() {
-                    err.help(&format!("message: {}", s));
-                }
-
-                err.emit();
-                FatalError.raise();
+        self.client.run(&EXEC_STRATEGY, server, input).map_err(|e| {
+            let mut err = ecx.struct_span_err(span, "proc macro panicked");
+            if let Some(s) = e.as_str() {
+                err.help(&format!("message: {}", s));
             }
-        }
+            err.emit();
+            ErrorReported
+        })
     }
 }
 
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
index 9de57da5af4..3f78dea917b 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_punct!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-2.rs b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
index 79f72324b1d..4e89e80ae7c 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-2.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-2.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_ident!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-3.rs b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
index d01e9b699ca..8d8ce8f932e 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-3.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-3.rs
@@ -14,3 +14,5 @@
 extern crate invalid_punct_ident;
 
 invalid_raw_ident!(); //~ ERROR proc macro panicked
+
+fn main() {}
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.rs b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
index e50f24deae3..ab0250f53f6 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.rs
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.rs
@@ -1,7 +1,10 @@
 // aux-build:invalid-punct-ident.rs
 
-#[macro_use]
+// We use `main` not found below as a witness for error recovery in proc macro expansion.
+
+#[macro_use] //~ ERROR `main` function not found
 extern crate invalid_punct_ident;
 
-lexer_failure!(); //~ ERROR proc macro panicked
-                  //~| ERROR unexpected closing delimiter: `)`
+lexer_failure!();
+//~^ ERROR proc macro panicked
+//~| ERROR unexpected closing delimiter: `)`
diff --git a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
index fe3e55b31be..296e2fb0942 100644
--- a/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
+++ b/src/test/ui/proc-macro/invalid-punct-ident-4.stderr
@@ -1,5 +1,5 @@
 error: unexpected closing delimiter: `)`
-  --> $DIR/invalid-punct-ident-4.rs:6:1
+  --> $DIR/invalid-punct-ident-4.rs:8:1
    |
 LL | lexer_failure!();
    | ^^^^^^^^^^^^^^^^^ unexpected closing delimiter
@@ -7,10 +7,20 @@ LL | lexer_failure!();
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: proc macro panicked
-  --> $DIR/invalid-punct-ident-4.rs:6:1
+  --> $DIR/invalid-punct-ident-4.rs:8:1
    |
 LL | lexer_failure!();
    | ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0601]: `main` function not found in crate `invalid_punct_ident_4`
+  --> $DIR/invalid-punct-ident-4.rs:5:1
+   |
+LL | / #[macro_use]
+LL | | extern crate invalid_punct_ident;
+LL | |
+LL | | lexer_failure!();
+   | |_________________^ consider adding a `main` function to `$DIR/invalid-punct-ident-4.rs`
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0601`.