@@ -201,83 +201,82 @@ fn expand_mac_invoc<T>(mac: ast::Mac, attrs: Vec<ast::Attribute>, span: Span,
201
201
fld : & mut MacroExpander ) -> T
202
202
where T : MacroGenerable ,
203
203
{
204
- check_attributes ( & attrs, fld) ;
205
-
206
204
// it would almost certainly be cleaner to pass the whole
207
205
// macro invocation in, rather than pulling it apart and
208
206
// marking the tts and the ctxt separately. This also goes
209
207
// for the other three macro invocation chunks of code
210
208
// in this file.
211
209
212
- let Mac_ { path : pth, tts, .. } = mac. node ;
213
- if pth. segments . len ( ) > 1 {
214
- fld. cx . span_err ( pth. span ,
215
- "expected macro name without module \
216
- separators") ;
217
- // let compilation continue
218
- return T :: dummy ( span) ;
219
- }
220
- let extname = pth. segments [ 0 ] . identifier . name ;
221
- match fld. cx . syntax_env . find ( extname) {
222
- None => {
223
- let mut err = fld. cx . struct_span_err (
224
- pth. span ,
225
- & format ! ( "macro undefined: '{}!'" ,
226
- & extname) ) ;
210
+ let Mac_ { path, tts, .. } = mac. node ;
211
+ let mark = fresh_mark ( ) ;
212
+
213
+ fn mac_result < ' a > ( path : & ast:: Path , tts : Vec < TokenTree > , mark : Mrk ,
214
+ attrs : Vec < ast:: Attribute > , call_site : Span , fld : & ' a mut MacroExpander )
215
+ -> Option < Box < MacResult + ' a > > {
216
+ check_attributes ( & attrs, fld) ;
217
+
218
+ if path. segments . len ( ) > 1 {
219
+ fld. cx . span_err ( path. span , "expected macro name without module separators" ) ;
220
+ return None ;
221
+ }
222
+
223
+ let extname = path. segments [ 0 ] . identifier . name ;
224
+ let extension = if let Some ( extension) = fld. cx . syntax_env . find ( extname) {
225
+ extension
226
+ } else {
227
+ let mut err = fld. cx . struct_span_err ( path. span ,
228
+ & format ! ( "macro undefined: '{}!'" , & extname) ) ;
227
229
fld. cx . suggest_macro_name ( & extname. as_str ( ) , & mut err) ;
228
230
err. emit ( ) ;
231
+ return None ;
232
+ } ;
229
233
230
- // let compilation continue
231
- T :: dummy ( span)
232
- }
233
- Some ( rc) => match * rc {
234
+ match * extension {
234
235
NormalTT ( ref expandfun, exp_span, allow_internal_unstable) => {
235
236
fld. cx . bt_push ( ExpnInfo {
236
- call_site : span,
237
- callee : NameAndSpan {
238
- format : MacroBang ( extname) ,
239
- span : exp_span,
240
- allow_internal_unstable : allow_internal_unstable,
241
- } ,
242
- } ) ;
243
- let fm = fresh_mark ( ) ;
244
- let marked_before = mark_tts ( & tts[ ..] , fm) ;
237
+ call_site : call_site,
238
+ callee : NameAndSpan {
239
+ format : MacroBang ( extname) ,
240
+ span : exp_span,
241
+ allow_internal_unstable : allow_internal_unstable,
242
+ } ,
243
+ } ) ;
245
244
246
245
// The span that we pass to the expanders we want to
247
246
// be the root of the call stack. That's the most
248
247
// relevant span and it's the actual invocation of
249
248
// the macro.
250
249
let mac_span = fld. cx . original_span ( ) ;
251
250
252
- let opt_parsed = {
253
- let expanded = expandfun. expand ( fld. cx ,
254
- mac_span,
255
- & marked_before[ ..] ) ;
256
- T :: make_with ( expanded)
257
- } ;
258
- let parsed = match opt_parsed {
259
- Some ( e) => e,
260
- None => {
261
- let msg = format ! ( "non-{kind} macro in {kind} position: {name}" ,
262
- name = extname, kind = T :: kind_name( ) ) ;
263
- fld. cx . span_err ( pth. span , & msg) ;
264
- return T :: dummy ( span) ;
265
- }
266
- } ;
267
- let marked = parsed. fold_with ( & mut Marker { mark : fm } ) ;
268
- let fully_expanded = marked. fold_with ( fld) ;
269
- fld. cx . bt_pop ( ) ;
270
- fully_expanded
251
+ let marked_tts = mark_tts ( & tts[ ..] , mark) ;
252
+ Some ( expandfun. expand ( fld. cx , mac_span, & marked_tts) )
271
253
}
272
254
_ => {
273
- fld. cx . span_err (
274
- pth. span ,
275
- & format ! ( "'{}' is not a tt-style macro" ,
276
- extname) ) ;
277
- T :: dummy ( span)
255
+ fld. cx . span_err ( path. span ,
256
+ & format ! ( "'{}' is not a tt-style macro" , extname) ) ;
257
+ None
278
258
}
279
259
}
280
260
}
261
+
262
+ let opt_expanded = T :: make_with ( match mac_result ( & path, tts, mark, attrs, span, fld) {
263
+ Some ( result) => result,
264
+ None => return T :: dummy ( span) ,
265
+ } ) ;
266
+
267
+ let expanded = if let Some ( expanded) = opt_expanded {
268
+ expanded
269
+ } else {
270
+ let msg = format ! ( "non-{kind} macro in {kind} position: {name}" ,
271
+ name = path. segments[ 0 ] . identifier. name, kind = T :: kind_name( ) ) ;
272
+ fld. cx . span_err ( path. span , & msg) ;
273
+ return T :: dummy ( span) ;
274
+ } ;
275
+
276
+ let marked = expanded. fold_with ( & mut Marker { mark : mark } ) ;
277
+ let fully_expanded = marked. fold_with ( fld) ;
278
+ fld. cx . bt_pop ( ) ;
279
+ fully_expanded
281
280
}
282
281
283
282
/// Rename loop label and expand its loop body
0 commit comments