Skip to content

Commit 3d8b961

Browse files
authored
Rollup merge of #70074 - Centril:unpanictry, r=petrochenkov
Expand: nix all fatal errors Basically, we go after all `.span_fatal` / `FatalError.raise()` and similar things and remove them one by one until there are no fatal errors left. r? @petrochenkov
2 parents 0a39964 + 470e163 commit 3d8b961

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+584
-274
lines changed

src/librustc_builtin_macros/cmdline_attrs.rs

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
use rustc_ast::ast::{self, AttrItem, AttrStyle};
44
use rustc_ast::attr::mk_attr;
55
use rustc_ast::token;
6-
use rustc_expand::panictry;
76
use rustc_session::parse::ParseSess;
87
use rustc_span::FileName;
98

@@ -16,7 +15,13 @@ pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -
1615
);
1716

1817
let start_span = parser.token.span;
19-
let AttrItem { path, args } = panictry!(parser.parse_attr_item());
18+
let AttrItem { path, args } = match parser.parse_attr_item() {
19+
Ok(ai) => ai,
20+
Err(mut err) => {
21+
err.emit();
22+
continue;
23+
}
24+
};
2025
let end_span = parser.token.span;
2126
if parser.token != token::Eof {
2227
parse_sess.span_diagnostic.span_err(start_span.to(end_span), "invalid crate attribute");

src/librustc_builtin_macros/source_util.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast_pretty::pprust;
66
use rustc_expand::base::{self, *};
77
use rustc_expand::module::DirectoryOwnership;
8-
use rustc_expand::panictry;
98
use rustc_parse::{self, new_parser_from_file, parser::Parser};
109
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
1110
use rustc_span::symbol::Symbol;
@@ -126,7 +125,7 @@ pub fn expand_include<'cx>(
126125
}
127126
impl<'a> base::MacResult for ExpandResult<'a> {
128127
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
129-
let r = panictry!(self.p.parse_expr());
128+
let r = base::parse_expr(&mut self.p)?;
130129
if self.p.token != token::Eof {
131130
self.p.sess.buffer_lint(
132131
&INCOMPLETE_INCLUDE,
@@ -141,18 +140,17 @@ pub fn expand_include<'cx>(
141140
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
142141
let mut ret = SmallVec::new();
143142
while self.p.token != token::Eof {
144-
match panictry!(self.p.parse_item()) {
145-
Some(item) => ret.push(item),
146-
None => {
143+
match self.p.parse_item() {
144+
Err(mut err) => {
145+
err.emit();
146+
break;
147+
}
148+
Ok(Some(item)) => ret.push(item),
149+
Ok(None) => {
147150
let token = pprust::token_to_string(&self.p.token);
148-
self.p
149-
.sess
150-
.span_diagnostic
151-
.span_fatal(
152-
self.p.token.span,
153-
&format!("expected item, found `{}`", token),
154-
)
155-
.raise();
151+
let msg = format!("expected item, found `{}`", token);
152+
self.p.struct_span_err(self.p.token.span, &msg).emit();
153+
break;
156154
}
157155
}
158156
}

src/librustc_builtin_macros/test.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,16 @@ pub fn expand_test_or_bench(
7474
return vec![];
7575
}
7676

77-
let item = if let Annotatable::Item(i) = item {
78-
i
79-
} else {
80-
cx.parse_sess
81-
.span_diagnostic
82-
.span_fatal(
83-
item.span(),
77+
let item = match item {
78+
Annotatable::Item(i) => i,
79+
other => {
80+
cx.struct_span_err(
81+
other.span(),
8482
"`#[test]` attribute is only allowed on non associated functions",
8583
)
86-
.raise();
84+
.emit();
85+
return vec![other];
86+
}
8787
};
8888

8989
if let ast::ItemKind::MacCall(_) = item.kind {

src/librustc_builtin_macros/test_harness.rs

+10-10
Original file line numberDiff line numberDiff line change
@@ -345,14 +345,14 @@ fn is_test_case(i: &ast::Item) -> bool {
345345

346346
fn get_test_runner(sd: &rustc_errors::Handler, krate: &ast::Crate) -> Option<ast::Path> {
347347
let test_attr = attr::find_by_name(&krate.attrs, sym::test_runner)?;
348-
test_attr.meta_item_list().map(|meta_list| {
349-
if meta_list.len() != 1 {
350-
sd.span_fatal(test_attr.span, "`#![test_runner(..)]` accepts exactly 1 argument")
351-
.raise()
352-
}
353-
match meta_list[0].meta_item() {
354-
Some(meta_item) if meta_item.is_word() => meta_item.path.clone(),
355-
_ => sd.span_fatal(test_attr.span, "`test_runner` argument must be a path").raise(),
356-
}
357-
})
348+
let meta_list = test_attr.meta_item_list()?;
349+
let span = test_attr.span;
350+
match &*meta_list {
351+
[single] => match single.meta_item() {
352+
Some(meta_item) if meta_item.is_word() => return Some(meta_item.path.clone()),
353+
_ => sd.struct_span_err(span, "`test_runner` argument must be a path").emit(),
354+
},
355+
_ => sd.struct_span_err(span, "`#![test_runner(..)]` accepts exactly 1 argument").emit(),
356+
}
357+
None
358358
}

src/librustc_expand/base.rs

+33-36
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
1010
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
1111
use rustc_data_structures::fx::FxHashMap;
1212
use rustc_data_structures::sync::{self, Lrc};
13-
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
13+
use rustc_errors::{DiagnosticBuilder, ErrorReported};
1414
use rustc_parse::{self, parser, MACRO_ARGUMENTS};
1515
use rustc_session::parse::ParseSess;
1616
use rustc_span::edition::Edition;
@@ -296,16 +296,26 @@ where
296296
}
297297

298298
pub trait ProcMacro {
299-
fn expand<'cx>(&self, ecx: &'cx mut ExtCtxt<'_>, span: Span, ts: TokenStream) -> TokenStream;
299+
fn expand<'cx>(
300+
&self,
301+
ecx: &'cx mut ExtCtxt<'_>,
302+
span: Span,
303+
ts: TokenStream,
304+
) -> Result<TokenStream, ErrorReported>;
300305
}
301306

302307
impl<F> ProcMacro for F
303308
where
304309
F: Fn(TokenStream) -> TokenStream,
305310
{
306-
fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream {
311+
fn expand<'cx>(
312+
&self,
313+
_ecx: &'cx mut ExtCtxt<'_>,
314+
_span: Span,
315+
ts: TokenStream,
316+
) -> Result<TokenStream, ErrorReported> {
307317
// FIXME setup implicit context in TLS before calling self.
308-
(*self)(ts)
318+
Ok((*self)(ts))
309319
}
310320
}
311321

@@ -316,7 +326,7 @@ pub trait AttrProcMacro {
316326
span: Span,
317327
annotation: TokenStream,
318328
annotated: TokenStream,
319-
) -> TokenStream;
329+
) -> Result<TokenStream, ErrorReported>;
320330
}
321331

322332
impl<F> AttrProcMacro for F
@@ -329,9 +339,9 @@ where
329339
_span: Span,
330340
annotation: TokenStream,
331341
annotated: TokenStream,
332-
) -> TokenStream {
342+
) -> Result<TokenStream, ErrorReported> {
333343
// FIXME setup implicit context in TLS before calling self.
334-
(*self)(annotation, annotated)
344+
Ok((*self)(annotation, annotated))
335345
}
336346
}
337347

@@ -1004,31 +1014,9 @@ impl<'a> ExtCtxt<'a> {
10041014
self.current_expansion.id.expansion_cause()
10051015
}
10061016

1007-
pub fn struct_span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
1008-
self.parse_sess.span_diagnostic.struct_span_warn(sp, msg)
1009-
}
10101017
pub fn struct_span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
10111018
self.parse_sess.span_diagnostic.struct_span_err(sp, msg)
10121019
}
1013-
pub fn struct_span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> DiagnosticBuilder<'a> {
1014-
self.parse_sess.span_diagnostic.struct_span_fatal(sp, msg)
1015-
}
1016-
1017-
/// Emit `msg` attached to `sp`, and stop compilation immediately.
1018-
///
1019-
/// `span_err` should be strongly preferred where-ever possible:
1020-
/// this should *only* be used when:
1021-
///
1022-
/// - continuing has a high risk of flow-on errors (e.g., errors in
1023-
/// declaring a macro would cause all uses of that macro to
1024-
/// complain about "undefined macro"), or
1025-
/// - there is literally nothing else that can be done (however,
1026-
/// in most cases one can construct a dummy expression/item to
1027-
/// substitute; we never hit resolve/type-checking so the dummy
1028-
/// value doesn't have to match anything)
1029-
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
1030-
self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise();
1031-
}
10321020

