@@ -288,8 +288,8 @@ struct TokenCursorFrame {
288288/// on the parser.
289289#[ derive( Clone ) ]
290290enum LastToken {
291- Collecting ( Vec < TokenTree > ) ,
292- Was ( Option < TokenTree > ) ,
291+ Collecting ( Vec < TokenStream > ) ,
292+ Was ( Option < TokenStream > ) ,
293293}
294294
295295impl TokenCursorFrame {
@@ -326,8 +326,8 @@ impl TokenCursor {
326326 } ;
327327
328328 match self . frame . last_token {
329- LastToken :: Collecting ( ref mut v) => v. push ( tree. clone ( ) ) ,
330- LastToken :: Was ( ref mut t) => * t = Some ( tree. clone ( ) ) ,
329+ LastToken :: Collecting ( ref mut v) => v. push ( tree. clone ( ) . into ( ) ) ,
330+ LastToken :: Was ( ref mut t) => * t = Some ( tree. clone ( ) . into ( ) ) ,
331331 }
332332
333333 match tree {
@@ -6723,11 +6723,49 @@ impl<'a> Parser<'a> {
67236723 }
67246724 }
67256725
6726+ fn parse_item_ (
6727+ & mut self ,
6728+ attrs : Vec < Attribute > ,
6729+ macros_allowed : bool ,
6730+ attributes_allowed : bool ,
6731+ ) -> PResult < ' a , Option < P < Item > > > {
6732+ let ( ret, tokens) = self . collect_tokens ( |this| {
6733+ this. parse_item_implementation ( attrs, macros_allowed, attributes_allowed)
6734+ } ) ?;
6735+
6736+ // Once we've parsed an item and recorded the tokens we got while
6737+ // parsing we may want to store `tokens` into the item we're about to
6738+ // return. Note, though, that we specifically didn't capture tokens
6739+ // related to outer attributes. The `tokens` field here may later be
6740+ // used with procedural macros to convert this item back into a token
6741+ // stream, but during expansion we may be removing attributes as we go
6742+ // along.
6743+ //
6744+ // If we've got inner attributes then the `tokens` we've got above holds
6745+ // these inner attributes. If an inner attribute is expanded we won't
6746+ // actually remove it from the token stream, so we'll just keep yielding
6747+ // it (bad!). To work around this case for now we just avoid recording
6748+ // `tokens` if we detect any inner attributes. This should help keep
6749+ // expansion correct, but we should fix this bug one day!
6750+ Ok ( ret. map ( |item| {
6751+ item. map ( |mut i| {
6752+ if !i. attrs . iter ( ) . any ( |attr| attr. style == AttrStyle :: Inner ) {
6753+ i. tokens = Some ( tokens) ;
6754+ }
6755+ i
6756+ } )
6757+ } ) )
6758+ }
6759+
67266760 /// Parse one of the items allowed by the flags.
67276761 /// NB: this function no longer parses the items inside an
67286762 /// extern crate.
6729- fn parse_item_ ( & mut self , attrs : Vec < Attribute > ,
6730- macros_allowed : bool , attributes_allowed : bool ) -> PResult < ' a , Option < P < Item > > > {
6763+ fn parse_item_implementation (
6764+ & mut self ,
6765+ attrs : Vec < Attribute > ,
6766+ macros_allowed : bool ,
6767+ attributes_allowed : bool ,
6768+ ) -> PResult < ' a , Option < P < Item > > > {
67316769 maybe_whole ! ( self , NtItem , |item| {
67326770 let mut item = item. into_inner( ) ;
67336771 let mut attrs = attrs;
@@ -7260,12 +7298,15 @@ impl<'a> Parser<'a> {
72607298 {
72617299 // Record all tokens we parse when parsing this item.
72627300 let mut tokens = Vec :: new ( ) ;
7263- match self . token_cursor . frame . last_token {
7264- LastToken :: Collecting ( _ ) => {
7265- panic ! ( "cannot collect tokens recursively yet" )
7301+ let prev_collecting = match self . token_cursor . frame . last_token {
7302+ LastToken :: Collecting ( ref mut list ) => {
7303+ Some ( mem :: replace ( list , Vec :: new ( ) ) )
72667304 }
7267- LastToken :: Was ( ref mut last) => tokens. extend ( last. take ( ) ) ,
7268- }
7305+ LastToken :: Was ( ref mut last) => {
7306+ tokens. extend ( last. take ( ) ) ;
7307+ None
7308+ }
7309+ } ;
72697310 self . token_cursor . frame . last_token = LastToken :: Collecting ( tokens) ;
72707311 let prev = self . token_cursor . stack . len ( ) ;
72717312 let ret = f ( self ) ;
@@ -7274,52 +7315,44 @@ impl<'a> Parser<'a> {
72747315 } else {
72757316 & mut self . token_cursor . stack [ prev] . last_token
72767317 } ;
7277- let mut tokens = match * last_token {
7318+
7319+ // Pull our the toekns that we've collected from the call to `f` above
7320+ let mut collected_tokens = match * last_token {
72787321 LastToken :: Collecting ( ref mut v) => mem:: replace ( v, Vec :: new ( ) ) ,
72797322 LastToken :: Was ( _) => panic ! ( "our vector went away?" ) ,
72807323 } ;
72817324
72827325 // If we're not at EOF our current token wasn't actually consumed by
72837326 // `f`, but it'll still be in our list that we pulled out. In that case
72847327 // put it back.
7285- if self . token = = token:: Eof {
7286- * last_token = LastToken :: Was ( None ) ;
7328+ let extra_token = if self . token ! = token:: Eof {
7329+ collected_tokens . pop ( )
72877330 } else {
7288- * last_token = LastToken :: Was ( tokens. pop ( ) ) ;
7331+ None
7332+ } ;
7333+
7334+ // If we were previously collecting tokens, then this was a recursive
7335+ // call. In that case we need to record all the tokens we collected in
7336+ // our parent list as well. To do that we push a clone of our stream
7337+ // onto the previous list.
7338+ let stream = collected_tokens. into_iter ( ) . collect :: < TokenStream > ( ) ;
7339+ match prev_collecting {
7340+ Some ( mut list) => {
7341+ list. push ( stream. clone ( ) ) ;
7342+ list. extend ( extra_token) ;
7343+ * last_token = LastToken :: Collecting ( list) ;
7344+ }
7345+ None => {
7346+ * last_token = LastToken :: Was ( extra_token) ;
7347+ }
72897348 }
72907349
7291- Ok ( ( ret?, tokens . into_iter ( ) . collect ( ) ) )
7350+ Ok ( ( ret?, stream ) )
72927351 }
72937352
72947353 pub fn parse_item ( & mut self ) -> PResult < ' a , Option < P < Item > > > {
72957354 let attrs = self . parse_outer_attributes ( ) ?;
7296-
7297- let ( ret, tokens) = self . collect_tokens ( |this| {
7298- this. parse_item_ ( attrs, true , false )
7299- } ) ?;
7300-
7301- // Once we've parsed an item and recorded the tokens we got while
7302- // parsing we may want to store `tokens` into the item we're about to
7303- // return. Note, though, that we specifically didn't capture tokens
7304- // related to outer attributes. The `tokens` field here may later be
7305- // used with procedural macros to convert this item back into a token
7306- // stream, but during expansion we may be removing attributes as we go
7307- // along.
7308- //
7309- // If we've got inner attributes then the `tokens` we've got above holds
7310- // these inner attributes. If an inner attribute is expanded we won't
7311- // actually remove it from the token stream, so we'll just keep yielding
7312- // it (bad!). To work around this case for now we just avoid recording
7313- // `tokens` if we detect any inner attributes. This should help keep
7314- // expansion correct, but we should fix this bug one day!
7315- Ok ( ret. map ( |item| {
7316- item. map ( |mut i| {
7317- if !i. attrs . iter ( ) . any ( |attr| attr. style == AttrStyle :: Inner ) {
7318- i. tokens = Some ( tokens) ;
7319- }
7320- i
7321- } )
7322- } ) )
7355+ self . parse_item_ ( attrs, true , false )
73237356 }
73247357
73257358 /// `::{` or `::*`
0 commit comments