Skip to content

Commit 9318ffa

Browse files
authored
Rollup merge of rust-lang#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 fc69654 + 7d38b0f commit 9318ffa

Some content is hidden

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

44 files changed

+548
-260
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
@@ -4,7 +4,6 @@ use rustc_ast::token;
44
use rustc_ast::tokenstream::TokenStream;
55
use rustc_ast_pretty::pprust;
66
use rustc_expand::base::{self, *};
7-
use rustc_expand::panictry;
87
use rustc_parse::{self, new_sub_parser_from_file, parser::Parser, DirectoryOwnership};
98
use rustc_session::lint::builtin::INCOMPLETE_INCLUDE;
109
use rustc_span::symbol::Symbol;
@@ -116,7 +115,7 @@ pub fn expand_include<'cx>(
116115
}
117116
impl<'a> base::MacResult for ExpandResult<'a> {
118117
fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
119-
let r = panictry!(self.p.parse_expr());
118+
let r = base::parse_expr(&mut self.p)?;
120119
if self.p.token != token::Eof {
121120
self.p.sess.buffer_lint(
122121
&INCOMPLETE_INCLUDE,
@@ -131,18 +130,17 @@ pub fn expand_include<'cx>(
131130
fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
132131
let mut ret = SmallVec::new();
133132
while self.p.token != token::Eof {
134-
match panictry!(self.p.parse_item()) {
135-
Some(item) => ret.push(item),
136-
None => {
133+
match self.p.parse_item() {
134+
Err(mut err) => {
135+
err.emit();
136+
break;
137+
}
138+
Ok(Some(item)) => ret.push(item),
139+
Ok(None) => {
137140
let token = pprust::token_to_string(&self.p.token);
138-
self.p
139-
.sess
140-
.span_diagnostic
141-
.span_fatal(
142-
self.p.token.span,
143-
&format!("expected item, found `{}`", token),
144-
)
145-
.raise();
141+
let msg = format!("expected item, found `{}`", token);
142+
self.p.struct_span_err(self.p.token.span, &msg).emit();
143+
break;
146144
}
147145
}
148146
}

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
@@ -9,7 +9,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
99
use rustc_attr::{self as attr, Deprecation, HasAttrs, Stability};
1010
use rustc_data_structures::fx::FxHashMap;
1111
use rustc_data_structures::sync::{self, Lrc};
12-
use rustc_errors::{DiagnosticBuilder, DiagnosticId};
12+
use rustc_errors::{DiagnosticBuilder, ErrorReported};
1313
use rustc_parse::{self, parser, DirectoryOwnership, MACRO_ARGUMENTS};
1414
use rustc_session::parse::ParseSess;
1515
use rustc_span::edition::Edition;
@@ -295,16 +295,26 @@ where
295295
}
296296

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

301306
impl<F> ProcMacro for F
302307
where
303308
F: Fn(TokenStream) -> TokenStream,
304309
{
305-
fn expand<'cx>(&self, _ecx: &'cx mut ExtCtxt<'_>, _span: Span, ts: TokenStream) -> TokenStream {
310+
fn expand<'cx>(
311+
&self,
312+
_ecx: &'cx mut ExtCtxt<'_>,
313+
_span: Span,
314+
ts: TokenStream,
315+
) -> Result<TokenStream, ErrorReported> {
306316
// FIXME setup implicit context in TLS before calling self.
307-
(*self)(ts)
317+
Ok((*self)(ts))
308318
}
309319
}
310320

@@ -315,7 +325,7 @@ pub trait AttrProcMacro {
315325
span: Span,
316326
annotation: TokenStream,
317327
annotated: TokenStream,
318-
) -> TokenStream;
328+
) -> Result<TokenStream, ErrorReported>;
319329
}
320330

321331
impl<F> AttrProcMacro for F
@@ -328,9 +338,9 @@ where
328338
_span: Span,
329339
annotation: TokenStream,
330340
annotated: TokenStream,
331-
) -> TokenStream {
341+
) -> Result<TokenStream, ErrorReported> {
332342
// FIXME setup implicit context in TLS before calling self.
333-
(*self)(annotation, annotated)
343+
Ok((*self)(annotation, annotated))
334344
}
335345
}
336346

@@ -999,31 +1009,9 @@ impl<'a> ExtCtxt<'a> {
9991009
self.current_expansion.id.expansion_cause()
10001010
}
10011011

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

10281016
/// Emit `msg` attached to `sp`, without immediately stopping
10291017
/// compilation.
@@ -1033,9 +1021,6 @@ impl<'a> ExtCtxt<'a> {
10331021
pub fn span_err<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
10341022
self.parse_sess.span_diagnostic.span_err(sp, msg);
10351023
}
1036-
pub fn span_err_with_code<S: Into<MultiSpan>>(&self, sp: S, msg: &str, code: DiagnosticId) {
1037-
self.parse_sess.span_diagnostic.span_err_with_code(sp, msg, code);
1038-
}
10391024
pub fn span_warn<S: Into<MultiSpan>>(&self, sp: S, msg: &str) {
10401025
self.parse_sess.span_diagnostic.span_warn(sp, msg);
10411026
}
@@ -1163,6 +1148,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str)
11631148
}
11641149
}
11651150

1151+
/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`.
1152+
pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
1153+
match p.parse_expr() {
1154+
Ok(e) => return Some(e),
1155+
Err(mut err) => err.emit(),
1156+
}
1157+
while p.token != token::Eof {
1158+
p.bump();
1159+
}
1160+
None
1161+
}
1162+
11661163
/// Interpreting `tts` as a comma-separated sequence of expressions,
11671164
/// expect exactly one string literal, or emit an error and return `None`.
11681165
pub fn get_single_str_from_tts(
@@ -1176,7 +1173,7 @@ pub fn get_single_str_from_tts(
11761173
cx.span_err(sp, &format!("{} takes 1 argument", name));
11771174
return None;
11781175
}
1179-
let ret = panictry!(p.parse_expr());
1176+
let ret = parse_expr(&mut p)?;
11801177
let _ = p.eat(&token::Comma);
11811178

11821179
if p.token != token::Eof {
@@ -1185,8 +1182,8 @@ pub fn get_single_str_from_tts(
11851182
expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| s.to_string())
11861183
}
11871184

1188-
/// Extracts comma-separated expressions from `tts`. If there is a
1189-
/// parsing error, emit a non-fatal error and return `None`.
1185+
/// Extracts comma-separated expressions from `tts`.
1186+
/// On error, emit it, and return `None`.
11901187
pub fn get_exprs_from_tts(
11911188
cx: &mut ExtCtxt<'_>,
11921189
sp: Span,
@@ -1195,7 +1192,7 @@ pub fn get_exprs_from_tts(
11951192
let mut p = cx.new_parser_from_tts(tts);
11961193
let mut es = Vec::new();
11971194
while p.token != token::Eof {
1198-
let expr = panictry!(p.parse_expr());
1195+
let expr = parse_expr(&mut p)?;
11991196

12001197
// Perform eager expansion on the expression.
12011198
// 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
@@ -7,25 +7,6 @@
77

88
extern crate proc_macro as pm;
99

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

0 commit comments

Comments
 (0)