22
22
use syntax:: ast;
23
23
use syntax:: codemap:: BytePos ;
24
24
use syntax:: parse:: new_parser_from_tts;
25
+ use syntax:: parse:: parser:: Parser ;
25
26
use syntax:: parse:: token:: Token ;
26
27
use syntax:: symbol;
27
28
use syntax:: tokenstream:: TokenStream ;
@@ -61,6 +62,51 @@ impl MacroStyle {
61
62
}
62
63
}
63
64
65
+ pub enum MacroArg {
66
+ Expr ( ast:: Expr ) ,
67
+ Ty ( ast:: Ty ) ,
68
+ Pat ( ast:: Pat ) ,
69
+ }
70
+
71
+ impl Rewrite for MacroArg {
72
+ fn rewrite ( & self , context : & RewriteContext , shape : Shape ) -> Option < String > {
73
+ match self {
74
+ & MacroArg :: Expr ( ref expr) => expr. rewrite ( context, shape) ,
75
+ & MacroArg :: Ty ( ref ty) => ty. rewrite ( context, shape) ,
76
+ & MacroArg :: Pat ( ref pat) => pat. rewrite ( context, shape) ,
77
+ }
78
+ }
79
+ }
80
+
81
+ fn parse_macro_arg ( parser : & mut Parser ) -> Option < MacroArg > {
82
+ macro_rules! parse_macro_arg {
83
+ ( $target: tt, $macro_arg: ident, $parser: ident) => {
84
+ let mut cloned_parser = ( * parser) . clone( ) ;
85
+ match cloned_parser. $parser( ) {
86
+ Ok ( $target) => {
87
+ if parser. sess. span_diagnostic. has_errors( ) {
88
+ parser. sess. span_diagnostic. reset_err_count( ) ;
89
+ } else {
90
+ // Parsing succeeded.
91
+ * parser = cloned_parser;
92
+ return Some ( MacroArg :: $macro_arg( ( * $target) . clone( ) ) ) ;
93
+ }
94
+ }
95
+ Err ( mut e) => {
96
+ e. cancel( ) ;
97
+ parser. sess. span_diagnostic. reset_err_count( ) ;
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ parse_macro_arg ! ( expr, Expr , parse_expr) ;
104
+ parse_macro_arg ! ( ty, Ty , parse_ty) ;
105
+ parse_macro_arg ! ( pat, Pat , parse_pat) ;
106
+
107
+ return None ;
108
+ }
109
+
64
110
pub fn rewrite_macro (
65
111
mac : & ast:: Mac ,
66
112
extra_ident : Option < ast:: Ident > ,
@@ -93,7 +139,7 @@ pub fn rewrite_macro(
93
139
original_style
94
140
} ;
95
141
96
- let ts: TokenStream = mac. node . tts . clone ( ) . into ( ) ;
142
+ let ts: TokenStream = mac. node . stream ( ) ;
97
143
if ts. is_empty ( ) && !contains_comment ( & context. snippet ( mac. span ) ) {
98
144
return match style {
99
145
MacroStyle :: Parens if position == MacroPosition :: Item => {
@@ -106,32 +152,16 @@ pub fn rewrite_macro(
106
152
}
107
153
108
154
let mut parser = new_parser_from_tts ( context. parse_session , ts. trees ( ) . collect ( ) ) ;
109
- let mut expr_vec = Vec :: new ( ) ;
155
+ let mut arg_vec = Vec :: new ( ) ;
110
156
let mut vec_with_semi = false ;
111
157
let mut trailing_comma = false ;
112
158
113
159
if MacroStyle :: Braces != style {
114
160
loop {
115
- let expr = match parser. parse_expr ( ) {
116
- Ok ( expr) => {
117
- // Recovered errors.
118
- if context. parse_session . span_diagnostic . has_errors ( ) {
119
- return indent_macro_snippet (
120
- context,
121
- & context. snippet ( mac. span ) ,
122
- shape. indent ,
123
- ) ;
124
- }
125
-
126
- expr
127
- }
128
- Err ( mut e) => {
129
- e. cancel ( ) ;
130
- return indent_macro_snippet ( context, & context. snippet ( mac. span ) , shape. indent ) ;
131
- }
132
- } ;
133
-
134
- expr_vec. push ( expr) ;
161
+ match parse_macro_arg ( & mut parser) {
162
+ Some ( arg) => arg_vec. push ( arg) ,
163
+ None => return Some ( context. snippet ( mac. span ) ) ,
164
+ }
135
165
136
166
match parser. token {
137
167
Token :: Eof => break ,
@@ -141,25 +171,22 @@ pub fn rewrite_macro(
141
171
if FORCED_BRACKET_MACROS . contains ( & & macro_name[ ..] ) {
142
172
parser. bump ( ) ;
143
173
if parser. token != Token :: Eof {
144
- match parser. parse_expr ( ) {
145
- Ok ( expr) => {
146
- if context. parse_session . span_diagnostic . has_errors ( ) {
147
- return None ;
148
- }
149
- expr_vec. push ( expr) ;
174
+ match parse_macro_arg ( & mut parser) {
175
+ Some ( arg) => {
176
+ arg_vec. push ( arg) ;
150
177
parser. bump ( ) ;
151
- if parser. token == Token :: Eof && expr_vec . len ( ) == 2 {
178
+ if parser. token == Token :: Eof && arg_vec . len ( ) == 2 {
152
179
vec_with_semi = true ;
153
180
break ;
154
181
}
155
182
}
156
- Err ( mut e ) => e . cancel ( ) ,
183
+ None => return Some ( context . snippet ( mac . span ) ) ,
157
184
}
158
185
}
159
186
}
160
- return None ;
187
+ return Some ( context . snippet ( mac . span ) ) ;
161
188
}
162
- _ => return None ,
189
+ _ => return Some ( context . snippet ( mac . span ) ) ,
163
190
}
164
191
165
192
parser. bump ( ) ;
@@ -178,7 +205,7 @@ pub fn rewrite_macro(
178
205
let rw = rewrite_call_inner (
179
206
context,
180
207
& macro_name,
181
- & expr_vec . iter ( ) . map ( |e| & * * e) . collect :: < Vec < _ > > ( ) [ ..] ,
208
+ & arg_vec . iter ( ) . map ( |e| & * e) . collect :: < Vec < _ > > ( ) [ ..] ,
182
209
mac. span ,
183
210
shape,
184
211
context. config . fn_call_width ( ) ,
@@ -201,8 +228,8 @@ pub fn rewrite_macro(
201
228
// 6 = `vec!` + `; `
202
229
let total_overhead = lbr. len ( ) + rbr. len ( ) + 6 ;
203
230
let nested_shape = mac_shape. block_indent ( context. config . tab_spaces ( ) ) ;
204
- let lhs = try_opt ! ( expr_vec [ 0 ] . rewrite( context, nested_shape) ) ;
205
- let rhs = try_opt ! ( expr_vec [ 1 ] . rewrite( context, nested_shape) ) ;
231
+ let lhs = try_opt ! ( arg_vec [ 0 ] . rewrite( context, nested_shape) ) ;
232
+ let rhs = try_opt ! ( arg_vec [ 1 ] . rewrite( context, nested_shape) ) ;
206
233
if !lhs. contains ( '\n' ) && !rhs. contains ( '\n' ) &&
207
234
lhs. len ( ) + rhs. len ( ) + total_overhead <= shape. width
208
235
{
@@ -228,14 +255,26 @@ pub fn rewrite_macro(
228
255
context. inside_macro = false ;
229
256
trailing_comma = false ;
230
257
}
258
+ // Convert `MacroArg` into `ast::Expr`, as `rewrite_array` only accepts the latter.
259
+ let expr_vec: Vec < _ > = arg_vec
260
+ . iter ( )
261
+ . filter_map ( |e| match * e {
262
+ MacroArg :: Expr ( ref e) => Some ( e. clone ( ) ) ,
263
+ _ => None ,
264
+ } )
265
+ . collect ( ) ;
266
+ if expr_vec. len ( ) != arg_vec. len ( ) {
267
+ return Some ( context. snippet ( mac. span ) ) ;
268
+ }
269
+ let sp = mk_sp (
270
+ context
271
+ . codemap
272
+ . span_after ( mac. span , original_style. opener ( ) ) ,
273
+ mac. span . hi ( ) - BytePos ( 1 ) ,
274
+ ) ;
231
275
let rewrite = try_opt ! ( rewrite_array(
232
- expr_vec. iter( ) . map( |x| & * * x) ,
233
- mk_sp(
234
- context
235
- . codemap
236
- . span_after( mac. span, original_style. opener( ) ) ,
237
- mac. span. hi( ) - BytePos ( 1 ) ,
238
- ) ,
276
+ expr_vec. iter( ) ,
277
+ sp,
239
278
context,
240
279
mac_shape,
241
280
trailing_comma,
0 commit comments