@@ -1706,50 +1706,18 @@ impl<'a> Parser<'a> {
17061706        // Parse any number of segments and bound sets. A segment is an 
17071707        // identifier followed by an optional lifetime and a set of types. 
17081708        // A bound set is a set of type parameter bounds. 
1709-         let  mut  segments = Vec :: new ( ) ; 
1710-         loop  { 
1711-             // First, parse an identifier. 
1712-             let  identifier = self . parse_ident ( ) ; 
1713- 
1714-             // Parse the '::' before type parameters if it's required. If 
1715-             // it is required and wasn't present, then we're done. 
1716-             if  mode == LifetimeAndTypesWithColons  &&
1717-                     !self . eat ( & token:: ModSep )  { 
1718-                 segments. push ( ast:: PathSegment  { 
1719-                     identifier :  identifier, 
1720-                     lifetimes :  Vec :: new ( ) , 
1721-                     types :  OwnedSlice :: empty ( ) , 
1722-                 } ) ; 
1723-                 break 
1709+         let  segments = match  mode { 
1710+             LifetimeAndTypesWithoutColons  |
1711+             LifetimeAndTypesAndBounds  => { 
1712+                 self . parse_path_segments_without_colons ( ) 
17241713            } 
1725- 
1726-             // Parse the `<` before the lifetime and types, if applicable. 
1727-             let  ( any_lifetime_or_types,  lifetimes,  types)  = { 
1728-                 if  mode != NoTypesAllowed  && self . eat_lt ( false )  { 
1729-                     let  ( lifetimes,  types)  =
1730-                         self . parse_generic_values_after_lt ( ) ; 
1731-                     ( true ,  lifetimes,  OwnedSlice :: from_vec ( types) ) 
1732-                 }  else  { 
1733-                     ( false ,  Vec :: new ( ) ,  OwnedSlice :: empty ( ) ) 
1734-                 } 
1735-             } ; 
1736- 
1737-             // Assemble and push the result. 
1738-             segments. push ( ast:: PathSegment  { 
1739-                 identifier :  identifier, 
1740-                 lifetimes :  lifetimes, 
1741-                 types :  types, 
1742-             } ) ; 
1743- 
1744-             // We're done if we don't see a '::', unless the mode required 
1745-             // a double colon to get here in the first place. 
1746-             if  !( mode == LifetimeAndTypesWithColons  &&
1747-                     !any_lifetime_or_types)  { 
1748-                 if  !self . eat ( & token:: ModSep )  { 
1749-                     break 
1750-                 } 
1714+             LifetimeAndTypesWithColons  => { 
1715+                 self . parse_path_segments_with_colons ( ) 
17511716            } 
1752-         } 
1717+             NoTypesAllowed  => { 
1718+                 self . parse_path_segments_without_types ( ) 
1719+             } 
1720+         } ; 
17531721
17541722        // Next, parse a plus and bounded type parameters, if 
17551723        // applicable. We need to remember whether the separate was 
@@ -1792,6 +1760,104 @@ impl<'a> Parser<'a> {
17921760        } 
17931761    } 
17941762
1763+     /// Examples: 
1764+ /// - `a::b<T,U>::c<V,W>` 
1765+ /// - `a::b<T,U>::c(V) -> W` 
1766+ /// - `a::b<T,U>::c(V)` 
1767+ pub  fn  parse_path_segments_without_colons ( & mut  self )  -> Vec < ast:: PathSegment >  { 
1768+         let  mut  segments = Vec :: new ( ) ; 
1769+         loop  { 
1770+             // First, parse an identifier. 
1771+             let  identifier = self . parse_ident ( ) ; 
1772+ 
1773+             // Parse types, optionally. 
1774+             let  ( lifetimes,  types)  = if  self . eat_lt ( false )  { 
1775+                 self . parse_generic_values_after_lt ( ) 
1776+             }  else  if  false  && self . eat ( & token:: LParen )  { 
1777+                 let  mut  types = self . parse_seq_to_end ( 
1778+                     & token:: RParen , 
1779+                     seq_sep_trailing_allowed ( token:: Comma ) , 
1780+                     |p| p. parse_ty ( true ) ) ; 
1781+ 
1782+                 if  self . eat ( & token:: RArrow )  { 
1783+                     types. push ( self . parse_ty ( true ) ) 
1784+                 } 
1785+ 
1786+                 ( Vec :: new ( ) ,  types) 
1787+             }  else  { 
1788+                 ( Vec :: new ( ) ,  Vec :: new ( ) ) 
1789+             } ; 
1790+ 
1791+             // Assemble and push the result. 
1792+             segments. push ( ast:: PathSegment  {  identifier :  identifier, 
1793+                                              lifetimes :  lifetimes, 
1794+                                              types :  OwnedSlice :: from_vec ( types) ,  } ) ; 
1795+ 
1796+             // Continue only if we see a `::` 
1797+             if  !self . eat ( & token:: ModSep )  { 
1798+                 return  segments; 
1799+             } 
1800+         } 
1801+     } 
1802+ 
1803+     /// Examples: 
1804+ /// - `a::b::<T,U>::c` 
1805+ pub  fn  parse_path_segments_with_colons ( & mut  self )  -> Vec < ast:: PathSegment >  { 
1806+         let  mut  segments = Vec :: new ( ) ; 
1807+         loop  { 
1808+             // First, parse an identifier. 
1809+             let  identifier = self . parse_ident ( ) ; 
1810+ 
1811+             // If we do not see a `::`, stop. 
1812+             if  !self . eat ( & token:: ModSep )  { 
1813+                 segments. push ( ast:: PathSegment  {  identifier :  identifier, 
1814+                                                  lifetimes :  Vec :: new ( ) , 
1815+                                                  types :  OwnedSlice :: empty ( )  } ) ; 
1816+                 return  segments; 
1817+             } 
1818+ 
1819+             // Check for a type segment. 
1820+             if  self . eat_lt ( false )  { 
1821+                 // Consumed `a::b::<`, go look for types 
1822+                 let  ( lifetimes,  types)  = self . parse_generic_values_after_lt ( ) ; 
1823+                 segments. push ( ast:: PathSegment  {  identifier :  identifier, 
1824+                                                  lifetimes :  lifetimes, 
1825+                                                  types :  OwnedSlice :: from_vec ( types)  } ) ; 
1826+ 
1827+                 // Consumed `a::b::<T,U>`, check for `::` before proceeding 
1828+                 if  !self . eat ( & token:: ModSep )  { 
1829+                     return  segments; 
1830+                 } 
1831+             }  else  { 
1832+                 // Consumed `a::`, go look for `b` 
1833+                 segments. push ( ast:: PathSegment  {  identifier :  identifier, 
1834+                                                  lifetimes :  Vec :: new ( ) , 
1835+                                                  types :  OwnedSlice :: empty ( )  } ) ; 
1836+             } 
1837+         } 
1838+     } 
1839+ 
1840+ 
1841+     /// Examples: 
1842+ /// - `a::b::c` 
1843+ pub  fn  parse_path_segments_without_types ( & mut  self )  -> Vec < ast:: PathSegment >  { 
1844+         let  mut  segments = Vec :: new ( ) ; 
1845+         loop  { 
1846+             // First, parse an identifier. 
1847+             let  identifier = self . parse_ident ( ) ; 
1848+ 
1849+             // Assemble and push the result. 
1850+             segments. push ( ast:: PathSegment  {  identifier :  identifier, 
1851+                                              lifetimes :  Vec :: new ( ) , 
1852+                                              types :  OwnedSlice :: empty ( ) ,  } ) ; 
1853+ 
1854+             // If we do not see a `::`, stop. 
1855+             if  !self . eat ( & token:: ModSep )  { 
1856+                 return  segments; 
1857+             } 
1858+         } 
1859+     } 
1860+ 
17951861    /// parses 0 or 1 lifetime 
17961862pub  fn  parse_opt_lifetime ( & mut  self )  -> Option < ast:: Lifetime >  { 
17971863        match  self . token  { 
0 commit comments