@@ -66,7 +66,11 @@ impl TokenIterExt for TokenIter {
6666
6767 while let Some ( tree) = self . peek ( ) {
6868 match tree {
69- TokenTree :: Punct ( punct) if punct. as_char ( ) == ',' && nesting == 0 => break ,
69+ TokenTree :: Punct ( punct)
70+ if [ ',' , ';' ] . contains ( & punct. as_char ( ) ) && nesting == 0 =>
71+ {
72+ break
73+ }
7074 TokenTree :: Punct ( punct) => {
7175 let ch = punct. as_char ( ) ;
7276
@@ -84,7 +88,43 @@ impl TokenIterExt for TokenIter {
8488 span. get_or_insert_with ( || ident. span ( ) ) ;
8589 path. push_str ( & ident. to_string ( ) ) ;
8690 }
87- _ => return Err ( spanned_error ( "Unexpected token" , self . next ( ) . as_span ( ) ) ) ,
91+ TokenTree :: Group ( group) => {
92+ span. get_or_insert ( group. span ( ) ) ;
93+ let mut stream = group. stream ( ) . into_token_iter ( ) ;
94+
95+ match group. delimiter ( ) {
96+ Delimiter :: Parenthesis => {
97+ // Tuples are comma-separated paths.
98+ path. push ( '(' ) ;
99+ while stream. peek ( ) . is_some ( ) {
100+ let ( inner, _span) = stream. parse_path ( ) ?;
101+ path. push_str ( & inner) ;
102+ if stream. peek ( ) . is_some ( ) {
103+ stream. expect_punct ( ',' ) ?;
104+ path. push_str ( ", " ) ;
105+ }
106+ }
107+ if path. ends_with ( ' ' ) {
108+ path. pop ( ) ;
109+ }
110+ path. push ( ')' ) ;
111+ }
112+ Delimiter :: Bracket => {
113+ // Arrays are in `[path; size]` form.
114+ path. push ( '[' ) ;
115+ let ( inner, _span) = stream. parse_path ( ) ?;
116+ path. push_str ( & inner) ;
117+ stream. expect_punct ( ';' ) ?;
118+ path. push_str ( "; " ) ;
119+ path. push_str ( & stream. try_lit ( ) ?. to_string ( ) ) ;
120+ path. push ( ']' ) ;
121+ }
122+ _ => return Err ( spanned_error ( "Unexpected token" , group. span ( ) ) ) ,
123+ }
124+ }
125+ TokenTree :: Literal ( _) => {
126+ return Err ( spanned_error ( "Unexpected token" , self . next ( ) . as_span ( ) ) )
127+ }
88128 }
89129
90130 self . next ( ) ;
@@ -192,6 +232,44 @@ mod tests {
192232 use super :: * ;
193233 use std:: str:: FromStr ;
194234
235+ #[ test]
236+ fn test_tokeniter_parse_path ( ) {
237+ let mut input = TokenStream :: from_str ( "foo::bar" ) . unwrap ( ) . into_token_iter ( ) ;
238+ assert_eq ! ( input. parse_path( ) . unwrap( ) . 0 , "foo::bar" ) ;
239+ assert ! ( input. next( ) . is_none( ) ) ;
240+
241+ let mut input = TokenStream :: from_str ( "foo::bar<baz>" )
242+ . unwrap ( )
243+ . into_token_iter ( ) ;
244+ assert_eq ! ( input. parse_path( ) . unwrap( ) . 0 , "foo::bar<baz>" ) ;
245+ assert ! ( input. next( ) . is_none( ) ) ;
246+
247+ let mut input = TokenStream :: from_str ( "foo::bar<()>" )
248+ . unwrap ( )
249+ . into_token_iter ( ) ;
250+ assert_eq ! ( input. parse_path( ) . unwrap( ) . 0 , "foo::bar<()>" ) ;
251+ assert ! ( input. next( ) . is_none( ) ) ;
252+
253+ let mut input = TokenStream :: from_str ( "foo::bar<(foo, bar::baz<T>)>" )
254+ . unwrap ( )
255+ . into_token_iter ( ) ;
256+ assert_eq ! (
257+ input. parse_path( ) . unwrap( ) . 0 ,
258+ "foo::bar<(foo, bar::baz<T>)>"
259+ ) ;
260+ assert ! ( input. next( ) . is_none( ) ) ;
261+
262+ let mut input = TokenStream :: from_str ( "foo<(bar, [i32; 4])>" )
263+ . unwrap ( )
264+ . into_token_iter ( ) ;
265+ assert_eq ! ( input. parse_path( ) . unwrap( ) . 0 , "foo<(bar, [i32; 4])>" ) ;
266+ assert ! ( input. next( ) . is_none( ) ) ;
267+
268+ let mut input = TokenStream :: from_str ( "(u8, )" ) . unwrap ( ) . into_token_iter ( ) ;
269+ assert_eq ! ( input. parse_path( ) . unwrap( ) . 0 , "(u8,)" ) ;
270+ assert ! ( input. next( ) . is_none( ) ) ;
271+ }
272+
195273 #[ test]
196274 fn test_tokeniter_expect_group ( ) {
197275 let mut input = TokenStream :: from_str ( "{ foo }" ) . unwrap ( ) . into_token_iter ( ) ;
0 commit comments