defatalize BangProcMacro::expand

This commit is contained in:
Mazdak Farrokhzad 2020-03-17 10:09:18 +01:00
parent b0537e2081
commit 35cca74212
8 changed files with 52 additions and 25 deletions

View file

@ -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))
}
}

View file

@ -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) => {

View file

@ -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
})
}
}

View file

@ -14,3 +14,5 @@
extern crate invalid_punct_ident;
invalid_punct!(); //~ ERROR proc macro panicked
fn main() {}

View file

@ -14,3 +14,5 @@
extern crate invalid_punct_ident;
invalid_ident!(); //~ ERROR proc macro panicked
fn main() {}

View file

@ -14,3 +14,5 @@
extern crate invalid_punct_ident;
invalid_raw_ident!(); //~ ERROR proc macro panicked
fn main() {}

View file

@ -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: `)`

View file

@ -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`.