@@ -400,7 +400,8 @@ fn push_fragment(buf: &mut Vec<tt::TokenTree>, fragment: Fragment) {
400400 }
401401 buf. push ( tt. into ( ) )
402402 }
403- Fragment :: Tokens ( tt) | Fragment :: Expr ( tt) => buf. push ( tt) ,
403+ Fragment :: Path ( tt:: TokenTree :: Subtree ( tt) ) => fix_up_and_push_path_tt ( buf, tt) ,
404+ Fragment :: Tokens ( tt) | Fragment :: Expr ( tt) | Fragment :: Path ( tt) => buf. push ( tt) ,
404405 }
405406}
406407
@@ -411,6 +412,45 @@ fn push_subtree(buf: &mut Vec<tt::TokenTree>, tt: tt::Subtree) {
411412 }
412413}
413414
415+ /// Inserts the path separator `::` between an identifier and its following generic
416+ /// argument list, and then pushes into the buffer. See [`Fragment::Path`] for why
417+ /// we need this fixup.
418+ fn fix_up_and_push_path_tt ( buf : & mut Vec < tt:: TokenTree > , subtree : tt:: Subtree ) {
419+ stdx:: always!( matches!( subtree. delimiter. kind, tt:: DelimiterKind :: Invisible ) ) ;
420+ let mut prev_was_ident = false ;
421+ // Note that we only need to fix up the top-level `TokenTree`s because the
422+ // context of the paths in the descendant `Subtree`s won't be changed by the
423+ // mbe transcription.
424+ for tt in subtree. token_trees {
425+ if prev_was_ident {
426+ // Pedantically, `(T) -> U` in `FnOnce(T) -> U` is treated as a generic
427+ // argument list and thus needs `::` between it and `FnOnce`. However in
428+ // today's Rust this type of path *semantically* cannot appear as a
429+ // top-level expression-context path, so we can safely ignore it.
430+ if let tt:: TokenTree :: Leaf ( tt:: Leaf :: Punct ( tt:: Punct { char : '<' , .. } ) ) = tt {
431+ buf. push (
432+ tt:: Leaf :: Punct ( tt:: Punct {
433+ char : ':' ,
434+ spacing : tt:: Spacing :: Joint ,
435+ span : tt:: Span :: unspecified ( ) ,
436+ } )
437+ . into ( ) ,
438+ ) ;
439+ buf. push (
440+ tt:: Leaf :: Punct ( tt:: Punct {
441+ char : ':' ,
442+ spacing : tt:: Spacing :: Alone ,
443+ span : tt:: Span :: unspecified ( ) ,
444+ } )
445+ . into ( ) ,
446+ ) ;
447+ }
448+ }
449+ prev_was_ident = matches ! ( tt, tt:: TokenTree :: Leaf ( tt:: Leaf :: Ident ( _) ) ) ;
450+ buf. push ( tt) ;
451+ }
452+ }
453+
414454/// Handles `${count(t, depth)}`. `our_depth` is the recursion depth and `count_depth` is the depth
415455/// defined by the metavar expression.
416456fn count (
0 commit comments