88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- pub use self :: SyntaxExtension :: { MultiDecorator , MultiModifier , NormalTT , IdentTT , MacroRulesTT } ;
11+ pub use self :: SyntaxExtension :: { MultiDecorator , MultiModifier , NormalTT , IdentTT } ;
1212
1313use ast:: { self , Attribute , Name , PatKind } ;
1414use attr:: HasAttrs ;
@@ -18,6 +18,7 @@ use errors::DiagnosticBuilder;
1818use ext:: expand:: { self , Invocation , Expansion } ;
1919use ext:: hygiene:: Mark ;
2020use ext:: tt:: macro_rules;
21+ use fold;
2122use parse;
2223use parse:: parser:: { self , Parser } ;
2324use parse:: token;
@@ -61,14 +62,6 @@ impl HasAttrs for Annotatable {
6162}
6263
6364impl 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-
7265 pub fn expect_item ( self ) -> P < ast:: Item > {
7366 match self {
7467 Annotatable :: Item ( i) => i,
@@ -160,21 +153,19 @@ pub trait ProcMacro {
160153 ecx : & ' cx mut ExtCtxt ,
161154 span : Span ,
162155 ts : TokenStream )
163- -> Box < MacResult + ' cx > ;
156+ -> TokenStream ;
164157}
165158
166159impl < F > ProcMacro for F
167160 where F : Fn ( TokenStream ) -> TokenStream
168161{
169162 fn expand < ' cx > ( & self ,
170- ecx : & ' cx mut ExtCtxt ,
171- span : Span ,
163+ _ecx : & ' cx mut ExtCtxt ,
164+ _span : Span ,
172165 ts : TokenStream )
173- -> Box < MacResult +' cx > {
174- let result = ( * self ) ( ts) ;
166+ -> TokenStream {
175167 // 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)
178169 }
179170}
180171
@@ -184,50 +175,63 @@ pub trait AttrProcMacro {
184175 span : Span ,
185176 annotation : TokenStream ,
186177 annotated : TokenStream )
187- -> Box < MacResult + ' cx > ;
178+ -> TokenStream ;
188179}
189180
190181impl < F > AttrProcMacro for F
191182 where F : Fn ( TokenStream , TokenStream ) -> TokenStream
192183{
193184 fn expand < ' cx > ( & self ,
194- ecx : & ' cx mut ExtCtxt ,
195- span : Span ,
185+ _ecx : & ' cx mut ExtCtxt ,
186+ _span : Span ,
196187 annotation : TokenStream ,
197188 annotated : TokenStream )
198- -> Box < MacResult + ' cx > {
189+ -> TokenStream {
199190 // 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)
202192 }
203193}
204194
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+ }
208216}
209217
210218impl < ' a > MacResult for TokResult < ' a > {
211219 fn make_items ( mut self : Box < Self > ) -> Option < SmallVector < P < ast:: Item > > > {
212220 if self . parser . sess . span_diagnostic . has_errors ( ) {
213- return None ;
221+ return Some ( SmallVector :: zero ( ) ) ;
214222 }
215223
216224 let mut items = SmallVector :: zero ( ) ;
217225 loop {
218226 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) ,
225228 Ok ( None ) => {
229+ self . ensure_complete_parse ( false ) ;
226230 return Some ( items) ;
227231 }
228232 Err ( mut e) => {
229233 e. emit ( ) ;
230- return None ;
234+ return Some ( SmallVector :: zero ( ) ) ;
231235 }
232236 }
233237 }
@@ -236,57 +240,61 @@ impl<'a> MacResult for TokResult<'a> {
236240 fn make_impl_items ( mut self : Box < Self > ) -> Option < SmallVector < ast:: ImplItem > > {
237241 let mut items = SmallVector :: zero ( ) ;
238242 loop {
243+ if self . parser . token == token:: Eof {
244+ break ;
245+ }
239246 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) ,
247248 Err ( mut e) => {
248249 e. emit ( ) ;
249- return None ;
250+ return Some ( SmallVector :: zero ( ) ) ;
250251 }
251252 }
252253 }
254+ self . ensure_complete_parse ( false ) ;
255+ Some ( items)
253256 }
254257
255258 fn make_trait_items ( mut self : Box < Self > ) -> Option < SmallVector < ast:: TraitItem > > {
256259 let mut items = SmallVector :: zero ( ) ;
257260 loop {
261+ if self . parser . token == token:: Eof {
262+ break ;
263+ }
258264 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) ,
266266 Err ( mut e) => {
267267 e. emit ( ) ;
268- return None ;
268+ return Some ( SmallVector :: zero ( ) ) ;
269269 }
270270 }
271271 }
272+ self . ensure_complete_parse ( false ) ;
273+ Some ( items)
272274 }
273275
274276 fn make_expr ( mut self : Box < Self > ) -> Option < P < ast:: Expr > > {
275277 match self . parser . parse_expr ( ) {
276- Ok ( e) => Some ( e) ,
278+ Ok ( e) => {
279+ self . ensure_complete_parse ( true ) ;
280+ Some ( e)
281+ }
277282 Err ( mut e) => {
278283 e. emit ( ) ;
279- return None ;
284+ Some ( DummyResult :: raw_expr ( self . span ) )
280285 }
281286 }
282287 }
283288
284289 fn make_pat ( mut self : Box < Self > ) -> Option < P < ast:: Pat > > {
285290 match self . parser . parse_pat ( ) {
286- Ok ( e) => Some ( e) ,
291+ Ok ( e) => {
292+ self . ensure_complete_parse ( false ) ;
293+ Some ( e)
294+ }
287295 Err ( mut e) => {
288296 e. emit ( ) ;
289- return None ;
297+ Some ( P ( DummyResult :: raw_pat ( self . span ) ) )
290298 }
291299 }
292300 }
@@ -295,28 +303,30 @@ impl<'a> MacResult for TokResult<'a> {
295303 let mut stmts = SmallVector :: zero ( ) ;
296304 loop {
297305 if self . parser . token == token:: Eof {
298- return Some ( stmts ) ;
306+ break ;
299307 }
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) ,
305310 Ok ( None ) => { /* continue */ }
306311 Err ( mut e) => {
307312 e. emit ( ) ;
308- return None ;
313+ return Some ( SmallVector :: zero ( ) ) ;
309314 }
310315 }
311316 }
317+ self . ensure_complete_parse ( false ) ;
318+ Some ( stmts)
312319 }
313320
314321 fn make_ty ( mut self : Box < Self > ) -> Option < P < ast:: Ty > > {
315322 match self . parser . parse_ty ( ) {
316- Ok ( e) => Some ( e) ,
323+ Ok ( e) => {
324+ self . ensure_complete_parse ( false ) ;
325+ Some ( e)
326+ }
317327 Err ( mut e) => {
318328 e. emit ( ) ;
319- return None ;
329+ Some ( DummyResult :: raw_ty ( self . span ) )
320330 }
321331 }
322332 }
@@ -1004,3 +1014,17 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt,
10041014 }
10051015 Some ( es)
10061016}
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