@@ -41,30 +41,41 @@ use std::rc::Rc;
41
41
use std:: path:: PathBuf ;
42
42
43
43
macro_rules! ast_fragments {
44
- ( $( $kind: ident: $ty: ty [ $( $vec: ident, $ty_elt: ty) * ] , $kind_name: expr, . $make: ident,
45
- $( . $fold: ident) * $( lift . $fold_elt: ident) * ,
46
- $( . $visit: ident) * $( lift . $visit_elt: ident) * ; ) * ) => {
44
+ (
45
+ $( $Kind: ident( $AstTy: ty) {
46
+ $kind_name: expr;
47
+ $( one fn $fold_ast: ident; fn $visit_ast: ident; ) ?
48
+ $( many fn $fold_ast_elt: ident; fn $visit_ast_elt: ident; ) ?
49
+ fn $make_ast: ident;
50
+ } ) *
51
+ ) => {
47
52
/// A fragment of AST that can be produced by a single macro expansion.
48
53
/// Can also serve as an input and intermediate result for macro expansion operations.
49
- pub enum AstFragment { OptExpr ( Option <P <ast:: Expr >>) , $( $kind( $ty) , ) * }
54
+ pub enum AstFragment {
55
+ OptExpr ( Option <P <ast:: Expr >>) ,
56
+ $( $Kind( $AstTy) , ) *
57
+ }
50
58
51
59
/// "Discriminant" of an AST fragment.
52
60
#[ derive( Copy , Clone , PartialEq , Eq ) ]
53
- pub enum AstFragmentKind { OptExpr , $( $kind, ) * }
61
+ pub enum AstFragmentKind {
62
+ OptExpr ,
63
+ $( $Kind, ) *
64
+ }
54
65
55
66
impl AstFragmentKind {
56
67
pub fn name( self ) -> & ' static str {
57
68
match self {
58
69
AstFragmentKind :: OptExpr => "expression" ,
59
- $( AstFragmentKind :: $kind => $kind_name, ) *
70
+ $( AstFragmentKind :: $Kind => $kind_name, ) *
60
71
}
61
72
}
62
73
63
74
fn make_from<' a>( self , result: Box <MacResult + ' a>) -> Option <AstFragment > {
64
75
match self {
65
76
AstFragmentKind :: OptExpr =>
66
77
result. make_expr( ) . map( Some ) . map( AstFragment :: OptExpr ) ,
67
- $( AstFragmentKind :: $kind => result. $make ( ) . map( AstFragment :: $kind ) , ) *
78
+ $( AstFragmentKind :: $Kind => result. $make_ast ( ) . map( AstFragment :: $Kind ) , ) *
68
79
}
69
80
}
70
81
}
@@ -76,70 +87,75 @@ macro_rules! ast_fragments {
76
87
_ => panic!( "AstFragment::make_* called on the wrong kind of fragment" ) ,
77
88
}
78
89
}
79
- $( pub fn $make( self ) -> $ty {
90
+
91
+ $( pub fn $make_ast( self ) -> $AstTy {
80
92
match self {
81
- AstFragment :: $kind ( ast) => ast,
93
+ AstFragment :: $Kind ( ast) => ast,
82
94
_ => panic!( "AstFragment::make_* called on the wrong kind of fragment" ) ,
83
95
}
84
- } ) *
96
+ } ) *
85
97
86
98
pub fn fold_with<F : Folder >( self , folder: & mut F ) -> Self {
87
- use self :: AstFragment :: * ;
88
99
match self {
89
- OptExpr ( expr) => OptExpr ( expr. and_then( |expr| folder. fold_opt_expr( expr) ) ) ,
90
- $( $( $kind( ast) => $kind( folder. $fold( ast) ) , ) * ) *
91
- $( $( $kind( ast) => {
92
- $kind( ast. into_iter( ) . flat_map( |ast| folder. $fold_elt( ast) ) . collect( ) )
93
- } , ) * ) *
100
+ AstFragment :: OptExpr ( expr) =>
101
+ AstFragment :: OptExpr ( expr. and_then( |expr| folder. fold_opt_expr( expr) ) ) ,
102
+ $( $( AstFragment :: $Kind( ast) =>
103
+ AstFragment :: $Kind( folder. $fold_ast( ast) ) , ) ?) *
104
+ $( $( AstFragment :: $Kind( ast) =>
105
+ AstFragment :: $Kind( ast. into_iter( )
106
+ . flat_map( |ast| folder. $fold_ast_elt( ast) )
107
+ . collect( ) ) , ) ?) *
94
108
}
95
109
}
96
110
97
111
pub fn visit_with<' a, V : Visitor <' a>>( & ' a self , visitor: & mut V ) {
98
112
match * self {
99
113
AstFragment :: OptExpr ( Some ( ref expr) ) => visitor. visit_expr( expr) ,
100
114
AstFragment :: OptExpr ( None ) => { }
101
- $( $( AstFragment :: $kind ( ref ast) => visitor. $visit ( ast) , ) * ) *
102
- $( $( AstFragment :: $kind ( ref ast) => for ast in & ast[ ..] {
103
- visitor. $visit_elt ( ast ) ;
104
- } , ) * ) *
115
+ $( $( AstFragment :: $Kind ( ref ast) => visitor. $visit_ast ( ast) , ) ? ) *
116
+ $( $( AstFragment :: $Kind ( ref ast) => for ast_elt in & ast[ ..] {
117
+ visitor. $visit_ast_elt ( ast_elt ) ;
118
+ } ) ? ) *
105
119
}
106
120
}
107
121
}
108
122
109
123
impl <' a, ' b> Folder for MacroExpander <' a, ' b> {
110
124
fn fold_opt_expr( & mut self , expr: P <ast:: Expr >) -> Option <P <ast:: Expr >> {
111
- self . expand ( AstFragment :: OptExpr ( Some ( expr) ) ) . make_opt_expr( )
125
+ self . expand_fragment ( AstFragment :: OptExpr ( Some ( expr) ) ) . make_opt_expr( )
112
126
}
113
- $( $( fn $fold ( & mut self , node : $ty ) -> $ty {
114
- self . expand ( AstFragment :: $kind ( node ) ) . $make ( )
115
- } ) * ) *
116
- $( $( fn $fold_elt ( & mut self , node : $ty_elt ) -> $ty {
117
- self . expand ( AstFragment :: $kind ( SmallVector :: one( node ) ) ) . $make ( )
118
- } ) * ) *
127
+ $( $( fn $fold_ast ( & mut self , ast : $AstTy ) -> $AstTy {
128
+ self . expand_fragment ( AstFragment :: $Kind ( ast ) ) . $make_ast ( )
129
+ } ) ? ) *
130
+ $( $( fn $fold_ast_elt ( & mut self , ast_elt : <$AstTy as IntoIterator > :: Item ) -> $AstTy {
131
+ self . expand_fragment ( AstFragment :: $Kind ( SmallVector :: one( ast_elt ) ) ) . $make_ast ( )
132
+ } ) ? ) *
119
133
}
120
134
121
135
impl <' a> MacResult for :: ext:: tt:: macro_rules:: ParserAnyMacro <' a> {
122
- $( fn $make( self : Box <:: ext:: tt:: macro_rules:: ParserAnyMacro <' a>>) -> Option <$ty> {
123
- Some ( self . make( AstFragmentKind :: $kind) . $make( ) )
136
+ $( fn $make_ast( self : Box <:: ext:: tt:: macro_rules:: ParserAnyMacro <' a>>)
137
+ -> Option <$AstTy> {
138
+ Some ( self . make( AstFragmentKind :: $Kind) . $make_ast( ) )
124
139
} ) *
125
140
}
126
141
}
127
142
}
128
143
129
144
ast_fragments ! {
130
- Expr : P <ast:: Expr > [ ] , "expression" , . make_expr, . fold_expr, . visit_expr;
131
- Pat : P <ast:: Pat > [ ] , "pattern" , . make_pat, . fold_pat, . visit_pat;
132
- Ty : P <ast:: Ty > [ ] , "type" , . make_ty, . fold_ty, . visit_ty;
133
- Stmts : SmallVector <ast:: Stmt > [ SmallVector , ast:: Stmt ] ,
134
- "statement" , . make_stmts, lift . fold_stmt, lift . visit_stmt;
135
- Items : SmallVector <P <ast:: Item >> [ SmallVector , P <ast:: Item >] ,
136
- "item" , . make_items, lift . fold_item, lift . visit_item;
137
- TraitItems : SmallVector <ast:: TraitItem > [ SmallVector , ast:: TraitItem ] ,
138
- "trait item" , . make_trait_items, lift . fold_trait_item, lift . visit_trait_item;
139
- ImplItems : SmallVector <ast:: ImplItem > [ SmallVector , ast:: ImplItem ] ,
140
- "impl item" , . make_impl_items, lift . fold_impl_item, lift . visit_impl_item;
141
- ForeignItems : SmallVector <ast:: ForeignItem > [ SmallVector , ast:: ForeignItem ] ,
142
- "foreign item" , . make_foreign_items, lift . fold_foreign_item, lift . visit_foreign_item;
145
+ Expr ( P <ast:: Expr >) { "expression" ; one fn fold_expr; fn visit_expr; fn make_expr; }
146
+ Pat ( P <ast:: Pat >) { "pattern" ; one fn fold_pat; fn visit_pat; fn make_pat; }
147
+ Ty ( P <ast:: Ty >) { "type" ; one fn fold_ty; fn visit_ty; fn make_ty; }
148
+ Stmts ( SmallVector <ast:: Stmt >) { "statement" ; many fn fold_stmt; fn visit_stmt; fn make_stmts; }
149
+ Items ( SmallVector <P <ast:: Item >>) { "item" ; many fn fold_item; fn visit_item; fn make_items; }
150
+ TraitItems ( SmallVector <ast:: TraitItem >) {
151
+ "trait item" ; many fn fold_trait_item; fn visit_trait_item; fn make_trait_items;
152
+ }
153
+ ImplItems ( SmallVector <ast:: ImplItem >) {
154
+ "impl item" ; many fn fold_impl_item; fn visit_impl_item; fn make_impl_items;
155
+ }
156
+ ForeignItems ( SmallVector <ast:: ForeignItem >) {
157
+ "foreign item" ; many fn fold_foreign_item; fn visit_foreign_item; fn make_foreign_items;
158
+ }
143
159
}
144
160
145
161
impl AstFragmentKind {
@@ -261,7 +277,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
261
277
tokens : None ,
262
278
} ) ) ) ;
263
279
264
- match self . expand ( krate_item) . make_items ( ) . pop ( ) . map ( P :: into_inner) {
280
+ match self . expand_fragment ( krate_item) . make_items ( ) . pop ( ) . map ( P :: into_inner) {
265
281
Some ( ast:: Item { attrs, node : ast:: ItemKind :: Mod ( module) , .. } ) => {
266
282
krate. attrs = attrs;
267
283
krate. module = module;
@@ -281,7 +297,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
281
297
}
282
298
283
299
// Fully expand all macro invocations in this AST fragment.
284
- fn expand ( & mut self , input_fragment : AstFragment ) -> AstFragment {
300
+ fn expand_fragment ( & mut self , input_fragment : AstFragment ) -> AstFragment {
285
301
let orig_expansion_data = self . cx . current_expansion . clone ( ) ;
286
302
self . cx . current_expansion . depth = 0 ;
287
303
0 commit comments