@@ -10,7 +10,7 @@ use rustc_ast::visit::{AssocCtxt, Visitor};
10
10
use rustc_attr:: { self as attr, Deprecation , HasAttrs , Stability } ;
11
11
use rustc_data_structures:: fx:: FxHashMap ;
12
12
use rustc_data_structures:: sync:: { self , Lrc } ;
13
- use rustc_errors:: { DiagnosticBuilder , DiagnosticId } ;
13
+ use rustc_errors:: { DiagnosticBuilder , ErrorReported } ;
14
14
use rustc_parse:: { self , parser, MACRO_ARGUMENTS } ;
15
15
use rustc_session:: parse:: ParseSess ;
16
16
use rustc_span:: edition:: Edition ;
@@ -296,16 +296,26 @@ where
296
296
}
297
297
298
298
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 > ;
300
305
}
301
306
302
307
impl < F > ProcMacro for F
303
308
where
304
309
F : Fn ( TokenStream ) -> TokenStream ,
305
310
{
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 > {
307
317
// FIXME setup implicit context in TLS before calling self.
308
- ( * self ) ( ts)
318
+ Ok ( ( * self ) ( ts) )
309
319
}
310
320
}
311
321
@@ -316,7 +326,7 @@ pub trait AttrProcMacro {
316
326
span : Span ,
317
327
annotation : TokenStream ,
318
328
annotated : TokenStream ,
319
- ) -> TokenStream ;
329
+ ) -> Result < TokenStream , ErrorReported > ;
320
330
}
321
331
322
332
impl < F > AttrProcMacro for F
@@ -329,9 +339,9 @@ where
329
339
_span : Span ,
330
340
annotation : TokenStream ,
331
341
annotated : TokenStream ,
332
- ) -> TokenStream {
342
+ ) -> Result < TokenStream , ErrorReported > {
333
343
// FIXME setup implicit context in TLS before calling self.
334
- ( * self ) ( annotation, annotated)
344
+ Ok ( ( * self ) ( annotation, annotated) )
335
345
}
336
346
}
337
347
@@ -1004,31 +1014,9 @@ impl<'a> ExtCtxt<'a> {
1004
1014
self . current_expansion . id . expansion_cause ( )
1005
1015
}
1006
1016
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
- }
1010
1017
pub fn struct_span_err < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) -> DiagnosticBuilder < ' a > {
1011
1018
self . parse_sess . span_diagnostic . struct_span_err ( sp, msg)
1012
1019
}
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
- }
1032
1020
1033
1021
/// Emit `msg` attached to `sp`, without immediately stopping
1034
1022
/// compilation.
@@ -1038,9 +1026,6 @@ impl<'a> ExtCtxt<'a> {
1038
1026
pub fn span_err < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
1039
1027
self . parse_sess . span_diagnostic . span_err ( sp, msg) ;
1040
1028
}
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
- }
1044
1029
pub fn span_warn < S : Into < MultiSpan > > ( & self , sp : S , msg : & str ) {
1045
1030
self . parse_sess . span_diagnostic . span_warn ( sp, msg) ;
1046
1031
}
@@ -1168,6 +1153,18 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, sp: Span, tts: TokenStream, name: &str)
1168
1153
}
1169
1154
}
1170
1155
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
+
1171
1168
/// Interpreting `tts` as a comma-separated sequence of expressions,
1172
1169
/// expect exactly one string literal, or emit an error and return `None`.
1173
1170
pub fn get_single_str_from_tts (
@@ -1181,7 +1178,7 @@ pub fn get_single_str_from_tts(
1181
1178
cx. span_err ( sp, & format ! ( "{} takes 1 argument" , name) ) ;
1182
1179
return None ;
1183
1180
}
1184
- let ret = panictry ! ( p . parse_expr( ) ) ;
1181
+ let ret = parse_expr ( & mut p ) ? ;
1185
1182
let _ = p. eat ( & token:: Comma ) ;
1186
1183
1187
1184
if p. token != token:: Eof {
@@ -1190,8 +1187,8 @@ pub fn get_single_str_from_tts(
1190
1187
expr_to_string ( cx, ret, "argument must be a string literal" ) . map ( |( s, _) | s. to_string ( ) )
1191
1188
}
1192
1189
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`.
1195
1192
pub fn get_exprs_from_tts (
1196
1193
cx : & mut ExtCtxt < ' _ > ,
1197
1194
sp : Span ,
@@ -1200,7 +1197,7 @@ pub fn get_exprs_from_tts(
1200
1197
let mut p = cx. new_parser_from_tts ( tts) ;
1201
1198
let mut es = Vec :: new ( ) ;
1202
1199
while p. token != token:: Eof {
1203
- let expr = panictry ! ( p . parse_expr( ) ) ;
1200
+ let expr = parse_expr ( & mut p ) ? ;
1204
1201
1205
1202
// Perform eager expansion on the expression.
1206
1203
// We want to be able to handle e.g., `concat!("foo", "bar")`.
0 commit comments