@@ -21,6 +21,8 @@ use rustc_macros::HashStable_Generic;
2121use rustc_span:: { Span , DUMMY_SP } ;
2222use smallvec:: { smallvec, SmallVec } ;
2323
24+ use log:: debug;
25+
2426use std:: { iter, mem} ;
2527
2628/// When the main rust parser encounters a syntax-extension invocation, it
@@ -358,14 +360,47 @@ impl TokenStream {
358360 // leading to some tokens being 'glued' together in one stream but not
359361 // the other. See #68489 for more details.
360362 fn break_tokens ( tree : TokenTree ) -> impl Iterator < Item = TokenTree > {
363+ // In almost all cases, we should have either zero or one levels
364+ // of 'unglueing'. However, in some unusual cases, we may need
365+ // to iterate breaking tokens mutliple times. For example:
366+ // '[BinOpEq(Shr)] => [Gt, Ge] -> [Gt, Gt, Eq]'
367+ let mut token_trees: SmallVec < [ _ ; 2 ] > ;
361368 if let TokenTree :: Token ( token) = & tree {
362- if let Some ( ( first, second) ) = token. kind . break_two_token_op ( ) {
363- return SmallVec :: from_buf ( [ TokenTree :: Token ( Token :: new ( first, DUMMY_SP ) ) , TokenTree :: Token ( Token :: new ( second, DUMMY_SP ) ) ] ) . into_iter ( )
369+ let mut out = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
370+ out. push ( token. clone ( ) ) ;
371+ // Iterate to fixpoint:
372+ // * We start off with 'out' containing our initial token, and `temp` empty
373+ // * If we are able to break any tokens in `out`, then `out` will have
374+ // at least one more element than 'temp', so we will try to break tokens
375+ // again.
376+ // * If we cannot break any tokens in 'out', we are done
377+ loop {
378+ let mut temp = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
379+ let mut changed = false ;
380+
381+ for token in out. into_iter ( ) {
382+ if let Some ( ( first, second) ) = token. kind . break_two_token_op ( ) {
383+ temp. push ( Token :: new ( first, DUMMY_SP ) ) ;
384+ temp. push ( Token :: new ( second, DUMMY_SP ) ) ;
385+ changed = true ;
386+ } else {
387+ temp. push ( token) ;
388+ }
389+ }
390+ out = temp;
391+ if !changed {
392+ break ;
393+ }
394+ }
395+ token_trees = out. into_iter ( ) . map ( |t| TokenTree :: Token ( t) ) . collect ( ) ;
396+ if token_trees. len ( ) != 1 {
397+ debug ! ( "break_tokens: broke {:?} to {:?}" , tree, token_trees) ;
364398 }
399+ } else {
400+ token_trees = SmallVec :: new ( ) ;
401+ token_trees. push ( tree) ;
365402 }
366- let mut vec = SmallVec :: < [ _ ; 2 ] > :: new ( ) ;
367- vec. push ( tree) ;
368- vec. into_iter ( )
403+ token_trees. into_iter ( )
369404 }
370405
371406 let mut t1 = self . trees ( ) . filter ( semantic_tree) . flat_map ( break_tokens) ;
0 commit comments