10331021
/// Emit `msg` attached to `sp`, without immediately stopping
10341022
/// compilation.
@@ -1038,9 +1026,6 @@ impl<'a> ExtCtxt<'a> {
10381026
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
10391027
self.parse_sess.span_diagnostic.span_err(sp, msg);
10401028
}
1041-
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
1042-
self.parse_sess.span_diagnostic.span_err_with_code(sp, msg, code);
1043-
}
10441029
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
10451030
self.parse_sess.span_diagnostic.span_warn(sp, msg);
10461031
}
@@ -1168,6 +1153,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str)
11681153
}
11691154
}
11701155

1156+
/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`.
1157+
pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
1158+
match p.parse_expr() {
1159+
Ok(e) => return Some(e),
1160+
Err(mut err) => err.emit(),
1161+
}
1162+
while p.token != token::Eof {
1163+
p.bump();
1164+
}
1165+
None
1166+
}
1167+
11711168
/// Interpreting `tts` as a comma-separated sequence of expressions,
11721169
/// expect exactly one string literal, or emit an error and return `None`.
11731170
pub fn get_single_str_from_tts(
@@ -1181,7 +1178,7 @@ pub fn get_single_str_from_tts(
11811178
cx.span_err(sp, &format!("{} takes 1 argument", name));
11821179
return None;
11831180
}
1184-
let ret = panictry!(p.parse_expr());
1181+
let ret = parse_expr(&mut p)?;
11851182
let _ = p.eat(&token::Comma);
11861183

11871184
if p.token != token::Eof {
@@ -1190,8 +1187,8 @@ pub fn get_single_str_from_tts(
11901187
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string())
11911188
}
11921189

1193-
/// Extracts comma-separated expressions from `tts`. If there is a
1194-
/// parsing error, emit a non-fatal error and return `None`.
1190+
/// Extracts comma-separated expressions from `tts`.
1191+
/// On error, emit it, and return `None`.
11951192
pub fn get_exprs_from_tts(
11961193
cx: &mut ExtCtxt<'_>,
11971194
sp: Span,
@@ -1200,7 +1197,7 @@ pub fn get_exprs_from_tts(
12001197
let mut p = cx.new_parser_from_tts(tts);
12011198
let mut es = Vec::new();
12021199
while p.token != token::Eof {
1203-
let expr = panictry!(p.parse_expr());
1200+
let expr = parse_expr(&mut p)?;
12041201

12051202
// Perform eager expansion on the expression.
12061203
// We want to be able to handle e.g., `concat!("foo", "bar")`.

src/librustc_expand/expand.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ ast_fragments! {
204204
}
205205

206206
impl AstFragmentKind {
207-
fn dummy(self, span: Span) -> AstFragment {
207+
crate fn dummy(self, span: Span) -> AstFragment {
208208
self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
209209
}
210210

@@ -682,7 +682,10 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
682682
InvocationKind::Bang { mac, .. } => match ext {
683683
SyntaxExtensionKind::Bang(expander) => {
684684
self.gate_proc_macro_expansion_kind(span, fragment_kind);
685-
let tok_result = expander.expand(self.cx, span, mac.args.inner_tokens());
685+
let tok_result = match expander.expand(self.cx, span, mac.args.inner_tokens()) {
686+
Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
687+
Ok(ts) => ts,
688+
};
686689
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
687690
}
688691
SyntaxExtensionKind::LegacyBang(expander) => {
@@ -709,8 +712,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
709712
if let MacArgs::Eq(..) = attr_item.args {
710713
self.cx.span_err(span, "key-value macro attributes are not supported");
711714
}
712-
let tok_result =
713-
expander.expand(self.cx, span, attr_item.args.inner_tokens(), tokens);
715+
let inner_tokens = attr_item.args.inner_tokens();
716+
let tok_result = match expander.expand(self.cx, span, inner_tokens, tokens) {
717+
Err(_) => return ExpandResult::Ready(fragment_kind.dummy(span)),
718+
Ok(ts) => ts,
719+
};
714720
self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
715721
}
716722
SyntaxExtensionKind::LegacyAttr(expander) => {
@@ -1139,6 +1145,8 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
11391145
// macros are expanded before any lint passes so this warning has to be hardcoded
11401146
if attr.has_name(sym::derive) {
11411147
self.cx
1148+
.parse_sess()
1149+
.span_diagnostic
11421150
.struct_span_warn(attr.span, "`#[derive]` does nothing on macro invocations")
11431151
.note("this may become a hard error in a future release")
11441152
.emit();

src/librustc_expand/lib.rs

-19
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,6 @@
99

1010
extern crate proc_macro as pm;
1111

12-
// A variant of 'try!' that panics on an Err. This is used as a crutch on the
13-
// way towards a non-panic!-prone parser. It should be used for fatal parsing
14-
// errors; eventually we plan to convert all code using panictry to just use
15-
// normal try.
16-
#[macro_export]
17-
macro_rules! panictry {
18-
($e:expr) => {{
19-
use rustc_errors::FatalError;
20-
use std::result::Result::{Err, Ok};
21-
match $e {
22-
Ok(e) => e,
23-
Err(mut e) => {
24-
e.emit();
25-
FatalError.raise()
26-
}
27-
}
28-
}};
29-
}
30-
3112
mod placeholders;
3213
mod proc_macro_server;
3314

0 commit comments

Comments
 (0)