@@ -109,29 +109,104 @@ impl ExpansionKind {
109
109
fn dummy ( self , span : Span ) -> Expansion {
110
110
self . make_from ( DummyResult :: any ( span) ) . unwrap ( )
111
111
}
112
+
113
+ fn expect_from_annotatables < I : IntoIterator < Item = Annotatable > > ( self , items : I ) -> Expansion {
114
+ let items = items. into_iter ( ) ;
115
+ match self {
116
+ ExpansionKind :: Items =>
117
+ Expansion :: Items ( items. map ( Annotatable :: expect_item) . collect ( ) ) ,
118
+ ExpansionKind :: ImplItems =>
119
+ Expansion :: ImplItems ( items. map ( Annotatable :: expect_impl_item) . collect ( ) ) ,
120
+ ExpansionKind :: TraitItems =>
121
+ Expansion :: TraitItems ( items. map ( Annotatable :: expect_trait_item) . collect ( ) ) ,
122
+ _ => unreachable ! ( ) ,
123
+ }
124
+ }
112
125
}
113
126
114
127
pub struct Invocation {
115
- span : Span ,
116
- attrs : Vec < ast:: Attribute > ,
117
- mac : ast:: Mac ,
118
- ident : Option < Ident > ,
128
+ kind : InvocationKind ,
129
+ expansion_kind : ExpansionKind ,
119
130
mark : Mark ,
120
- kind : ExpansionKind ,
131
+ }
132
+
133
+ enum InvocationKind {
134
+ Bang {
135
+ attrs : Vec < ast:: Attribute > ,
136
+ mac : ast:: Mac ,
137
+ ident : Option < Ident > ,
138
+ span : Span ,
139
+ } ,
140
+ Attr {
141
+ attr : ast:: Attribute ,
142
+ item : Annotatable ,
143
+ } ,
121
144
}
122
145
123
146
pub fn expand_expr ( expr : ast:: Expr , fld : & mut MacroExpander ) -> P < ast:: Expr > {
124
147
if let ast:: ExprKind :: Mac ( mac) = expr. node {
125
- let invoc = fld. new_invoc ( mac, expr. attrs . into ( ) , expr. span , ExpansionKind :: Expr ) ;
126
- expand_mac_invoc ( invoc, fld) . make_expr ( )
148
+ let invoc = fld. new_bang_invoc ( mac, expr. attrs . into ( ) , expr. span , ExpansionKind :: Expr ) ;
149
+ expand_invoc ( invoc, fld) . make_expr ( )
127
150
} else {
128
151
P ( noop_fold_expr ( expr, fld) )
129
152
}
130
153
}
131
154
155
+ fn expand_invoc ( invoc : Invocation , fld : & mut MacroExpander ) -> Expansion {
156
+ match invoc. kind {
157
+ InvocationKind :: Bang { .. } => expand_bang_invoc ( invoc, fld) ,
158
+ InvocationKind :: Attr { .. } => expand_attr_invoc ( invoc, fld) ,
159
+ }
160
+ }
161
+
162
+ fn expand_attr_invoc ( invoc : Invocation , fld : & mut MacroExpander ) -> Expansion {
163
+ let Invocation { expansion_kind : kind, .. } = invoc;
164
+ let ( attr, item) = match invoc. kind {
165
+ InvocationKind :: Attr { attr, item } => ( attr, item) ,
166
+ _ => unreachable ! ( ) ,
167
+ } ;
168
+
169
+ let extension = match fld. cx . syntax_env . find ( intern ( & attr. name ( ) ) ) {
170
+ Some ( extension) => extension,
171
+ None => unreachable ! ( ) ,
172
+ } ;
173
+
174
+ attr:: mark_used ( & attr) ;
175
+ fld. cx . bt_push ( ExpnInfo {
176
+ call_site : attr. span ,
177
+ callee : NameAndSpan {
178
+ format : MacroAttribute ( intern ( & attr. name ( ) ) ) ,
179
+ span : Some ( attr. span ) ,
180
+ allow_internal_unstable : false ,
181
+ }
182
+ } ) ;
183
+
184
+ let modified = match * extension {
185
+ MultiModifier ( ref mac) => {
186
+ kind. expect_from_annotatables ( mac. expand ( fld. cx , attr. span , & attr. node . value , item) )
187
+ }
188
+ MultiDecorator ( ref mac) => {
189
+ let mut items = Vec :: new ( ) ;
190
+ mac. expand ( fld. cx , attr. span , & attr. node . value , & item, & mut |item| items. push ( item) ) ;
191
+ items. push ( item) ;
192
+ kind. expect_from_annotatables ( items)
193
+ }
194
+ _ => unreachable ! ( ) ,
195
+ } ;
196
+
197
+ fld. cx . bt_pop ( ) ;
198
+
199
+ let configured = modified. fold_with ( & mut fld. strip_unconfigured ( ) ) ;
200
+ configured. fold_with ( fld)
201
+ }
202
+
132
203
/// Expand a macro invocation. Returns the result of expansion.
133
- fn expand_mac_invoc ( invoc : Invocation , fld : & mut MacroExpander ) -> Expansion {
134
- let Invocation { span, attrs, mac, ident, mark, kind } = invoc;
204
+ fn expand_bang_invoc ( invoc : Invocation , fld : & mut MacroExpander ) -> Expansion {
205
+ let Invocation { mark, expansion_kind : kind, .. } = invoc;
206
+ let ( attrs, mac, ident, span) = match invoc. kind {
207
+ InvocationKind :: Bang { attrs, mac, ident, span } => ( attrs, mac, ident, span) ,
208
+ _ => unreachable ! ( ) ,
209
+ } ;
135
210
let Mac_ { path, tts, .. } = mac. node ;
136
211
137
212
// Detect use of feature-gated or invalid attributes on macro invoations
@@ -270,11 +345,8 @@ fn expand_mac_invoc(invoc: Invocation, fld: &mut MacroExpander) -> Expansion {
270
345
fully_expanded
271
346
}
272
347
273
- // When we enter a module, record it, for the sake of `module!`
274
- pub fn expand_item ( it : P < ast:: Item > , fld : & mut MacroExpander )
275
- -> SmallVector < P < ast:: Item > > {
276
- expand_annotatable ( Annotatable :: Item ( it) , fld)
277
- . into_iter ( ) . map ( |i| i. expect_item ( ) ) . collect ( )
348
+ pub fn expand_item ( it : P < ast:: Item > , fld : & mut MacroExpander ) -> SmallVector < P < ast:: Item > > {
349
+ expand_annotatable ( Annotatable :: Item ( it) , fld) . make_items ( )
278
350
}
279
351
280
352
// does this attribute list contain "macro_use" ?
@@ -311,8 +383,8 @@ fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector<Stmt> {
311
383
_ => return noop_fold_stmt ( stmt, fld)
312
384
} ;
313
385
314
- let invoc = fld. new_invoc ( mac, attrs. into ( ) , stmt. span , ExpansionKind :: Stmts ) ;
315
- let mut fully_expanded = expand_mac_invoc ( invoc, fld) . make_stmts ( ) ;
386
+ let invoc = fld. new_bang_invoc ( mac, attrs. into ( ) , stmt. span , ExpansionKind :: Stmts ) ;
387
+ let mut fully_expanded = expand_invoc ( invoc, fld) . make_stmts ( ) ;
316
388
317
389
// If this is a macro invocation with a semicolon, then apply that
318
390
// semicolon to the final statement produced by expansion.
@@ -332,28 +404,30 @@ fn expand_pat(p: P<ast::Pat>, fld: &mut MacroExpander) -> P<ast::Pat> {
332
404
}
333
405
p. and_then ( |p| match p. node {
334
406
PatKind :: Mac ( mac) => {
335
- let invoc = fld. new_invoc ( mac, Vec :: new ( ) , p. span , ExpansionKind :: Pat ) ;
336
- expand_mac_invoc ( invoc, fld) . make_pat ( )
407
+ let invoc = fld. new_bang_invoc ( mac, Vec :: new ( ) , p. span , ExpansionKind :: Pat ) ;
408
+ expand_invoc ( invoc, fld) . make_pat ( )
337
409
}
338
410
_ => unreachable ! ( ) ,
339
411
} )
340
412
}
341
413
342
- fn expand_multi_modified ( a : Annotatable , fld : & mut MacroExpander ) -> SmallVector < Annotatable > {
414
+ fn expand_multi_modified ( a : Annotatable , fld : & mut MacroExpander ) -> Expansion {
343
415
match a {
344
416
Annotatable :: Item ( it) => match it. node {
345
417
ast:: ItemKind :: Mac ( ..) => {
346
418
if match it. node {
347
419
ItemKind :: Mac ( ref mac) => mac. node . path . segments . is_empty ( ) ,
348
420
_ => unreachable ! ( ) ,
349
421
} {
350
- return SmallVector :: one ( Annotatable :: Item ( it) ) ;
422
+ return Expansion :: Items ( SmallVector :: one ( it) ) ;
351
423
}
352
424
it. and_then ( |it| match it. node {
353
425
ItemKind :: Mac ( mac) => {
354
- let mut invoc = fld. new_invoc ( mac, it. attrs , it. span , ExpansionKind :: Items ) ;
355
- invoc. ident = Some ( it. ident ) ;
356
- expand_mac_invoc ( invoc, fld) . make_items ( )
426
+ let invoc =
427
+ fld. new_invoc ( ExpansionKind :: Items , InvocationKind :: Bang {
428
+ mac : mac, attrs : it. attrs , ident : Some ( it. ident ) , span : it. span ,
429
+ } ) ;
430
+ expand_invoc ( invoc, fld)
357
431
}
358
432
_ => unreachable ! ( ) ,
359
433
} )
@@ -370,31 +444,24 @@ fn expand_multi_modified(a: Annotatable, fld: &mut MacroExpander) -> SmallVector
370
444
if valid_ident {
371
445
fld. cx . mod_pop ( ) ;
372
446
}
373
- result
447
+ Expansion :: Items ( result)
374
448
} ,
375
- _ => noop_fold_item ( it, fld) ,
376
- } . into_iter ( ) . map ( |i| Annotatable :: Item ( i) ) . collect ( ) ,
377
-
378
- Annotatable :: TraitItem ( it) => {
379
- expand_trait_item ( it. unwrap ( ) , fld) . into_iter ( ) .
380
- map ( |it| Annotatable :: TraitItem ( P ( it) ) ) . collect ( )
381
- }
449
+ _ => Expansion :: Items ( noop_fold_item ( it, fld) ) ,
450
+ } ,
382
451
383
- Annotatable :: ImplItem ( ii) => {
384
- expand_impl_item ( ii. unwrap ( ) , fld) . into_iter ( ) .
385
- map ( |ii| Annotatable :: ImplItem ( P ( ii) ) ) . collect ( )
386
- }
452
+ Annotatable :: TraitItem ( it) => Expansion :: TraitItems ( expand_trait_item ( it. unwrap ( ) , fld) ) ,
453
+ Annotatable :: ImplItem ( ii) => Expansion :: ImplItems ( expand_impl_item ( ii. unwrap ( ) , fld) ) ,
387
454
}
388
455
}
389
456
390
- fn expand_annotatable ( mut item : Annotatable , fld : & mut MacroExpander ) -> SmallVector < Annotatable > {
391
- let mut multi_modifier = None ;
457
+ fn expand_annotatable ( mut item : Annotatable , fld : & mut MacroExpander ) -> Expansion {
458
+ let mut attr = None ;
392
459
item = item. map_attrs ( |mut attrs| {
393
460
for i in 0 ..attrs. len ( ) {
394
461
if let Some ( extension) = fld. cx . syntax_env . find ( intern ( & attrs[ i] . name ( ) ) ) {
395
462
match * extension {
396
463
MultiModifier ( ..) | MultiDecorator ( ..) => {
397
- multi_modifier = Some ( ( attrs. remove ( i) , extension ) ) ;
464
+ attr = Some ( attrs. remove ( i) ) ;
398
465
break ;
399
466
}
400
467
_ => { }
@@ -404,47 +471,25 @@ fn expand_annotatable(mut item: Annotatable, fld: &mut MacroExpander) -> SmallVe
404
471
attrs
405
472
} ) ;
406
473
407
- match multi_modifier {
408
- None => expand_multi_modified ( item, fld) ,
409
- Some ( ( attr, extension) ) => {
410
- attr:: mark_used ( & attr) ;
411
- fld. cx . bt_push ( ExpnInfo {
412
- call_site : attr. span ,
413
- callee : NameAndSpan {
414
- format : MacroAttribute ( intern ( & attr. name ( ) ) ) ,
415
- span : Some ( attr. span ) ,
416
- allow_internal_unstable : false ,
417
- }
418
- } ) ;
419
-
420
- let modified = match * extension {
421
- MultiModifier ( ref mac) => mac. expand ( fld. cx , attr. span , & attr. node . value , item) ,
422
- MultiDecorator ( ref mac) => {
423
- let mut items = Vec :: new ( ) ;
424
- mac. expand ( fld. cx , attr. span , & attr. node . value , & item,
425
- & mut |item| items. push ( item) ) ;
426
- items. push ( item) ;
427
- items
428
- }
429
- _ => unreachable ! ( ) ,
430
- } ;
431
-
432
- fld. cx . bt_pop ( ) ;
433
- let configured = modified. into_iter ( ) . flat_map ( |it| {
434
- it. fold_with ( & mut fld. strip_unconfigured ( ) )
435
- } ) . collect :: < SmallVector < _ > > ( ) ;
436
-
437
- configured. into_iter ( ) . flat_map ( |it| expand_annotatable ( it, fld) ) . collect ( )
438
- }
474
+ if let Some ( attr) = attr {
475
+ let kind = match item {
476
+ Annotatable :: Item ( _) => ExpansionKind :: Items ,
477
+ Annotatable :: ImplItem ( _) => ExpansionKind :: ImplItems ,
478
+ Annotatable :: TraitItem ( _) => ExpansionKind :: TraitItems ,
479
+ } ;
480
+ let invoc = fld. new_invoc ( kind, InvocationKind :: Attr { attr : attr, item : item } ) ;
481
+ expand_invoc ( invoc, fld)
482
+ } else {
483
+ expand_multi_modified ( item, fld)
439
484
}
440
485
}
441
486
442
487
fn expand_impl_item ( ii : ast:: ImplItem , fld : & mut MacroExpander )
443
488
-> SmallVector < ast:: ImplItem > {
444
489
match ii. node {
445
490
ast:: ImplItemKind :: Macro ( mac) => {
446
- let invoc = fld. new_invoc ( mac, ii. attrs , ii. span , ExpansionKind :: ImplItems ) ;
447
- expand_mac_invoc ( invoc, fld) . make_impl_items ( )
491
+ let invoc = fld. new_bang_invoc ( mac, ii. attrs , ii. span , ExpansionKind :: ImplItems ) ;
492
+ expand_invoc ( invoc, fld) . make_impl_items ( )
448
493
}
449
494
_ => fold:: noop_fold_impl_item ( ii, fld)
450
495
}
@@ -454,8 +499,8 @@ fn expand_trait_item(ti: ast::TraitItem, fld: &mut MacroExpander)
454
499
-> SmallVector < ast:: TraitItem > {
455
500
match ti. node {
456
501
ast:: TraitItemKind :: Macro ( mac) => {
457
- let invoc = fld. new_invoc ( mac, ti. attrs , ti. span , ExpansionKind :: TraitItems ) ;
458
- expand_mac_invoc ( invoc, fld) . make_trait_items ( )
502
+ let invoc = fld. new_bang_invoc ( mac, ti. attrs , ti. span , ExpansionKind :: TraitItems ) ;
503
+ expand_invoc ( invoc, fld) . make_trait_items ( )
459
504
}
460
505
_ => fold:: noop_fold_trait_item ( ti, fld)
461
506
}
@@ -469,8 +514,8 @@ pub fn expand_type(t: P<ast::Ty>, fld: &mut MacroExpander) -> P<ast::Ty> {
469
514
470
515
match t. node {
471
516
ast:: TyKind :: Mac ( mac) => {
472
- let invoc = fld. new_invoc ( mac, Vec :: new ( ) , t. span , ExpansionKind :: Ty ) ;
473
- expand_mac_invoc ( invoc, fld) . make_ty ( )
517
+ let invoc = fld. new_bang_invoc ( mac, Vec :: new ( ) , t. span , ExpansionKind :: Ty ) ;
518
+ expand_invoc ( invoc, fld) . make_ty ( )
474
519
}
475
520
_ => unreachable ! ( ) ,
476
521
}
@@ -542,10 +587,20 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
542
587
} ) ;
543
588
}
544
589
545
- fn new_invoc ( & self , mac : ast :: Mac , attrs : Vec < ast :: Attribute > , span : Span , kind : ExpansionKind )
590
+ fn new_invoc ( & self , expansion_kind : ExpansionKind , kind : InvocationKind )
546
591
-> Invocation {
547
- let mark = Mark :: fresh ( ) ;
548
- Invocation { span : span, attrs : attrs, mac : mac, mark : mark, kind : kind, ident : None }
592
+ Invocation { mark : Mark :: fresh ( ) , kind : kind, expansion_kind : expansion_kind }
593
+ }
594
+
595
+ fn new_bang_invoc (
596
+ & self , mac : ast:: Mac , attrs : Vec < ast:: Attribute > , span : Span , kind : ExpansionKind ,
597
+ ) -> Invocation {
598
+ self . new_invoc ( kind, InvocationKind :: Bang {
599
+ attrs : attrs,
600
+ mac : mac,
601
+ ident : None ,
602
+ span : span,
603
+ } )
549
604
}
550
605
551
606
fn with_exts_frame < T , F : FnOnce ( & mut Self ) -> T > ( & mut self , macros_escape : bool , f : F ) -> T {
@@ -573,8 +628,8 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
573
628
expr. and_then ( |expr| match expr. node {
574
629
ast:: ExprKind :: Mac ( mac) => {
575
630
let invoc =
576
- self . new_invoc ( mac, expr. attrs . into ( ) , expr. span , ExpansionKind :: OptExpr ) ;
577
- expand_mac_invoc ( invoc, self ) . make_opt_expr ( )
631
+ self . new_bang_invoc ( mac, expr. attrs . into ( ) , expr. span , ExpansionKind :: OptExpr ) ;
632
+ expand_invoc ( invoc, self ) . make_opt_expr ( )
578
633
}
579
634
_ => Some ( expand_expr ( expr, self ) ) ,
580
635
} )
@@ -624,13 +679,11 @@ impl<'a, 'b> Folder for MacroExpander<'a, 'b> {
624
679
}
625
680
626
681
fn fold_trait_item ( & mut self , i : ast:: TraitItem ) -> SmallVector < ast:: TraitItem > {
627
- expand_annotatable ( Annotatable :: TraitItem ( P ( i) ) , self )
628
- . into_iter ( ) . map ( |i| i. expect_trait_item ( ) ) . collect ( )
682
+ expand_annotatable ( Annotatable :: TraitItem ( P ( i) ) , self ) . make_trait_items ( )
629
683
}
630
684
631
685
fn fold_impl_item ( & mut self , i : ast:: ImplItem ) -> SmallVector < ast:: ImplItem > {
632
- expand_annotatable ( Annotatable :: ImplItem ( P ( i) ) , self )
633
- . into_iter ( ) . map ( |i| i. expect_impl_item ( ) ) . collect ( )
686
+ expand_annotatable ( Annotatable :: ImplItem ( P ( i) ) , self ) . make_impl_items ( )
634
687
}
635
688
636
689
fn fold_ty ( & mut self , ty : P < ast:: Ty > ) -> P < ast:: Ty > {
0 commit comments