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