8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- pub use self :: SyntaxExtension :: { MultiDecorator , MultiModifier , NormalTT , IdentTT , MacroRulesTT } ;
11
+ pub use self :: SyntaxExtension :: { MultiDecorator , MultiModifier , NormalTT , IdentTT } ;
12
12
13
13
use ast:: { self , Attribute , Name , PatKind } ;
14
14
use attr:: HasAttrs ;
@@ -18,6 +18,7 @@ use errors::DiagnosticBuilder;
18
18
use ext:: expand:: { self , Invocation , Expansion } ;
19
19
use ext:: hygiene:: Mark ;
20
20
use ext:: tt:: macro_rules;
21
+ use fold;
21
22
use parse;
22
23
use parse:: parser:: { self , Parser } ;
23
24
use parse:: token;
@@ -61,14 +62,6 @@ impl HasAttrs for Annotatable {
61
62
}
62
63
63
64
impl Annotatable {
64
- pub fn span ( & self ) -> Span {
65
- match * self {
66
- Annotatable :: Item ( ref item) => item. span ,
67
- Annotatable :: TraitItem ( ref trait_item) => trait_item. span ,
68
- Annotatable :: ImplItem ( ref impl_item) => impl_item. span ,
69
- }
70
- }
71
-
72
65
pub fn expect_item ( self ) -> P < ast:: Item > {
73
66
match self {
74
67
Annotatable :: Item ( i) => i,
@@ -160,21 +153,19 @@ pub trait ProcMacro {
160
153
ecx : & ' cx mut ExtCtxt ,
161
154
span : Span ,
162
155
ts : TokenStream )
163
- -> Box < MacResult + ' cx > ;
156
+ -> TokenStream ;
164
157
}
165
158
166
159
impl < F > ProcMacro for F
167
160
where F : Fn ( TokenStream ) -> TokenStream
168
161
{
169
162
fn expand < ' cx > ( & self ,
170
- ecx : & ' cx mut ExtCtxt ,
171
- span : Span ,
163
+ _ecx : & ' cx mut ExtCtxt ,
164
+ _span : Span ,
172
165
ts : TokenStream )
173
- -> Box < MacResult +' cx > {
174
- let result = ( * self ) ( ts) ;
166
+ -> TokenStream {
175
167
// FIXME setup implicit context in TLS before calling self.
176
- let parser = ecx. new_parser_from_tts ( & result. to_tts ( ) ) ;
177
- Box :: new ( TokResult { parser : parser, span : span } )
168
+ ( * self ) ( ts)
178
169
}
179
170
}
180
171
@@ -184,50 +175,63 @@ pub trait AttrProcMacro {
184
175
span : Span ,
185
176
annotation : TokenStream ,
186
177
annotated : TokenStream )
187
- -> Box < MacResult + ' cx > ;
178
+ -> TokenStream ;
188
179
}
189
180
190
181
impl < F > AttrProcMacro for F
191
182
where F : Fn ( TokenStream , TokenStream ) -> TokenStream
192
183
{
193
184
fn expand < ' cx > ( & self ,
194
- ecx : & ' cx mut ExtCtxt ,
195
- span : Span ,
185
+ _ecx : & ' cx mut ExtCtxt ,
186
+ _span : Span ,
196
187
annotation : TokenStream ,
197
188
annotated : TokenStream )
198
- -> Box < MacResult + ' cx > {
189
+ -> TokenStream {
199
190
// FIXME setup implicit context in TLS before calling self.
200
- let parser = ecx. new_parser_from_tts ( & ( * self ) ( annotation, annotated) . to_tts ( ) ) ;
201
- Box :: new ( TokResult { parser : parser, span : span } )
191
+ ( * self ) ( annotation, annotated)
202
192
}
203
193
}
204
194
205
- struct TokResult < ' a > {
206
- parser : Parser < ' a > ,
207
- span : Span ,
195
+ pub struct TokResult < ' a > {
196
+ pub parser : Parser < ' a > ,
197
+ pub span : Span ,
198
+ }
199
+
200
+ impl < ' a > TokResult < ' a > {
201
+ // There is quite a lot of overlap here with ParserAnyMacro in ext/tt/macro_rules.rs
202
+ // We could probably share more code.
203
+ // FIXME(#36641) Unify TokResult and ParserAnyMacro.
204
+ fn ensure_complete_parse ( & mut self , allow_semi : bool ) {
205
+ let macro_span = & self . span ;
206
+ self . parser . ensure_complete_parse ( allow_semi, |parser| {
207
+ let token_str = parser. this_token_to_string ( ) ;
208
+ let msg = format ! ( "macro expansion ignores token `{}` and any following" , token_str) ;
209
+ let span = parser. span ;
210
+ parser. diagnostic ( )
211
+ . struct_span_err ( span, & msg)
212
+ . span_note ( * macro_span, "caused by the macro expansion here" )
213
+ . emit ( ) ;
214
+ } ) ;
215
+ }
208
216
}
209
217
210
218
impl < ' a > MacResult for TokResult < ' a > {
211
219
fn make_items ( mut self : Box < Self > ) -> Option < SmallVector < P < ast:: Item > > > {
212
220
if self . parser . sess . span_diagnostic . has_errors ( ) {
213
- return None ;
221
+ return Some ( SmallVector :: zero ( ) ) ;
214
222
}
215
223
216
224
let mut items = SmallVector :: zero ( ) ;
217
225
loop {
218
226
match self . parser . parse_item ( ) {
219
- Ok ( Some ( item) ) => {
220
- // FIXME better span info.
221
- let mut item = item. unwrap ( ) ;
222
- item. span = self . span ;
223
- items. push ( P ( item) ) ;
224
- }
227
+ Ok ( Some ( item) ) => items. push ( item) ,
225
228
Ok ( None ) => {
229
+ self . ensure_complete_parse ( false ) ;
226
230
return Some ( items) ;
227
231
}
228
232
Err ( mut e) => {
229
233
e. emit ( ) ;
230
- return None ;
234
+ return Some ( SmallVector :: zero ( ) ) ;
231
235
}
232
236
}
233
237
}
@@ -236,57 +240,61 @@ impl<'a> MacResult for TokResult<'a> {
236
240
fn make_impl_items ( mut self : Box < Self > ) -> Option < SmallVector < ast:: ImplItem > > {
237
241
let mut items = SmallVector :: zero ( ) ;
238
242
loop {
243
+ if self . parser . token == token:: Eof {
244
+ break ;
245
+ }
239
246
match self . parser . parse_impl_item ( ) {
240
- Ok ( mut item) => {
241
- // FIXME better span info.
242
- item. span = self . span ;
243
- items. push ( item) ;
244
-
245
- return Some ( items) ;
246
- }
247
+ Ok ( item) => items. push ( item) ,
247
248
Err ( mut e) => {
248
249
e. emit ( ) ;
249
- return None ;
250
+ return Some ( SmallVector :: zero ( ) ) ;
250
251
}
251
252
}
252
253
}
254
+ self . ensure_complete_parse ( false ) ;
255
+ Some ( items)
253
256
}
254
257
255
258
fn make_trait_items ( mut self : Box < Self > ) -> Option < SmallVector < ast:: TraitItem > > {
256
259
let mut items = SmallVector :: zero ( ) ;
257
260
loop {
261
+ if self . parser . token == token:: Eof {
262
+ break ;
263
+ }
258
264
match self . parser . parse_trait_item ( ) {
259
- Ok ( mut item) => {
260
- // FIXME better span info.
261
- item. span = self . span ;
262
- items. push ( item) ;
263
-
264
- return Some ( items) ;
265
- }
265
+ Ok ( item) => items. push ( item) ,
266
266
Err ( mut e) => {
267
267
e. emit ( ) ;
268
- return None ;
268
+ return Some ( SmallVector :: zero ( ) ) ;
269
269
}
270
270
}
271
271
}
272
+ self . ensure_complete_parse ( false ) ;
273
+ Some ( items)
272
274
}
273
275
274
276
fn make_expr ( mut self : Box < Self > ) -> Option < P < ast:: Expr > > {
275
277
match self . parser . parse_expr ( ) {
276
- Ok ( e) => Some ( e) ,
278
+ Ok ( e) => {
279
+ self . ensure_complete_parse ( true ) ;
280
+ Some ( e)
281
+ }
277
282
Err ( mut e) => {
278
283
e. emit ( ) ;
279
- return None ;
284
+ Some ( DummyResult :: raw_expr ( self . span ) )
280
285
}
281
286
}
282
287
}
283
288
284
289
fn make_pat ( mut self : Box < Self > ) -> Option < P < ast:: Pat > > {
285
290
match self . parser . parse_pat ( ) {
286
- Ok ( e) => Some ( e) ,
291
+ Ok ( e) => {
292
+ self . ensure_complete_parse ( false ) ;
293
+ Some ( e)
294
+ }
287
295
Err ( mut e) => {
288
296
e. emit ( ) ;
289
- return None ;
297
+ Some ( P ( DummyResult :: raw_pat ( self . span ) ) )
290
298
}
291
299
}
292
300
}
@@ -295,28 +303,30 @@ impl<'a> MacResult for TokResult<'a> {
295
303
let mut stmts = SmallVector :: zero ( ) ;
296
304
loop {
297
305
if self . parser . token == token:: Eof {
298
- return Some ( stmts ) ;
306
+ break ;
299
307
}
300
- match self . parser . parse_full_stmt ( true ) {
301
- Ok ( Some ( mut stmt) ) => {
302
- stmt. span = self . span ;
303
- stmts. push ( stmt) ;
304
- }
308
+ match self . parser . parse_full_stmt ( false ) {
309
+ Ok ( Some ( stmt) ) => stmts. push ( stmt) ,
305
310
Ok ( None ) => { /* continue */ }
306
311
Err ( mut e) => {
307
312
e. emit ( ) ;
308
- return None ;
313
+ return Some ( SmallVector :: zero ( ) ) ;
309
314
}
310
315
}
311
316
}
317
+ self . ensure_complete_parse ( false ) ;
318
+ Some ( stmts)
312
319
}
313
320
314
321
fn make_ty ( mut self : Box < Self > ) -> Option < P < ast:: Ty > > {
315
322
match self . parser . parse_ty ( ) {
316
- Ok ( e) => Some ( e) ,
323
+ Ok ( e) => {
324
+ self . ensure_complete_parse ( false ) ;
325
+ Some ( e)
326
+ }
317
327
Err ( mut e) => {
318
328
e. emit ( ) ;
319
- return None ;
329
+ Some ( DummyResult :: raw_ty ( self . span ) )
320
330
}
321
331
}
322
332
}
@@ -1004,3 +1014,17 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
1004
1014
}
1005
1015
Some ( es)
1006
1016
}
1017
+
1018
+ pub struct ChangeSpan {
1019
+ pub span : Span
1020
+ }
1021
+
1022
+ impl Folder for ChangeSpan {
1023
+ fn new_span ( & mut self , _sp : Span ) -> Span {
1024
+ self . span
1025
+ }
1026
+
1027
+ fn fold_mac ( & mut self , mac : ast:: Mac ) -> ast:: Mac {
1028
+ fold:: noop_fold_mac ( mac, self )
1029
+ }
1030
+ }
0 commit comments